1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -*- mode:
2 // C++ -*-
3 //
4 // Copyright (C) 2013-2022 Red Hat, Inc.
5 //
6 //Author: Dodji Seketeli
7
8 /// @file
9 ///
10 /// Definitions for the Internal Representation artifacts of libabigail.
11
12 #include <cxxabi.h>
13 #include <algorithm>
14 #include <cstdint>
15 #include <functional>
16 #include <iterator>
17 #include <memory>
18 #include <sstream>
19 #include <typeinfo>
20 #include <unordered_map>
21 #include <utility>
22 #include <vector>
23
24 #include "abg-internal.h"
25 // <headers defining libabigail's API go under here>
26 ABG_BEGIN_EXPORT_DECLARATIONS
27
28 #include "abg-interned-str.h"
29 #include "abg-ir.h"
30 #include "abg-corpus.h"
31
32 ABG_END_EXPORT_DECLARATIONS
33 // </headers defining libabigail's API>
34
35 #include "abg-corpus-priv.h"
36 #include "abg-tools-utils.h"
37 #include "abg-comp-filter.h"
38 #include "abg-ir-priv.h"
39
40 namespace
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().
45 class qualified_name_setter : public abigail::ir::ir_node_visitor
46 {
47
48 public:
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
61 namespace abigail
62 {
63
64 // Inject.
65 using std::string;
66 using std::list;
67 using std::vector;
68 using std::unordered_map;
69 using std::dynamic_pointer_cast;
70 using std::static_pointer_cast;
71
72 /// Convenience typedef for a map of string -> string*.
73 typedef unordered_map<string, string*> pool_map_type;
74
75 /// The type of the private data structure of type @ref
76 /// intered_string_pool.
77 struct interned_string_pool::priv
78 {
79 pool_map_type map;
80 }; //end struc struct interned_string_pool::priv
81
82 /// Default constructor.
interned_string_pool()83 interned_string_pool::interned_string_pool()
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.
95 bool
has_string(const char * s) const96 interned_string_pool::has_string(const char* s) const
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.
105 const char*
get_string(const char * s) const106 interned_string_pool::get_string(const char* s) const
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.
122 interned_string
create_string(const std::string & str_value)123 interned_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.
~interned_string_pool()132 interned_string_pool::~interned_string_pool()
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.
150 bool
operator ==(const std::string & l,const interned_string & r)151 operator==(const std::string& l, const interned_string& r)
152 {return r.operator==(l);}
153
154 bool
operator !=(const std::string & l,const interned_string & r)155 operator!=(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.
167 std::ostream&
operator <<(std::ostream & o,const interned_string & s)168 operator<<(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.
184 std::string
operator +(const interned_string & s1,const std::string & s2)185 operator+(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.
198 std::string
operator +(const std::string & s1,const interned_string & s2)199 operator+(const std::string& s1, const interned_string& s2)
200 {return s1 + static_cast<std::string>(s2);}
201
202 namespace ir
203 {
204
205 static size_t
206 hash_as_canonical_type_or_constant(const type_base *t);
207
208 static bool
209 has_generic_anonymous_internal_type_name(const decl_base *d);
210
211 static interned_string
212 get_generic_anonymous_internal_type_name(const decl_base *d);
213
214 static string
215 get_internal_integral_type_name(const type_base*);
216
217 static void
218 update_qualified_name(decl_base * d);
219
220 static void
221 update_qualified_name(decl_base_sptr d);
222
223 void
224 push_composite_type_comparison_operands(const type_base& left,
225 const type_base& right);
226
227 void
228 pop_composite_type_comparison_operands(const type_base& left,
229 const type_base& right);
230
231 bool
232 mark_dependant_types_compared_until(const type_base &r);
233
234 /// Push a pair of operands on the stack of operands of the current
235 /// type comparison, during type canonicalization.
236 ///
237 /// For more information on this, please look at the description of
238 /// the environment::priv::right_type_comp_operands_ data member.
239 ///
240 /// @param left the left-hand-side comparison operand to push.
241 ///
242 /// @param right the right-hand-side comparison operand to push.
243 void
push_composite_type_comparison_operands(const type_base & left,const type_base & right)244 push_composite_type_comparison_operands(const type_base& left,
245 const type_base& right)
246 {
247 const environment& env = left.get_environment();
248 env.priv_->push_composite_type_comparison_operands(&left, &right);
249 }
250
251 /// Pop a pair of operands from the stack of operands to the current
252 /// type comparison.
253 ///
254 /// For more information on this, please look at the description of
255 /// the environment::privright_type_comp_operands_ data member.
256 ///
257 /// @param left the left-hand-side comparison operand we expect to
258 /// pop from the top of the stack. If this doesn't match the
259 /// operand found on the top of the stack, the function aborts.
260 ///
261 /// @param right the right-hand-side comparison operand we expect to
262 /// pop from the bottom of the stack. If this doesn't match the
263 /// operand found on the top of the stack, the function aborts.
264 void
pop_composite_type_comparison_operands(const type_base & left,const type_base & right)265 pop_composite_type_comparison_operands(const type_base& left,
266 const type_base& right)
267 {
268 const environment& env = left.get_environment();
269 env.priv_->pop_composite_type_comparison_operands(&left, &right);
270 }
271
272 /// In the stack of the current types being compared (as part of type
273 /// canonicalization), mark all the types that comes after a certain
274 /// one as NOT being eligible to the canonical type propagation
275 /// optimization.
276 ///
277 /// For a starter, please read about the @ref
278 /// OnTheFlyCanonicalization, aka, "canonical type propagation
279 /// optimization".
280 ///
281 /// To implement that optimization, we need, among other things to
282 /// maintain stack of the types (and their sub-types) being
283 /// currently compared as part of type canonicalization.
284 ///
285 /// Note that we only consider the type that is the right-hand-side
286 /// operand of the comparison because it's that one that is being
287 /// canonicalized and thus, that is not yet canonicalized.
288 ///
289 /// The reason why a type is deemed NON-eligible to the canonical
290 /// type propagation optimization is that it "depends" on
291 /// recursively present type. Let me explain.
292 ///
293 /// Suppose we have a type T that has sub-types named ST0 and ST1.
294 /// Suppose ST1 itself has a sub-type that is T itself. In this
295 /// case, we say that T is a recursive type, because it has T
296 /// (itself) as one of its sub-types:
297 ///
298 /// T
299 /// +-- ST0
300 /// |
301 /// +-- ST1
302 /// +
303 /// |
304 /// +-- T
305 ///
306 /// ST1 is said to "depend" on T because it has T as a sub-type.
307 /// But because T is recursive, then ST1 is said to depend on a
308 /// recursive type. Notice however that ST0 does not depend on any
309 /// recursive type.
310 ///
311 /// When we are at the point of comparing the sub-type T of ST1
312 /// against its counterpart, the stack of the right-hand-side
313 /// operands of the type canonicalization is going to look like
314 /// this:
315 ///
316 /// | T | ST1 |
317 ///
318 /// We don't add the type T to the stack as we detect that T was
319 /// already in there (recursive cycle).
320 ///
321 /// So, this function will basically mark ST1 as being NON-eligible
322 /// to being the target of canonical type propagation, by marking ST1
323 /// as being dependant on T.
324 ///
325 /// @param right the right-hand-side operand of the type comparison.
326 ///
327 /// @return true iff the operation was successful.
328 bool
mark_dependant_types_compared_until(const type_base & r)329 mark_dependant_types_compared_until(const type_base &r)
330 {
331 const environment& env = r.get_environment();
332 if (env.do_on_the_fly_canonicalization())
333 return env.priv_->mark_dependant_types_compared_until(&r);
334 return false;
335 }
336
337 /// @brief the location of a token represented in its simplest form.
338 /// Instances of this type are to be stored in a sorted vector, so the
339 /// type must have proper relational operators.
340 class expanded_location
341 {
342 string path_;
343 unsigned line_;
344 unsigned column_;
345
346 expanded_location();
347
348 public:
349
350 friend class location_manager;
351
expanded_location(const string & path,unsigned line,unsigned column)352 expanded_location(const string& path, unsigned line, unsigned column)
353 : path_(path), line_(line), column_(column)
354 {}
355
356 bool
operator ==(const expanded_location & l) const357 operator==(const expanded_location& l) const
358 {
359 return (path_ == l.path_
360 && line_ == l.line_
361 && column_ && l.column_);
362 }
363
364 bool
operator <(const expanded_location & l) const365 operator<(const expanded_location& l) const
366 {
367 if (path_ < l.path_)
368 return true;
369 else if (path_ > l.path_)
370 return false;
371
372 if (line_ < l.line_)
373 return true;
374 else if (line_ > l.line_)
375 return false;
376
377 return column_ < l.column_;
378 }
379 };
380
381 /// Expand the location into a tripplet path, line and column number.
382 ///
383 /// @param path the output parameter where this function sets the
384 /// expanded path.
385 ///
386 /// @param line the output parameter where this function sets the
387 /// expanded line.
388 ///
389 /// @param column the ouptut parameter where this function sets the
390 /// expanded column.
391 void
expand(std::string & path,unsigned & line,unsigned & column) const392 location::expand(std::string& path, unsigned& line, unsigned& column) const
393 {
394 if (!get_location_manager())
395 {
396 // We don't have a location manager maybe because this location
397 // was just freshly instanciated. We still want to be able to
398 // expand to default values.
399 path = "";
400 line = 0;
401 column = 0;
402 return;
403 }
404 get_location_manager()->expand_location(*this, path, line, column);
405 }
406
407
408 /// Expand the location into a string.
409 ///
410 /// @return the string representing the location.
411 string
expand(void) const412 location::expand(void) const
413 {
414 string path, result;
415 unsigned line = 0, column = 0;
416 expand(path, line, column);
417
418 std::ostringstream o;
419 o << path << ":" << line << ":" << column;
420 return o.str();
421 }
422
423 struct location_manager::priv
424 {
425 /// This sorted vector contains the expanded locations of the tokens
426 /// coming from a given ABI Corpus. The index of a given expanded
427 /// location in the table gives us an integer that is used to build
428 /// instance of location types.
429 std::vector<expanded_location> locs;
430 };
431
location_manager()432 location_manager::location_manager()
433 : priv_(new location_manager::priv)
434 {}
435
436 location_manager::~location_manager() = default;
437
438 /// Insert the triplet representing a source locus into our internal
439 /// vector of location triplet. Return an instance of location type,
440 /// built from an integral type that represents the index of the
441 /// source locus triplet into our source locus table.
442 ///
443 /// @param file_path the file path of the source locus
444 /// @param line the line number of the source location
445 /// @param col the column number of the source location
446 location
create_new_location(const std::string & file_path,size_t line,size_t col)447 location_manager::create_new_location(const std::string& file_path,
448 size_t line,
449 size_t col)
450 {
451 expanded_location l(file_path, line, col);
452
453 // Just append the new expanded location to the end of the vector
454 // and return its index. Note that indexes start at 1.
455 priv_->locs.push_back(l);
456 return location(priv_->locs.size(), this);
457 }
458
459 /// Given an instance of location type, return the triplet
460 /// {path,line,column} that represents the source locus. Note that
461 /// the location must have been previously created from the function
462 /// location_manager::create_new_location, otherwise this function yields
463 /// unexpected results, including possibly a crash.
464 ///
465 /// @param location the instance of location type to expand
466 /// @param path the resulting path of the source locus
467 /// @param line the resulting line of the source locus
468 /// @param column the resulting colum of the source locus
469 void
expand_location(const location & location,std::string & path,unsigned & line,unsigned & column) const470 location_manager::expand_location(const location& location,
471 std::string& path,
472 unsigned& line,
473 unsigned& column) const
474 {
475 if (location.value_ == 0)
476 return;
477 expanded_location &l = priv_->locs[location.value_ - 1];
478 path = l.path_;
479 line = l.line_;
480 column = l.column_;
481 }
482
483 typedef unordered_map<function_type_sptr,
484 bool,
485 function_type::hash,
486 type_shared_ptr_equal> fn_type_ptr_map;
487
488 // <type_maps stuff>
489
490 struct type_maps::priv
491 {
492 mutable istring_type_base_wptrs_map_type basic_types_;
493 mutable istring_type_base_wptrs_map_type class_types_;
494 mutable istring_type_base_wptrs_map_type union_types_;
495 mutable istring_type_base_wptrs_map_type enum_types_;
496 mutable istring_type_base_wptrs_map_type typedef_types_;
497 mutable istring_type_base_wptrs_map_type qualified_types_;
498 mutable istring_type_base_wptrs_map_type pointer_types_;
499 mutable istring_type_base_wptrs_map_type reference_types_;
500 mutable istring_type_base_wptrs_map_type array_types_;
501 mutable istring_type_base_wptrs_map_type subrange_types_;
502 mutable istring_type_base_wptrs_map_type function_types_;
503 mutable vector<type_base_wptr> sorted_types_;
504 }; // end struct type_maps::priv
505
type_maps()506 type_maps::type_maps()
507 : priv_(new priv)
508 {}
509
510 type_maps::~type_maps() = default;
511
512 /// Test if the type_maps is empty.
513 ///
514 /// @return true iff the type_maps is empty.
515 bool
empty() const516 type_maps::empty() const
517 {
518 return (basic_types().empty()
519 && class_types().empty()
520 && union_types().empty()
521 && enum_types().empty()
522 && typedef_types().empty()
523 && qualified_types().empty()
524 && pointer_types().empty()
525 && reference_types().empty()
526 && array_types().empty()
527 && subrange_types().empty()
528 && function_types().empty());
529 }
530
531 /// Getter for the map that associates the name of a basic type to the
532 /// vector instances of type_decl_sptr that represents that type.
533 const istring_type_base_wptrs_map_type&
basic_types() const534 type_maps::basic_types() const
535 {return priv_->basic_types_;}
536
537 /// Getter for the map that associates the name of a basic type to the
538 /// vector of instances of @ref type_decl_sptr that represents that
539 /// type.
540 istring_type_base_wptrs_map_type&
basic_types()541 type_maps::basic_types()
542 {return priv_->basic_types_;}
543
544 /// Getter for the map that associates the name of a class type to the
545 /// vector of instances of @ref class_decl_sptr that represents that
546 /// type.
547 const istring_type_base_wptrs_map_type&
class_types() const548 type_maps::class_types() const
549 {return priv_->class_types_;}
550
551 /// Getter for the map that associates the name of a class type to the
552 /// vector of instances of @ref class_decl_sptr that represents that
553 /// type.
554 istring_type_base_wptrs_map_type&
class_types()555 type_maps::class_types()
556 {return priv_->class_types_;}
557
558 /// Getter for the map that associates the name of a union type to the
559 /// vector of instances of @ref union_decl_sptr that represents that
560 /// type.
561 istring_type_base_wptrs_map_type&
union_types()562 type_maps::union_types()
563 {return priv_->union_types_;}
564
565 /// Getter for the map that associates the name of a union type to the
566 /// vector of instances of @ref union_decl_sptr that represents that
567 /// type.
568 const istring_type_base_wptrs_map_type&
union_types() const569 type_maps::union_types() const
570 {return priv_->union_types_;}
571
572 /// Getter for the map that associates the name of an enum type to the
573 /// vector of instances of @ref enum_type_decl_sptr that represents
574 /// that type.
575 istring_type_base_wptrs_map_type&
enum_types()576 type_maps::enum_types()
577 {return priv_->enum_types_;}
578
579 /// Getter for the map that associates the name of an enum type to the
580 /// vector of instances of @ref enum_type_decl_sptr that represents
581 /// that type.
582 const istring_type_base_wptrs_map_type&
enum_types() const583 type_maps::enum_types() const
584 {return priv_->enum_types_;}
585
586 /// Getter for the map that associates the name of a typedef to the
587 /// vector of instances of @ref typedef_decl_sptr that represents tha
588 /// type.
589 istring_type_base_wptrs_map_type&
typedef_types()590 type_maps::typedef_types()
591 {return priv_->typedef_types_;}
592
593 /// Getter for the map that associates the name of a typedef to the
594 /// vector of instances of @ref typedef_decl_sptr that represents tha
595 /// type.
596 const istring_type_base_wptrs_map_type&
typedef_types() const597 type_maps::typedef_types() const
598 {return priv_->typedef_types_;}
599
600 /// Getter for the map that associates the name of a qualified type to
601 /// the vector of instances of @ref qualified_type_def_sptr.
602 istring_type_base_wptrs_map_type&
qualified_types()603 type_maps::qualified_types()
604 {return priv_->qualified_types_;}
605
606 /// Getter for the map that associates the name of a qualified type to
607 /// the vector of instances of @ref qualified_type_def_sptr.
608 const istring_type_base_wptrs_map_type&
qualified_types() const609 type_maps::qualified_types() const
610 {return priv_->qualified_types_;}
611
612 /// Getter for the map that associates the name of a pointer type to
613 /// the vector of instances of @ref pointer_type_def_sptr that
614 /// represents that type.
615 istring_type_base_wptrs_map_type&
pointer_types()616 type_maps::pointer_types()
617 {return priv_->pointer_types_;}
618
619 /// Getter for the map that associates the name of a pointer type to
620 /// the vector of instances of @ref pointer_type_def_sptr that
621 /// represents that type.
622 const istring_type_base_wptrs_map_type&
pointer_types() const623 type_maps::pointer_types() const
624 {return priv_->pointer_types_;}
625
626 /// Getter for the map that associates the name of a reference type to
627 /// the vector of instances of @ref reference_type_def_sptr that
628 /// represents that type.
629 istring_type_base_wptrs_map_type&
reference_types()630 type_maps::reference_types()
631 {return priv_->reference_types_;}
632
633 /// Getter for the map that associates the name of a reference type to
634 /// the vector of instances of @ref reference_type_def_sptr that
635 /// represents that type.
636 const istring_type_base_wptrs_map_type&
reference_types() const637 type_maps::reference_types() const
638 {return priv_->reference_types_;}
639
640 /// Getter for the map that associates the name of an array type to
641 /// the vector of instances of @ref array_type_def_sptr that
642 /// represents that type.
643 istring_type_base_wptrs_map_type&
array_types()644 type_maps::array_types()
645 {return priv_->array_types_;}
646
647 /// Getter for the map that associates the name of an array type to
648 /// the vector of instances of @ref array_type_def_sptr that
649 /// represents that type.
650 const istring_type_base_wptrs_map_type&
array_types() const651 type_maps::array_types() const
652 {return priv_->array_types_;}
653
654 /// Getter for the map that associates the name of a subrange type to
655 /// the vector of instances of @ref array_type_def::subrange_sptr that
656 /// represents that type.
657 istring_type_base_wptrs_map_type&
subrange_types()658 type_maps::subrange_types()
659 {return priv_->subrange_types_;}
660
661 /// Getter for the map that associates the name of a subrange type to
662 /// the vector of instances of @ref array_type_def::subrange_sptr that
663 /// represents that type.
664 const istring_type_base_wptrs_map_type&
subrange_types() const665 type_maps::subrange_types() const
666 {return priv_->subrange_types_;}
667
668 /// Getter for the map that associates the name of a function type to
669 /// the vector of instances of @ref function_type_sptr that represents
670 /// that type.
671 const istring_type_base_wptrs_map_type&
function_types() const672 type_maps::function_types() const
673 {return priv_->function_types_;}
674
675 /// Getter for the map that associates the name of a function type to
676 /// the vector of instances of @ref function_type_sptr that represents
677 /// that type.
678 istring_type_base_wptrs_map_type&
function_types()679 type_maps::function_types()
680 {return priv_->function_types_;}
681
682 /// A comparison functor to compare/sort types based on their pretty
683 /// representations.
684 struct type_name_comp
685 {
686 /// Comparison operator for two instances of @ref type_base.
687 ///
688 /// This compares the two types by lexicographically comparing their
689 /// pretty representation.
690 ///
691 /// @param l the left-most type to compare.
692 ///
693 /// @param r the right-most type to compare.
694 ///
695 /// @return true iff @p l < @p r.
696 bool
operator ()abigail::ir::type_name_comp697 operator()(type_base *l, type_base *r) const
698 {
699 if (l == 0 && r == 0)
700 return false;
701
702 string l_repr = get_pretty_representation(l);
703 string r_repr = get_pretty_representation(r);
704 return l_repr < r_repr;
705 }
706
707 /// Comparison operator for two instances of @ref type_base.
708 ///
709 /// This compares the two types by lexicographically comparing their
710 /// pretty representation.
711 ///
712 /// @param l the left-most type to compare.
713 ///
714 /// @param r the right-most type to compare.
715 ///
716 /// @return true iff @p l < @p r.
717 bool
operator ()abigail::ir::type_name_comp718 operator()(const type_base_sptr &l, const type_base_sptr &r) const
719 {return operator()(l.get(), r.get());}
720
721 /// Comparison operator for two instances of @ref type_base.
722 ///
723 /// This compares the two types by lexicographically comparing their
724 /// pretty representation.
725 ///
726 /// @param l the left-most type to compare.
727 ///
728 /// @param r the right-most type to compare.
729 ///
730 /// @return true iff @p l < @p r.
731 bool
operator ()abigail::ir::type_name_comp732 operator()(const type_base_wptr &l, const type_base_wptr &r) const
733 {return operator()(type_base_sptr(l), type_base_sptr(r));}
734 }; // end struct type_name_comp
735
736 #ifdef WITH_DEBUG_SELF_COMPARISON
737
738 /// This is a function called when the ABG_RETURN* macros defined
739 /// below return false.
740 ///
741 /// The purpose of this function is to ease debugging. To know where
742 /// the equality functions first compare non-equal, we can just set a
743 /// breakpoint on this notify_equality_failed function and run the
744 /// equality functions. Because all the equality functions use the
745 /// ABG_RETURN* macros to return their values, this function is always
746 /// called when any of those equality function return false.
747 ///
748 /// @param l the first operand of the equality.
749 ///
750 /// @param r the second operand of the equality.
751 static void
notify_equality_failed(const type_or_decl_base & l,const type_or_decl_base & r)752 notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
753 const type_or_decl_base &r __attribute__((unused)))
754 {}
755
756 /// This is a function called when the ABG_RETURN* macros defined
757 /// below return false.
758 ///
759 /// The purpose of this function is to ease debugging. To know where
760 /// the equality functions first compare non-equal, we can just set a
761 /// breakpoint on this notify_equality_failed function and run the
762 /// equality functions. Because all the equality functions use the
763 /// ABG_RETURN* macros to return their values, this function is always
764 /// called when any of those equality function return false.
765 ///
766 /// @param l the first operand of the equality.
767 ///
768 /// @param r the second operand of the equality.
769 static void
notify_equality_failed(const type_or_decl_base * l,const type_or_decl_base * r)770 notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
771 const type_or_decl_base *r __attribute__((unused)))
772 {}
773
774 #define ABG_RETURN_EQUAL(l, r) \
775 do \
776 { \
777 if (l != r) \
778 notify_equality_failed(l, r); \
779 return (l == r); \
780 } \
781 while(false)
782
783
784 #define ABG_RETURN_FALSE \
785 do \
786 { \
787 notify_equality_failed(l, r); \
788 return false; \
789 } while(false)
790
791 #define ABG_RETURN(value) \
792 do \
793 { \
794 if (value == false) \
795 notify_equality_failed(l, r); \
796 return value; \
797 } while (false)
798
799 #else // WITH_DEBUG_SELF_COMPARISON
800
801 #define ABG_RETURN_FALSE return false
802 #define ABG_RETURN(value) return (value)
803 #define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
804 #endif
805
806 /// Compare two types by comparing their canonical types if present.
807 ///
808 /// If the canonical types are not present (because the types have not
809 /// yet been canonicalized, for instance) then the types are compared
810 /// structurally.
811 ///
812 /// @param l the first type to take into account in the comparison.
813 ///
814 /// @param r the second type to take into account in the comparison.
815 template<typename T>
816 bool
try_canonical_compare(const T * l,const T * r)817 try_canonical_compare(const T *l, const T *r)
818 {
819 #if WITH_DEBUG_TYPE_CANONICALIZATION
820 // We are debugging the canonicalization of a type down the stack.
821 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
822 // type being canonicalized. We are at a point where we can compare
823 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
824 // have canonical types) or structural comparison.
825 //
826 // Because we are debugging the process of type canonicalization, we
827 // want to compare 'l' and 'r' canonically *AND* structurally. Both
828 // kinds of comparison should yield the same result, otherwise type
829 // canonicalization just failed for the subtype 'r' of the type
830 // being canonicalized.
831 //
832 // In concrete terms, this function is going to be called twice with
833 // the same pair {'l', 'r'} to compare: The first time with
834 // environment::priv_->use_canonical_type_comparison_ set to true,
835 // instructing us to compare them canonically, and the second time
836 // with that boolean set to false, instructing us to compare them
837 // structurally.
838 const environment&env = l->get_environment();
839 if (env.priv_->use_canonical_type_comparison_)
840 {
841 if (const type_base *lc = l->get_naked_canonical_type())
842 if (const type_base *rc = r->get_naked_canonical_type())
843 ABG_RETURN_EQUAL(lc, rc);
844 }
845 return equals(*l, *r, 0);
846 #else
847 if (const type_base *lc = l->get_naked_canonical_type())
848 if (const type_base *rc = r->get_naked_canonical_type())
849 ABG_RETURN_EQUAL(lc, rc);
850 return equals(*l, *r, 0);
851 #endif
852
853
854 }
855
856 /// Detect if a recursive comparison cycle is detected while
857 /// structurally comparing two types (a.k.a member-wise comparison).
858 ///
859 /// @param l the left-hand-side operand of the current comparison.
860 ///
861 /// @param r the right-hand-side operand of the current comparison.
862 ///
863 /// @return true iff a comparison cycle is detected.
864 template<typename T>
865 bool
is_comparison_cycle_detected(T & l,T & r)866 is_comparison_cycle_detected(T& l, T& r)
867 {
868 bool result = l.priv_->comparison_started(l, r);
869 return result ;
870 }
871
872 /// Detect if a recursive comparison cycle is detected while
873 /// structurally comparing two @ref class_decl types.
874 ///
875 /// @param l the left-hand-side operand of the current comparison.
876 ///
877 /// @param r the right-hand-side operand of the current comparison.
878 ///
879 /// @return true iff a comparison cycle is detected.
880 template<>
881 bool
is_comparison_cycle_detected(const class_decl & l,const class_decl & r)882 is_comparison_cycle_detected(const class_decl& l, const class_decl& r)
883 {
884 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
885 static_cast<const class_or_union&>(r));
886 }
887
888 /// This macro is to be used while comparing composite types that
889 /// might recursively refer to themselves. Comparing two such types
890 /// might get us into a cyle.
891 ///
892 /// Practically, if we detect that we are already into comparing 'l'
893 /// and 'r'; then, this is a cycle.
894 //
895 /// To break the cycle, we assume the result of the comparison is true
896 /// for now. Comparing the other sub-types of l & r will tell us later
897 /// if l & r are actually different or not.
898 ///
899 /// In the mean time, returning true from this macro should not be
900 /// used to propagate the canonical type of 'l' onto 'r' as we don't
901 /// know yet if l equals r. All the types that depend on l and r
902 /// can't (and that are in the comparison stack currently) can't have
903 /// their canonical type propagated either. So this macro disallows
904 /// canonical type propagation for those types that depend on a
905 /// recursively defined sub-type for now.
906 ///
907 /// @param l the left-hand-side operand of the comparison.
908 #define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
909 do \
910 { \
911 if (is_comparison_cycle_detected(l, r)) \
912 { \
913 mark_dependant_types_compared_until(r); \
914 return true; \
915 } \
916 } \
917 while(false)
918
919
920 /// Mark a pair of types as being compared.
921 ///
922 /// This is helpful to later detect recursive cycles in the comparison
923 /// stack.
924 ///
925 /// @param l the left-hand-side operand of the comparison.
926 ///
927 /// @parm r the right-hand-side operand of the comparison.
928 template<typename T>
929 void
mark_types_as_being_compared(T & l,T & r)930 mark_types_as_being_compared(T& l, T&r)
931 {
932 l.priv_->mark_as_being_compared(l, r);
933 push_composite_type_comparison_operands(l, r);
934 }
935
936 /// Mark a pair of @ref class_decl types as being compared.
937 ///
938 /// This is helpful to later detect recursive cycles in the comparison
939 /// stack.
940 ///
941 /// @param l the left-hand-side operand of the comparison.
942 ///
943 /// @parm r the right-hand-side operand of the comparison.
944 template<>
945 void
mark_types_as_being_compared(const class_decl & l,const class_decl & r)946 mark_types_as_being_compared(const class_decl& l, const class_decl &r)
947 {
948 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
949 static_cast<const class_or_union&>(r));
950 }
951
952 /// Mark a pair of types as being not compared anymore.
953 ///
954 /// This is helpful to later detect recursive cycles in the comparison
955 /// stack.
956 ///
957 /// Note that the types must have been passed to
958 /// mark_types_as_being_compared prior to calling this function.
959 ///
960 /// @param l the left-hand-side operand of the comparison.
961 ///
962 /// @parm r the right-hand-side operand of the comparison.
963 template<typename T>
964 void
unmark_types_as_being_compared(T & l,T & r)965 unmark_types_as_being_compared(T& l, T&r)
966 {
967 l.priv_->unmark_as_being_compared(l, r);
968 pop_composite_type_comparison_operands(l, r);
969 }
970
971 /// Mark a pair of @ref class_decl types as being not compared
972 /// anymore.
973 ///
974 /// This is helpful to later detect recursive cycles in the comparison
975 /// stack.
976 ///
977 /// Note that the types must have been passed to
978 /// mark_types_as_being_compared prior to calling this function.
979 ///
980 /// @param l the left-hand-side operand of the comparison.
981 ///
982 /// @parm r the right-hand-side operand of the comparison.
983 template<>
984 void
unmark_types_as_being_compared(const class_decl & l,const class_decl & r)985 unmark_types_as_being_compared(const class_decl& l, const class_decl &r)
986 {
987 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
988 static_cast<const class_or_union&>(r));
989 }
990
991 /// Return the result of the comparison of two (sub) types.
992 ///
993 /// The function does the necessary book keeping before returning the
994 /// result of the comparison of two (sub) types.
995 ///
996 /// The book-keeping done is in the following
997 /// areas:
998 ///
999 /// * Management of the Canonical Type Propagation optimization
1000 /// * type comparison cycle detection
1001 ///
1002 /// @param l the left-hand-side operand of the type comparison
1003 ///
1004 /// @param r the right-hand-side operand of the type comparison
1005 ///
1006 /// @param propagate_canonical_type if true, it means the function
1007 /// performs the @ref OnTheFlyCanonicalization, aka, "canonical type
1008 /// propagation optimization".
1009 ///
1010 /// @param value the result of the comparison of @p l and @p r.
1011 ///
1012 /// @return the value @p value.
1013 template<typename T>
1014 bool
return_comparison_result(T & l,T & r,bool value,bool propagate_canonical_type=true)1015 return_comparison_result(T& l, T& r, bool value,
1016 bool propagate_canonical_type = true)
1017 {
1018 if (propagate_canonical_type && (value == true))
1019 maybe_propagate_canonical_type(l, r);
1020
1021 unmark_types_as_being_compared(l, r);
1022
1023 const environment& env = l.get_environment();
1024 if (env.do_on_the_fly_canonicalization())
1025 // We are instructed to perform the "canonical type propagation"
1026 // optimization, making 'r' to possibly get the canonical type of
1027 // 'l' if it has one. This mostly means that we are currently
1028 // canonicalizing the type that contain the subtype provided in
1029 // the 'r' argument.
1030 {
1031 if (value == true
1032 && (is_type(&r)->priv_->depends_on_recursive_type()
1033 || env.priv_->is_recursive_type(&r))
1034 && is_type(&r)->priv_->canonical_type_propagated()
1035 && !is_type(&r)->priv_->propagated_canonical_type_confirmed()
1036 && !env.priv_->right_type_comp_operands_.empty())
1037 {
1038 // Track the object 'r' for which the propagated canonical
1039 // type might be re-initialized if the current comparison
1040 // eventually fails.
1041 env.priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
1042 }
1043 else if (value == true && env.priv_->right_type_comp_operands_.empty())
1044 {
1045 // The type provided in the 'r' argument is the type that is
1046 // being canonicalized; 'r' is not a mere subtype being
1047 // compared, it's the whole type being canonicalized. And
1048 // its canonicalization has just succeeded. So let's
1049 // confirm the "canonical type propagation" of all the
1050 // sub-types that were compared during the comparison of
1051 // 'r'.
1052 env.priv_->confirm_ct_propagation(&r);
1053 }
1054 else if (value == false)
1055 {
1056 // The comparison of the current sub-type failed. So all
1057 // the types in
1058 // env.prix_->types_with_non_confirmed_propagated_ct_
1059 // should see their tentatively propagated canonical type
1060 // cancelled.
1061 env.priv_->cancel_ct_propagation(&r);
1062 }
1063 }
1064
1065 // If we reached this point with value == true and the stack of
1066 // types being compared is empty, then it means that the type pair
1067 // that was at the bottom of the stack is now fully compared.
1068 //
1069 // It follows that all types that were target of canonical type
1070 // propagation can now see their tentative canonical type be
1071 // confirmed for real.
1072 if (value == true
1073 && env.priv_->right_type_comp_operands_.empty()
1074 && !env.priv_->types_with_non_confirmed_propagated_ct_.empty())
1075 // So the comparison is completely done and there are some
1076 // types for which their propagated canonical type is sitll
1077 // considered not confirmed. As the comparison did yield true, we
1078 // shall now confirm the propagation for all those types.
1079 env.priv_->confirm_ct_propagation();
1080
1081 ABG_RETURN(value);
1082 }
1083
1084 /// Getter of all types types sorted by their pretty representation.
1085 ///
1086 /// @return a sorted vector of all types sorted by their pretty
1087 /// representation.
1088 const vector<type_base_wptr>&
get_types_sorted_by_name() const1089 type_maps::get_types_sorted_by_name() const
1090 {
1091 if (priv_->sorted_types_.empty())
1092 {
1093 istring_type_base_wptrs_map_type::const_iterator i;
1094 vector<type_base_wptr>::const_iterator j;
1095
1096 for (i = basic_types().begin(); i != basic_types().end(); ++i)
1097 for (j = i->second.begin(); j != i->second.end(); ++j)
1098 priv_->sorted_types_.push_back(*j);
1099
1100 for (i = class_types().begin(); i != class_types().end(); ++i)
1101 for (j = i->second.begin(); j != i->second.end(); ++j)
1102 priv_->sorted_types_.push_back(*j);
1103
1104 for (i = union_types().begin(); i != union_types().end(); ++i)
1105 for (j = i->second.begin(); j != i->second.end(); ++j)
1106 priv_->sorted_types_.push_back(*j);
1107
1108 for (i = enum_types().begin(); i != enum_types().end(); ++i)
1109 for (j = i->second.begin(); j != i->second.end(); ++j)
1110 priv_->sorted_types_.push_back(*j);
1111
1112 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1113 for (j = i->second.begin(); j != i->second.end(); ++j)
1114 priv_->sorted_types_.push_back(*j);
1115
1116 type_name_comp comp;
1117 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1118 }
1119
1120 return priv_->sorted_types_;
1121 }
1122
1123 // </type_maps stuff>
1124
1125 // <translation_unit stuff>
1126
1127 /// Constructor of translation_unit.
1128 ///
1129 /// @param env the environment of this translation unit. Please note
1130 /// that the life time of the environment must be greater than the
1131 /// life time of the translation unit because the translation uses
1132 /// resources that are allocated in the environment.
1133 ///
1134 /// @param path the location of the translation unit.
1135 ///
1136 /// @param address_size the size of addresses in the translation unit,
1137 /// in bits.
translation_unit(const environment & env,const std::string & path,char address_size)1138 translation_unit::translation_unit(const environment& env,
1139 const std::string& path,
1140 char address_size)
1141 : priv_(new priv(env))
1142 {
1143 priv_->path_ = path;
1144 priv_->address_size_ = address_size;
1145 }
1146
1147 /// Getter of the the global scope of the translation unit.
1148 ///
1149 /// @return the global scope of the current translation unit. If
1150 /// there is not global scope allocated yet, this function creates one
1151 /// and returns it.
1152 const scope_decl_sptr&
get_global_scope() const1153 translation_unit::get_global_scope() const
1154 {
1155 return const_cast<translation_unit*>(this)->get_global_scope();
1156 }
1157
1158 /// Getter of the the global scope of the translation unit.
1159 ///
1160 /// @return the global scope of the current translation unit. If
1161 /// there is not global scope allocated yet, this function creates one
1162 /// and returns it.
1163 scope_decl_sptr&
get_global_scope()1164 translation_unit::get_global_scope()
1165 {
1166 if (!priv_->global_scope_)
1167 {
1168 priv_->global_scope_.reset
1169 (new global_scope(const_cast<translation_unit*>(this)));
1170 priv_->global_scope_->set_translation_unit
1171 (const_cast<translation_unit*>(this));
1172 }
1173 return priv_->global_scope_;
1174 }
1175
1176 /// Getter of the types of the current @ref translation_unit.
1177 ///
1178 /// @return the maps of the types of the translation unit.
1179 const type_maps&
get_types() const1180 translation_unit::get_types() const
1181 {return priv_->types_;}
1182
1183 /// Getter of the types of the current @ref translation_unit.
1184 ///
1185 /// @return the maps of the types of the translation unit.
1186 type_maps&
get_types()1187 translation_unit::get_types()
1188 {return priv_->types_;}
1189
1190 /// Get the vector of function types that are used in the current
1191 /// translation unit.
1192 ///
1193 /// @return the vector of function types that are used in the current
1194 /// translation unit.
1195 const vector<function_type_sptr>&
get_live_fn_types() const1196 translation_unit::get_live_fn_types() const
1197 {return priv_->live_fn_types_;}
1198
1199 /// Getter of the environment of the current @ref translation_unit.
1200 ///
1201 /// @return the translation unit of the current translation unit.
1202 const environment&
get_environment() const1203 translation_unit::get_environment() const
1204 {return priv_->env_;}
1205
1206 /// Getter of the language of the source code of the translation unit.
1207 ///
1208 /// @return the language of the source code.
1209 translation_unit::language
get_language() const1210 translation_unit::get_language() const
1211 {return priv_->language_;}
1212
1213 /// Setter of the language of the source code of the translation unit.
1214 ///
1215 /// @param l the new language.
1216 void
set_language(language l)1217 translation_unit::set_language(language l)
1218 {priv_->language_ = l;}
1219
1220
1221 /// Get the path of the current translation unit.
1222 ///
1223 /// This path is relative to the build directory of the translation
1224 /// unit as returned by translation_unit::get_compilation_dir_path.
1225 ///
1226 /// @return the relative path of the compilation unit associated to
1227 /// the current instance of translation_unit.
1228 //
1229 const std::string&
get_path() const1230 translation_unit::get_path() const
1231 {return priv_->path_;}
1232
1233 /// Set the path associated to the current instance of
1234 /// translation_unit.
1235 ///
1236 /// This path is relative to the build directory of the translation
1237 /// unit as returned by translation_unit::get_compilation_dir_path.
1238 ///
1239 /// @param a_path the new relative path to set.
1240 void
set_path(const string & a_path)1241 translation_unit::set_path(const string& a_path)
1242 {priv_->path_ = a_path;}
1243
1244
1245 /// Get the path of the directory that was 'current' when the
1246 /// translation unit was compiled.
1247 ///
1248 /// Note that the path returned by translation_unit::get_path is
1249 /// relative to the path returned by this function.
1250 ///
1251 /// @return the compilation directory for the current translation
1252 /// unit.
1253 const std::string&
get_compilation_dir_path() const1254 translation_unit::get_compilation_dir_path() const
1255 {return priv_->comp_dir_path_;}
1256
1257 /// Set the path of the directory that was 'current' when the
1258 /// translation unit was compiled.
1259 ///
1260 /// Note that the path returned by translation_unit::get_path is
1261 /// relative to the path returned by this function.
1262 ///
1263 /// @param the compilation directory for the current translation unit.
1264 void
set_compilation_dir_path(const std::string & d)1265 translation_unit::set_compilation_dir_path(const std::string& d)
1266 {priv_->comp_dir_path_ = d;}
1267
1268 /// Get the concatenation of the build directory and the relative path
1269 /// of the translation unit.
1270 ///
1271 /// @return the absolute path of the translation unit.
1272 const std::string&
get_absolute_path() const1273 translation_unit::get_absolute_path() const
1274 {
1275 if (priv_->abs_path_.empty())
1276 {
1277 string path;
1278 if (!priv_->path_.empty())
1279 {
1280 if (!priv_->comp_dir_path_.empty())
1281 {
1282 path = priv_->comp_dir_path_;
1283 path += "/";
1284 }
1285 path += priv_->path_;
1286 }
1287 priv_->abs_path_ = path;
1288 }
1289
1290 return priv_->abs_path_;
1291 }
1292
1293 /// Set the corpus this translation unit is a member of.
1294 ///
1295 /// Note that adding a translation unit to a @ref corpus automatically
1296 /// triggers a call to this member function.
1297 ///
1298 /// @param corpus the corpus.
1299 void
set_corpus(corpus * c)1300 translation_unit::set_corpus(corpus* c)
1301 {priv_->corp = c;}
1302
1303 /// Get the corpus this translation unit is a member of.
1304 ///
1305 /// @return the parent corpus, or nil if this doesn't belong to any
1306 /// corpus yet.
1307 corpus*
get_corpus()1308 translation_unit::get_corpus()
1309 {return priv_->corp;}
1310
1311 /// Get the corpus this translation unit is a member of.
1312 ///
1313 /// @return the parent corpus, or nil if this doesn't belong to any
1314 /// corpus yet.
1315 const corpus*
get_corpus() const1316 translation_unit::get_corpus() const
1317 {return const_cast<translation_unit*>(this)->get_corpus();}
1318
1319 /// Getter of the location manager for the current translation unit.
1320 ///
1321 /// @return a reference to the location manager for the current
1322 /// translation unit.
1323 location_manager&
get_loc_mgr()1324 translation_unit::get_loc_mgr()
1325 {return priv_->loc_mgr_;}
1326
1327 /// const Getter of the location manager.
1328 ///
1329 /// @return a const reference to the location manager for the current
1330 /// translation unit.
1331 const location_manager&
get_loc_mgr() const1332 translation_unit::get_loc_mgr() const
1333 {return priv_->loc_mgr_;}
1334
1335 /// Tests whether if the current translation unit contains ABI
1336 /// artifacts or not.
1337 ///
1338 /// @return true iff the current translation unit is empty.
1339 bool
is_empty() const1340 translation_unit::is_empty() const
1341 {
1342 if (!priv_->global_scope_)
1343 return true;
1344 return get_global_scope()->is_empty();
1345 }
1346
1347 /// Getter of the address size in this translation unit.
1348 ///
1349 /// @return the address size, in bits.
1350 char
get_address_size() const1351 translation_unit::get_address_size() const
1352 {return priv_->address_size_;}
1353
1354 /// Setter of the address size in this translation unit.
1355 ///
1356 /// @param a the new address size in bits.
1357 void
set_address_size(char a)1358 translation_unit::set_address_size(char a)
1359 {priv_->address_size_= a;}
1360
1361 /// Getter of the 'is_constructed" flag. It says if the translation
1362 /// unit is fully constructed or not.
1363 ///
1364 /// This flag is important for cases when comparison might depend on
1365 /// if the translation unit is fully built or not. For instance, when
1366 /// reading types from DWARF, the virtual methods of a class are not
1367 /// necessarily fully constructed until we have reached the end of the
1368 /// translation unit. In that case, before we've reached the end of
1369 /// the translation unit, we might not take virtual functions into
1370 /// account when comparing classes.
1371 ///
1372 /// @return true if the translation unit is constructed.
1373 bool
is_constructed() const1374 translation_unit::is_constructed() const
1375 {return priv_->is_constructed_;}
1376
1377 /// Setter of the 'is_constructed" flag. It says if the translation
1378 /// unit is fully constructed or not.
1379 ///
1380 /// This flag is important for cases when comparison might depend on
1381 /// if the translation unit is fully built or not. For instance, when
1382 /// reading types from DWARF, the virtual methods of a class are not
1383 /// necessarily fully constructed until we have reached the end of the
1384 /// translation unit. In that case, before we've reached the end of
1385 /// the translation unit, we might not take virtual functions into
1386 /// account when comparing classes.
1387 ///
1388 /// @param f true if the translation unit is constructed.
1389 void
set_is_constructed(bool f)1390 translation_unit::set_is_constructed(bool f)
1391 {priv_->is_constructed_ = f;}
1392
1393 /// Compare the current translation unit against another one.
1394 ///
1395 /// @param other the other tu to compare against.
1396 ///
1397 /// @return true if the two translation units are equal, false
1398 /// otherwise.
1399 bool
operator ==(const translation_unit & other) const1400 translation_unit::operator==(const translation_unit& other)const
1401 {
1402 if (get_address_size() != other.get_address_size())
1403 return false;
1404
1405 return *get_global_scope() == *other.get_global_scope();
1406 }
1407
1408 /// Inequality operator.
1409 ///
1410 /// @param o the instance of @ref translation_unit to compare the
1411 /// current instance against.
1412 ///
1413 /// @return true iff the current instance is different from @p o.
1414 bool
operator !=(const translation_unit & o) const1415 translation_unit::operator!=(const translation_unit& o) const
1416 {return ! operator==(o);}
1417
1418 /// Ensure that the life time of a function type is bound to the life
1419 /// time of the current translation unit.
1420 ///
1421 /// @param ftype the function time which life time to bind to the life
1422 /// time of the current instance of @ref translation_unit. That is,
1423 /// it's onlyh when the translation unit is destroyed that the
1424 /// function type can be destroyed to.
1425 void
bind_function_type_life_time(function_type_sptr ftype) const1426 translation_unit::bind_function_type_life_time(function_type_sptr ftype) const
1427 {
1428 const environment& env = get_environment();
1429
1430 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1431
1432 interned_string repr = get_type_name(ftype);
1433 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1434 push_back(ftype);
1435
1436 // The function type must be out of the same environment as its
1437 // translation unit.
1438 {
1439 const environment& e = ftype->get_environment();
1440 ABG_ASSERT(&env == &e);
1441 }
1442
1443 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1444 ABG_ASSERT(existing_tu == this);
1445 else
1446 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1447 }
1448
1449 /// This implements the ir_traversable_base::traverse virtual
1450 /// function.
1451 ///
1452 /// @param v the visitor used on the member nodes of the translation
1453 /// unit during the traversal.
1454 ///
1455 /// @return true if the entire type IR tree got traversed, false
1456 /// otherwise.
1457 bool
traverse(ir_node_visitor & v)1458 translation_unit::traverse(ir_node_visitor& v)
1459 {return get_global_scope()->traverse(v);}
1460
~translation_unit()1461 translation_unit::~translation_unit()
1462 {}
1463
1464 /// Converts a translation_unit::language enumerator into a string.
1465 ///
1466 /// @param l the language enumerator to translate.
1467 ///
1468 /// @return the resulting string.
1469 string
translation_unit_language_to_string(translation_unit::language l)1470 translation_unit_language_to_string(translation_unit::language l)
1471 {
1472 switch (l)
1473 {
1474 case translation_unit::LANG_UNKNOWN:
1475 return "LANG_UNKNOWN";
1476 case translation_unit::LANG_Cobol74:
1477 return "LANG_Cobol74";
1478 case translation_unit::LANG_Cobol85:
1479 return "LANG_Cobol85";
1480 case translation_unit::LANG_C89:
1481 return "LANG_C89";
1482 case translation_unit::LANG_C99:
1483 return "LANG_C99";
1484 case translation_unit::LANG_C11:
1485 return "LANG_C11";
1486 case translation_unit::LANG_C:
1487 return "LANG_C";
1488 case translation_unit::LANG_C_plus_plus_11:
1489 return "LANG_C_plus_plus_11";
1490 case translation_unit::LANG_C_plus_plus_14:
1491 return "LANG_C_plus_plus_14";
1492 case translation_unit::LANG_C_plus_plus:
1493 return "LANG_C_plus_plus";
1494 case translation_unit::LANG_ObjC:
1495 return "LANG_ObjC";
1496 case translation_unit::LANG_ObjC_plus_plus:
1497 return "LANG_ObjC_plus_plus";
1498 case translation_unit::LANG_Fortran77:
1499 return "LANG_Fortran77";
1500 case translation_unit::LANG_Fortran90:
1501 return "LANG_Fortran90";
1502 case translation_unit::LANG_Fortran95:
1503 return "LANG_Fortran95";
1504 case translation_unit::LANG_Ada83:
1505 return "LANG_Ada83";
1506 case translation_unit::LANG_Ada95:
1507 return "LANG_Ada95";
1508 case translation_unit::LANG_Pascal83:
1509 return "LANG_Pascal83";
1510 case translation_unit::LANG_Modula2:
1511 return "LANG_Modula2";
1512 case translation_unit::LANG_Java:
1513 return "LANG_Java";
1514 case translation_unit::LANG_PLI:
1515 return "LANG_PLI";
1516 case translation_unit::LANG_UPC:
1517 return "LANG_UPC";
1518 case translation_unit::LANG_D:
1519 return "LANG_D";
1520 case translation_unit::LANG_Python:
1521 return "LANG_Python";
1522 case translation_unit::LANG_Go:
1523 return "LANG_Go";
1524 case translation_unit::LANG_Mips_Assembler:
1525 return "LANG_Mips_Assembler";
1526 default:
1527 return "LANG_UNKNOWN";
1528 }
1529
1530 return "LANG_UNKNOWN";
1531 }
1532
1533 /// Parse a string representing a language into a
1534 /// translation_unit::language enumerator into a string.
1535 ///
1536 /// @param l the string representing the language.
1537 ///
1538 /// @return the resulting translation_unit::language enumerator.
1539 translation_unit::language
string_to_translation_unit_language(const string & l)1540 string_to_translation_unit_language(const string& l)
1541 {
1542 if (l == "LANG_Cobol74")
1543 return translation_unit::LANG_Cobol74;
1544 else if (l == "LANG_Cobol85")
1545 return translation_unit::LANG_Cobol85;
1546 else if (l == "LANG_C89")
1547 return translation_unit::LANG_C89;
1548 else if (l == "LANG_C99")
1549 return translation_unit::LANG_C99;
1550 else if (l == "LANG_C11")
1551 return translation_unit::LANG_C11;
1552 else if (l == "LANG_C")
1553 return translation_unit::LANG_C;
1554 else if (l == "LANG_C_plus_plus_11")
1555 return translation_unit::LANG_C_plus_plus_11;
1556 else if (l == "LANG_C_plus_plus_14")
1557 return translation_unit::LANG_C_plus_plus_14;
1558 else if (l == "LANG_C_plus_plus")
1559 return translation_unit::LANG_C_plus_plus;
1560 else if (l == "LANG_ObjC")
1561 return translation_unit::LANG_ObjC;
1562 else if (l == "LANG_ObjC_plus_plus")
1563 return translation_unit::LANG_ObjC_plus_plus;
1564 else if (l == "LANG_Fortran77")
1565 return translation_unit::LANG_Fortran77;
1566 else if (l == "LANG_Fortran90")
1567 return translation_unit::LANG_Fortran90;
1568 else if (l == "LANG_Fortran95")
1569 return translation_unit::LANG_Fortran95;
1570 else if (l == "LANG_Ada83")
1571 return translation_unit::LANG_Ada83;
1572 else if (l == "LANG_Ada95")
1573 return translation_unit::LANG_Ada95;
1574 else if (l == "LANG_Pascal83")
1575 return translation_unit::LANG_Pascal83;
1576 else if (l == "LANG_Modula2")
1577 return translation_unit::LANG_Modula2;
1578 else if (l == "LANG_Java")
1579 return translation_unit::LANG_Java;
1580 else if (l == "LANG_PLI")
1581 return translation_unit::LANG_PLI;
1582 else if (l == "LANG_UPC")
1583 return translation_unit::LANG_UPC;
1584 else if (l == "LANG_D")
1585 return translation_unit::LANG_D;
1586 else if (l == "LANG_Python")
1587 return translation_unit::LANG_Python;
1588 else if (l == "LANG_Go")
1589 return translation_unit::LANG_Go;
1590 else if (l == "LANG_Mips_Assembler")
1591 return translation_unit::LANG_Mips_Assembler;
1592
1593 return translation_unit::LANG_UNKNOWN;
1594 }
1595
1596 /// Test if a language enumerator designates the C language.
1597 ///
1598 /// @param l the language enumerator to consider.
1599 ///
1600 /// @return true iff @p l designates the C language.
1601 bool
is_c_language(translation_unit::language l)1602 is_c_language(translation_unit::language l)
1603 {
1604 return (l == translation_unit::LANG_C89
1605 || l == translation_unit::LANG_C99
1606 || l == translation_unit::LANG_C11
1607 || l == translation_unit::LANG_C);
1608 }
1609
1610 /// Test if a language enumerator designates the C++ language.
1611 ///
1612 /// @param l the language enumerator to consider.
1613 ///
1614 /// @return true iff @p l designates the C++ language.
1615 bool
is_cplus_plus_language(translation_unit::language l)1616 is_cplus_plus_language(translation_unit::language l)
1617 {
1618 return (l == translation_unit::LANG_C_plus_plus_03
1619 || l == translation_unit::LANG_C_plus_plus_11
1620 || l == translation_unit::LANG_C_plus_plus_14
1621 || l == translation_unit::LANG_C_plus_plus);
1622 }
1623
1624 /// Test if a language enumerator designates the Java language.
1625 ///
1626 /// @param l the language enumerator to consider.
1627 ///
1628 /// @return true iff @p l designates the Java language.
1629 bool
is_java_language(translation_unit::language l)1630 is_java_language(translation_unit::language l)
1631 {return l == translation_unit::LANG_Java;}
1632
1633 /// Test if a language enumerator designates the Ada language.
1634 ///
1635 /// @param l the language enumerator to consider.
1636 ///
1637 /// @return true iff @p l designates the Ada language.
1638 bool
is_ada_language(translation_unit::language l)1639 is_ada_language(translation_unit::language l)
1640 {
1641 return (l == translation_unit::LANG_Ada83
1642 || l == translation_unit::LANG_Ada95);
1643 }
1644
1645 /// A deep comparison operator for pointers to translation units.
1646 ///
1647 /// @param l the first translation unit to consider for the comparison.
1648 ///
1649 /// @param r the second translation unit to consider for the comparison.
1650 ///
1651 /// @return true if the two translation units are equal, false otherwise.
1652 bool
operator ==(const translation_unit_sptr & l,const translation_unit_sptr & r)1653 operator==(const translation_unit_sptr& l, const translation_unit_sptr& r)
1654 {
1655 if (l.get() == r.get())
1656 return true;
1657
1658 if (!!l != !!r)
1659 return false;
1660
1661 return *l == *r;
1662 }
1663
1664 /// A deep inequality operator for pointers to translation units.
1665 ///
1666 /// @param l the first translation unit to consider for the comparison.
1667 ///
1668 /// @param r the second translation unit to consider for the comparison.
1669 ///
1670 /// @return true iff the two translation units are different.
1671 bool
operator !=(const translation_unit_sptr & l,const translation_unit_sptr & r)1672 operator!=(const translation_unit_sptr& l, const translation_unit_sptr& r)
1673 {return !operator==(l, r);}
1674
1675 // </translation_unit stuff>
1676
1677 // <elf_symbol stuff>
1678 struct elf_symbol::priv
1679 {
1680 const environment& env_;
1681 size_t index_;
1682 size_t size_;
1683 string name_;
1684 elf_symbol::type type_;
1685 elf_symbol::binding binding_;
1686 elf_symbol::version version_;
1687 elf_symbol::visibility visibility_;
1688 bool is_defined_;
1689 // This flag below says if the symbol is a common elf symbol. In
1690 // relocatable files, a common symbol is a symbol defined in a
1691 // section of kind SHN_COMMON.
1692 //
1693 // Note that a symbol of kind STT_COMMON is also considered a common
1694 // symbol. Here is what the gABI says about STT_COMMON and
1695 // SHN_COMMON:
1696 //
1697 // Symbols with type STT_COMMON label uninitialized common
1698 // blocks. In relocatable objects, these symbols are not
1699 // allocated and must have the special section index SHN_COMMON
1700 // (see below). In shared objects and executables these symbols
1701 // must be allocated to some section in the defining object.
1702 //
1703 // In relocatable objects, symbols with type STT_COMMON are
1704 // treated just as other symbols with index SHN_COMMON. If the
1705 // link-editor allocates space for the SHN_COMMON symbol in an
1706 // output section of the object it is producing, it must
1707 // preserve the type of the output symbol as STT_COMMON.
1708 //
1709 // When the dynamic linker encounters a reference to a symbol
1710 // that resolves to a definition of type STT_COMMON, it may (but
1711 // is not required to) change its symbol resolution rules as
1712 // follows: instead of binding the reference to the first symbol
1713 // found with the given name, the dynamic linker searches for
1714 // the first symbol with that name with type other than
1715 // STT_COMMON. If no such symbol is found, it looks for the
1716 // STT_COMMON definition of that name that has the largest size.
1717 bool is_common_;
1718 bool is_in_ksymtab_;
1719 abg_compat::optional<uint32_t> crc_;
1720 abg_compat::optional<std::string> namespace_;
1721 bool is_suppressed_;
1722 elf_symbol_wptr main_symbol_;
1723 elf_symbol_wptr next_alias_;
1724 elf_symbol_wptr next_common_instance_;
1725 string id_string_;
1726
privabigail::ir::elf_symbol::priv1727 priv(const environment& e)
1728 : env_(e),
1729 index_(),
1730 size_(),
1731 type_(elf_symbol::NOTYPE_TYPE),
1732 binding_(elf_symbol::GLOBAL_BINDING),
1733 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1734 is_defined_(false),
1735 is_common_(false),
1736 is_in_ksymtab_(false),
1737 crc_(),
1738 namespace_(),
1739 is_suppressed_(false)
1740 {}
1741
privabigail::ir::elf_symbol::priv1742 priv(const environment& e,
1743 size_t i,
1744 size_t s,
1745 const string& n,
1746 elf_symbol::type t,
1747 elf_symbol::binding b,
1748 bool d,
1749 bool c,
1750 const elf_symbol::version& ve,
1751 elf_symbol::visibility vi,
1752 bool is_in_ksymtab,
1753 const abg_compat::optional<uint32_t>& crc,
1754 const abg_compat::optional<std::string>& ns,
1755 bool is_suppressed)
1756 : env_(e),
1757 index_(i),
1758 size_(s),
1759 name_(n),
1760 type_(t),
1761 binding_(b),
1762 version_(ve),
1763 visibility_(vi),
1764 is_defined_(d),
1765 is_common_(c),
1766 is_in_ksymtab_(is_in_ksymtab),
1767 crc_(crc),
1768 namespace_(ns),
1769 is_suppressed_(is_suppressed)
1770 {
1771 if (!is_common_)
1772 is_common_ = type_ == COMMON_TYPE;
1773 }
1774 }; // end struct elf_symbol::priv
1775
1776 /// Constructor of the @ref elf_symbol type.
1777 ///
1778 /// Note that this constructor is private, so client code cannot use
1779 /// it to create instances of @ref elf_symbol. Rather, client code
1780 /// should use the @ref elf_symbol::create() function to create
1781 /// instances of @ref elf_symbol instead.
1782 ///
1783 /// @param e the environment we are operating from.
1784 ///
1785 /// @param i the index of the symbol in the (ELF) symbol table.
1786 ///
1787 /// @param s the size of the symbol.
1788 ///
1789 /// @param n the name of the symbol.
1790 ///
1791 /// @param t the type of the symbol.
1792 ///
1793 /// @param b the binding of the symbol.
1794 ///
1795 /// @param d true if the symbol is defined, false otherwise.
1796 ///
1797 /// @param c true if the symbol is a common symbol, false otherwise.
1798 ///
1799 /// @param ve the version of the symbol.
1800 ///
1801 /// @param vi the visibility of the symbol.
1802 ///
1803 /// @param crc the CRC (modversions) value of Linux Kernel symbols
1804 ///
1805 /// @param ns the namespace of Linux Kernel symbols, if any
elf_symbol(const environment & e,size_t i,size_t s,const string & n,type t,binding b,bool d,bool c,const version & ve,visibility vi,bool is_in_ksymtab,const abg_compat::optional<uint32_t> & crc,const abg_compat::optional<std::string> & ns,bool is_suppressed)1806 elf_symbol::elf_symbol(const environment& e,
1807 size_t i,
1808 size_t s,
1809 const string& n,
1810 type t,
1811 binding b,
1812 bool d,
1813 bool c,
1814 const version& ve,
1815 visibility vi,
1816 bool is_in_ksymtab,
1817 const abg_compat::optional<uint32_t>& crc,
1818 const abg_compat::optional<std::string>& ns,
1819 bool is_suppressed)
1820 : priv_(new priv(e,
1821 i,
1822 s,
1823 n,
1824 t,
1825 b,
1826 d,
1827 c,
1828 ve,
1829 vi,
1830 is_in_ksymtab,
1831 crc,
1832 ns,
1833 is_suppressed))
1834 {}
1835
1836 /// Factory of instances of @ref elf_symbol.
1837 ///
1838 /// This is the function to use to create instances of @ref elf_symbol.
1839 ///
1840 /// @param e the environment we are operating from.
1841 ///
1842 /// @param i the index of the symbol in the (ELF) symbol table.
1843 ///
1844 /// @param s the size of the symbol.
1845 ///
1846 /// @param n the name of the symbol.
1847 ///
1848 /// @param t the type of the symbol.
1849 ///
1850 /// @param b the binding of the symbol.
1851 ///
1852 /// @param d true if the symbol is defined, false otherwise.
1853 ///
1854 /// @param c true if the symbol is a common symbol.
1855 ///
1856 /// @param ve the version of the symbol.
1857 ///
1858 /// @param vi the visibility of the symbol.
1859 ///
1860 /// @param crc the CRC (modversions) value of Linux Kernel symbols
1861 ///
1862 /// @param ns the namespace of Linux Kernel symbols, if any
1863 ///
1864 /// @return a (smart) pointer to a newly created instance of @ref
1865 /// elf_symbol.
1866 elf_symbol_sptr
create(const environment & e,size_t i,size_t s,const string & n,type t,binding b,bool d,bool c,const version & ve,visibility vi,bool is_in_ksymtab,const abg_compat::optional<uint32_t> & crc,const abg_compat::optional<std::string> & ns,bool is_suppressed)1867 elf_symbol::create(const environment& e,
1868 size_t i,
1869 size_t s,
1870 const string& n,
1871 type t,
1872 binding b,
1873 bool d,
1874 bool c,
1875 const version& ve,
1876 visibility vi,
1877 bool is_in_ksymtab,
1878 const abg_compat::optional<uint32_t>& crc,
1879 const abg_compat::optional<std::string>& ns,
1880 bool is_suppressed)
1881 {
1882 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
1883 is_in_ksymtab, crc, ns, is_suppressed));
1884 sym->priv_->main_symbol_ = sym;
1885 return sym;
1886 }
1887
1888 /// Test textual equality between two symbols.
1889 ///
1890 /// Textual equality means that the aliases of the compared symbols
1891 /// are not taken into account. Only the name, type, and version of
1892 /// the symbols are compared.
1893 ///
1894 /// @return true iff the two symbols are textually equal.
1895 static bool
textually_equals(const elf_symbol & l,const elf_symbol & r)1896 textually_equals(const elf_symbol&l,
1897 const elf_symbol&r)
1898 {
1899 bool equals = (l.get_name() == r.get_name()
1900 && l.get_type() == r.get_type()
1901 && l.is_public() == r.is_public()
1902 && l.is_defined() == r.is_defined()
1903 && l.is_common_symbol() == r.is_common_symbol()
1904 && l.get_version() == r.get_version()
1905 && l.get_crc() == r.get_crc()
1906 && l.get_namespace() == r.get_namespace());
1907
1908 if (equals && l.is_variable())
1909 // These are variable symbols. Let's compare their symbol size.
1910 // The symbol size in this case is the size taken by the storage
1911 // of the variable. If that size changes, then it's an ABI
1912 // change.
1913 equals = l.get_size() == r.get_size();
1914
1915 return equals;
1916 }
1917
1918 /// Getter of the environment used by the current instance of @ref
1919 /// elf_symbol.
1920 ///
1921 /// @return the enviroment used by the current instance of @ref elf_symbol.
1922 const environment&
get_environment() const1923 elf_symbol::get_environment() const
1924 {return priv_->env_;}
1925
1926 /// Getter for the index
1927 ///
1928 /// @return the index of the symbol.
1929 size_t
get_index() const1930 elf_symbol::get_index() const
1931 {return priv_->index_;}
1932
1933 /// Setter for the index.
1934 ///
1935 /// @param s the new index.
1936 void
set_index(size_t s)1937 elf_symbol::set_index(size_t s)
1938 {priv_->index_ = s;}
1939
1940 /// Getter for the name of the @ref elf_symbol.
1941 ///
1942 /// @return a reference to the name of the @ref symbol.
1943 const string&
get_name() const1944 elf_symbol::get_name() const
1945 {return priv_->name_;}
1946
1947 /// Setter for the name of the current intance of @ref elf_symbol.
1948 ///
1949 /// @param n the new name.
1950 void
set_name(const string & n)1951 elf_symbol::set_name(const string& n)
1952 {
1953 priv_->name_ = n;
1954 priv_->id_string_.clear();
1955 }
1956
1957 /// Getter for the type of the current instance of @ref elf_symbol.
1958 ///
1959 /// @return the type of the elf symbol.
1960 elf_symbol::type
get_type() const1961 elf_symbol::get_type() const
1962 {return priv_->type_;}
1963
1964 /// Setter for the type of the current instance of @ref elf_symbol.
1965 ///
1966 /// @param t the new symbol type.
1967 void
set_type(type t)1968 elf_symbol::set_type(type t)
1969 {priv_->type_ = t;}
1970
1971 /// Getter of the size of the symbol.
1972 ///
1973 /// @return the size of the symbol, in bytes.
1974 size_t
get_size() const1975 elf_symbol::get_size() const
1976 {return priv_->size_;}
1977
1978 /// Setter of the size of the symbol.
1979 ///
1980 /// @param size the new size of the symbol, in bytes.
1981 void
set_size(size_t size)1982 elf_symbol::set_size(size_t size)
1983 {priv_->size_ = size;}
1984
1985 /// Getter for the binding of the current instance of @ref elf_symbol.
1986 ///
1987 /// @return the binding of the symbol.
1988 elf_symbol::binding
get_binding() const1989 elf_symbol::get_binding() const
1990 {return priv_->binding_;}
1991
1992 /// Setter for the binding of the current instance of @ref elf_symbol.
1993 ///
1994 /// @param b the new binding.
1995 void
set_binding(binding b)1996 elf_symbol::set_binding(binding b)
1997 {priv_->binding_ = b;}
1998
1999 /// Getter for the version of the current instanc of @ref elf_symbol.
2000 ///
2001 /// @return the version of the elf symbol.
2002 elf_symbol::version&
get_version() const2003 elf_symbol::get_version() const
2004 {return priv_->version_;}
2005
2006 /// Setter for the version of the current instance of @ref elf_symbol.
2007 ///
2008 /// @param v the new version of the elf symbol.
2009 void
set_version(const version & v)2010 elf_symbol::set_version(const version& v)
2011 {
2012 priv_->version_ = v;
2013 priv_->id_string_.clear();
2014 }
2015
2016 /// Setter of the visibility of the current instance of @ref
2017 /// elf_symbol.
2018 ///
2019 /// @param v the new visibility of the elf symbol.
2020 void
set_visibility(visibility v)2021 elf_symbol::set_visibility(visibility v)
2022 {priv_->visibility_ = v;}
2023
2024 /// Getter of the visibility of the current instance of @ref
2025 /// elf_symbol.
2026 ///
2027 /// @return the visibility of the elf symbol.
2028 elf_symbol::visibility
get_visibility() const2029 elf_symbol::get_visibility() const
2030 {return priv_->visibility_;}
2031
2032 /// Test if the current instance of @ref elf_symbol is defined or not.
2033 ///
2034 /// @return true if the current instance of @ref elf_symbol is
2035 /// defined, false otherwise.
2036 bool
is_defined() const2037 elf_symbol::is_defined() const
2038 {return priv_->is_defined_;}
2039
2040 /// Sets a flag saying if the current instance of @ref elf_symbol is
2041 /// defined
2042 ///
2043 /// @param b the new value of the flag.
2044 void
is_defined(bool d)2045 elf_symbol::is_defined(bool d)
2046 {priv_->is_defined_ = d;}
2047
2048 /// Test if the current instance of @ref elf_symbol is public or not.
2049 ///
2050 /// This tests if the symbol is defined, has default or protected
2051 ///visibility, and either:
2052 /// - has global binding
2053 /// - has weak binding
2054 /// - or has a GNU_UNIQUE binding.
2055 ///
2056 /// return true if the current instance of @ref elf_symbol is public,
2057 /// false otherwise.
2058 bool
is_public() const2059 elf_symbol::is_public() const
2060 {
2061 return (is_defined()
2062 && (get_binding() == GLOBAL_BINDING
2063 || get_binding() == WEAK_BINDING
2064 || get_binding() == GNU_UNIQUE_BINDING)
2065 && (get_visibility() == DEFAULT_VISIBILITY
2066 || get_visibility() == PROTECTED_VISIBILITY));
2067 }
2068
2069 /// Test if the current instance of @ref elf_symbol is a function
2070 /// symbol or not.
2071 ///
2072 /// @return true if the current instance of @ref elf_symbol is a
2073 /// function symbol, false otherwise.
2074 bool
is_function() const2075 elf_symbol::is_function() const
2076 {return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2077
2078 /// Test if the current instance of @ref elf_symbol is a variable
2079 /// symbol or not.
2080 ///
2081 /// @return true if the current instance of @ref elf_symbol is a
2082 /// variable symbol, false otherwise.
2083 bool
is_variable() const2084 elf_symbol::is_variable() const
2085 {return get_type() == OBJECT_TYPE || get_type() == TLS_TYPE;}
2086
2087 /// Getter of the 'is-in-ksymtab' property.
2088 ///
2089 /// @return true iff the current symbol is in the Linux Kernel
2090 /// specific 'ksymtab' symbol table.
2091 bool
is_in_ksymtab() const2092 elf_symbol::is_in_ksymtab() const
2093 {return priv_->is_in_ksymtab_;}
2094
2095 /// Setter of the 'is-in-ksymtab' property.
2096 ///
2097 /// @param is_in_ksymtab this is true iff the current symbol is in the
2098 /// Linux Kernel specific 'ksymtab' symbol table.
2099 void
set_is_in_ksymtab(bool is_in_ksymtab)2100 elf_symbol::set_is_in_ksymtab(bool is_in_ksymtab)
2101 {priv_->is_in_ksymtab_ = is_in_ksymtab;}
2102
2103 /// Getter of the 'crc' property.
2104 ///
2105 /// @return the CRC (modversions) value for Linux Kernel symbols, if any
2106 const abg_compat::optional<uint32_t>&
get_crc() const2107 elf_symbol::get_crc() const
2108 {return priv_->crc_;}
2109
2110 /// Setter of the 'crc' property.
2111 ///
2112 /// @param crc the new CRC (modversions) value for Linux Kernel symbols
2113 void
set_crc(const abg_compat::optional<uint32_t> & crc)2114 elf_symbol::set_crc(const abg_compat::optional<uint32_t>& crc)
2115 {priv_->crc_ = crc;}
2116
2117 /// Getter of the 'namespace' property.
2118 ///
2119 /// @return the namespace for Linux Kernel symbols, if any
2120 const abg_compat::optional<std::string>&
get_namespace() const2121 elf_symbol::get_namespace() const
2122 {return priv_->namespace_;}
2123
2124 /// Setter of the 'namespace' property.
2125 ///
2126 /// @param ns the new namespace for Linux Kernel symbols, if any
2127 void
set_namespace(const abg_compat::optional<std::string> & ns)2128 elf_symbol::set_namespace(const abg_compat::optional<std::string>& ns)
2129 {priv_->namespace_ = ns;}
2130
2131 /// Getter for the 'is-suppressed' property.
2132 ///
2133 /// @return true iff the current symbol has been suppressed by a
2134 /// suppression specification that was provided in the context that
2135 /// led to the creation of the corpus this ELF symbol belongs to.
2136 bool
is_suppressed() const2137 elf_symbol::is_suppressed() const
2138 {return priv_->is_suppressed_;}
2139
2140 /// Setter for the 'is-suppressed' property.
2141 ///
2142 /// @param true iff the current symbol has been suppressed by a
2143 /// suppression specification that was provided in the context that
2144 /// led to the creation of the corpus this ELF symbol belongs to.
2145 void
set_is_suppressed(bool is_suppressed)2146 elf_symbol::set_is_suppressed(bool is_suppressed)
2147 {priv_->is_suppressed_ = is_suppressed;}
2148
2149 /// @name Elf symbol aliases
2150 ///
2151 /// An alias A for an elf symbol S is a symbol that is defined at the
2152 /// same address as S. S is chained to A through the
2153 /// elf_symbol::get_next_alias() method.
2154 ///
2155 /// When there are several aliases to a symbol, the main symbol is the
2156 /// the first symbol found in the symbol table for a given address.
2157 ///
2158 /// The alias chain is circular. That means if S is the main symbol
2159 /// and A is the alias, S is chained to A and A
2160 /// is chained back to the main symbol S. The last alias in an alias
2161 ///chain is always chained to the main symbol.
2162 ///
2163 /// Thus, when looping over the aliases of an elf_symbol A, detecting
2164 /// an alias that is equal to the main symbol should logically be a
2165 /// loop exit condition.
2166 ///
2167 /// Accessing and adding aliases for instances of elf_symbol is done
2168 /// through the member functions below.
2169
2170 /// @{
2171
2172 /// Get the main symbol of an alias chain.
2173 ///
2174 ///@return the main symbol.
2175 const elf_symbol_sptr
get_main_symbol() const2176 elf_symbol::get_main_symbol() const
2177 {return priv_->main_symbol_.lock();}
2178
2179 /// Get the main symbol of an alias chain.
2180 ///
2181 ///@return the main symbol.
2182 elf_symbol_sptr
get_main_symbol()2183 elf_symbol::get_main_symbol()
2184 {return priv_->main_symbol_.lock();}
2185
2186 /// Tests whether this symbol is the main symbol.
2187 ///
2188 /// @return true iff this symbol is the main symbol.
2189 bool
is_main_symbol() const2190 elf_symbol::is_main_symbol() const
2191 {return get_main_symbol().get() == this;}
2192
2193 /// Get the next alias of the current symbol.
2194 ///
2195 ///@return the alias, or NULL if there is no alias.
2196 elf_symbol_sptr
get_next_alias() const2197 elf_symbol::get_next_alias() const
2198 {return priv_->next_alias_.lock();}
2199
2200
2201 /// Check if the current elf_symbol has an alias.
2202 ///
2203 ///@return true iff the current elf_symbol has an alias.
2204 bool
has_aliases() const2205 elf_symbol::has_aliases() const
2206 {return bool(get_next_alias());}
2207
2208 /// Get the number of aliases to this elf symbol
2209 ///
2210 /// @return the number of aliases to this elf symbol.
2211 int
get_number_of_aliases() const2212 elf_symbol::get_number_of_aliases() const
2213 {
2214 int result = 0;
2215
2216 for (elf_symbol_sptr a = get_next_alias();
2217 a && a.get() != get_main_symbol().get();
2218 a = a->get_next_alias())
2219 ++result;
2220
2221 return result;
2222 }
2223
2224 /// Add an alias to the current elf symbol.
2225 ///
2226 /// @param alias the new alias. Note that this elf_symbol should *NOT*
2227 /// have aliases prior to the invocation of this function.
2228 void
add_alias(const elf_symbol_sptr & alias)2229 elf_symbol::add_alias(const elf_symbol_sptr& alias)
2230 {
2231 if (!alias)
2232 return;
2233
2234 ABG_ASSERT(!alias->has_aliases());
2235 ABG_ASSERT(is_main_symbol());
2236
2237 if (has_aliases())
2238 {
2239 elf_symbol_sptr last_alias;
2240 for (elf_symbol_sptr a = get_next_alias();
2241 a && !a->is_main_symbol();
2242 a = a->get_next_alias())
2243 {
2244 if (a->get_next_alias()->is_main_symbol())
2245 {
2246 ABG_ASSERT(last_alias == 0);
2247 last_alias = a;
2248 }
2249 }
2250 ABG_ASSERT(last_alias);
2251
2252 last_alias->priv_->next_alias_ = alias;
2253 }
2254 else
2255 priv_->next_alias_ = alias;
2256
2257 alias->priv_->next_alias_ = get_main_symbol();
2258 alias->priv_->main_symbol_ = get_main_symbol();
2259 }
2260
2261 /// Update the main symbol for a group of aliased symbols
2262 ///
2263 /// If after the construction of the symbols (in order of discovery), the
2264 /// actual main symbol can be identified (e.g. as the symbol that actually is
2265 /// defined in the code), this method offers a way of updating the main symbol
2266 /// through one of the aliased symbols.
2267 ///
2268 /// For that, locate the new main symbol by name and update all references to
2269 /// the main symbol among the group of aliased symbols.
2270 ///
2271 /// @param name the name of the main symbol
2272 ///
2273 /// @return the new main elf_symbol
2274 elf_symbol_sptr
update_main_symbol(const std::string & name)2275 elf_symbol::update_main_symbol(const std::string& name)
2276 {
2277 ABG_ASSERT(is_main_symbol());
2278 if (!has_aliases() || get_name() == name)
2279 return get_main_symbol();
2280
2281 // find the new main symbol
2282 elf_symbol_sptr new_main;
2283 // we've already checked this; check the rest of the aliases
2284 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2285 a = a->get_next_alias())
2286 if (a->get_name() == name)
2287 {
2288 new_main = a;
2289 break;
2290 }
2291
2292 if (!new_main)
2293 return get_main_symbol();
2294
2295 // now update all main symbol references
2296 priv_->main_symbol_ = new_main;
2297 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2298 a = a->get_next_alias())
2299 a->priv_->main_symbol_ = new_main;
2300
2301 return new_main;
2302 }
2303
2304 /// Return true if the symbol is a common one.
2305 ///
2306 /// @return true iff the symbol is common.
2307 bool
is_common_symbol() const2308 elf_symbol::is_common_symbol() const
2309 {return priv_->is_common_;}
2310
2311 /// Return true if this common common symbol has other common instances.
2312 ///
2313 /// A common instance of a given common symbol is another common
2314 /// symbol with the same name. Those exist in relocatable files. The
2315 /// linker normally allocates all the instances into a common block in
2316 /// the final output file.
2317 ///
2318 /// Note that the current object must be a common symbol, otherwise,
2319 /// this function aborts.
2320 ///
2321 /// @return true iff the current common symbol has other common
2322 /// instances.
2323 bool
has_other_common_instances() const2324 elf_symbol::has_other_common_instances() const
2325 {
2326 ABG_ASSERT(is_common_symbol());
2327 return bool(get_next_common_instance());
2328 }
2329
2330 /// Get the next common instance of the current common symbol.
2331 ///
2332 /// A common instance of a given common symbol is another common
2333 /// symbol with the same name. Those exist in relocatable files. The
2334 /// linker normally allocates all the instances into a common block in
2335 /// the final output file.
2336 ///
2337 /// @return the next common instance, or nil if there is not any.
2338 elf_symbol_sptr
get_next_common_instance() const2339 elf_symbol::get_next_common_instance() const
2340 {return priv_->next_common_instance_.lock();}
2341
2342 /// Add a common instance to the current common elf symbol.
2343 ///
2344 /// Note that this symbol must be the main symbol. Being the main
2345 /// symbol means being the first common symbol to appear in the symbol
2346 /// table.
2347 ///
2348 /// @param common the other common instance to add.
2349 void
add_common_instance(const elf_symbol_sptr & common)2350 elf_symbol::add_common_instance(const elf_symbol_sptr& common)
2351 {
2352 if (!common)
2353 return;
2354
2355 ABG_ASSERT(!common->has_other_common_instances());
2356 ABG_ASSERT(is_common_symbol());
2357 ABG_ASSERT(is_main_symbol());
2358
2359 if (has_other_common_instances())
2360 {
2361 elf_symbol_sptr last_common_instance;
2362 for (elf_symbol_sptr c = get_next_common_instance();
2363 c && (c.get() != get_main_symbol().get());
2364 c = c->get_next_common_instance())
2365 {
2366 if (c->get_next_common_instance().get() == get_main_symbol().get())
2367 {
2368 ABG_ASSERT(last_common_instance == 0);
2369 last_common_instance = c;
2370 }
2371 }
2372 ABG_ASSERT(last_common_instance);
2373
2374 last_common_instance->priv_->next_common_instance_ = common;
2375 }
2376 else
2377 priv_->next_common_instance_ = common;
2378
2379 common->priv_->next_common_instance_ = get_main_symbol();
2380 common->priv_->main_symbol_ = get_main_symbol();
2381 }
2382
2383 /// Get a string that is representative of a given elf_symbol.
2384 ///
2385 /// If the symbol has a version, then the ID string is the
2386 /// concatenation of the name of the symbol, the '@' character, and
2387 /// the version of the symbol. If the version is the default version
2388 /// of the symbol then the '@' character is replaced by a "@@" string.
2389 ///
2390 /// Otherwise, if the symbol does not have any version, this function
2391 /// returns the name of the symbol.
2392 ///
2393 /// @return a the ID string.
2394 const string&
get_id_string() const2395 elf_symbol::get_id_string() const
2396 {
2397 if (priv_->id_string_.empty())
2398 {
2399 string s = get_name ();
2400
2401 if (!get_version().is_empty())
2402 {
2403 if (get_version().is_default())
2404 s += "@@";
2405 else
2406 s += "@";
2407 s += get_version().str();
2408 }
2409 priv_->id_string_ = s;
2410 }
2411
2412 return priv_->id_string_;
2413 }
2414
2415 /// From the aliases of the current symbol, lookup one with a given name.
2416 ///
2417 /// @param name the name of symbol alias we are looking for.
2418 ///
2419 /// @return the symbol alias that has the name @p name, or nil if none
2420 /// has been found.
2421 elf_symbol_sptr
get_alias_from_name(const string & name) const2422 elf_symbol::get_alias_from_name(const string& name) const
2423 {
2424 if (name == get_name())
2425 return elf_symbol_sptr(priv_->main_symbol_);
2426
2427 for (elf_symbol_sptr a = get_next_alias();
2428 a && a.get() != get_main_symbol().get();
2429 a = a->get_next_alias())
2430 if (a->get_name() == name)
2431 return a;
2432
2433 return elf_symbol_sptr();
2434 }
2435
2436 /// In the list of aliases of a given elf symbol, get the alias that
2437 /// equals this current symbol.
2438 ///
2439 /// @param other the elf symbol to get the potential aliases from.
2440 ///
2441 /// @return the alias of @p other that texually equals the current
2442 /// symbol, or nil if no alias textually equals the current symbol.
2443 elf_symbol_sptr
get_alias_which_equals(const elf_symbol & other) const2444 elf_symbol::get_alias_which_equals(const elf_symbol& other) const
2445 {
2446 for (elf_symbol_sptr a = other.get_next_alias();
2447 a && a.get() != a->get_main_symbol().get();
2448 a = a->get_next_alias())
2449 if (textually_equals(*this, *a))
2450 return a;
2451 return elf_symbol_sptr();
2452 }
2453
2454 /// Return a comma separated list of the id of the current symbol as
2455 /// well as the id string of its aliases.
2456 ///
2457 /// @param syms a map of all the symbols of the corpus the current
2458 /// symbol belongs to.
2459 ///
2460 /// @param include_symbol_itself if set to true, then the name of the
2461 /// current symbol is included in the list of alias names that is emitted.
2462 ///
2463 /// @return the string.
2464 string
get_aliases_id_string(const string_elf_symbols_map_type & syms,bool include_symbol_itself) const2465 elf_symbol::get_aliases_id_string(const string_elf_symbols_map_type& syms,
2466 bool include_symbol_itself) const
2467 {
2468 string result;
2469
2470 if (include_symbol_itself)
2471 result = get_id_string();
2472
2473 vector<elf_symbol_sptr> aliases;
2474 compute_aliases_for_elf_symbol(*this, syms, aliases);
2475 if (!aliases.empty() && include_symbol_itself)
2476 result += ", ";
2477
2478 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2479 i != aliases.end();
2480 ++i)
2481 {
2482 if (i != aliases.begin())
2483 result += ", ";
2484 result += (*i)->get_id_string();
2485 }
2486 return result;
2487 }
2488
2489 /// Return a comma separated list of the id of the current symbol as
2490 /// well as the id string of its aliases.
2491 ///
2492 /// @param include_symbol_itself if set to true, then the name of the
2493 /// current symbol is included in the list of alias names that is emitted.
2494 ///
2495 /// @return the string.
2496 string
get_aliases_id_string(bool include_symbol_itself) const2497 elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2498 {
2499 vector<elf_symbol_sptr> aliases;
2500 if (include_symbol_itself)
2501 aliases.push_back(get_main_symbol());
2502
2503 for (elf_symbol_sptr a = get_next_alias();
2504 a && a.get() != get_main_symbol().get();
2505 a = a->get_next_alias())
2506 aliases.push_back(a);
2507
2508 string result;
2509 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2510 i != aliases.end();
2511 ++i)
2512 {
2513 if (i != aliases.begin())
2514 result += ", ";
2515 result += (*i)->get_id_string();
2516 }
2517
2518 return result;
2519 }
2520
2521 /// Given the ID of a symbol, get the name and the version of said
2522 /// symbol.
2523 ///
2524 /// @param id the symbol ID to consider.
2525 ///
2526 /// @param name the symbol name extracted from the ID. This is set
2527 /// only if the function returned true.
2528 ///
2529 /// @param ver the symbol version extracted from the ID.
2530 bool
get_name_and_version_from_id(const string & id,string & name,string & ver)2531 elf_symbol::get_name_and_version_from_id(const string& id,
2532 string& name,
2533 string& ver)
2534 {
2535 name.clear(), ver.clear();
2536
2537 string::size_type i = id.find('@');
2538 if (i == string::npos)
2539 {
2540 name = id;
2541 return true;
2542 }
2543
2544 name = id.substr(0, i);
2545 ++i;
2546
2547 if (i >= id.size())
2548 return true;
2549
2550 string::size_type j = id.find('@', i);
2551 if (j == string::npos)
2552 j = i;
2553 else
2554 ++j;
2555
2556 if (j >= id.size())
2557 {
2558 ver = "";
2559 return true;
2560 }
2561
2562 ver = id.substr(j);
2563 return true;
2564 }
2565
2566 ///@}
2567
2568 /// Test if two main symbols are textually equal, or, if they have
2569 /// aliases that are textually equal.
2570 ///
2571 /// @param other the symbol to compare against.
2572 ///
2573 /// @return true iff the current instance of elf symbol equals the @p
2574 /// other.
2575 bool
operator ==(const elf_symbol & other) const2576 elf_symbol::operator==(const elf_symbol& other) const
2577 {
2578 bool are_equal = textually_equals(*this, other);
2579 if (!are_equal)
2580 are_equal = bool(get_alias_which_equals(other));
2581 return are_equal;
2582 }
2583
2584 /// Test if the current symbol aliases another one.
2585 ///
2586 /// @param o the other symbol to test against.
2587 ///
2588 /// @return true iff the current symbol aliases @p o.
2589 bool
does_alias(const elf_symbol & o) const2590 elf_symbol::does_alias(const elf_symbol& o) const
2591 {
2592 if (*this == o)
2593 return true;
2594
2595 if (get_main_symbol() == o.get_main_symbol())
2596 return true;
2597
2598 for (elf_symbol_sptr a = get_next_alias();
2599 a && !a->is_main_symbol();
2600 a = a->get_next_alias())
2601 {
2602 if (o == *a)
2603 return true;
2604 }
2605 return false;
2606 }
2607
2608 /// Equality operator for smart pointers to elf_symbol.
2609 ///
2610 /// @param lhs the first elf symbol to consider.
2611 ///
2612 /// @param rhs the second elf symbol to consider.
2613 ///
2614 /// @return true iff @p lhs equals @p rhs.
2615 bool
operator ==(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2616 operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2617 {
2618 if (!!lhs != !!rhs)
2619 return false;
2620
2621 if (!lhs)
2622 return true;
2623
2624 return *lhs == *rhs;
2625 }
2626
2627 /// Inequality operator for smart pointers to elf_symbol.
2628 ///
2629 /// @param lhs the first elf symbol to consider.
2630 ///
2631 /// @param rhs the second elf symbol to consider.
2632 ///
2633 /// @return true iff @p lhs is different from @p rhs.
2634 bool
operator !=(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2635 operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2636 {return !operator==(lhs, rhs);}
2637
2638 /// Test if two symbols alias.
2639 ///
2640 /// @param s1 the first symbol to consider.
2641 ///
2642 /// @param s2 the second symbol to consider.
2643 ///
2644 /// @return true if @p s1 aliases @p s2.
2645 bool
elf_symbols_alias(const elf_symbol & s1,const elf_symbol & s2)2646 elf_symbols_alias(const elf_symbol& s1, const elf_symbol& s2)
2647 {return s1.does_alias(s2) || s2.does_alias(s1);}
2648
2649 void
compute_aliases_for_elf_symbol(const elf_symbol & sym,const string_elf_symbols_map_type & symtab,vector<elf_symbol_sptr> & aliases)2650 compute_aliases_for_elf_symbol(const elf_symbol& sym,
2651 const string_elf_symbols_map_type& symtab,
2652 vector<elf_symbol_sptr>& aliases)
2653 {
2654
2655 if (elf_symbol_sptr a = sym.get_next_alias())
2656 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2657 aliases.push_back(a);
2658 else
2659 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2660 i != symtab.end();
2661 ++i)
2662 for (elf_symbols::const_iterator j = i->second.begin();
2663 j != i->second.end();
2664 ++j)
2665 {
2666 if (**j == sym)
2667 for (elf_symbol_sptr s = (*j)->get_next_alias();
2668 s && !s->is_main_symbol();
2669 s = s->get_next_alias())
2670 aliases.push_back(s);
2671 else
2672 for (elf_symbol_sptr s = (*j)->get_next_alias();
2673 s && !s->is_main_symbol();
2674 s = s->get_next_alias())
2675 if (*s == sym)
2676 aliases.push_back(*j);
2677 }
2678 }
2679
2680 /// Test if two symbols alias.
2681 ///
2682 /// @param s1 the first symbol to consider.
2683 ///
2684 /// @param s2 the second symbol to consider.
2685 ///
2686 /// @return true if @p s1 aliases @p s2.
2687 bool
elf_symbols_alias(const elf_symbol * s1,const elf_symbol * s2)2688 elf_symbols_alias(const elf_symbol* s1, const elf_symbol* s2)
2689 {
2690 if (!!s1 != !!s2)
2691 return false;
2692 if (s1 == s2)
2693 return true;
2694 return elf_symbols_alias(*s1, *s2);
2695 }
2696
2697 /// Test if two symbols alias.
2698 ///
2699 /// @param s1 the first symbol to consider.
2700 ///
2701 /// @param s2 the second symbol to consider.
2702 ///
2703 /// @return true if @p s1 aliases @p s2.
2704 bool
elf_symbols_alias(const elf_symbol_sptr s1,const elf_symbol_sptr s2)2705 elf_symbols_alias(const elf_symbol_sptr s1, const elf_symbol_sptr s2)
2706 {return elf_symbols_alias(s1.get(), s2.get());}
2707
2708 /// Serialize an instance of @ref symbol_type and stream it to a given
2709 /// output stream.
2710 ///
2711 /// @param o the output stream to serialize the symbole type to.
2712 ///
2713 /// @param t the symbol type to serialize.
2714 std::ostream&
operator <<(std::ostream & o,elf_symbol::type t)2715 operator<<(std::ostream& o, elf_symbol::type t)
2716 {
2717 string repr;
2718
2719 switch (t)
2720 {
2721 case elf_symbol::NOTYPE_TYPE:
2722 repr = "unspecified symbol type";
2723 break;
2724 case elf_symbol::OBJECT_TYPE:
2725 repr = "variable symbol type";
2726 break;
2727 case elf_symbol::FUNC_TYPE:
2728 repr = "function symbol type";
2729 break;
2730 case elf_symbol::SECTION_TYPE:
2731 repr = "section symbol type";
2732 break;
2733 case elf_symbol::FILE_TYPE:
2734 repr = "file symbol type";
2735 break;
2736 case elf_symbol::COMMON_TYPE:
2737 repr = "common data object symbol type";
2738 break;
2739 case elf_symbol::TLS_TYPE:
2740 repr = "thread local data object symbol type";
2741 break;
2742 case elf_symbol::GNU_IFUNC_TYPE:
2743 repr = "indirect function symbol type";
2744 break;
2745 default:
2746 {
2747 std::ostringstream s;
2748 s << "unknown symbol type (" << (char)t << ')';
2749 repr = s.str();
2750 }
2751 break;
2752 }
2753
2754 o << repr;
2755 return o;
2756 }
2757
2758 /// Serialize an instance of @ref symbol_binding and stream it to a
2759 /// given output stream.
2760 ///
2761 /// @param o the output stream to serialize the symbole type to.
2762 ///
2763 /// @param b the symbol binding to serialize.
2764 std::ostream&
operator <<(std::ostream & o,elf_symbol::binding b)2765 operator<<(std::ostream& o, elf_symbol::binding b)
2766 {
2767 string repr;
2768
2769 switch (b)
2770 {
2771 case elf_symbol::LOCAL_BINDING:
2772 repr = "local binding";
2773 break;
2774 case elf_symbol::GLOBAL_BINDING:
2775 repr = "global binding";
2776 break;
2777 case elf_symbol::WEAK_BINDING:
2778 repr = "weak binding";
2779 break;
2780 case elf_symbol::GNU_UNIQUE_BINDING:
2781 repr = "GNU unique binding";
2782 break;
2783 default:
2784 {
2785 std::ostringstream s;
2786 s << "unknown binding (" << (unsigned char) b << ")";
2787 repr = s.str();
2788 }
2789 break;
2790 }
2791
2792 o << repr;
2793 return o;
2794 }
2795
2796 /// Serialize an instance of @ref elf_symbol::visibility and stream it
2797 /// to a given output stream.
2798 ///
2799 /// @param o the output stream to serialize the symbole type to.
2800 ///
2801 /// @param v the symbol visibility to serialize.
2802 std::ostream&
operator <<(std::ostream & o,elf_symbol::visibility v)2803 operator<<(std::ostream& o, elf_symbol::visibility v)
2804 {
2805 string repr;
2806
2807 switch (v)
2808 {
2809 case elf_symbol::DEFAULT_VISIBILITY:
2810 repr = "default visibility";
2811 break;
2812 case elf_symbol::PROTECTED_VISIBILITY:
2813 repr = "protected visibility";
2814 break;
2815 case elf_symbol::HIDDEN_VISIBILITY:
2816 repr = "hidden visibility";
2817 break;
2818 case elf_symbol::INTERNAL_VISIBILITY:
2819 repr = "internal visibility";
2820 break;
2821 default:
2822 {
2823 std::ostringstream s;
2824 s << "unknown visibility (" << (unsigned char) v << ")";
2825 repr = s.str();
2826 }
2827 break;
2828 }
2829
2830 o << repr;
2831 return o;
2832 }
2833
2834 /// Convert a string representing a symbol type into an
2835 /// elf_symbol::type.
2836 ///
2837 ///@param s the string to convert.
2838 ///
2839 ///@param t the resulting elf_symbol::type.
2840 ///
2841 /// @return true iff the conversion completed successfully.
2842 bool
string_to_elf_symbol_type(const string & s,elf_symbol::type & t)2843 string_to_elf_symbol_type(const string& s, elf_symbol::type& t)
2844 {
2845 if (s == "no-type")
2846 t = elf_symbol::NOTYPE_TYPE;
2847 else if (s == "object-type")
2848 t = elf_symbol::OBJECT_TYPE;
2849 else if (s == "func-type")
2850 t = elf_symbol::FUNC_TYPE;
2851 else if (s == "section-type")
2852 t = elf_symbol::SECTION_TYPE;
2853 else if (s == "file-type")
2854 t = elf_symbol::FILE_TYPE;
2855 else if (s == "common-type")
2856 t = elf_symbol::COMMON_TYPE;
2857 else if (s == "tls-type")
2858 t = elf_symbol::TLS_TYPE;
2859 else if (s == "gnu-ifunc-type")
2860 t = elf_symbol::GNU_IFUNC_TYPE;
2861 else
2862 return false;
2863
2864 return true;
2865 }
2866
2867 /// Convert a string representing a an elf symbol binding into an
2868 /// elf_symbol::binding.
2869 ///
2870 /// @param s the string to convert.
2871 ///
2872 /// @param b the resulting elf_symbol::binding.
2873 ///
2874 /// @return true iff the conversion completed successfully.
2875 bool
string_to_elf_symbol_binding(const string & s,elf_symbol::binding & b)2876 string_to_elf_symbol_binding(const string& s, elf_symbol::binding& b)
2877 {
2878 if (s == "local-binding")
2879 b = elf_symbol::LOCAL_BINDING;
2880 else if (s == "global-binding")
2881 b = elf_symbol::GLOBAL_BINDING;
2882 else if (s == "weak-binding")
2883 b = elf_symbol::WEAK_BINDING;
2884 else if (s == "gnu-unique-binding")
2885 b = elf_symbol::GNU_UNIQUE_BINDING;
2886 else
2887 return false;
2888
2889 return true;
2890 }
2891
2892 /// Convert a string representing a an elf symbol visibility into an
2893 /// elf_symbol::visibility.
2894 ///
2895 /// @param s the string to convert.
2896 ///
2897 /// @param b the resulting elf_symbol::visibility.
2898 ///
2899 /// @return true iff the conversion completed successfully.
2900 bool
string_to_elf_symbol_visibility(const string & s,elf_symbol::visibility & v)2901 string_to_elf_symbol_visibility(const string& s, elf_symbol::visibility& v)
2902 {
2903 if (s == "default-visibility")
2904 v = elf_symbol::DEFAULT_VISIBILITY;
2905 else if (s == "protected-visibility")
2906 v = elf_symbol::PROTECTED_VISIBILITY;
2907 else if (s == "hidden-visibility")
2908 v = elf_symbol::HIDDEN_VISIBILITY;
2909 else if (s == "internal-visibility")
2910 v = elf_symbol::INTERNAL_VISIBILITY;
2911 else
2912 return false;
2913
2914 return true;
2915 }
2916
2917 /// Test if the type of an ELF symbol denotes a function symbol.
2918 ///
2919 /// @param t the type of the ELF symbol.
2920 ///
2921 /// @return true iff elf symbol type @p t denotes a function symbol
2922 /// type.
2923 bool
elf_symbol_is_function(elf_symbol::type t)2924 elf_symbol_is_function(elf_symbol::type t)
2925 {return t == elf_symbol::FUNC_TYPE;}
2926
2927 /// Test if the type of an ELF symbol denotes a function symbol.
2928 ///
2929 /// @param t the type of the ELF symbol.
2930 ///
2931 /// @return true iff elf symbol type @p t denotes a function symbol
2932 /// type.
2933 bool
elf_symbol_is_variable(elf_symbol::type t)2934 elf_symbol_is_variable(elf_symbol::type t)
2935 {return t == elf_symbol::OBJECT_TYPE;}
2936
2937 // <elf_symbol::version stuff>
2938
2939 struct elf_symbol::version::priv
2940 {
2941 string version_;
2942 bool is_default_;
2943
privabigail::ir::elf_symbol::version::priv2944 priv()
2945 : is_default_(false)
2946 {}
2947
privabigail::ir::elf_symbol::version::priv2948 priv(const string& v,
2949 bool d)
2950 : version_(v),
2951 is_default_(d)
2952 {}
2953 }; // end struct elf_symbol::version::priv
2954
version()2955 elf_symbol::version::version()
2956 : priv_(new priv)
2957 {}
2958
2959 /// @param v the name of the version.
2960 ///
2961 /// @param is_default true if this is a default version.
version(const string & v,bool is_default)2962 elf_symbol::version::version(const string& v,
2963 bool is_default)
2964 : priv_(new priv(v, is_default))
2965 {}
2966
version(const elf_symbol::version & v)2967 elf_symbol::version::version(const elf_symbol::version& v)
2968 : priv_(new priv(v.str(), v.is_default()))
2969 {
2970 }
2971
2972 elf_symbol::version::~version() = default;
2973
2974 /// Cast the version_type into a string that is its name.
2975 ///
2976 /// @return the name of the version.
operator const string&() const2977 elf_symbol::version::operator const string&() const
2978 {return priv_->version_;}
2979
2980 /// Getter for the version name.
2981 ///
2982 /// @return the version name.
2983 const string&
str() const2984 elf_symbol::version::str() const
2985 {return priv_->version_;}
2986
2987 /// Setter for the version name.
2988 ///
2989 /// @param s the version name.
2990 void
str(const string & s)2991 elf_symbol::version::str(const string& s)
2992 {priv_->version_ = s;}
2993
2994 /// Getter for the 'is_default' property of the version.
2995 ///
2996 /// @return true iff this is a default version.
2997 bool
is_default() const2998 elf_symbol::version::is_default() const
2999 {return priv_->is_default_;}
3000
3001 /// Setter for the 'is_default' property of the version.
3002 ///
3003 /// @param f true if this is the default version.
3004 void
is_default(bool f)3005 elf_symbol::version::is_default(bool f)
3006 {priv_->is_default_ = f;}
3007
3008 bool
is_empty() const3009 elf_symbol::version::is_empty() const
3010 {return str().empty();}
3011
3012 /// Compares the current version against another one.
3013 ///
3014 /// @param o the other version to compare the current one to.
3015 ///
3016 /// @return true iff the current version equals @p o.
3017 bool
operator ==(const elf_symbol::version & o) const3018 elf_symbol::version::operator==(const elf_symbol::version& o) const
3019 {return str() == o.str();}
3020
3021 /// Inequality operator.
3022 ///
3023 /// @param o the version to compare against the current one.
3024 ///
3025 /// @return true iff both versions are different.
3026 bool
operator !=(const version & o) const3027 elf_symbol::version::operator!=(const version& o) const
3028 {return !operator==(o);}
3029
3030 /// Assign a version to the current one.
3031 ///
3032 /// @param o the other version to assign to this one.
3033 ///
3034 /// @return a reference to the assigned version.
3035 elf_symbol::version&
operator =(const elf_symbol::version & o)3036 elf_symbol::version::operator=(const elf_symbol::version& o)
3037 {
3038 str(o.str());
3039 is_default(o.is_default());
3040 return *this;
3041 }
3042
3043 // </elf_symbol::version stuff>
3044
3045 // </elf_symbol stuff>
3046
3047 // <class dm_context_rel stuff>
3048 struct dm_context_rel::priv
3049 {
3050 bool is_laid_out_;
3051 size_t offset_in_bits_;
3052 var_decl* anonymous_data_member_;
3053
privabigail::ir::dm_context_rel::priv3054 priv(bool is_static = false)
3055 : is_laid_out_(!is_static),
3056 offset_in_bits_(0),
3057 anonymous_data_member_()
3058 {}
3059
privabigail::ir::dm_context_rel::priv3060 priv(bool is_laid_out, size_t offset_in_bits)
3061 : is_laid_out_(is_laid_out),
3062 offset_in_bits_(offset_in_bits),
3063 anonymous_data_member_()
3064 {}
3065 }; //end struct dm_context_rel::priv
3066
dm_context_rel()3067 dm_context_rel::dm_context_rel()
3068 : context_rel(),
3069 priv_(new priv)
3070 {}
3071
dm_context_rel(scope_decl * s,bool is_laid_out,size_t offset_in_bits,access_specifier a,bool is_static)3072 dm_context_rel::dm_context_rel(scope_decl* s,
3073 bool is_laid_out,
3074 size_t offset_in_bits,
3075 access_specifier a,
3076 bool is_static)
3077 : context_rel(s, a, is_static),
3078 priv_(new priv(is_laid_out, offset_in_bits))
3079 {}
3080
dm_context_rel(scope_decl * s)3081 dm_context_rel::dm_context_rel(scope_decl* s)
3082 : context_rel(s),
3083 priv_(new priv())
3084 {}
3085
3086 bool
get_is_laid_out() const3087 dm_context_rel::get_is_laid_out() const
3088 {return priv_->is_laid_out_;}
3089
3090 void
set_is_laid_out(bool f)3091 dm_context_rel::set_is_laid_out(bool f)
3092 {priv_->is_laid_out_ = f;}
3093
3094 size_t
get_offset_in_bits() const3095 dm_context_rel::get_offset_in_bits() const
3096 {return priv_->offset_in_bits_;}
3097
3098 void
set_offset_in_bits(size_t o)3099 dm_context_rel::set_offset_in_bits(size_t o)
3100 {priv_->offset_in_bits_ = o;}
3101
3102 bool
operator ==(const dm_context_rel & o) const3103 dm_context_rel::operator==(const dm_context_rel& o) const
3104 {
3105 if (!context_rel::operator==(o))
3106 return false;
3107
3108 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3109 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3110 }
3111
3112 bool
operator !=(const dm_context_rel & o) const3113 dm_context_rel::operator!=(const dm_context_rel& o) const
3114 {return !operator==(o);}
3115
3116 /// Return a non-nil value if this data member context relationship
3117 /// has an anonymous data member. That means, if the data member this
3118 /// relation belongs to is part of an anonymous data member.
3119 ///
3120 /// @return the containing anonymous data member of this data member
3121 /// relationship. Nil if there is none.
3122 const var_decl*
get_anonymous_data_member() const3123 dm_context_rel::get_anonymous_data_member() const
3124 {return priv_->anonymous_data_member_;}
3125
3126 /// Set the containing anonymous data member of this data member
3127 /// context relationship. That means that the data member this
3128 /// relation belongs to is part of an anonymous data member.
3129 ///
3130 /// @param anon_dm the containing anonymous data member of this data
3131 /// member relationship. Nil if there is none.
3132 void
set_anonymous_data_member(var_decl * anon_dm)3133 dm_context_rel::set_anonymous_data_member(var_decl* anon_dm)
3134 {priv_->anonymous_data_member_ = anon_dm;}
3135
~dm_context_rel()3136 dm_context_rel::~dm_context_rel()
3137 {}
3138 // </class dm_context_rel stuff>
3139
3140 // <environment stuff>
3141
3142 /// Convenience typedef for a map of interned_string -> bool.
3143 typedef unordered_map<interned_string,
3144 bool, hash_interned_string> interned_string_bool_map_type;
3145
3146
3147 /// Default constructor of the @ref environment type.
environment()3148 environment::environment()
3149 :priv_(new priv)
3150 {}
3151
3152 /// Destructor for the @ref environment type.
~environment()3153 environment::~environment()
3154 {}
3155
3156 /// Getter the map of canonical types.
3157 ///
3158 /// @return the map of canonical types. The key of the map is the
3159 /// hash of the canonical type and its value if the canonical type.
3160 environment::canonical_types_map_type&
get_canonical_types_map()3161 environment::get_canonical_types_map()
3162 {return priv_->canonical_types_;}
3163
3164 /// Getter the map of canonical types.
3165 ///
3166 /// @return the map of canonical types. The key of the map is the
3167 /// hash of the canonical type and its value if the canonical type.
3168 const environment::canonical_types_map_type&
get_canonical_types_map() const3169 environment::get_canonical_types_map() const
3170 {return const_cast<environment*>(this)->get_canonical_types_map();}
3171
3172 /// Helper to detect if a type is either a reference, a pointer, or a
3173 /// qualified type.
3174 static bool
is_ptr_ref_or_qual_type(const type_base * t)3175 is_ptr_ref_or_qual_type(const type_base *t)
3176 {
3177 if (is_pointer_type(t)
3178 || is_reference_type(t)
3179 || is_qualified_type(t))
3180 return true;
3181 return false;
3182 }
3183
3184 /// Compare decls using their locations.
3185 ///
3186 /// @param f the first decl to compare.
3187 ///
3188 /// @param s the second decl to compare.
3189 ///
3190 /// @return true if @p f compares less than @p s.
3191 static bool
compare_using_locations(const decl_base * f,const decl_base * s)3192 compare_using_locations(const decl_base *f,
3193 const decl_base *s)
3194 {
3195 // If a decl has artificial location, then use that one over the
3196 // natural one.
3197 location fl = get_artificial_or_natural_location(f);
3198 location sl = get_artificial_or_natural_location(s);
3199
3200 ABG_ASSERT(fl.get_value() && sl.get_value());
3201 if (fl.get_is_artificial() == sl.get_is_artificial())
3202 {
3203 // The locations of the two artfifacts have the same
3204 // artificial-ness so they can be compared.
3205 string p1, p2;
3206 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3207 fl.expand(p1, l1, c1);
3208 sl.expand(p2, l2, c2);
3209 if (p1 != p2)
3210 return p1 < p2;
3211 if (l1 != l2)
3212 return l1 < l2;
3213 if (c1 != c2)
3214 return c1 < c2;
3215 }
3216
3217 return (get_pretty_representation(f, /*internal=*/false)
3218 < get_pretty_representation(s, /*internal=*/false));
3219 }
3220
3221 /// A functor to sort decls somewhat topologically. That is, types
3222 /// are sorted in a way that makes the ones that are defined "first"
3223 /// to come first.
3224 ///
3225 /// The topological criteria is a lexicographic sort of the definition
3226 /// location of the type. For types that have no location (or the
3227 /// same location), it's their qualified name that is used for the
3228 /// lexicographic sort.
3229 struct decl_topo_comp
3230 {
3231
3232 /// The "Less Than" comparison operator of this functor.
3233 ///
3234 /// @param f the first decl to be considered for the comparison.
3235 ///
3236 /// @param s the second decl to be considered for the comparison.
3237 ///
3238 /// @return true iff @p f is less than @p s.
3239 bool
operator ()abigail::ir::decl_topo_comp3240 operator()(const decl_base *f,
3241 const decl_base *s)
3242 {
3243 if (!!f != !!s)
3244 return f && !s;
3245
3246 if (!f)
3247 return false;
3248
3249 // If both decls come from an abixml file, keep the order they
3250 // have from that abixml file.
3251 if ((!f->get_corpus() && !s->get_corpus())
3252 || (f->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
3253 && s->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN))
3254 return compare_using_locations(f, s);
3255
3256 // If a decl has artificial location, then use that one over the
3257 // natural one.
3258 location fl = get_artificial_or_natural_location(f);
3259 location sl = get_artificial_or_natural_location(s);
3260
3261 if (fl.get_value() && sl.get_value())
3262 return compare_using_locations(f, s);
3263 else if (!!fl != !!sl)
3264 // So one of the decls doesn't have location data.
3265 // The first decl is less than the second if it's the one not
3266 // having location data.
3267 return !fl && sl;
3268
3269 // We reach this point if location data is useless.
3270 if (f->get_is_anonymous()
3271 && s->get_is_anonymous()
3272 && (get_pretty_representation(f, /*internal=*/false)
3273 == get_pretty_representation(s, /*internal=*/false)))
3274 return f->get_name() < s->get_name();
3275
3276 return (get_pretty_representation(f, /*internal=*/false)
3277 < get_pretty_representation(s, /*internal=*/false));
3278 }
3279
3280 /// The "Less Than" comparison operator of this functor.
3281 ///
3282 /// @param f the first decl to be considered for the comparison.
3283 ///
3284 /// @param s the second decl to be considered for the comparison.
3285 ///
3286 /// @return true iff @p f is less than @p s.
3287 bool
operator ()abigail::ir::decl_topo_comp3288 operator()(const decl_base_sptr &f,
3289 const decl_base_sptr &s)
3290 {return operator()(f.get(), s.get());}
3291
3292 }; // end struct decl_topo_comp
3293
3294 /// A functor to sort types somewhat topologically. That is, types
3295 /// are sorted in a way that makes the ones that are defined "first"
3296 /// to come first.
3297 ///
3298 /// The topological criteria is a lexicographic sort of the definition
3299 /// location of the type. For types that have no location, it's their
3300 /// qualified name that is used for the lexicographic sort.
3301 struct type_topo_comp
3302 {
3303 /// Test if a decl has an artificial or natural location.
3304 ///
3305 /// @param d the decl to consider
3306 ///
3307 /// @return true iff @p d has a location.
3308 bool
has_artificial_or_natural_locationabigail::ir::type_topo_comp3309 has_artificial_or_natural_location(const decl_base* d)
3310 {return get_artificial_or_natural_location(d);}
3311
3312 /// Test if a type has an artificial or natural location.
3313 ///
3314 /// @param t the type to consider
3315 ///
3316 /// @return true iff @p t has a location.
3317 bool
has_artificial_or_natural_locationabigail::ir::type_topo_comp3318 has_artificial_or_natural_location(const type_base* t)
3319 {
3320 if (decl_base *d = is_decl(t))
3321 return has_artificial_or_natural_location(d);
3322 return false;
3323 }
3324
3325 /// The "Less Than" comparison operator of this functor.
3326 ///
3327 /// @param f the first type to be considered for the comparison.
3328 ///
3329 /// @param s the second type to be considered for the comparison.
3330 ///
3331 /// @return true iff @p f is less than @p s.
3332 bool
operator ()abigail::ir::type_topo_comp3333 operator()(const type_base_sptr &f,
3334 const type_base_sptr &s)
3335 {return operator()(f.get(), s.get());}
3336
3337 /// The "Less Than" comparison operator of this functor.
3338 ///
3339 /// @param f the first type to be considered for the comparison.
3340 ///
3341 /// @param s the second type to be considered for the comparison.
3342 ///
3343 /// @return true iff @p f is less than @p s.
3344 bool
operator ()abigail::ir::type_topo_comp3345 operator()(const type_base *f,
3346 const type_base *s)
3347 {
3348 // If both decls come from an abixml file, keep the order they
3349 // have from that abixml file.
3350 if ((!f->get_corpus() && !s->get_corpus())
3351 || (f->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
3352 && s->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN))
3353 return compare_using_locations(is_decl(f), is_decl(s));
3354
3355 bool f_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(f);
3356 bool s_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(s);
3357
3358 if (f_is_ptr_ref_or_qual != s_is_ptr_ref_or_qual)
3359 return !f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual;
3360
3361 if (f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual
3362 && !has_artificial_or_natural_location(f)
3363 && !has_artificial_or_natural_location(s))
3364 {
3365 string s1 = get_pretty_representation(f, /*internal=*/false);
3366 string s2 = get_pretty_representation(s, /*internal=*/false);
3367 if (s1 == s2)
3368 {
3369 if (qualified_type_def * q = is_qualified_type(f))
3370 {
3371 if (q->get_cv_quals() == qualified_type_def::CV_NONE)
3372 if (!is_qualified_type(s))
3373 // We are looking at two types that are the result of
3374 // an optimization that happens during the IR
3375 // construction. Namely, type f is a cv-qualified
3376 // type with no qualifier (no const, no volatile, no
3377 // nothing, we call it an empty-qualified type).
3378 // These are the result of an optimization which
3379 // removes "redundant qualifiers" from some types.
3380 // For instance, consider a "const reference". The
3381 // const there is redundant because a reference is
3382 // always const. So as a result of the optimizaton
3383 // that type is going to be transformed into an
3384 // empty-qualified reference. If we don't make that
3385 // optimization, then we risk having spurious change
3386 // reports down the road. But then, as a consequence
3387 // of that optimization, we need to sort the
3388 // empty-qualified type and its non-qualified variant
3389 // e.g, to ensure stability in the abixml output; both
3390 // types are logically equal, but here, we decide that
3391 // the empty-qualified one is topologically "less
3392 // than" the non-qualified counterpart.
3393 //
3394 // So here, type f is an empty-qualified type and type
3395 // s is its non-qualified variant. We decide that f
3396 // is topologically less than s.
3397 return true;
3398 }
3399 // Now let's peel off the pointer (or reference types) and
3400 // see if the ultimate underlying types have the same
3401 // textual representation; if not, use that as sorting
3402 // criterion.
3403 type_base *peeled_f =
3404 peel_pointer_or_reference_type(f, true);
3405 type_base *peeled_s =
3406 peel_pointer_or_reference_type(s, true);
3407
3408 s1 = get_pretty_representation(peeled_f, /*internal=*/false);
3409 s2 = get_pretty_representation(peeled_s, /*internal=*/false);
3410 if (s1 != s2)
3411 return s1 < s2;
3412
3413 // The underlying type of pointer/reference have the same
3414 // textual representation; let's try to peel of typedefs
3415 // as well and we'll consider sorting the result as decls.
3416 peeled_f = peel_typedef_pointer_or_reference_type(peeled_f, true);
3417 peeled_s = peel_typedef_pointer_or_reference_type(peeled_s, true);
3418
3419 s1 = get_pretty_representation(peeled_f, false);
3420 s2 = get_pretty_representation(peeled_s, false);
3421 if (s1 != s2)
3422 return s1 < s2;
3423 }
3424 }
3425
3426 string s1 = get_pretty_representation(f, false);
3427 string s2 = get_pretty_representation(s, false);
3428
3429 if (s1 != s2)
3430 return s1 < s2;
3431
3432 if (is_typedef(f) && is_typedef(s))
3433 {
3434 s1 = get_pretty_representation(is_typedef(f)->get_underlying_type(),
3435 false);
3436 s2 = get_pretty_representation(is_typedef(s)->get_underlying_type(),
3437 false);
3438 if (s1 != s2)
3439 return s1 < s2;
3440 }
3441
3442 type_base *peeled_f = peel_typedef_pointer_or_reference_type(f, true);
3443 type_base *peeled_s = peel_typedef_pointer_or_reference_type(s, true);
3444
3445 s1 = get_pretty_representation(peeled_f, false);
3446 s2 = get_pretty_representation(peeled_s, false);
3447
3448 if (s1 != s2)
3449 return s1 < s2;
3450
3451 decl_base *fd = is_decl(f);
3452 decl_base *sd = is_decl(s);
3453
3454 if (!!fd != !!sd)
3455 return fd && !sd;
3456
3457 // If the two types have no decls, how come we could not sort them
3458 // until now? Let's investigate.
3459 ABG_ASSERT(fd);
3460
3461 // From this point, fd and sd should be non-nil
3462 decl_topo_comp decl_comp;
3463 return decl_comp(fd, sd);
3464 }
3465 }; //end struct type_topo_comp
3466
3467 /// Sort types in a hopefully stable manner.
3468 ///
3469 /// @param types a set of types with canonical types to sort.
3470 ///
3471 /// @param result the resulting sorted vector.
3472 void
sort_types(const canonical_type_sptr_set_type & types,vector<type_base_sptr> & result)3473 sort_types(const canonical_type_sptr_set_type& types,
3474 vector<type_base_sptr>& result)
3475 {
3476 for (auto t: types)
3477 result.push_back(t);
3478
3479 type_topo_comp comp;
3480 std::stable_sort(result.begin(), result.end(), comp);
3481 }
3482
3483 /// Get a @ref type_decl that represents a "void" type for the current
3484 /// environment.
3485 ///
3486 /// @return the @ref type_decl that represents a "void" type.
3487 const type_base_sptr&
get_void_type() const3488 environment::get_void_type() const
3489 {
3490 if (!priv_->void_type_)
3491 priv_->void_type_.reset(new type_decl(*this,
3492 intern("void"),
3493 0, 0, location()));
3494 return priv_->void_type_;
3495 }
3496
3497 /// Get a @ref type_decl instance that represents a the type of a
3498 /// variadic function parameter.
3499 ///
3500 /// @return the Get a @ref type_decl instance that represents a the
3501 /// type of a variadic function parameter.
3502 const type_base_sptr&
get_variadic_parameter_type() const3503 environment::get_variadic_parameter_type() const
3504 {
3505 if (!priv_->variadic_marker_type_)
3506 priv_->variadic_marker_type_.
3507 reset(new type_decl(*this,
3508 intern("variadic parameter type"),
3509 0, 0, location()));
3510 return priv_->variadic_marker_type_;
3511 }
3512
3513 /// Test if the canonicalization of types created out of the current
3514 /// environment is done.
3515 ///
3516 /// @return true iff the canonicalization of types created out of the current
3517 /// environment is done.
3518 bool
canonicalization_is_done() const3519 environment::canonicalization_is_done() const
3520 {return priv_->canonicalization_is_done_;}
3521
3522 /// Set a flag saying if the canonicalization of types created out of
3523 /// the current environment is done or not.
3524 ///
3525 /// Note that this function must only be called by internal code of
3526 /// the library that creates ABI artifacts (e.g, read an abi corpus
3527 /// from elf or from our own xml format and creates representations of
3528 /// types out of it) and thus needs to canonicalize types to speed-up
3529 /// further type comparison.
3530 ///
3531 /// @param f the new value of the flag.
3532 void
canonicalization_is_done(bool f)3533 environment::canonicalization_is_done(bool f)
3534 {priv_->canonicalization_is_done_ = f;}
3535
3536 /// Getter for the "on-the-fly-canonicalization" flag.
3537 ///
3538 /// @return true iff @ref OnTheFlyCanonicalization
3539 /// "on-the-fly-canonicalization" is to be performed during
3540 /// comparison.
3541 bool
do_on_the_fly_canonicalization() const3542 environment::do_on_the_fly_canonicalization() const
3543 {return priv_->do_on_the_fly_canonicalization_;}
3544
3545 /// Setter for the "on-the-fly-canonicalization" flag.
3546 ///
3547 /// @param f If this is true then @ref OnTheFlyCanonicalization
3548 /// "on-the-fly-canonicalization" is to be performed during
3549 /// comparison.
3550 void
do_on_the_fly_canonicalization(bool f)3551 environment::do_on_the_fly_canonicalization(bool f)
3552 {priv_->do_on_the_fly_canonicalization_ = f;}
3553
3554 /// Getter of the "decl-only-class-equals-definition" flag.
3555 ///
3556 /// Usually, a declaration-only class named 'struct foo' compares
3557 /// equal to any class definition named "struct foo'. This is at
3558 /// least true for C++.
3559 ///
3560 /// In C, though, because there can be multiple definitions of 'struct
3561 /// foo' in the binary, a declaration-only "struct foo" might be
3562 /// considered to *NOT* resolve to any of the struct foo defined. In
3563 /// that case, the declaration-only "struct foo" is considered
3564 /// different from the definitions.
3565 ///
3566 /// This flag controls the behaviour of the comparison of an
3567 /// unresolved decl-only class against a definition of the same name.
3568 ///
3569 /// If set to false, the the declaration equals the definition. If
3570 /// set to false, then the decalration is considered different from
3571 /// the declaration.
3572 ///
3573 /// @return the value of the "decl-only-class-equals-definition" flag.
3574 bool
decl_only_class_equals_definition() const3575 environment::decl_only_class_equals_definition() const
3576 {return priv_->decl_only_class_equals_definition_;}
3577
3578 /// Setter of the "decl-only-class-equals-definition" flag.
3579 ///
3580 /// Usually, a declaration-only class named 'struct foo' compares
3581 /// equal to any class definition named "struct foo'. This is at
3582 /// least true for C++.
3583 ///
3584 /// In C, though, because there can be multiple definitions of 'struct
3585 /// foo' in the binary, a declaration-only "struct foo" might be
3586 /// considered to *NOT* resolve to any of the struct foo defined. In
3587 /// that case, the declaration-only "struct foo" is considered
3588 /// different from the definitions.
3589 ///
3590 /// This flag controls the behaviour of the comparison of an
3591 /// unresolved decl-only class against a definition of the same name.
3592 ///
3593 /// If set to false, the the declaration equals the definition. If
3594 /// set to false, then the decalration is considered different from
3595 /// the declaration.
3596 ///
3597 /// @param the new value of the "decl-only-class-equals-definition"
3598 /// flag.
3599 void
decl_only_class_equals_definition(bool f) const3600 environment::decl_only_class_equals_definition(bool f) const
3601 {priv_->decl_only_class_equals_definition_ = f;}
3602
3603 /// Test if a given type is a void type as defined in the current
3604 /// environment.
3605 ///
3606 /// @param t the type to consider.
3607 ///
3608 /// @return true iff @p t is a void type as defined in the current
3609 /// environment.
3610 bool
is_void_type(const type_base_sptr & t) const3611 environment::is_void_type(const type_base_sptr& t) const
3612 {
3613 if (!t)
3614 return false;
3615 return t.get() == get_void_type().get();
3616 }
3617
3618 /// Test if a given type is a void type as defined in the current
3619 /// environment.
3620 ///
3621 /// @param t the type to consider.
3622 ///
3623 /// @return true iff @p t is a void type as defined in the current
3624 /// environment.
3625 bool
is_void_type(const type_base * t) const3626 environment::is_void_type(const type_base* t) const
3627 {
3628 if (!t)
3629 return false;
3630 return t == get_void_type().get();
3631 }
3632
3633 /// Test if a type is a variadic parameter type as defined in the
3634 /// current environment.
3635 ///
3636 /// @param t the type to consider.
3637 ///
3638 /// @return true iff @p t is a variadic parameter type as defined in
3639 /// the current environment.
3640 bool
is_variadic_parameter_type(const type_base * t) const3641 environment::is_variadic_parameter_type(const type_base* t) const
3642 {
3643 if (!t)
3644 return false;
3645 return t == get_variadic_parameter_type().get();
3646 }
3647
3648 /// Test if a type is a variadic parameter type as defined in the
3649 /// current environment.
3650 ///
3651 /// @param t the type to consider.
3652 ///
3653 /// @return true iff @p t is a variadic parameter type as defined in
3654 /// the current environment.
3655 bool
is_variadic_parameter_type(const type_base_sptr & t) const3656 environment::is_variadic_parameter_type(const type_base_sptr& t) const
3657 {return is_variadic_parameter_type(t.get());}
3658
3659 /// Do intern a string.
3660 ///
3661 /// If a value of this string already exists in the interned string
3662 /// pool of the current environment, then this function returns a new
3663 /// interned_string pointing to that already existing string.
3664 /// Otherwise, a new string is created, stored in the interned string
3665 /// pool and a new interned_string instance is created to point to
3666 /// that new intrerned string, and it's return.
3667 ///
3668 /// @param s the value of the string to intern.
3669 ///
3670 /// @return the interned string.
3671 interned_string
intern(const string & s) const3672 environment::intern(const string& s) const
3673 {return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3674
3675 /// Getter of the general configuration object.
3676 ///
3677 /// @return the configuration object.
3678 const config&
get_config() const3679 environment::get_config() const
3680 {return priv_->config_;}
3681
3682 /// Getter for a property that says if the user actually did set the
3683 /// analyze_exported_interfaces_only() property. If not, it means
3684 /// the default behaviour prevails.
3685 ///
3686 /// @return tru iff the user did set the
3687 /// analyze_exported_interfaces_only() property.
3688 bool
user_set_analyze_exported_interfaces_only() const3689 environment::user_set_analyze_exported_interfaces_only() const
3690 {return priv_->analyze_exported_interfaces_only_.has_value();}
3691
3692 /// Setter for the property that controls if we are to restrict the
3693 /// analysis to the types that are only reachable from the exported
3694 /// interfaces only, or if the set of types should be more broad than
3695 /// that. Typically, we'd restrict the analysis to types reachable
3696 /// from exported interfaces only (stricto sensu, that would really be
3697 /// only the types that are part of the ABI of well designed
3698 /// libraries) for performance reasons.
3699 ///
3700 /// @param f the value of the flag.
3701 void
analyze_exported_interfaces_only(bool f)3702 environment::analyze_exported_interfaces_only(bool f)
3703 {priv_->analyze_exported_interfaces_only_ = f;}
3704
3705 /// Getter for the property that controls if we are to restrict the
3706 /// analysis to the types that are only reachable from the exported
3707 /// interfaces only, or if the set of types should be more broad than
3708 /// that. Typically, we'd restrict the analysis to types reachable
3709 /// from exported interfaces only (stricto sensu, that would really be
3710 /// only the types that are part of the ABI of well designed
3711 /// libraries) for performance reasons.
3712 ///
3713 /// @param f the value of the flag.
3714 bool
analyze_exported_interfaces_only() const3715 environment::analyze_exported_interfaces_only() const
3716 {return priv_->analyze_exported_interfaces_only_.value_or(false);}
3717
3718 #ifdef WITH_DEBUG_SELF_COMPARISON
3719 /// Setter of the corpus of the input corpus of the self comparison
3720 /// that takes place when doing "abidw --debug-abidiff <binary>".
3721 ///
3722 /// The first invocation of this function sets the first corpus of the
3723 /// self comparison. The second invocation of this very same function
3724 /// sets the second corpus of the self comparison. That second corpus
3725 /// is supposed to come from the abixml serialization of the first
3726 /// corpus.
3727 ///
3728 /// @param c the corpus of the input binary or the corpus of the
3729 /// abixml serialization of the initial binary input.
3730 void
set_self_comparison_debug_input(const corpus_sptr & c)3731 environment::set_self_comparison_debug_input(const corpus_sptr& c)
3732 {
3733 self_comparison_debug_is_on(true);
3734 if (priv_->first_self_comparison_corpus_.expired())
3735 priv_->first_self_comparison_corpus_ = c;
3736 else if (priv_->second_self_comparison_corpus_.expired()
3737 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3738 priv_->second_self_comparison_corpus_ = c;
3739 }
3740
3741 /// Getter for the corpora of the input binary and the intermediate
3742 /// abixml of the self comparison that takes place when doing
3743 /// 'abidw --debug-abidiff <binary>'.
3744 ///
3745 /// @param first_corpus output parameter that is set to the corpus of
3746 /// the input corpus.
3747 ///
3748 /// @param second_corpus output parameter that is set to the corpus of
3749 /// the second corpus.
3750 void
get_self_comparison_debug_inputs(corpus_sptr & first_corpus,corpus_sptr & second_corpus)3751 environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3752 corpus_sptr& second_corpus)
3753 {
3754 first_corpus = priv_->first_self_comparison_corpus_.lock();
3755 second_corpus = priv_->second_self_comparison_corpus_.lock();
3756 }
3757
3758 /// Turn on/off the self comparison debug mode.
3759 ///
3760 /// @param f true iff the self comparison debug mode is turned on.
3761 void
self_comparison_debug_is_on(bool f)3762 environment::self_comparison_debug_is_on(bool f)
3763 {priv_->self_comparison_debug_on_ = f;}
3764
3765 /// Test if we are in the process of the 'self-comparison
3766 /// debugging' as triggered by 'abidw --debug-abidiff' command.
3767 ///
3768 /// @return true if self comparison debug is on.
3769 bool
self_comparison_debug_is_on() const3770 environment::self_comparison_debug_is_on() const
3771 {return priv_->self_comparison_debug_on_;}
3772 #endif
3773
3774 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3775 /// Set the "type canonicalization debugging" mode, triggered by using
3776 /// the command: "abidw --debug-tc".
3777 ///
3778 /// @param flag if true then the type canonicalization debugging mode
3779 /// is enabled.
3780 void
debug_type_canonicalization_is_on(bool flag)3781 environment::debug_type_canonicalization_is_on(bool flag)
3782 {priv_->debug_type_canonicalization_ = flag;}
3783
3784 /// Getter of the "type canonicalization debugging" mode, triggered by
3785 /// using the command: "abidw --debug-tc".
3786 ///
3787 /// @return true iff the type canonicalization debugging mode is
3788 /// enabled.
3789 bool
debug_type_canonicalization_is_on() const3790 environment::debug_type_canonicalization_is_on() const
3791 {return priv_->debug_type_canonicalization_;}
3792
3793 /// Setter of the "DIE canonicalization debugging" mode, triggered by
3794 /// using the command: "abidw --debug-dc".
3795 ///
3796 /// @param flag true iff the DIE canonicalization debugging mode is
3797 /// enabled.
3798 void
debug_die_canonicalization_is_on(bool flag)3799 environment::debug_die_canonicalization_is_on(bool flag)
3800 {priv_->debug_die_canonicalization_ = flag;}
3801
3802 /// Getter of the "DIE canonicalization debugging" mode, triggered by
3803 /// using the command: "abidw --debug-dc".
3804 ///
3805 /// @return true iff the DIE canonicalization debugging mode is
3806 /// enabled.
3807 bool
debug_die_canonicalization_is_on() const3808 environment::debug_die_canonicalization_is_on() const
3809 {return priv_->debug_die_canonicalization_;}
3810 #endif // WITH_DEBUG_TYPE_CANONICALIZATION
3811
3812 /// Get the vector of canonical types which have a given "string
3813 /// representation".
3814 ///
3815 /// @param 'name', the textual representation of the type as returned
3816 /// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3817 /// /*qualified=*/true)
3818 ///
3819 /// This is useful to for debugging purposes as it's handy to use from
3820 /// inside a debugger like GDB.
3821 ///
3822 /// @return a pointer to the vector of canonical types having the
3823 /// representation @p name, or nullptr if no type with that
3824 /// representation exists.
3825 vector<type_base_sptr>*
get_canonical_types(const char * name)3826 environment::get_canonical_types(const char* name)
3827 {
3828 auto ti = get_canonical_types_map().find(name);
3829 if (ti == get_canonical_types_map().end())
3830 return nullptr;
3831 return &ti->second;
3832 }
3833
3834 /// Get a given canonical type which has a given "string
3835 /// representation".
3836 ///
3837 /// @param 'name', the textual representation of the type as returned
3838 /// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3839 /// /*qualified=*/true).
3840 ///
3841 /// @param index, the index of the type in the vector of types that
3842 /// all have the same textual representation @p 'name'. That vector
3843 /// is returned by the function environment::get_canonical_types().
3844 ///
3845 /// @return the canonical type which has the representation @p name,
3846 /// and which is at index @p index in the vector of canonical types
3847 /// having that same textual representation.
3848 type_base*
get_canonical_type(const char * name,unsigned index)3849 environment::get_canonical_type(const char* name, unsigned index)
3850 {
3851 vector<type_base_sptr> *types = get_canonical_types(name);
3852 if (!types ||index >= types->size())
3853 return nullptr;
3854 return (*types)[index].get();
3855 }
3856
3857 #ifdef WITH_DEBUG_SELF_COMPARISON
3858 /// Get the set of abixml type-id and the pointer value of the
3859 /// (canonical) type it's associated to.
3860 ///
3861 /// This is useful for debugging purposes, especially in the context
3862 /// of the use of the command:
3863 /// 'abidw --debug-abidiff <binary>'.
3864 ///
3865 /// @return the set of abixml type-id and the pointer value of the
3866 /// (canonical) type it's associated to.
3867 unordered_map<string, uintptr_t>&
get_type_id_canonical_type_map() const3868 environment::get_type_id_canonical_type_map() const
3869 {return priv_->type_id_canonical_type_map_;}
3870
3871 /// Getter of the map that associates the values of type pointers to
3872 /// their type-id strings.
3873 ///
3874 /// Note that this map is populated at abixml reading time, (by
3875 /// build_type()) when a given XML element representing a type is
3876 /// read into a corresponding abigail::ir::type_base.
3877 ///
3878 /// This is used only for the purpose of debugging the
3879 /// self-comparison process. That is, when invoking "abidw
3880 /// --debug-abidiff".
3881 ///
3882 /// @return the map that associates the values of type pointers to
3883 /// their type-id strings.
3884 unordered_map<uintptr_t, string>&
get_pointer_type_id_map()3885 environment::get_pointer_type_id_map()
3886 {return priv_->pointer_type_id_map_;}
3887
3888 /// Getter of the type-id that corresponds to the value of a pointer
3889 /// to abigail::ir::type_base that was created from the abixml reader.
3890 ///
3891 /// That value is retrieved from the map returned from
3892 /// environment::get_pointer_type_id_map().
3893 ///
3894 /// That map is populated at abixml reading time, (by build_type())
3895 /// when a given XML element representing a type is read into a
3896 /// corresponding abigail::ir::type_base.
3897 ///
3898 /// This is used only for the purpose of debugging the
3899 /// self-comparison process. That is, when invoking "abidw
3900 /// --debug-abidiff".
3901 ///
3902 /// @return the type-id strings that corresponds
3903 string
get_type_id_from_pointer(uintptr_t ptr)3904 environment::get_type_id_from_pointer(uintptr_t ptr)
3905 {
3906 auto it = get_pointer_type_id_map().find(ptr);
3907 if (it != get_pointer_type_id_map().end())
3908 return it->second;
3909 return "";
3910 }
3911
3912 /// Getter of the canonical type of the artifact designated by a
3913 /// type-id.
3914 ///
3915 /// That type-id was generated by the abixml writer at the emitting
3916 /// time of the abixml file. The corresponding canonical type was
3917 /// stored in the map returned by
3918 /// environment::get_type_id_canonical_type_map().
3919 ///
3920 /// This is useful for debugging purposes, especially in the context
3921 /// of the use of the command:
3922 /// 'abidw --debug-abidiff <binary>'.
3923 ///
3924 /// @return the set of abixml type-id and the pointer value of the
3925 /// (canonical) type it's associated to.
3926 uintptr_t
get_canonical_type_from_type_id(const char * type_id)3927 environment::get_canonical_type_from_type_id(const char* type_id)
3928 {
3929 if (!type_id)
3930 return 0;
3931 auto it = get_type_id_canonical_type_map().find(type_id);
3932 if (it != get_type_id_canonical_type_map().end())
3933 return it->second;
3934 return 0;
3935 }
3936 #endif
3937 // </environment stuff>
3938
3939 // <type_or_decl_base stuff>
3940
3941 /// The private data of @ref type_or_decl_base.
3942 struct type_or_decl_base::priv
3943 {
3944 // This holds the kind of dynamic type of particular instance.
3945 // Yes, this is part of the implementation of a "poor man" runtime
3946 // type identification. We are doing this because profiling shows
3947 // that using dynamic_cast in some places is really to slow and is
3948 // constituting a hotspot. This poor man's implementation made
3949 // things be much faster.
3950 enum type_or_decl_kind kind_;
3951 // This holds the runtime type instance pointer of particular
3952 // instance. In other words, this is the "this pointer" of the
3953 // dynamic type of a particular instance.
3954 void* rtti_;
3955 // This holds a pointer to either the type_base sub-object (if the
3956 // current instance is a type) or the decl_base sub-object (if the
3957 // current instance is a decl). This is used by the is_decl() and
3958 // is_type() functions, which also show up during profiling as
3959 // hotspots, due to their use of dynamic_cast.
3960 void* type_or_decl_ptr_;
3961 bool hashing_started_;
3962 const environment& env_;
3963 translation_unit* translation_unit_;
3964 // The location of an artifact as seen from its input by the
3965 // artifact reader. This might be different from the source
3966 // location advertised by the original emitter of the artifact
3967 // emitter.
3968 location artificial_location_;
3969 // Flags if the current ABI artifact is artificial (i.e, *NOT*
3970 // generated from the initial source code, but rather either
3971 // artificially by the compiler or by libabigail itself).
3972 bool is_artificial_;
3973
3974 /// Constructor of the type_or_decl_base::priv private type.
3975 ///
3976 /// @param e the environment in which the ABI artifact was created.
3977 ///
3978 /// @param k the identifier of the runtime type of the current
3979 /// instance of ABI artifact.
privabigail::ir::type_or_decl_base::priv3980 priv(const environment& e,
3981 enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
3982 : kind_(k),
3983 rtti_(),
3984 type_or_decl_ptr_(),
3985 hashing_started_(),
3986 env_(e),
3987 translation_unit_(),
3988 is_artificial_()
3989 {}
3990
3991 enum type_or_decl_kind
kindabigail::ir::type_or_decl_base::priv3992 kind() const
3993 {return kind_;}
3994
3995 void
kindabigail::ir::type_or_decl_base::priv3996 kind (enum type_or_decl_kind k)
3997 {kind_ |= k;}
3998 }; // end struct type_or_decl_base::priv
3999
4000 /// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4001 /// bitmap type.
4002 type_or_decl_base::type_or_decl_kind
operator |(type_or_decl_base::type_or_decl_kind l,type_or_decl_base::type_or_decl_kind r)4003 operator|(type_or_decl_base::type_or_decl_kind l,
4004 type_or_decl_base::type_or_decl_kind r)
4005 {
4006 return static_cast<type_or_decl_base::type_or_decl_kind>
4007 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4008 }
4009
4010 /// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4011 /// bitmap type.
4012 type_or_decl_base::type_or_decl_kind&
operator |=(type_or_decl_base::type_or_decl_kind & l,type_or_decl_base::type_or_decl_kind r)4013 operator|=(type_or_decl_base::type_or_decl_kind& l,
4014 type_or_decl_base::type_or_decl_kind r)
4015 {
4016 l = l | r;
4017 return l;
4018 }
4019
4020 /// bitwise "AND" operator for the
4021 /// type_or_decl_base::type_or_decl_kind bitmap type.
4022 type_or_decl_base::type_or_decl_kind
operator &(type_or_decl_base::type_or_decl_kind l,type_or_decl_base::type_or_decl_kind r)4023 operator&(type_or_decl_base::type_or_decl_kind l,
4024 type_or_decl_base::type_or_decl_kind r)
4025 {
4026 return static_cast<type_or_decl_base::type_or_decl_kind>
4027 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4028 }
4029
4030 /// bitwise "A&=" operator for the
4031 /// type_or_decl_base::type_or_decl_kind bitmap type.
4032 type_or_decl_base::type_or_decl_kind&
operator &=(type_or_decl_base::type_or_decl_kind & l,type_or_decl_base::type_or_decl_kind r)4033 operator&=(type_or_decl_base::type_or_decl_kind& l,
4034 type_or_decl_base::type_or_decl_kind r)
4035 {
4036 l = l & r;
4037 return l;
4038 }
4039
4040 /// Constructor of @ref type_or_decl_base.
4041 ///
4042 /// @param the environment the current ABI artifact is constructed
4043 /// from.
4044 ///
4045 /// @param k the runtime identifier bitmap of the type being built.
type_or_decl_base(const environment & e,enum type_or_decl_kind k)4046 type_or_decl_base::type_or_decl_base(const environment& e,
4047 enum type_or_decl_kind k)
4048 :priv_(new priv(e, k))
4049 {}
4050
4051 /// The destructor of the @ref type_or_decl_base type.
~type_or_decl_base()4052 type_or_decl_base::~type_or_decl_base()
4053 {}
4054
4055 /// Getter of the flag that says if the artefact is artificial.
4056 ///
4057 /// Being artificial means it was not explicitely mentionned in the
4058 /// source code, but was rather artificially created by the compiler
4059 /// or libabigail.
4060 ///
4061 /// @return true iff the declaration is artificial.
4062 bool
get_is_artificial() const4063 type_or_decl_base::get_is_artificial() const
4064 {return priv_->is_artificial_;}
4065
4066 /// Setter of the flag that says if the artefact is artificial.
4067 ///
4068 /// Being artificial means the artefact was not explicitely
4069 /// mentionned in the source code, but was rather artificially created
4070 /// by the compiler or by libabigail.
4071 ///
4072 /// @param f the new value of the flag that says if the artefact is
4073 /// artificial.
4074 void
set_is_artificial(bool f)4075 type_or_decl_base::set_is_artificial(bool f)
4076 {priv_->is_artificial_ = f;}
4077
4078 /// Getter for the "kind" property of @ref type_or_decl_base type.
4079 ///
4080 /// This property holds the identifier bitmap of the runtime type of
4081 /// an ABI artifact.
4082 ///
4083 /// @return the runtime type identifier bitmap of the current ABI
4084 /// artifact.
4085 enum type_or_decl_base::type_or_decl_kind
kind() const4086 type_or_decl_base::kind() const
4087 {return priv_->kind();}
4088
4089 /// Setter for the "kind" property of @ref type_or_decl_base type.
4090 ///
4091 /// This property holds the identifier bitmap of the runtime type of
4092 /// an ABI artifact.
4093 ///
4094 /// @param the runtime type identifier bitmap of the current ABI
4095 /// artifact.
4096 void
kind(enum type_or_decl_kind k)4097 type_or_decl_base::kind(enum type_or_decl_kind k)
4098 {priv_->kind(k);}
4099
4100 /// Getter of the pointer to the runtime type sub-object of the
4101 /// current instance.
4102 ///
4103 /// @return the pointer to the runtime type sub-object of the current
4104 /// instance.
4105 const void*
runtime_type_instance() const4106 type_or_decl_base::runtime_type_instance() const
4107 {return priv_->rtti_;}
4108
4109 /// Getter of the pointer to the runtime type sub-object of the
4110 /// current instance.
4111 ///
4112 /// @return the pointer to the runtime type sub-object of the current
4113 /// instance.
4114 void*
runtime_type_instance()4115 type_or_decl_base::runtime_type_instance()
4116 {return priv_->rtti_;}
4117
4118 /// Setter of the pointer to the runtime type sub-object of the
4119 /// current instance.
4120 ///
4121 /// @param i the new pointer to the runtime type sub-object of the
4122 /// current instance.
4123 void
runtime_type_instance(void * i)4124 type_or_decl_base::runtime_type_instance(void* i)
4125 {
4126 priv_->rtti_ = i;
4127 if (type_base* t = dynamic_cast<type_base*>(this))
4128 priv_->type_or_decl_ptr_ = t;
4129 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4130 priv_->type_or_decl_ptr_ = d;
4131 }
4132
4133 /// Getter of the pointer to either the type_base sub-object of the
4134 /// current instance if it's a type, or to the decl_base sub-object of
4135 /// the current instance if it's a decl.
4136 ///
4137 /// @return the pointer to either the type_base sub-object of the
4138 /// current instance if it's a type, or to the decl_base sub-object of
4139 /// the current instance if it's a decl.
4140 const void*
type_or_decl_base_pointer() const4141 type_or_decl_base::type_or_decl_base_pointer() const
4142 {return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
4143
4144 /// Getter of the pointer to either the type_base sub-object of the
4145 /// current instance if it's a type, or to the decl_base sub-object of
4146 /// the current instance if it's a decl.
4147 ///
4148 /// @return the pointer to either the type_base sub-object of the
4149 /// current instance if it's a type, or to the decl_base sub-object of
4150 /// the current instance if it's a decl.
4151 void*
type_or_decl_base_pointer()4152 type_or_decl_base::type_or_decl_base_pointer()
4153 {return priv_->type_or_decl_ptr_;}
4154
4155 /// Getter for the 'hashing_started' property.
4156 ///
4157 /// @return the 'hashing_started' property.
4158 bool
hashing_started() const4159 type_or_decl_base::hashing_started() const
4160 {return priv_->hashing_started_;}
4161
4162 /// Setter for the 'hashing_started' property.
4163 ///
4164 /// @param b the value to set the 'hashing_property' to.
4165 void
hashing_started(bool b) const4166 type_or_decl_base::hashing_started(bool b) const
4167 {priv_->hashing_started_ = b;}
4168
4169 /// Getter of the environment of the current ABI artifact.
4170 ///
4171 /// @return the environment of the artifact.
4172 const environment&
get_environment() const4173 type_or_decl_base::get_environment() const
4174 {return priv_->env_;}
4175
4176 /// Setter of the artificial location of the artificat.
4177 ///
4178 /// The artificial location is a location that was artificially
4179 /// generated by libabigail, not generated by the original emitter of
4180 /// the ABI meta-data. For instance, when reading an XML element from
4181 /// an abixml file, the artificial location is the source location of
4182 /// the XML element within the file, not the value of the
4183 /// 'location'property that might be carried by the element.
4184 ///
4185 /// Artificial locations might be useful to ensure that abixml emitted
4186 /// by the abixml writer are sorted the same way as the input abixml
4187 /// read by the reader.
4188 ///
4189 /// @param l the new artificial location.
4190 void
set_artificial_location(const location & l)4191 type_or_decl_base::set_artificial_location(const location &l)
4192 {priv_->artificial_location_ = l;}
4193
4194 /// Getter of the artificial location of the artifact.
4195 ///
4196 /// The artificial location is a location that was artificially
4197 /// generated by libabigail, not generated by the original emitter of
4198 /// the ABI meta-data. For instance, when reading an XML element from
4199 /// an abixml file, the artificial location is the source location of
4200 /// the XML element within the file, not the value of the
4201 /// 'location'property that might be carried by the element.
4202 ///
4203 /// Artificial locations might be useful to ensure that the abixml
4204 /// emitted by the abixml writer is sorted the same way as the input
4205 /// abixml read by the reader.
4206 ///
4207 /// @return the new artificial location.
4208 location&
get_artificial_location() const4209 type_or_decl_base::get_artificial_location() const
4210 {return priv_->artificial_location_;}
4211
4212 /// Test if the current ABI artifact carries an artificial location.
4213 ///
4214 /// @return true iff the current ABI artifact carries an artificial location.
4215 bool
has_artificial_location() const4216 type_or_decl_base::has_artificial_location() const
4217 {
4218 return (priv_->artificial_location_
4219 && priv_->artificial_location_.get_is_artificial());
4220 }
4221
4222 /// Get the @ref corpus this ABI artifact belongs to.
4223 ///
4224 /// @return the corpus this ABI artifact belongs to, or nil if it
4225 /// belongs to none for now.
4226 corpus*
get_corpus()4227 type_or_decl_base::get_corpus()
4228 {
4229 translation_unit* tu = get_translation_unit();
4230 if (!tu)
4231 return 0;
4232 return tu->get_corpus();
4233 }
4234
4235
4236 /// Get the @ref corpus this ABI artifact belongs to.
4237 ///
4238 /// @return the corpus this ABI artifact belongs to, or nil if it
4239 /// belongs to none for now.
4240 const corpus*
get_corpus() const4241 type_or_decl_base::get_corpus() const
4242 {return const_cast<type_or_decl_base*>(this)->get_corpus();}
4243
4244 /// Set the @ref translation_unit this ABI artifact belongs to.
4245 ///
4246 /// Note that adding an ABI artifact to a containining on should
4247 /// invoke this member function.
4248 void
set_translation_unit(translation_unit * tu)4249 type_or_decl_base::set_translation_unit(translation_unit* tu)
4250 {priv_->translation_unit_ = tu;}
4251
4252
4253 /// Get the @ref translation_unit this ABI artifact belongs to.
4254 ///
4255 /// @return the translation unit this ABI artifact belongs to, or nil
4256 /// if belongs to none for now.
4257 translation_unit*
get_translation_unit()4258 type_or_decl_base::get_translation_unit()
4259 {return priv_->translation_unit_;}
4260
4261 /// Get the @ref translation_unit this ABI artifact belongs to.
4262 ///
4263 /// @return the translation unit this ABI artifact belongs to, or nil
4264 /// if belongs to none for now.
4265 const translation_unit*
get_translation_unit() const4266 type_or_decl_base::get_translation_unit() const
4267 {return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4268
4269 /// Traverse the the ABI artifact.
4270 ///
4271 /// @param v the visitor used to traverse the sub-tree nodes of the
4272 /// artifact.
4273 bool
traverse(ir_node_visitor &)4274 type_or_decl_base::traverse(ir_node_visitor&)
4275 {return true;}
4276
4277 /// Non-member equality operator for the @type_or_decl_base type.
4278 ///
4279 /// @param lr the left-hand operand of the equality.
4280 ///
4281 /// @param rr the right-hand operatnr of the equality.
4282 ///
4283 /// @return true iff @p lr equals @p rr.
4284 bool
operator ==(const type_or_decl_base & lr,const type_or_decl_base & rr)4285 operator==(const type_or_decl_base& lr, const type_or_decl_base& rr)
4286 {
4287 const type_or_decl_base* l = &lr;
4288 const type_or_decl_base* r = &rr;
4289
4290 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4291 *dr = dynamic_cast<const decl_base*>(r);
4292
4293 if (!!dl != !!dr)
4294 return false;
4295
4296 if (dl && dr)
4297 return *dl == *dr;
4298
4299 const type_base* tl = dynamic_cast<const type_base*>(l),
4300 *tr = dynamic_cast<const type_base*>(r);
4301
4302 if (!!tl != !!tr)
4303 return false;
4304
4305 if (tl && tr)
4306 return *tl == *tr;
4307
4308 return false;
4309 }
4310
4311 /// Non-member equality operator for the @type_or_decl_base type.
4312 ///
4313 /// @param l the left-hand operand of the equality.
4314 ///
4315 /// @param r the right-hand operatnr of the equality.
4316 ///
4317 /// @return true iff @p l equals @p r.
4318 bool
operator ==(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)4319 operator==(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
4320 {
4321 if (!! l != !!r)
4322 return false;
4323
4324 if (!l)
4325 return true;
4326
4327 return *r == *l;
4328 }
4329
4330 /// Non-member inequality operator for the @type_or_decl_base type.
4331 ///
4332 /// @param l the left-hand operand of the equality.
4333 ///
4334 /// @param r the right-hand operator of the equality.
4335 ///
4336 /// @return true iff @p l is different from @p r.
4337 bool
operator !=(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)4338 operator!=(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
4339 {return !operator==(l, r);}
4340
4341 // </type_or_decl_base stuff>
4342
4343 // <Decl definition>
4344
4345 struct decl_base::priv
4346 {
4347 bool in_pub_sym_tab_;
4348 bool is_anonymous_;
4349 location location_;
4350 context_rel *context_;
4351 interned_string name_;
4352 interned_string qualified_parent_name_;
4353 // This temporary qualified name is the cache used for the qualified
4354 // name before the type associated to this decl (if applicable) is
4355 // canonicalized. Once the type is canonicalized, the cached use is
4356 // the data member qualified_parent_name_ above.
4357 interned_string temporary_qualified_name_;
4358 // This is the fully qualified name of the decl. It contains the
4359 // name of the decl and the qualified name of its scope. So if in
4360 // the parent scopes of the decl, there is one anonymous struct,
4361 // somewhere in the name, there is going to by an
4362 // __anonymous_struct__ string, even if the anonymous struct is not
4363 // the direct containing scope of this decl.
4364 interned_string qualified_name_;
4365 interned_string temporary_internal_qualified_name_;
4366 interned_string internal_qualified_name_;
4367 // Unline qualified_name_, scoped_name_ contains the name of the
4368 // decl and the name of its scope; not the qualified name of the
4369 // scope.
4370 interned_string scoped_name_;
4371 interned_string linkage_name_;
4372 visibility visibility_;
4373 decl_base_sptr declaration_;
4374 decl_base_wptr definition_of_declaration_;
4375 decl_base* naked_definition_of_declaration_;
4376 bool is_declaration_only_;
4377 typedef_decl_sptr naming_typedef_;
4378
privabigail::ir::decl_base::priv4379 priv()
4380 : in_pub_sym_tab_(false),
4381 is_anonymous_(true),
4382 context_(),
4383 visibility_(VISIBILITY_DEFAULT),
4384 naked_definition_of_declaration_(),
4385 is_declaration_only_(false)
4386 {}
4387
privabigail::ir::decl_base::priv4388 priv(interned_string name, interned_string linkage_name, visibility vis)
4389 : in_pub_sym_tab_(false),
4390 context_(),
4391 name_(name),
4392 qualified_name_(name),
4393 linkage_name_(linkage_name),
4394 visibility_(vis),
4395 naked_definition_of_declaration_(),
4396 is_declaration_only_(false)
4397 {
4398 is_anonymous_ = name_.empty();
4399 }
4400
~privabigail::ir::decl_base::priv4401 ~priv()
4402 {
4403 delete context_;
4404 }
4405 };// end struct decl_base::priv
4406
4407 /// Constructor for the @ref decl_base type.
4408 ///
4409 /// @param e the environment the current @ref decl_base is being
4410 /// created in.
4411 ///
4412 /// @param name the name of the declaration.
4413 ///
4414 /// @param locus the location where to find the declaration in the
4415 /// source code.
4416 ///
4417 /// @param linkage_name the linkage name of the declaration.
4418 ///
4419 /// @param vis the visibility of the declaration.
decl_base(const environment & e,const string & name,const location & locus,const string & linkage_name,visibility vis)4420 decl_base::decl_base(const environment& e,
4421 const string& name,
4422 const location& locus,
4423 const string& linkage_name,
4424 visibility vis)
4425 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4426 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4427 {
4428 set_location(locus);
4429 }
4430
4431 /// Constructor.
4432 ///
4433 /// @param e the environment this instance of @ref decl_base is
4434 /// created in.
4435 ///
4436 /// @param name the name of the declaration being constructed.
4437 ///
4438 /// @param locus the source location of the declaration being constructed.
4439 ///
4440 /// @param linkage_name the linkage name of the declaration being
4441 /// constructed.
4442 ///
4443 /// @param vis the visibility of the declaration being constructed.
decl_base(const environment & e,const interned_string & name,const location & locus,const interned_string & linkage_name,visibility vis)4444 decl_base::decl_base(const environment& e,
4445 const interned_string& name,
4446 const location& locus,
4447 const interned_string& linkage_name,
4448 visibility vis)
4449 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4450 priv_(new priv(name, linkage_name, vis))
4451 {
4452 set_location(locus);
4453 }
4454
4455 /// Constructor for the @ref decl_base type.
4456 ///
4457 ///@param environment the environment this instance of @ref decl_base
4458 /// is being constructed in.
4459 ///
4460 /// @param l the location where to find the declaration in the source
4461 /// code.
decl_base(const environment & e,const location & l)4462 decl_base::decl_base(const environment& e, const location& l)
4463 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4464 priv_(new priv())
4465 {
4466 set_location(l);
4467 }
4468
4469 /// Getter for the qualified name.
4470 ///
4471 /// Unlike decl_base::get_qualified_name() this doesn't try to update
4472 /// the qualified name.
4473 ///
4474 /// @return the qualified name.
4475 const interned_string&
peek_qualified_name() const4476 decl_base::peek_qualified_name() const
4477 {return priv_->qualified_name_;}
4478
4479 /// Clear the qualified name of this decl.
4480 ///
4481 /// This is useful to ensure that the cache for the qualified name of
4482 /// the decl is refreshed right after type canonicalization, for
4483 /// instance.
4484 void
clear_qualified_name()4485 decl_base::clear_qualified_name()
4486 {priv_->qualified_name_.clear();}
4487
4488 /// Setter for the qualified name.
4489 ///
4490 /// @param n the new qualified name.
4491 void
set_qualified_name(const interned_string & n) const4492 decl_base::set_qualified_name(const interned_string& n) const
4493 {priv_->qualified_name_ = n;}
4494
4495 /// Getter of the temporary qualified name of the current declaration.
4496 ///
4497 /// This temporary qualified name is used as a qualified name cache by
4498 /// the type for which this is the declaration (when applicable)
4499 /// before the type is canonicalized. Once the type is canonicalized,
4500 /// it's the result of decl_base::peek_qualified_name() that becomes
4501 /// the qualified name cached.
4502 ///
4503 /// @return the temporary qualified name.
4504 const interned_string&
peek_temporary_qualified_name() const4505 decl_base::peek_temporary_qualified_name() const
4506 {return priv_->temporary_qualified_name_;}
4507
4508 /// Setter for the temporary qualified name of the current
4509 /// declaration.
4510 ///
4511 ///@param n the new temporary qualified name.
4512 ///
4513 /// This temporary qualified name is used as a qualified name cache by
4514 /// the type for which this is the declaration (when applicable)
4515 /// before the type is canonicalized. Once the type is canonicalized,
4516 /// it's the result of decl_base::peek_qualified_name() that becomes
4517 /// the qualified name cached.
4518 void
set_temporary_qualified_name(const interned_string & n) const4519 decl_base::set_temporary_qualified_name(const interned_string& n) const
4520 {priv_->temporary_qualified_name_ = n;}
4521
4522 ///Getter for the context relationship.
4523 ///
4524 ///@return the context relationship for the current decl_base.
4525 const context_rel*
get_context_rel() const4526 decl_base::get_context_rel() const
4527 {return priv_->context_;}
4528
4529 ///Getter for the context relationship.
4530 ///
4531 ///@return the context relationship for the current decl_base.
4532 context_rel*
get_context_rel()4533 decl_base::get_context_rel()
4534 {return priv_->context_;}
4535
4536 void
set_context_rel(context_rel * c)4537 decl_base::set_context_rel(context_rel *c)
4538 {priv_->context_ = c;}
4539
4540 /// Get the hash of a decl. If the hash hasn't been computed yet,
4541 /// compute it ans store its value; otherwise, just return the hash.
4542 ///
4543 /// @return the hash of the decl.
4544 size_t
get_hash() const4545 decl_base::get_hash() const
4546 {
4547 size_t result = 0;
4548
4549 if (const type_base* t = dynamic_cast<const type_base*>(this))
4550 {
4551 type_base::dynamic_hash hash;
4552 result = hash(t);
4553 }
4554 else
4555 // If we reach this point, it mean we are missing a virtual
4556 // overload for decl_base::get_hash. Add it!
4557 abort();
4558
4559 return result;
4560 }
4561
4562 /// Test if the decl is defined in a ELF symbol table as a public
4563 /// symbol.
4564 ///
4565 /// @return true iff the decl is defined in a ELF symbol table as a
4566 /// public symbol.
4567 bool
get_is_in_public_symbol_table() const4568 decl_base::get_is_in_public_symbol_table() const
4569 {return priv_->in_pub_sym_tab_;}
4570
4571 /// Set the flag saying if this decl is from a symbol that is in
4572 /// a public symbols table, defined as public (global or weak).
4573 ///
4574 /// @param f the new flag value.
4575 void
set_is_in_public_symbol_table(bool f)4576 decl_base::set_is_in_public_symbol_table(bool f)
4577 {priv_->in_pub_sym_tab_ = f;}
4578
4579 /// Get the location of a given declaration.
4580 ///
4581 /// The location is an abstraction for the tripplet {file path,
4582 /// line, column} that defines where the declaration appeared in the
4583 /// source code.
4584 ///
4585 /// To get the value of the tripplet {file path, line, column} from
4586 /// the @ref location, you need to use the
4587 /// location_manager::expand_location() method.
4588 ///
4589 /// The instance of @ref location_manager that you want is
4590 /// accessible from the instance of @ref translation_unit that the
4591 /// current instance of @ref decl_base belongs to, via a call to
4592 /// translation_unit::get_loc_mgr().
4593 ///
4594 /// @return the location of the current instance of @ref decl_base.
4595 const location&
get_location() const4596 decl_base::get_location() const
4597 {return priv_->location_;}
4598
4599 /// Set the location for a given declaration.
4600 ///
4601 /// The location is an abstraction for the tripplet {file path,
4602 /// line, column} that defines where the declaration appeared in the
4603 /// source code.
4604 ///
4605 /// To create a location from a tripplet {file path, line, column},
4606 /// you need to use the method @ref
4607 /// location_manager::create_new_location().
4608 ///
4609 /// Note that there can be two kinds of location. An artificial
4610 /// location and a non-artificial one. The non-artificial location is
4611 /// the one emitted by the original emitter of the ABI artifact, for
4612 /// instance, if the ABI artifact comes from debug info, then the
4613 /// source location that is present in the debug info represent a
4614 /// non-artificial location. When looking at an abixml file on the
4615 /// other hand, the value of the 'location' attribute of an XML
4616 /// element describing an artifact is the non-artificial location.
4617 /// The artificial location is the location (line number from the
4618 /// beginning of the file) of the XML element within the abixml file.
4619 ///
4620 /// So, if the location that is being set is artificial, note that the
4621 /// type_or_decl_base::has_artificial_location() method of this decl will
4622 /// subsequently return true and that artificial location will have to
4623 /// be retrieved using type_or_decl_base::get_artificial_location().
4624 /// If the location is non-artificial however,
4625 /// type_or_decl_base::has_artificial_location() will subsequently
4626 /// return false and the non-artificial location will have to be
4627 /// retrieved using decl_base::get_location().
4628 ///
4629 /// The instance of @ref location_manager that you want is
4630 /// accessible from the instance of @ref translation_unit that the
4631 /// current instance of @ref decl_base belongs to, via a call to
4632 /// translation_unit::get_loc_mgr().
4633 void
set_location(const location & l)4634 decl_base::set_location(const location& l)
4635 {
4636 if (l.get_is_artificial())
4637 set_artificial_location(l);
4638 else
4639 priv_->location_ = l;
4640 }
4641
4642 /// Setter for the name of the decl.
4643 ///
4644 /// @param n the new name to set.
4645 void
set_name(const string & n)4646 decl_base::set_name(const string& n)
4647 {
4648 priv_->name_ = get_environment().intern(n);
4649 priv_->is_anonymous_ = n.empty();
4650 }
4651
4652 /// Test if the current declaration is anonymous.
4653 ///
4654 /// Being anonymous means that the declaration was created without a
4655 /// name. This can usually happen for enum or struct types.
4656 ///
4657 /// @return true iff the type is anonymous.
4658 bool
get_is_anonymous() const4659 decl_base::get_is_anonymous() const
4660 {return priv_->is_anonymous_;}
4661
4662 /// Set the "is_anonymous" flag of the current declaration.
4663 ///
4664 /// Being anonymous means that the declaration was created without a
4665 /// name. This can usually happen for enum or struct types.
4666 ///
4667 /// @param f the new value of the flag.
4668 void
set_is_anonymous(bool f)4669 decl_base::set_is_anonymous(bool f)
4670 {priv_->is_anonymous_ = f;}
4671
4672
4673 /// Get the "has_anonymous_parent" flag of the current declaration.
4674 ///
4675 /// Having an anoymous parent means having a anonymous parent scope
4676 /// (containing type or namespace) which is either direct or indirect.
4677 ///
4678 /// @return true iff the current decl has a direct or indirect scope
4679 /// which is anonymous.
4680 bool
get_has_anonymous_parent() const4681 decl_base::get_has_anonymous_parent() const
4682 {
4683 scope_decl *scope = get_scope();
4684 if (!scope)
4685 return false;
4686 return scope->get_is_anonymous();
4687 }
4688
4689 /// @return the logical "OR" of decl_base::get_is_anonymous() and
4690 /// decl_base::get_has_anonymous_parent().
4691 bool
get_is_anonymous_or_has_anonymous_parent() const4692 decl_base::get_is_anonymous_or_has_anonymous_parent() const
4693 {return get_is_anonymous() || get_has_anonymous_parent();}
4694
4695 /// Getter for the naming typedef of the current decl.
4696 ///
4697 /// Consider the C idiom:
4698 ///
4699 /// typedef struct {int member;} foo_type;
4700 ///
4701 /// In that idiom, foo_type is the naming typedef of the anonymous
4702 /// struct that is declared.
4703 ///
4704 /// @return the naming typedef, if any. Otherwise, returns nil.
4705 typedef_decl_sptr
get_naming_typedef() const4706 decl_base::get_naming_typedef() const
4707 {return priv_->naming_typedef_;}
4708
4709 /// Set the naming typedef of the current instance of @ref decl_base.
4710 ///
4711 /// Consider the C idiom:
4712 ///
4713 /// typedef struct {int member;} foo_type;
4714 ///
4715 /// In that idiom, foo_type is the naming typedef of the anonymous
4716 /// struct that is declared.
4717 ///
4718 /// After completion of this function, the decl will not be considered
4719 /// anonymous anymore. It's name is going to be the name of the
4720 /// naming typedef.
4721 ///
4722 /// @param typedef_type the new naming typedef.
4723 void
set_naming_typedef(const typedef_decl_sptr & t)4724 decl_base::set_naming_typedef(const typedef_decl_sptr& t)
4725 {
4726 // A naming typedef is usually for an anonymous type.
4727 ABG_ASSERT(get_is_anonymous()
4728 // Whe the typedef-named decl is saved into abixml, it's
4729 // not anonymous anymore. Its name is the typedef name.
4730 // So when we read it back, we must still be able to
4731 // apply the naming typedef to the decl.
4732 || t->get_name() == get_name());
4733 // Only non canonicalized types can be edited this way.
4734 ABG_ASSERT(is_type(this)
4735 && is_type(this)->get_naked_canonical_type() == nullptr);
4736
4737 priv_->naming_typedef_ = t;
4738 set_name(t->get_name());
4739 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4740 set_qualified_name(get_environment().intern(qualified_name));
4741 set_is_anonymous(false);
4742 // Now that the qualified type of the decl has changed, let's update
4743 // the qualified names of the member types of this decls.
4744 update_qualified_name(this);
4745 }
4746
4747 /// Getter for the mangled name.
4748 ///
4749 /// @return the new mangled name.
4750 const interned_string&
get_linkage_name() const4751 decl_base::get_linkage_name() const
4752 {return priv_->linkage_name_;}
4753
4754 /// Setter for the linkage name.
4755 ///
4756 /// @param m the new linkage name.
4757 void
set_linkage_name(const string & m)4758 decl_base::set_linkage_name(const string& m)
4759 {
4760 const environment& env = get_environment();
4761 priv_->linkage_name_ = env.intern(m);
4762 }
4763
4764 /// Getter for the visibility of the decl.
4765 ///
4766 /// @return the new visibility.
4767 decl_base::visibility
get_visibility() const4768 decl_base::get_visibility() const
4769 {return priv_->visibility_;}
4770
4771 /// Setter for the visibility of the decl.
4772 ///
4773 /// @param v the new visibility.
4774 void
set_visibility(visibility v)4775 decl_base::set_visibility(visibility v)
4776 {priv_->visibility_ = v;}
4777
4778 /// Return the type containing the current decl, if any.
4779 ///
4780 /// @return the type that contains the current decl, or NULL if there
4781 /// is none.
4782 scope_decl*
get_scope() const4783 decl_base::get_scope() const
4784 {
4785 if (priv_->context_)
4786 return priv_->context_->get_scope();
4787 return 0;
4788 }
4789
4790 /// Return a copy of the qualified name of the parent of the current
4791 /// decl.
4792 ///
4793 /// @return the newly-built qualified name of the of the current decl.
4794 const interned_string&
get_qualified_parent_name() const4795 decl_base::get_qualified_parent_name() const
4796 {return priv_->qualified_parent_name_;}
4797
4798 /// Getter for the name of the current decl.
4799 ///
4800 /// @return the name of the current decl.
4801 const interned_string&
get_name() const4802 decl_base::get_name() const
4803 {return priv_->name_;}
4804
4805 /// Compute the qualified name of the decl.
4806 ///
4807 /// @param qn the resulting qualified name.
4808 ///
4809 /// @param internal set to true if the call is intended for an
4810 /// internal use (for technical use inside the library itself), false
4811 /// otherwise. If you don't know what this is for, then set it to
4812 /// false.
4813 void
get_qualified_name(interned_string & qn,bool internal) const4814 decl_base::get_qualified_name(interned_string& qn, bool internal) const
4815 {qn = get_qualified_name(internal);}
4816
4817 /// Get the pretty representatin of the current declaration.
4818 ///
4819 ///
4820 /// @param internal set to true if the call is intended to get a
4821 /// representation of the decl (or type) for the purpose of canonical
4822 /// type comparison. This is mainly used in the function
4823 /// type_base::get_canonical_type_for().
4824 ///
4825 /// In other words if the argument for this parameter is true then the
4826 /// call is meant for internal use (for technical use inside the
4827 /// library itself), false otherwise. If you don't know what this is
4828 /// for, then set it to false.
4829 ///
4830 /// @param qualified_name if true, names emitted in the pretty
4831 /// representation are fully qualified.
4832 ///
4833 /// @return the default pretty representation for a decl. This is
4834 /// basically the fully qualified name of the decl optionally prefixed
4835 /// with a meaningful string to add context for the user.
4836 string
get_pretty_representation(bool internal,bool qualified_name) const4837 decl_base::get_pretty_representation(bool internal,
4838 bool qualified_name) const
4839 {
4840 if (internal
4841 && get_is_anonymous()
4842 && has_generic_anonymous_internal_type_name(this))
4843 {
4844 // We are looking at an anonymous enum, union or class and we
4845 // want an *internal* pretty representation for it. All
4846 // anonymous types of this kind in the same namespace must have
4847 // the same internal representation for type canonicalization to
4848 // work properly.
4849 //
4850 // OK, in practise, we are certainly looking at an enum because
4851 // classes and unions should have their own overloaded virtual
4852 // member function for this.
4853 string name = get_generic_anonymous_internal_type_name(this);
4854 if (qualified_name && !get_qualified_parent_name().empty())
4855 name = get_qualified_parent_name() + "::" + name;
4856 return name;
4857 }
4858
4859 if (qualified_name)
4860 return get_qualified_name(internal);
4861 return get_name();
4862 }
4863
4864 /// Return the qualified name of the decl.
4865 ///
4866 /// This is the fully qualified name of the decl. It's made of the
4867 /// concatenation of the name of the decl with the qualified name of
4868 /// its scope.
4869 ///
4870 /// Note that the value returned by this function is computed by @ref
4871 /// update_qualified_name when the decl is added to its scope.
4872 ///
4873 /// @param internal set to true if the call is intended for an
4874 /// internal use (for technical use inside the library itself), false
4875 /// otherwise. If you don't know what this is for, then set it to
4876 /// false.
4877 ///
4878 /// @return the resulting qualified name.
4879 const interned_string&
get_qualified_name(bool) const4880 decl_base::get_qualified_name(bool /*internal*/) const
4881 {return priv_->qualified_name_;}
4882
4883 /// Return the scoped name of the decl.
4884 ///
4885 /// This is made of the concatenation of the name of the decl with the
4886 /// name of its scope. It doesn't contain the qualified name of its
4887 /// scope, unlike what is returned by decl_base::get_qualified_name.
4888 ///
4889 /// Note that the value returned by this function is computed by @ref
4890 /// update_qualified_name when the decl is added to its scope.
4891 ///
4892 /// @return the scoped name of the decl.
4893 const interned_string&
get_scoped_name() const4894 decl_base::get_scoped_name() const
4895 {return priv_->scoped_name_;}
4896
4897 /// If this @ref decl_base is a definition, get its earlier
4898 /// declaration.
4899 ///
4900 /// @return the earlier declaration of the class, if any.
4901 const decl_base_sptr
get_earlier_declaration() const4902 decl_base::get_earlier_declaration() const
4903 {return priv_->declaration_;}
4904
4905 /// set the earlier declaration of this @ref decl_base definition.
4906 ///
4907 /// @param d the earlier declaration to set. Note that it's set only
4908 /// if it's a pure declaration.
4909 void
set_earlier_declaration(const decl_base_sptr & d)4910 decl_base::set_earlier_declaration(const decl_base_sptr& d)
4911 {
4912 if (d && d->get_is_declaration_only())
4913 priv_->declaration_ = d;
4914 }
4915
4916
4917 /// If this @ref decl_base is declaration-only, get its definition, if
4918 /// any.
4919 ///
4920 /// @return the definition of this decl-only @ref decl_base.
4921 const decl_base_sptr
get_definition_of_declaration() const4922 decl_base::get_definition_of_declaration() const
4923 {return priv_->definition_of_declaration_.lock();}
4924
4925 /// If this @ref decl_base is declaration-only, get its definition,
4926 /// if any.
4927 ///
4928 /// Note that this function doesn't return a smart pointer, but rather
4929 /// the underlying pointer managed by the smart pointer. So it's as
4930 /// fast as possible. This getter is to be used in code paths that
4931 /// are proven to be performance hot spots; especially, when comparing
4932 /// sensitive types like enums, classes or unions. Those are compared
4933 /// extremely frequently and thus, their access to the definition of
4934 /// declaration must be fast.
4935 ///
4936 /// @return the definition of the declaration.
4937 const decl_base*
get_naked_definition_of_declaration() const4938 decl_base::get_naked_definition_of_declaration() const
4939 {return priv_->naked_definition_of_declaration_;}
4940
4941 /// Test if a @ref decl_base is a declaration-only decl.
4942 ///
4943 /// @return true iff the current @ref decl_base is declaration-only.
4944 bool
get_is_declaration_only() const4945 decl_base::get_is_declaration_only() const
4946 {return priv_->is_declaration_only_;}
4947
4948 /// Set a flag saying if the @ref enum_type_decl is a declaration-only
4949 /// @ref enum_type_decl.
4950 ///
4951 /// @param f true if the @ref enum_type_decl is a declaration-only
4952 /// @ref enum_type_decl.
4953 void
set_is_declaration_only(bool f)4954 decl_base::set_is_declaration_only(bool f)
4955 {
4956 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
4957
4958 priv_->is_declaration_only_ = f;
4959
4960 if (update_types_lookup_map)
4961 if (scope_decl* s = get_scope())
4962 {
4963 scope_decl::declarations::iterator i;
4964 if (s->find_iterator_for_member(this, i))
4965 maybe_update_types_lookup_map(*i);
4966 else
4967 ABG_ASSERT_NOT_REACHED;
4968 }
4969 }
4970
4971 change_kind
operator |(change_kind l,change_kind r)4972 operator|(change_kind l, change_kind r)
4973 {
4974 return static_cast<change_kind>(static_cast<unsigned>(l)
4975 | static_cast<unsigned>(r));
4976 }
4977
4978 change_kind
operator &(change_kind l,change_kind r)4979 operator&(change_kind l, change_kind r)
4980 {
4981 return static_cast<change_kind>(static_cast<unsigned>(l)
4982 & static_cast<unsigned>(r));
4983 }
4984
4985 change_kind&
operator |=(change_kind & l,change_kind r)4986 operator|=(change_kind& l, change_kind r)
4987 {
4988 l = l | r;
4989 return l;
4990 }
4991
4992 change_kind&
operator &=(change_kind & l,change_kind r)4993 operator&=(change_kind& l, change_kind r)
4994 {
4995 l = l & r;
4996 return l;
4997 }
4998
4999 /// Compare the properties that belong to the "is-a-member-relation"
5000 /// of a decl.
5001 ///
5002 /// For instance, access specifiers are part of the
5003 /// "is-a-member-relation" of a decl.
5004 ///
5005 /// This comparison however doesn't take decl names into account. So
5006 /// typedefs for instance are decls that we want to compare with this
5007 /// function.
5008 ///
5009 /// This function is a sub-routine of the more general 'equals'
5010 /// overload for instances of decl_base.
5011 ///
5012 /// @param l the left-hand side operand of the comparison.
5013 ///
5014 /// @param r the right-hand side operand of the comparison.
5015 ///
5016 /// @return true iff @p l compare equals, as a member decl, to @p r.
5017 bool
maybe_compare_as_member_decls(const decl_base & l,const decl_base & r,change_kind * k)5018 maybe_compare_as_member_decls(const decl_base& l,
5019 const decl_base& r,
5020 change_kind* k)
5021 {
5022 bool result = true;
5023 if (is_member_decl(l) && is_member_decl(r))
5024 {
5025 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5026 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5027
5028 access_specifier la = no_access, ra = no_access;
5029 bool member_types_or_functions =
5030 ((is_type(l) && is_type(r))
5031 || (is_function_decl(l) && is_function_decl(r)));
5032
5033 if (member_types_or_functions)
5034 {
5035 // Access specifiers on member types in DWARF is not
5036 // reliable; in the same DSO, the same struct can be either
5037 // a class or a struct, and the access specifiers of its
5038 // member types are not necessarily given, so they
5039 // effectively can be considered differently, again, in the
5040 // same DSO. So, here, let's avoid considering those!
5041 // during comparison.
5042 la = r1->get_access_specifier();
5043 ra = r2->get_access_specifier();
5044 r1->set_access_specifier(no_access);
5045 r2->set_access_specifier(no_access);
5046 }
5047
5048 bool rels_are_different = *r1 != *r2;
5049
5050 if (member_types_or_functions)
5051 {
5052 // restore the access specifiers.
5053 r1->set_access_specifier(la);
5054 r2->set_access_specifier(ra);
5055 }
5056
5057 if (rels_are_different)
5058 {
5059 result = false;
5060 if (k)
5061 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
5062 }
5063 }
5064 ABG_RETURN(result);
5065 }
5066
5067 /// Get the name of a decl for the purpose of comparing two decl
5068 /// names.
5069 ///
5070 /// This is a sub-routine of the 'equal' overload for decl_base.
5071 ///
5072 /// This function takes into account the fact that all anonymous names
5073 /// shall have the same name for the purpose of comparison.
5074 ///
5075 /// For decls that are part of an anonymous scope, only the
5076 /// non-qualified name should be taken into account.
5077 static interned_string
get_decl_name_for_comparison(const decl_base & d)5078 get_decl_name_for_comparison(const decl_base &d)
5079 {
5080 if (has_generic_anonymous_internal_type_name(&d)
5081 && d.get_is_anonymous())
5082 {
5083 // The decl is anonymous. It should have the same name ass the
5084 // other anymous types of the same kind.
5085 string r;
5086 r += get_generic_anonymous_internal_type_name(&d);
5087 return d.get_environment().intern(r);
5088 }
5089
5090 interned_string n = (is_anonymous_or_typedef_named(d)
5091 || scope_anonymous_or_typedef_named(d))
5092 ? d.get_name()
5093 : d.get_qualified_name(/*internal=*/true);
5094 return n;
5095 }
5096
5097 /// Compares two instances of @ref decl_base.
5098 ///
5099 /// If the two intances are different, set a bitfield to give some
5100 /// insight about the kind of differences there are.
5101 ///
5102 /// @param l the first artifact of the comparison.
5103 ///
5104 /// @param r the second artifact of the comparison.
5105 ///
5106 /// @param k a pointer to a bitfield that gives information about the
5107 /// kind of changes there are between @p l and @p r. This one is set
5108 /// iff it's non-null and if the function returns false.
5109 ///
5110 /// Please note that setting k to a non-null value does have a
5111 /// negative performance impact because even if @p l and @p r are not
5112 /// equal, the function keeps up the comparison in order to determine
5113 /// the different kinds of ways in which they are different.
5114 ///
5115 /// @return true if @p l equals @p r, false otherwise.
5116 bool
equals(const decl_base & l,const decl_base & r,change_kind * k)5117 equals(const decl_base& l, const decl_base& r, change_kind* k)
5118 {
5119 bool result = true;
5120 const interned_string &l_linkage_name = l.get_linkage_name();
5121 const interned_string &r_linkage_name = r.get_linkage_name();
5122 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5123 {
5124 if (l_linkage_name != r_linkage_name)
5125 {
5126 // Linkage names are different. That usually means the two
5127 // decls are different, unless we are looking at two
5128 // function declarations which have two different symbols
5129 // that are aliases of each other.
5130 const function_decl *f1 = is_function_decl(&l),
5131 *f2 = is_function_decl(&r);
5132 if (f1 && f2 && function_decls_alias(*f1, *f2))
5133 ;// The two functions are aliases, so they are not
5134 // different.
5135 else
5136 {
5137 result = false;
5138 if (k)
5139 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
5140 else
5141 ABG_RETURN_FALSE;
5142 }
5143 }
5144 }
5145
5146 // This is the qualified name of the decls that we want to compare.
5147 // We want to use the "internal" version of the qualified name as
5148 // that one is stable even for anonymous decls.
5149 interned_string ln = get_decl_name_for_comparison(l);
5150 interned_string rn = get_decl_name_for_comparison(r);
5151
5152 /// If both of the current decls have an anonymous scope then let's
5153 /// compare their name component by component by properly handling
5154 /// anonymous scopes. That's the slow path.
5155 ///
5156 /// Otherwise, let's just compare their name, the obvious way.
5157 /// That's the fast path because in that case the names are
5158 /// interned_string and comparing them is much faster.
5159 bool decls_are_same = (ln == rn);
5160 if (!decls_are_same
5161 && l.get_is_anonymous()
5162 && !l.get_has_anonymous_parent()
5163 && r.get_is_anonymous()
5164 && !r.get_has_anonymous_parent())
5165 // Both decls are anonymous and their scope are *NOT* anonymous.
5166 // So we consider the decls to have equivalent names (both
5167 // anonymous, remember). We are still in the fast path here.
5168 decls_are_same = true;
5169
5170 if (!decls_are_same
5171 && l.get_has_anonymous_parent()
5172 && r.get_has_anonymous_parent())
5173 // This is the slow path as we are comparing the decl qualified
5174 // names component by component, properly handling anonymous
5175 // scopes.
5176 decls_are_same = tools_utils::decl_names_equal(ln, rn);
5177
5178 if (!decls_are_same)
5179 {
5180 result = false;
5181 if (k)
5182 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
5183 else
5184 ABG_RETURN_FALSE;
5185 }
5186
5187 result &= maybe_compare_as_member_decls(l, r, k);
5188
5189 ABG_RETURN(result);
5190 }
5191
5192 /// Return true iff the two decls have the same name.
5193 ///
5194 /// This function doesn't test if the scopes of the the two decls are
5195 /// equal.
5196 ///
5197 /// Note that this virtual function is to be implemented by classes
5198 /// that extend the \p decl_base class.
5199 bool
operator ==(const decl_base & other) const5200 decl_base::operator==(const decl_base& other) const
5201 {return equals(*this, other, 0);}
5202
5203 /// Inequality operator.
5204 ///
5205 /// @param other to other instance of @ref decl_base to compare the
5206 /// current instance to.
5207 ///
5208 /// @return true iff the current instance of @ref decl_base is
5209 /// different from @p other.
5210 bool
operator !=(const decl_base & other) const5211 decl_base::operator!=(const decl_base& other) const
5212 {return !operator==(other);}
5213
5214 /// Destructor of the @ref decl_base type.
~decl_base()5215 decl_base::~decl_base()
5216 {delete priv_;}
5217
5218 /// This implements the ir_traversable_base::traverse pure virtual
5219 /// function.
5220 ///
5221 /// @param v the visitor used on the member nodes of the translation
5222 /// unit during the traversal.
5223 ///
5224 /// @return true if the entire IR node tree got traversed, false
5225 /// otherwise.
5226 bool
traverse(ir_node_visitor &)5227 decl_base::traverse(ir_node_visitor&)
5228 {
5229 // Do nothing in the base class.
5230 return true;
5231 }
5232
5233 /// Setter of the scope of the current decl.
5234 ///
5235 /// Note that the decl won't hold a reference on the scope. It's
5236 /// rather the scope that holds a reference on its members.
5237 void
set_scope(scope_decl * scope)5238 decl_base::set_scope(scope_decl* scope)
5239 {
5240 if (!priv_->context_)
5241 priv_->context_ = new context_rel(scope);
5242 else
5243 priv_->context_->set_scope(scope);
5244 }
5245
5246 // </decl_base definition>
5247
5248 /// Streaming operator for the decl_base::visibility.
5249 ///
5250 /// @param o the output stream to serialize the visibility to.
5251 ///
5252 /// @param v the visibility to serialize.
5253 ///
5254 /// @return the output stream.
5255 std::ostream&
operator <<(std::ostream & o,decl_base::visibility v)5256 operator<<(std::ostream& o, decl_base::visibility v)
5257 {
5258 string r;
5259 switch (v)
5260 {
5261 case decl_base::VISIBILITY_NONE:
5262 r = "none";
5263 break;
5264 case decl_base::VISIBILITY_DEFAULT:
5265 r = "default";
5266 break;
5267 case decl_base::VISIBILITY_PROTECTED:
5268 r = "protected";
5269 break;
5270 case decl_base::VISIBILITY_HIDDEN:
5271 r = "hidden";
5272 break;
5273 case decl_base::VISIBILITY_INTERNAL:
5274 r = "internal";
5275 break;
5276 }
5277 return o;
5278 }
5279
5280 /// Streaming operator for decl_base::binding.
5281 ///
5282 /// @param o the output stream to serialize the visibility to.
5283 ///
5284 /// @param b the binding to serialize.
5285 ///
5286 /// @return the output stream.
5287 std::ostream&
operator <<(std::ostream & o,decl_base::binding b)5288 operator<<(std::ostream& o, decl_base::binding b)
5289 {
5290 string r;
5291 switch (b)
5292 {
5293 case decl_base::BINDING_NONE:
5294 r = "none";
5295 break;
5296 case decl_base::BINDING_LOCAL:
5297 r = "local";
5298 break;
5299 case decl_base::BINDING_GLOBAL:
5300 r = "global";
5301 break;
5302 case decl_base::BINDING_WEAK:
5303 r = "weak";
5304 break;
5305 }
5306 o << r;
5307 return o;
5308 }
5309
5310 /// Turn equality of shared_ptr of decl_base into a deep equality;
5311 /// that is, make it compare the pointed to objects, not just the
5312 /// pointers.
5313 ///
5314 /// @param l the shared_ptr of decl_base on left-hand-side of the
5315 /// equality.
5316 ///
5317 /// @param r the shared_ptr of decl_base on right-hand-side of the
5318 /// equality.
5319 ///
5320 /// @return true if the decl_base pointed to by the shared_ptrs are
5321 /// equal, false otherwise.
5322 bool
operator ==(const decl_base_sptr & l,const decl_base_sptr & r)5323 operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5324 {
5325 if (l.get() == r.get())
5326 return true;
5327 if (!!l != !!r)
5328 return false;
5329
5330 return *l == *r;
5331 }
5332
5333 /// Inequality operator of shared_ptr of @ref decl_base.
5334 ///
5335 /// This is a deep equality operator, that is, it compares the
5336 /// pointed-to objects, rather than just the pointers.
5337 ///
5338 /// @param l the left-hand-side operand.
5339 ///
5340 /// @param r the right-hand-side operand.
5341 ///
5342 /// @return true iff @p l is different from @p r.
5343 bool
operator !=(const decl_base_sptr & l,const decl_base_sptr & r)5344 operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5345 {return !operator==(l, r);}
5346
5347 /// Turn equality of shared_ptr of type_base into a deep equality;
5348 /// that is, make it compare the pointed to objects too.
5349 ///
5350 /// @param l the shared_ptr of type_base on left-hand-side of the
5351 /// equality.
5352 ///
5353 /// @param r the shared_ptr of type_base on right-hand-side of the
5354 /// equality.
5355 ///
5356 /// @return true if the type_base pointed to by the shared_ptrs are
5357 /// equal, false otherwise.
5358 bool
operator ==(const type_base_sptr & l,const type_base_sptr & r)5359 operator==(const type_base_sptr& l, const type_base_sptr& r)
5360 {
5361 if (l.get() == r.get())
5362 return true;
5363 if (!!l != !!r)
5364 return false;
5365
5366 return *l == *r;
5367 }
5368
5369 /// Turn inequality of shared_ptr of type_base into a deep equality;
5370 /// that is, make it compare the pointed to objects..
5371 ///
5372 /// @param l the shared_ptr of type_base on left-hand-side of the
5373 /// equality.
5374 ///
5375 /// @param r the shared_ptr of type_base on right-hand-side of the
5376 /// equality.
5377 ///
5378 /// @return true iff the type_base pointed to by the shared_ptrs are
5379 /// different.
5380 bool
operator !=(const type_base_sptr & l,const type_base_sptr & r)5381 operator!=(const type_base_sptr& l, const type_base_sptr& r)
5382 {return !operator==(l, r);}
5383
5384 /// Tests if a declaration has got a scope.
5385 ///
5386 /// @param d the declaration to consider.
5387 ///
5388 /// @return true if the declaration has got a scope, false otherwise.
5389 bool
has_scope(const decl_base & d)5390 has_scope(const decl_base& d)
5391 {return (d.get_scope());}
5392
5393 /// Tests if a declaration has got a scope.
5394 ///
5395 /// @param d the declaration to consider.
5396 ///
5397 /// @return true if the declaration has got a scope, false otherwise.
5398 bool
has_scope(const decl_base_sptr d)5399 has_scope(const decl_base_sptr d)
5400 {return has_scope(*d.get());}
5401
5402 /// Tests if a declaration is a class member.
5403 ///
5404 /// @param d the declaration to consider.
5405 ///
5406 /// @return true if @p d is a class member, false otherwise.
5407 bool
is_member_decl(const decl_base_sptr d)5408 is_member_decl(const decl_base_sptr d)
5409 {return is_at_class_scope(d) || is_method_decl(d);}
5410
5411 /// Tests if a declaration is a class member.
5412 ///
5413 /// @param d the declaration to consider.
5414 ///
5415 /// @return true if @p d is a class member, false otherwise.
5416 bool
is_member_decl(const decl_base * d)5417 is_member_decl(const decl_base* d)
5418 {return is_at_class_scope(d) || is_method_decl(d);}
5419
5420 /// Tests if a declaration is a class member.
5421 ///
5422 /// @param d the declaration to consider.
5423 ///
5424 /// @return true if @p d is a class member, false otherwise.
5425 bool
is_member_decl(const decl_base & d)5426 is_member_decl(const decl_base& d)
5427 {return is_at_class_scope(d) || is_method_decl(d);}
5428
5429 /// Test if a declaration is a @ref scope_decl.
5430 ///
5431 /// @param d the declaration to take in account.
5432 ///
5433 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
5434 /// if d is a @ref scope_decl.
5435 scope_decl*
is_scope_decl(decl_base * d)5436 is_scope_decl(decl_base* d)
5437 {return dynamic_cast<scope_decl*>(d);}
5438
5439 /// Test if a declaration is a @ref scope_decl.
5440 ///
5441 /// @param d the declaration to take in account.
5442 ///
5443 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
5444 /// if d is a @ref scope_decl.
5445 scope_decl_sptr
is_scope_decl(const decl_base_sptr & d)5446 is_scope_decl(const decl_base_sptr& d)
5447 {return dynamic_pointer_cast<scope_decl>(d);}
5448
5449 /// Tests if a type is a class member.
5450 ///
5451 /// @param t the type to consider.
5452 ///
5453 /// @return true if @p t is a class member type, false otherwise.
5454 bool
is_member_type(const type_base_sptr & t)5455 is_member_type(const type_base_sptr& t)
5456 {
5457 decl_base_sptr d = get_type_declaration(t);
5458 return is_member_decl(d);
5459 }
5460
5461 /// Test if a type is user-defined.
5462 ///
5463 /// A type is considered user-defined if it's a
5464 /// struct/class/union/enum that is *NOT* artificial.
5465 ///
5466 /// @param t the type to consider.
5467 ///
5468 /// @return true iff the type @p t is user-defined.
5469 bool
is_user_defined_type(const type_base * t)5470 is_user_defined_type(const type_base* t)
5471 {
5472 if (t == 0)
5473 return false;
5474
5475 t = peel_qualified_or_typedef_type(t);
5476 decl_base *d = is_decl(t);
5477
5478 if ((is_class_or_union_type(t) || is_enum_type(t))
5479 && d && !d->get_is_artificial())
5480 return true;
5481
5482 return false;
5483 }
5484
5485 /// Test if a type is user-defined.
5486 ///
5487 /// A type is considered user-defined if it's a
5488 /// struct/class/union/enum.
5489 ///
5490 ///
5491 /// @param t the type to consider.
5492 ///
5493 /// @return true iff the type @p t is user-defined.
5494 bool
is_user_defined_type(const type_base_sptr & t)5495 is_user_defined_type(const type_base_sptr& t)
5496 {return is_user_defined_type(t.get());}
5497
5498 /// Gets the access specifier for a class member.
5499 ///
5500 /// @param d the declaration of the class member to consider. Note
5501 /// that this must be a class member otherwise the function aborts the
5502 /// current process.
5503 ///
5504 /// @return the access specifier for the class member @p d.
5505 access_specifier
get_member_access_specifier(const decl_base & d)5506 get_member_access_specifier(const decl_base& d)
5507 {
5508 ABG_ASSERT(is_member_decl(d));
5509
5510 const context_rel* c = d.get_context_rel();
5511 ABG_ASSERT(c);
5512
5513 return c->get_access_specifier();
5514 }
5515
5516 /// Gets the access specifier for a class member.
5517 ///
5518 /// @param d the declaration of the class member to consider. Note
5519 /// that this must be a class member otherwise the function aborts the
5520 /// current process.
5521 ///
5522 /// @return the access specifier for the class member @p d.
5523 access_specifier
get_member_access_specifier(const decl_base_sptr & d)5524 get_member_access_specifier(const decl_base_sptr& d)
5525 {return get_member_access_specifier(*d);}
5526
5527 /// Sets the access specifier for a class member.
5528 ///
5529 /// @param d the class member to set the access specifier for. Note
5530 /// that this must be a class member otherwise the function aborts the
5531 /// current process.
5532 ///
5533 /// @param a the new access specifier to set the class member to.
5534 void
set_member_access_specifier(decl_base & d,access_specifier a)5535 set_member_access_specifier(decl_base& d,
5536 access_specifier a)
5537 {
5538 ABG_ASSERT(is_member_decl(d));
5539
5540 context_rel* c = d.get_context_rel();
5541 ABG_ASSERT(c);
5542
5543 c->set_access_specifier(a);
5544 }
5545
5546 /// Sets the access specifier for a class member.
5547 ///
5548 /// @param d the class member to set the access specifier for. Note
5549 /// that this must be a class member otherwise the function aborts the
5550 /// current process.
5551 ///
5552 /// @param a the new access specifier to set the class member to.
5553 void
set_member_access_specifier(const decl_base_sptr & d,access_specifier a)5554 set_member_access_specifier(const decl_base_sptr& d,
5555 access_specifier a)
5556 {set_member_access_specifier(*d, a);}
5557
5558 /// Gets a flag saying if a class member is static or not.
5559 ///
5560 /// @param d the declaration for the class member to consider. Note
5561 /// that this must be a class member otherwise the function aborts the
5562 /// current process.
5563 ///
5564 /// @return true if the class member @p d is static, false otherwise.
5565 bool
get_member_is_static(const decl_base & d)5566 get_member_is_static(const decl_base&d)
5567 {
5568 ABG_ASSERT(is_member_decl(d));
5569
5570 const context_rel* c = d.get_context_rel();
5571 ABG_ASSERT(c);
5572
5573 return c->get_is_static();
5574 }
5575
5576 /// Gets a flag saying if a class member is static or not.
5577 ///
5578 /// @param d the declaration for the class member to consider. Note
5579 /// that this must be a class member otherwise the function aborts the
5580 /// current process.
5581 ///
5582 /// @return true if the class member @p d is static, false otherwise.
5583 bool
get_member_is_static(const decl_base * d)5584 get_member_is_static(const decl_base* d)
5585 {return get_member_is_static(*d);}
5586
5587 /// Gets a flag saying if a class member is static or not.
5588 ///
5589 /// @param d the declaration for the class member to consider. Note
5590 /// that this must be a class member otherwise the function aborts the
5591 /// current process.
5592 ///
5593 /// @return true if the class member @p d is static, false otherwise.
5594 bool
get_member_is_static(const decl_base_sptr & d)5595 get_member_is_static(const decl_base_sptr& d)
5596 {return get_member_is_static(*d);}
5597
5598 /// Test if a var_decl is a data member.
5599 ///
5600 /// @param v the var_decl to consider.
5601 ///
5602 /// @return true if @p v is data member, false otherwise.
5603 bool
is_data_member(const var_decl & v)5604 is_data_member(const var_decl& v)
5605 {return is_at_class_scope(v);}
5606
5607 /// Test if a var_decl is a data member.
5608 ///
5609 /// @param v the var_decl to consider.
5610 ///
5611 /// @return true if @p v is data member, false otherwise.
5612 bool
is_data_member(const var_decl * v)5613 is_data_member(const var_decl* v)
5614 {return is_data_member(*v);}
5615
5616 /// Test if a var_decl is a data member.
5617 ///
5618 /// @param v the var_decl to consider.
5619 ///
5620 /// @return true if @p v is data member, false otherwise.
5621 bool
is_data_member(const var_decl_sptr d)5622 is_data_member(const var_decl_sptr d)
5623 {return is_at_class_scope(d);}
5624
5625 /// Test if a decl is a data member.
5626 ///
5627 /// @param d the decl to consider.
5628 ///
5629 /// @return a pointer to the data member iff @p d is a data member, or
5630 /// a null pointer.
5631 var_decl_sptr
is_data_member(const decl_base_sptr & d)5632 is_data_member(const decl_base_sptr& d)
5633 {
5634 if (var_decl_sptr v = is_var_decl(d))
5635 {
5636 if (is_data_member(v))
5637 return v;
5638 }
5639 return var_decl_sptr();
5640 }
5641
5642 /// Test if a decl is a data member.
5643 ///
5644 /// @param d the decl to consider.
5645 ///
5646 /// @return a pointer to the data member iff @p d is a data member, or
5647 /// a null pointer.
5648 var_decl_sptr
is_data_member(const type_or_decl_base_sptr & d)5649 is_data_member(const type_or_decl_base_sptr& d)
5650 {
5651 if (var_decl_sptr v = is_var_decl(d))
5652 {
5653 if (is_data_member(v))
5654 return v;
5655 }
5656 return var_decl_sptr();
5657 }
5658
5659 /// Test if a decl is a data member.
5660 ///
5661 /// @param d the decl to consider.
5662 ///
5663 /// @return a pointer to the data member iff @p d is a data member, or
5664 /// a null pointer.
5665 var_decl*
is_data_member(const type_or_decl_base * d)5666 is_data_member(const type_or_decl_base* d)
5667 {
5668 if (var_decl *v = is_var_decl(d))
5669 if (is_data_member(v))
5670 return v;
5671 return 0;
5672 }
5673
5674 /// Test if a decl is a data member.
5675 ///
5676 /// @param d the decl to consider.
5677 ///
5678 /// @return a pointer to the data member iff @p d is a data member, or
5679 /// a null pointer.
5680 var_decl*
is_data_member(const decl_base * d)5681 is_data_member(const decl_base *d)
5682 {
5683 if (var_decl *v = is_var_decl(d))
5684 if (is_data_member(v))
5685 return v;
5686 return 0;
5687 }
5688
5689 /// Get the first non-anonymous data member of a given anonymous data
5690 /// member.
5691 ///
5692 /// E.g:
5693 ///
5694 /// struct S
5695 /// {
5696 /// union // <-- for this anonymous data member, the function
5697 /// // returns a.
5698 /// {
5699 /// int a;
5700 /// charb;
5701 /// };
5702 /// };
5703 ///
5704 /// @return anon_dm the anonymous data member to consider.
5705 ///
5706 /// @return the first non-anonymous data member of @p anon_dm. If no
5707 /// data member was found then this function returns @p anon_dm.
5708 const var_decl_sptr
get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)5709 get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
5710 {
5711 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5712 return anon_dm;
5713
5714 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5715 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5716
5717 if (is_anonymous_data_member(first))
5718 return get_first_non_anonymous_data_member(first);
5719
5720 return first;
5721 }
5722
5723 /// In the context of a given class or union, this function returns
5724 /// the data member that is located after a given data member.
5725 ///
5726 /// @param klass the class or union to consider.
5727 ///
5728 /// @param the data member to consider.
5729 ///
5730 /// @return the data member that is located right after @p
5731 /// data_member.
5732 const var_decl_sptr
get_next_data_member(const class_or_union_sptr & klass,const var_decl_sptr & data_member)5733 get_next_data_member(const class_or_union_sptr &klass,
5734 const var_decl_sptr &data_member)
5735 {
5736 if (!klass ||!data_member)
5737 return var_decl_sptr();
5738
5739 for (class_or_union::data_members::const_iterator it =
5740 klass->get_non_static_data_members().begin();
5741 it != klass->get_non_static_data_members().end();
5742 ++it)
5743 if (**it == *data_member)
5744 {
5745 ++it;
5746 if (it != klass->get_non_static_data_members().end())
5747 return get_first_non_anonymous_data_member(*it);
5748 break;
5749 }
5750
5751 return var_decl_sptr();
5752 }
5753
5754 /// Get the last data member of a class type.
5755 ///
5756 /// @param klass the class type to consider.
5757 var_decl_sptr
get_last_data_member(const class_or_union_sptr & klass)5758 get_last_data_member(const class_or_union_sptr &klass)
5759 {return klass->get_non_static_data_members().back();}
5760
5761 /// Test if a decl is an anonymous data member.
5762 ///
5763 /// @param d the decl to consider.
5764 ///
5765 /// @return true iff @p d is an anonymous data member.
5766 bool
is_anonymous_data_member(const decl_base & d)5767 is_anonymous_data_member(const decl_base& d)
5768 {return is_anonymous_data_member(&d);}
5769
5770 /// Test if a decl is an anonymous data member.
5771 ///
5772 /// @param d the decl to consider.
5773 ///
5774 /// @return the var_decl representing the data member iff @p d is an
5775 /// anonymous data member.
5776 const var_decl*
is_anonymous_data_member(const type_or_decl_base * d)5777 is_anonymous_data_member(const type_or_decl_base* d)
5778 {
5779 if (const var_decl* v = is_data_member(d))
5780 {
5781 if (is_anonymous_data_member(v))
5782 return v;
5783 }
5784 return 0;
5785 }
5786
5787 /// Test if a decl is an anonymous data member.
5788 ///
5789 /// @param d the decl to consider.
5790 ///
5791 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5792 /// it's an anonymous data member. Otherwise returns a nil pointer.
5793 const var_decl*
is_anonymous_data_member(const decl_base * d)5794 is_anonymous_data_member(const decl_base* d)
5795 {
5796 if (const var_decl* v = is_data_member(d))
5797 {
5798 if (is_anonymous_data_member(v))
5799 return v;
5800 }
5801 return 0;
5802 }
5803
5804 /// Test if a decl is an anonymous data member.
5805 ///
5806 /// @param d the decl to consider.
5807 ///
5808 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5809 /// it's an anonymous data member. Otherwise returns a nil pointer.
5810 var_decl_sptr
is_anonymous_data_member(const type_or_decl_base_sptr & d)5811 is_anonymous_data_member(const type_or_decl_base_sptr& d)
5812 {
5813 if (var_decl_sptr v = is_data_member(d))
5814 {
5815 if (is_anonymous_data_member(v))
5816 return v;
5817 }
5818 return var_decl_sptr();
5819 }
5820
5821 /// Test if a decl is an anonymous data member.
5822 ///
5823 /// @param d the decl to consider.
5824 ///
5825 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5826 /// it's an anonymous data member. Otherwise returns a nil pointer.
5827 var_decl_sptr
is_anonymous_data_member(const decl_base_sptr & d)5828 is_anonymous_data_member(const decl_base_sptr& d)
5829 {
5830 if (var_decl_sptr v = is_data_member(d))
5831 return is_anonymous_data_member(v);
5832 return var_decl_sptr();
5833 }
5834
5835 /// Test if a @ref var_decl is an anonymous data member.
5836 ///
5837 /// @param d the @ref var_decl to consider.
5838 ///
5839 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5840 /// it's an anonymous data member. Otherwise returns a nil pointer.
5841 var_decl_sptr
is_anonymous_data_member(const var_decl_sptr & d)5842 is_anonymous_data_member(const var_decl_sptr& d)
5843 {
5844 if (is_anonymous_data_member(d.get()))
5845 return d;
5846 return var_decl_sptr();
5847 }
5848
5849 /// Test if a @ref var_decl is an anonymous data member.
5850 ///
5851 /// @param d the @ref var_decl to consider.
5852 ///
5853 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5854 /// it's an anonymous data member. Otherwise returns a nil pointer.
5855 const var_decl*
is_anonymous_data_member(const var_decl * d)5856 is_anonymous_data_member(const var_decl* d)
5857 {
5858 if (d && is_anonymous_data_member(*d))
5859 return d;
5860 return 0;
5861 }
5862
5863 /// Test if a @ref var_decl is an anonymous data member.
5864 ///
5865 /// @param d the @ref var_decl to consider.
5866 ///
5867 /// @return true iff @p d is an anonymous data member.
5868 bool
is_anonymous_data_member(const var_decl & d)5869 is_anonymous_data_member(const var_decl& d)
5870 {
5871 return (is_data_member(d)
5872 && d.get_is_anonymous()
5873 && d.get_name().empty()
5874 && is_class_or_union_type(d.get_type()));
5875 }
5876
5877 /// Get the @ref class_or_union type of a given anonymous data member.
5878 ///
5879 /// @param d the anonymous data member to consider.
5880 ///
5881 /// @return the @ref class_or_union type of the anonymous data member
5882 /// @p d.
5883 class_or_union*
anonymous_data_member_to_class_or_union(const var_decl * d)5884 anonymous_data_member_to_class_or_union(const var_decl* d)
5885 {
5886 if ((d = is_anonymous_data_member(d)))
5887 return is_class_or_union_type(d->get_type().get());
5888 return 0;
5889 }
5890
5891 /// Test if a data member has annonymous type or not.
5892 ///
5893 /// @param d the data member to consider.
5894 ///
5895 /// @return the anonymous class or union type iff @p turns out to have
5896 /// an anonymous type. Otherwise, returns nil.
5897 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl & d)5898 data_member_has_anonymous_type(const var_decl& d)
5899 {
5900 if (is_data_member(d))
5901 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
5902 if (cou->get_is_anonymous())
5903 return cou;
5904
5905 return class_or_union_sptr();
5906 }
5907
5908 /// Test if a data member has annonymous type or not.
5909 ///
5910 /// @param d the data member to consider.
5911 ///
5912 /// @return the anonymous class or union type iff @p turns out to have
5913 /// an anonymous type. Otherwise, returns nil.
5914 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl * d)5915 data_member_has_anonymous_type(const var_decl* d)
5916 {
5917 if (d)
5918 return data_member_has_anonymous_type(*d);
5919 return class_or_union_sptr();
5920 }
5921
5922 /// Test if a data member has annonymous type or not.
5923 ///
5924 /// @param d the data member to consider.
5925 ///
5926 /// @return the anonymous class or union type iff @p turns out to have
5927 /// an anonymous type. Otherwise, returns nil.
5928 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl_sptr & d)5929 data_member_has_anonymous_type(const var_decl_sptr& d)
5930 {return data_member_has_anonymous_type(d.get());}
5931
5932 /// Get the @ref class_or_union type of a given anonymous data member.
5933 ///
5934 /// @param d the anonymous data member to consider.
5935 ///
5936 /// @return the @ref class_or_union type of the anonymous data member
5937 /// @p d.
5938 class_or_union_sptr
anonymous_data_member_to_class_or_union(const var_decl_sptr & d)5939 anonymous_data_member_to_class_or_union(const var_decl_sptr &d)
5940 {
5941 if (var_decl_sptr v = is_anonymous_data_member(d))
5942 return is_class_or_union_type(v->get_type());
5943 return class_or_union_sptr();
5944 }
5945
5946 /// Test if the scope of a given decl is anonymous or anonymous with a
5947 /// naming typedef.
5948 ///
5949 /// @param d the decl consider.
5950 ///
5951 /// @return true iff the scope of @p d is anonymous or anonymous with
5952 /// a naming typedef.
5953 bool
scope_anonymous_or_typedef_named(const decl_base & d)5954 scope_anonymous_or_typedef_named(const decl_base& d)
5955 {
5956 if (d.get_has_anonymous_parent()
5957 || (d.get_scope() && d.get_scope()->get_naming_typedef()))
5958 return true;
5959 return false;
5960 }
5961
5962 /// Test if a given decl is anonymous or has a naming typedef.
5963 ///
5964 /// @param d the decl to consider.
5965 ///
5966 /// @return true iff @p d is anonymous or has a naming typedef.
5967 bool
is_anonymous_or_typedef_named(const decl_base & d)5968 is_anonymous_or_typedef_named(const decl_base& d)
5969 {
5970 if (d.get_is_anonymous() || d.get_naming_typedef())
5971 return true;
5972 return false;
5973 }
5974
5975 /// Set the offset of a data member into its containing class.
5976 ///
5977 /// @param m the data member to consider.
5978 ///
5979 /// @param o the offset, in bits.
5980 void
set_data_member_offset(var_decl_sptr m,uint64_t o)5981 set_data_member_offset(var_decl_sptr m, uint64_t o)
5982 {
5983 ABG_ASSERT(is_data_member(m));
5984
5985 dm_context_rel* ctxt_rel =
5986 dynamic_cast<dm_context_rel*>(m->get_context_rel());
5987 ABG_ASSERT(ctxt_rel);
5988
5989 ctxt_rel->set_offset_in_bits(o);
5990 }
5991
5992 /// Get the offset of a data member.
5993 ///
5994 /// @param m the data member to consider.
5995 ///
5996 /// @return the offset (in bits) of @p m in its containing class.
5997 uint64_t
get_data_member_offset(const var_decl & m)5998 get_data_member_offset(const var_decl& m)
5999 {
6000 ABG_ASSERT(is_data_member(m));
6001 const dm_context_rel* ctxt_rel =
6002 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6003 ABG_ASSERT(ctxt_rel);
6004 return ctxt_rel->get_offset_in_bits();
6005 }
6006
6007 /// Get the offset of a data member.
6008 ///
6009 /// @param m the data member to consider.
6010 ///
6011 /// @return the offset (in bits) of @p m in its containing class.
6012 uint64_t
get_data_member_offset(const var_decl_sptr m)6013 get_data_member_offset(const var_decl_sptr m)
6014 {return get_data_member_offset(*m);}
6015
6016 /// Get the offset of a data member.
6017 ///
6018 /// @param m the data member to consider.
6019 ///
6020 /// @return the offset (in bits) of @p m in its containing class.
6021 uint64_t
get_data_member_offset(const decl_base_sptr d)6022 get_data_member_offset(const decl_base_sptr d)
6023 {return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6024
6025 /// Get the offset of the non-static data member that comes after a
6026 /// given one.
6027 ///
6028 /// If there is no data member after after the one given to this
6029 /// function (maybe because the given one is the last data member of
6030 /// the class type) then the function return false.
6031 ///
6032 /// @param klass the class to consider.
6033 ///
6034 /// @param dm the data member before the one we want to retrieve.
6035 ///
6036 /// @param offset out parameter. This parameter is set by the
6037 /// function to the offset of the data member that comes right after
6038 /// the data member @p dm, iff the function returns true.
6039 ///
6040 /// @return true iff the data member coming right after @p dm was
6041 /// found.
6042 bool
get_next_data_member_offset(const class_or_union_sptr & klass,const var_decl_sptr & dm,uint64_t & offset)6043 get_next_data_member_offset(const class_or_union_sptr& klass,
6044 const var_decl_sptr& dm,
6045 uint64_t& offset)
6046 {
6047 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6048 if (!next_dm)
6049 return false;
6050 offset = get_data_member_offset(next_dm);
6051 return true;
6052 }
6053
6054 /// Get the absolute offset of a data member.
6055 ///
6056 /// If the data member is part of an anonymous data member then this
6057 /// returns the absolute offset -- relative to the beginning of the
6058 /// containing class of the anonymous data member.
6059 ///
6060 /// @param m the data member to consider.
6061 ///
6062 /// @return the aboslute offset of the data member @p m.
6063 uint64_t
get_absolute_data_member_offset(const var_decl & m)6064 get_absolute_data_member_offset(const var_decl& m)
6065 {
6066 ABG_ASSERT(is_data_member(m));
6067 const dm_context_rel* ctxt_rel =
6068 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6069 ABG_ASSERT(ctxt_rel);
6070
6071 const var_decl *containing_anonymous_data_member =
6072 ctxt_rel->get_anonymous_data_member();
6073
6074 uint64_t containing_anonymous_data_member_offset = 0;
6075 if (containing_anonymous_data_member)
6076 containing_anonymous_data_member_offset =
6077 get_absolute_data_member_offset(*containing_anonymous_data_member);
6078
6079 return (ctxt_rel->get_offset_in_bits()
6080 +
6081 containing_anonymous_data_member_offset);
6082 }
6083
6084 /// Get the absolute offset of a data member.
6085 ///
6086 /// If the data member is part of an anonymous data member then this
6087 /// returns the absolute offset -- relative to the beginning of the
6088 /// containing class of the anonymous data member.
6089 ///
6090 /// @param m the data member to consider.
6091 ///
6092 /// @return the aboslute offset of the data member @p m.
6093 uint64_t
get_absolute_data_member_offset(const var_decl_sptr & m)6094 get_absolute_data_member_offset(const var_decl_sptr& m)
6095 {
6096 if (!m)
6097 return 0;
6098 return get_absolute_data_member_offset(*m);
6099 }
6100
6101 /// Get the size of a given variable.
6102 ///
6103 /// @param v the variable to consider.
6104 ///
6105 /// @return the size of variable @p v.
6106 uint64_t
get_var_size_in_bits(const var_decl_sptr & v)6107 get_var_size_in_bits(const var_decl_sptr& v)
6108 {
6109 type_base_sptr t = v->get_type();
6110 ABG_ASSERT(t);
6111
6112 return t->get_size_in_bits();
6113 }
6114
6115 /// Set a flag saying if a data member is laid out.
6116 ///
6117 /// @param m the data member to consider.
6118 ///
6119 /// @param l true if @p m is to be considered as laid out.
6120 void
set_data_member_is_laid_out(var_decl_sptr m,bool l)6121 set_data_member_is_laid_out(var_decl_sptr m, bool l)
6122 {
6123 ABG_ASSERT(is_data_member(m));
6124 dm_context_rel* ctxt_rel =
6125 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6126 ctxt_rel->set_is_laid_out(l);
6127 }
6128
6129 /// Test whether a data member is laid out.
6130 ///
6131 /// @param m the data member to consider.
6132 ///
6133 /// @return true if @p m is laid out, false otherwise.
6134 bool
get_data_member_is_laid_out(const var_decl & m)6135 get_data_member_is_laid_out(const var_decl& m)
6136 {
6137 ABG_ASSERT(is_data_member(m));
6138 const dm_context_rel* ctxt_rel =
6139 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6140
6141 return ctxt_rel->get_is_laid_out();
6142 }
6143
6144 /// Test whether a data member is laid out.
6145 ///
6146 /// @param m the data member to consider.
6147 ///
6148 /// @return true if @p m is laid out, false otherwise.
6149 bool
get_data_member_is_laid_out(const var_decl_sptr m)6150 get_data_member_is_laid_out(const var_decl_sptr m)
6151 {return get_data_member_is_laid_out(*m);}
6152
6153 /// Test whether a function_decl is a member function.
6154 ///
6155 /// @param f the function_decl to test.
6156 ///
6157 /// @return true if @p f is a member function, false otherwise.
6158 bool
is_member_function(const function_decl & f)6159 is_member_function(const function_decl& f)
6160 {return is_member_decl(f);}
6161
6162 /// Test whether a function_decl is a member function.
6163 ///
6164 /// @param f the function_decl to test.
6165 ///
6166 /// @return true if @p f is a member function, false otherwise.
6167 bool
is_member_function(const function_decl * f)6168 is_member_function(const function_decl* f)
6169 {return is_member_decl(*f);}
6170
6171 /// Test whether a function_decl is a member function.
6172 ///
6173 /// @param f the function_decl to test.
6174 ///
6175 /// @return true if @p f is a member function, false otherwise.
6176 bool
is_member_function(const function_decl_sptr & f)6177 is_member_function(const function_decl_sptr& f)
6178 {return is_member_decl(*f);}
6179
6180 /// Test whether a member function is a constructor.
6181 ///
6182 /// @param f the member function to test.
6183 ///
6184 /// @return true if @p f is a constructor, false otherwise.
6185 bool
get_member_function_is_ctor(const function_decl & f)6186 get_member_function_is_ctor(const function_decl& f)
6187 {
6188 ABG_ASSERT(is_member_function(f));
6189
6190 const method_decl* m = is_method_decl(&f);
6191 ABG_ASSERT(m);
6192
6193 const mem_fn_context_rel* ctxt =
6194 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6195
6196 return ctxt->is_constructor();
6197 }
6198
6199 /// Test whether a member function is a constructor.
6200 ///
6201 /// @param f the member function to test.
6202 ///
6203 /// @return true if @p f is a constructor, false otherwise.
6204 bool
get_member_function_is_ctor(const function_decl_sptr & f)6205 get_member_function_is_ctor(const function_decl_sptr& f)
6206 {return get_member_function_is_ctor(*f);}
6207
6208
6209 /// Setter for the is_ctor property of the member function.
6210 ///
6211 /// @param f the member function to set.
6212 ///
6213 /// @param f the new boolean value of the is_ctor property. Is true
6214 /// if @p f is a constructor, false otherwise.
6215 void
set_member_function_is_ctor(function_decl & f,bool c)6216 set_member_function_is_ctor(function_decl& f, bool c)
6217 {
6218 ABG_ASSERT(is_member_function(f));
6219
6220 method_decl* m = is_method_decl(&f);
6221 ABG_ASSERT(m);
6222
6223 mem_fn_context_rel* ctxt =
6224 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6225
6226 ctxt->is_constructor(c);
6227 }
6228
6229 /// Setter for the is_ctor property of the member function.
6230 ///
6231 /// @param f the member function to set.
6232 ///
6233 /// @param f the new boolean value of the is_ctor property. Is true
6234 /// if @p f is a constructor, false otherwise.
6235 void
set_member_function_is_ctor(const function_decl_sptr & f,bool c)6236 set_member_function_is_ctor(const function_decl_sptr& f, bool c)
6237 {set_member_function_is_ctor(*f, c);}
6238
6239 /// Test whether a member function is a destructor.
6240 ///
6241 /// @param f the function to test.
6242 ///
6243 /// @return true if @p f is a destructor, false otherwise.
6244 bool
get_member_function_is_dtor(const function_decl & f)6245 get_member_function_is_dtor(const function_decl& f)
6246 {
6247 ABG_ASSERT(is_member_function(f));
6248
6249 const method_decl* m = is_method_decl(&f);
6250 ABG_ASSERT(m);
6251
6252 const mem_fn_context_rel* ctxt =
6253 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6254
6255 return ctxt->is_destructor();
6256 }
6257
6258 /// Test whether a member function is a destructor.
6259 ///
6260 /// @param f the function to test.
6261 ///
6262 /// @return true if @p f is a destructor, false otherwise.
6263 bool
get_member_function_is_dtor(const function_decl_sptr & f)6264 get_member_function_is_dtor(const function_decl_sptr& f)
6265 {return get_member_function_is_dtor(*f);}
6266
6267 /// Set the destructor-ness property of a member function.
6268 ///
6269 /// @param f the function to set.
6270 ///
6271 /// @param d true if @p f is a destructor, false otherwise.
6272 void
set_member_function_is_dtor(function_decl & f,bool d)6273 set_member_function_is_dtor(function_decl& f, bool d)
6274 {
6275 ABG_ASSERT(is_member_function(f));
6276
6277 method_decl* m = is_method_decl(&f);
6278 ABG_ASSERT(m);
6279
6280 mem_fn_context_rel* ctxt =
6281 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6282
6283 ctxt->is_destructor(d);
6284 }
6285
6286 /// Set the destructor-ness property of a member function.
6287 ///
6288 /// @param f the function to set.
6289 ///
6290 /// @param d true if @p f is a destructor, false otherwise.
6291 void
set_member_function_is_dtor(const function_decl_sptr & f,bool d)6292 set_member_function_is_dtor(const function_decl_sptr& f, bool d)
6293 {set_member_function_is_dtor(*f, d);}
6294
6295 /// Test whether a member function is const.
6296 ///
6297 /// @param f the function to test.
6298 ///
6299 /// @return true if @p f is const, false otherwise.
6300 bool
get_member_function_is_const(const function_decl & f)6301 get_member_function_is_const(const function_decl& f)
6302 {
6303 ABG_ASSERT(is_member_function(f));
6304
6305 const method_decl* m = is_method_decl(&f);
6306 ABG_ASSERT(m);
6307
6308 const mem_fn_context_rel* ctxt =
6309 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6310
6311 return ctxt->is_const();
6312 }
6313
6314 /// Test whether a member function is const.
6315 ///
6316 /// @param f the function to test.
6317 ///
6318 /// @return true if @p f is const, false otherwise.
6319 bool
get_member_function_is_const(const function_decl_sptr & f)6320 get_member_function_is_const(const function_decl_sptr& f)
6321 {return get_member_function_is_const(*f);}
6322
6323 /// set the const-ness property of a member function.
6324 ///
6325 /// @param f the function to set.
6326 ///
6327 /// @param is_const the new value of the const-ness property of @p f
6328 void
set_member_function_is_const(function_decl & f,bool is_const)6329 set_member_function_is_const(function_decl& f, bool is_const)
6330 {
6331 ABG_ASSERT(is_member_function(f));
6332
6333 method_decl* m = is_method_decl(&f);
6334 ABG_ASSERT(m);
6335
6336 mem_fn_context_rel* ctxt =
6337 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6338
6339 ctxt->is_const(is_const);
6340 }
6341
6342 /// set the const-ness property of a member function.
6343 ///
6344 /// @param f the function to set.
6345 ///
6346 /// @param is_const the new value of the const-ness property of @p f
6347 void
set_member_function_is_const(const function_decl_sptr & f,bool is_const)6348 set_member_function_is_const(const function_decl_sptr& f, bool is_const)
6349 {set_member_function_is_const(*f, is_const);}
6350
6351 /// Test if a virtual member function has a vtable offset set.
6352 ///
6353 /// @param f the virtual member function to consider.
6354 ///
6355 /// @return true iff the virtual member function has its vtable offset
6356 /// set, i.e, if the vtable offset of @p is different from -1.
6357 bool
member_function_has_vtable_offset(const function_decl & f)6358 member_function_has_vtable_offset(const function_decl& f)
6359 {return get_member_function_vtable_offset(f) != -1;}
6360
6361 /// Get the vtable offset of a member function.
6362 ///
6363 /// @param f the member function to consider.
6364 ///
6365 /// @return the vtable offset of @p f. Note that a vtable offset of
6366 /// value -1 means that the member function does *NOT* yet have a
6367 /// vtable offset associated to it.
6368 ssize_t
get_member_function_vtable_offset(const function_decl & f)6369 get_member_function_vtable_offset(const function_decl& f)
6370 {
6371 ABG_ASSERT(is_member_function(f));
6372
6373 const method_decl* m =
6374 dynamic_cast<const method_decl*>(&f);
6375 ABG_ASSERT(m);
6376
6377 const mem_fn_context_rel* ctxt =
6378 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6379
6380 return ctxt->vtable_offset();
6381 }
6382
6383 /// Get the vtable offset of a member function.
6384 ///
6385 /// @param f the member function to consider.
6386 ///
6387 /// @return the vtable offset of @p f. Note that a vtable offset of
6388 /// value -1 means that the member function does *NOT* yet have a
6389 /// vtable offset associated to it.
6390 ssize_t
get_member_function_vtable_offset(const function_decl_sptr & f)6391 get_member_function_vtable_offset(const function_decl_sptr& f)
6392 {return get_member_function_vtable_offset(*f);}
6393
6394 /// Set the vtable offset of a member function.
6395 ///
6396 /// @param f the member function to consider.
6397 ///
6398 /// @param s the new vtable offset. Please note that a vtable offset
6399 /// of value -1 means that the virtual member function does not (yet)
6400 /// have any vtable offset associated to it.
6401 void
set_member_function_vtable_offset(function_decl & f,ssize_t s)6402 set_member_function_vtable_offset(function_decl& f, ssize_t s)
6403 {
6404 ABG_ASSERT(is_member_function(f));
6405
6406 method_decl* m = is_method_decl(&f);
6407 ABG_ASSERT(m);
6408
6409 mem_fn_context_rel* ctxt =
6410 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6411
6412 ctxt->vtable_offset(s);
6413 }
6414
6415 /// Get the vtable offset of a member function.
6416 ///
6417 /// @param f the member function to consider.
6418 ///
6419 /// @param s the new vtable offset. Please note that a vtable offset
6420 /// of value -1 means that the virtual member function does not (yet)
6421 /// have any vtable offset associated to it.
6422 void
set_member_function_vtable_offset(const function_decl_sptr & f,ssize_t s)6423 set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6424 {return set_member_function_vtable_offset(*f, s);}
6425
6426 /// Test if a given member function is virtual.
6427 ///
6428 /// @param mem_fn the member function to consider.
6429 ///
6430 /// @return true iff a @p mem_fn is virtual.
6431 bool
get_member_function_is_virtual(const function_decl & f)6432 get_member_function_is_virtual(const function_decl& f)
6433 {
6434 ABG_ASSERT(is_member_function(f));
6435
6436 const method_decl* m =
6437 dynamic_cast<const method_decl*>(&f);
6438 ABG_ASSERT(m);
6439
6440 const mem_fn_context_rel* ctxt =
6441 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6442
6443 return ctxt->is_virtual();
6444 }
6445
6446 /// Test if a given member function is virtual.
6447 ///
6448 /// @param mem_fn the member function to consider.
6449 ///
6450 /// @return true iff a @p mem_fn is virtual.
6451 bool
get_member_function_is_virtual(const function_decl_sptr & mem_fn)6452 get_member_function_is_virtual(const function_decl_sptr& mem_fn)
6453 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6454
6455 /// Test if a given member function is virtual.
6456 ///
6457 /// @param mem_fn the member function to consider.
6458 ///
6459 /// @return true iff a @p mem_fn is virtual.
6460 bool
get_member_function_is_virtual(const function_decl * mem_fn)6461 get_member_function_is_virtual(const function_decl* mem_fn)
6462 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6463
6464 /// Set the virtual-ness of a member function.
6465 ///
6466 /// @param f the member function to consider.
6467 ///
6468 /// @param is_virtual set to true if the function is virtual.
6469 void
set_member_function_is_virtual(function_decl & f,bool is_virtual)6470 set_member_function_is_virtual(function_decl& f, bool is_virtual)
6471 {
6472 ABG_ASSERT(is_member_function(f));
6473
6474 method_decl* m = is_method_decl(&f);
6475 ABG_ASSERT(m);
6476
6477 mem_fn_context_rel* ctxt =
6478 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6479
6480 ctxt->is_virtual(is_virtual);
6481 }
6482
6483 /// Set the virtual-ness of a member function.
6484 ///
6485 /// @param f the member function to consider.
6486 ///
6487 /// @param is_virtual set to true if the function is virtual.
6488 void
set_member_function_is_virtual(const function_decl_sptr & fn,bool is_virtual)6489 set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6490 {
6491 if (fn)
6492 {
6493 set_member_function_is_virtual(*fn, is_virtual);
6494 fixup_virtual_member_function
6495 (dynamic_pointer_cast<method_decl>(fn));
6496 }
6497 }
6498
6499 /// Recursively returns the the underlying type of a typedef. The
6500 /// return type should not be a typedef of anything anymore.
6501 ///
6502 ///
6503 /// Also recursively strip typedefs from the sub-types of the type
6504 /// given in arguments.
6505 ///
6506 /// Note that this function builds types in which typedefs are
6507 /// stripped off. Usually, types are held by their scope, so their
6508 /// life time is bound to the life time of their scope. But as this
6509 /// function cannot really insert the built type into it's scope, it
6510 /// must ensure that the newly built type stays live long enough.
6511 ///
6512 /// So, if the newly built type has a canonical type, this function
6513 /// returns the canonical type. Otherwise, this function ensure that
6514 /// the newly built type has a life time that is the same as the life
6515 /// time of the entire libabigail library.
6516 ///
6517 /// @param type the type to strip the typedefs from.
6518 ///
6519 /// @return the resulting type stripped from its typedefs, or just
6520 /// return @p type if it has no typedef in any of its sub-types.
6521 type_base_sptr
strip_typedef(const type_base_sptr type)6522 strip_typedef(const type_base_sptr type)
6523 {
6524 if (!type)
6525 return type;
6526
6527 // If type is a class type then do not try to strip typedefs from it.
6528 // And if it has no canonical type (which can mean that it's a
6529 // declaration-only class), then, make sure its live for ever and
6530 // return it.
6531 if (class_decl_sptr cl = is_class_type(type))
6532 {
6533 if (!cl->get_canonical_type())
6534 keep_type_alive(type);
6535 return type;
6536 }
6537
6538 const environment& env = type->get_environment();
6539 type_base_sptr t = type;
6540
6541 if (const typedef_decl_sptr ty = is_typedef(t))
6542 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6543 else if (const reference_type_def_sptr ty = is_reference_type(t))
6544 {
6545 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6546 env));
6547 ABG_ASSERT(p);
6548 t.reset(new reference_type_def(p,
6549 ty->is_lvalue(),
6550 ty->get_size_in_bits(),
6551 ty->get_alignment_in_bits(),
6552 ty->get_location()));
6553 }
6554 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6555 {
6556 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6557 env));
6558 ABG_ASSERT(p);
6559 t.reset(new pointer_type_def(p,
6560 ty->get_size_in_bits(),
6561 ty->get_alignment_in_bits(),
6562 ty->get_location()));
6563 }
6564 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6565 {
6566 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6567 env));
6568 ABG_ASSERT(p);
6569 t.reset(new qualified_type_def(p,
6570 ty->get_cv_quals(),
6571 ty->get_location()));
6572 }
6573 else if (const array_type_def_sptr ty = is_array_type(t))
6574 {
6575 type_base_sptr p = strip_typedef(ty->get_element_type());
6576 ABG_ASSERT(p);
6577 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6578 }
6579 else if (const method_type_sptr ty = is_method_type(t))
6580 {
6581 function_decl::parameters parm;
6582 for (function_decl::parameters::const_iterator i =
6583 ty->get_parameters().begin();
6584 i != ty->get_parameters().end();
6585 ++i)
6586 {
6587 function_decl::parameter_sptr p = *i;
6588 type_base_sptr typ = strip_typedef(p->get_type());
6589 ABG_ASSERT(typ);
6590 function_decl::parameter_sptr stripped
6591 (new function_decl::parameter(typ,
6592 p->get_index(),
6593 p->get_name(),
6594 p->get_location(),
6595 p->get_variadic_marker(),
6596 p->get_is_artificial()));
6597 parm.push_back(stripped);
6598 }
6599 type_base_sptr p = strip_typedef(ty->get_return_type());
6600 ABG_ASSERT(!!p == !!ty->get_return_type());
6601 t.reset(new method_type(p, ty->get_class_type(),
6602 parm, ty->get_is_const(),
6603 ty->get_size_in_bits(),
6604 ty->get_alignment_in_bits()));
6605 }
6606 else if (const function_type_sptr ty = is_function_type(t))
6607 {
6608 function_decl::parameters parm;
6609 for (function_decl::parameters::const_iterator i =
6610 ty->get_parameters().begin();
6611 i != ty->get_parameters().end();
6612 ++i)
6613 {
6614 function_decl::parameter_sptr p = *i;
6615 type_base_sptr typ = strip_typedef(p->get_type());
6616 ABG_ASSERT(typ);
6617 function_decl::parameter_sptr stripped
6618 (new function_decl::parameter(typ,
6619 p->get_index(),
6620 p->get_name(),
6621 p->get_location(),
6622 p->get_variadic_marker(),
6623 p->get_is_artificial()));
6624 parm.push_back(stripped);
6625 }
6626 type_base_sptr p = strip_typedef(ty->get_return_type());
6627 ABG_ASSERT(!!p == !!ty->get_return_type());
6628 t.reset(new function_type(p, parm,
6629 ty->get_size_in_bits(),
6630 ty->get_alignment_in_bits()));
6631 }
6632
6633 if (!t->get_translation_unit())
6634 t->set_translation_unit(type->get_translation_unit());
6635
6636 if (!(type->get_canonical_type() && canonicalize(t)))
6637 keep_type_alive(t);
6638
6639 return t->get_canonical_type() ? t->get_canonical_type() : t;
6640 }
6641
6642 /// Strip qualification from a qualified type, when it makes sense.
6643 ///
6644 /// DWARF constructs "const reference". This is redundant because a
6645 /// reference is always const. It also constructs the useless "const
6646 /// void" type. The issue is these redundant types then leak into the
6647 /// IR and make for bad diagnostics.
6648 ///
6649 /// This function thus strips the const qualifier from the type in
6650 /// that case. It might contain code to strip other cases like this
6651 /// in the future.
6652 ///
6653 /// @param t the type to strip const qualification from.
6654 ///
6655 /// @return the stripped type or just return @p t.
6656 decl_base_sptr
strip_useless_const_qualification(const qualified_type_def_sptr t)6657 strip_useless_const_qualification(const qualified_type_def_sptr t)
6658 {
6659 if (!t)
6660 return t;
6661
6662 decl_base_sptr result = t;
6663 type_base_sptr u = t->get_underlying_type();
6664 const environment& env = t->get_environment();
6665
6666 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6667 && (is_reference_type(u)))
6668 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6669 && env.is_void_type(u))
6670 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6671 // Let's strip the const qualifier because a reference is always
6672 // 'const' and a const void doesn't make sense. They will just
6673 // lead to spurious changes later down the pipeline, that we'll
6674 // have to deal with by doing painful and error-prone editing of
6675 // the diff IR. Dropping that useless and inconsistent artefact
6676 // right here seems to be a good way to go.
6677 result = is_decl(u);
6678
6679 return result;
6680 }
6681
6682 /// Merge redundant qualifiers from a tree of qualified types.
6683 ///
6684 /// Suppose a tree of qualified types leads to:
6685 ///
6686 /// const virtual const restrict const int;
6687 ///
6688 /// Suppose the IR tree of qualified types ressembles (with C meaning
6689 /// const, V meaning virtual and R meaning restrict):
6690 ///
6691 /// [C|V]-->[C|R] -->[C] --> [int].
6692 ///
6693 /// This function walks the IR and remove the redundant CV qualifiers
6694 /// so the IR becomes:
6695 ///
6696 /// [C|V] --> [R] --> [] -->[int].
6697 ///
6698 /// Note that the empty qualified type (noted []) represents a
6699 /// qualified type with no qualifier. It's rare, but it can exist.
6700 /// I've put it here just for the sake of example.
6701 ///
6702 /// The resulting IR thus represents the (merged) type:
6703 ///
6704 /// const virtual restrict int.
6705 ///
6706 /// This function is a sub-routine of the overload @ref
6707 /// strip_useless_const_qualification which doesn't return any value.
6708 ///
6709 /// @param t the qualified type to consider.
6710 ///
6711 /// @param redundant_quals the (redundant) qualifiers to be removed
6712 /// from the qualifiers of the underlying types of @p t.
6713 ///
6714 /// @return the underlying type of @p t which might have had its
6715 /// redundant qualifiers removed.
6716 static qualified_type_def_sptr
strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr & t,qualified_type_def::CV redundant_quals)6717 strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
6718 qualified_type_def::CV redundant_quals)
6719 {
6720 if (!t)
6721 return t;
6722
6723 // We must NOT edit canonicalized types.
6724 ABG_ASSERT(!t->get_canonical_type());
6725
6726 qualified_type_def_sptr underlying_qualified_type =
6727 is_qualified_type(t->get_underlying_type());
6728
6729 // Let's build 'currated qualifiers' that are the qualifiers of the
6730 // current type from which redundant qualifiers are removed.
6731 qualified_type_def::CV currated_quals = t->get_cv_quals();
6732
6733 // Remove the redundant qualifiers from these currated qualifiers
6734 currated_quals &= ~redundant_quals;
6735 t->set_cv_quals(currated_quals);
6736
6737 // The redundant qualifiers, moving forward, is now the union of the
6738 // previous set of redundant qualifiers and the currated qualifiers.
6739 redundant_quals |= currated_quals;
6740
6741 qualified_type_def_sptr result = t;
6742 if (underlying_qualified_type)
6743 // Now remove the redundant qualifiers from the qualified types
6744 // potentially carried by the underlying type.
6745 result =
6746 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
6747 redundant_quals);
6748
6749 return result;
6750 }
6751
6752 /// Merge redundant qualifiers from a tree of qualified types.
6753 ///
6754 /// Suppose a tree of qualified types leads to:
6755 ///
6756 /// const virtual const restrict const int;
6757 ///
6758 /// Suppose the IR tree of qualified types ressembles (with C meaning
6759 /// const, V meaning virtual and R meaning restrict):
6760 ///
6761 /// [C|V]-->[C|R] -->[C] --> [int].
6762 ///
6763 /// This function walks the IR and remove the redundant CV qualifiers
6764 /// so the IR becomes:
6765 ///
6766 /// [C|V] --> [R] --> [] -->[int].
6767 ///
6768 /// Note that the empty qualified type (noted []) represents a
6769 /// qualified type with no qualifier. It's rare, but it can exist.
6770 /// I've put it here just for the sake of example.
6771 ///
6772 /// The resulting IR thus represents the (merged) type:
6773 ///
6774 /// const virtual restrict int.
6775 ///
6776 /// @param t the qualified type to consider. The IR below the
6777 /// argument to this parameter will be edited to remove redundant
6778 /// qualifiers where applicable.
6779 void
strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr & t)6780 strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
6781 {
6782 if (!t)
6783 return;
6784
6785 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
6786 strip_redundant_quals_from_underyling_types(t, redundant_quals);
6787 }
6788
6789 /// Return the leaf underlying type node of a @ref typedef_decl node.
6790 ///
6791 /// If the underlying type of a @ref typedef_decl node is itself a
6792 /// @ref typedef_decl node, then recursively look at the underlying
6793 /// type nodes to get the first one that is not a a @ref typedef_decl
6794 /// node. This is what a leaf underlying type node means.
6795 ///
6796 /// Otherwise, if the underlying type node of @ref typedef_decl is
6797 /// *NOT* a @ref typedef_decl node, then just return the underlying
6798 /// type node.
6799 ///
6800 /// And if the type node considered is not a @ref typedef_decl node,
6801 /// then just return it.
6802 ///
6803 /// @return the leaf underlying type node of a @p type.
6804 type_base_sptr
peel_typedef_type(const type_base_sptr & type)6805 peel_typedef_type(const type_base_sptr& type)
6806 {
6807 typedef_decl_sptr t = is_typedef(type);
6808 if (!t)
6809 return type;
6810
6811 if (is_typedef(t->get_underlying_type()))
6812 return peel_typedef_type(t->get_underlying_type());
6813 return t->get_underlying_type();
6814 }
6815
6816 /// Return the leaf underlying type node of a @ref typedef_decl node.
6817 ///
6818 /// If the underlying type of a @ref typedef_decl node is itself a
6819 /// @ref typedef_decl node, then recursively look at the underlying
6820 /// type nodes to get the first one that is not a a @ref typedef_decl
6821 /// node. This is what a leaf underlying type node means.
6822 ///
6823 /// Otherwise, if the underlying type node of @ref typedef_decl is
6824 /// *NOT* a @ref typedef_decl node, then just return the underlying
6825 /// type node.
6826 ///
6827 /// And if the type node considered is not a @ref typedef_decl node,
6828 /// then just return it.
6829 ///
6830 /// @return the leaf underlying type node of a @p type.
6831 const type_base*
peel_typedef_type(const type_base * type)6832 peel_typedef_type(const type_base* type)
6833 {
6834 const typedef_decl* t = is_typedef(type);
6835 if (!t)
6836 return type;
6837
6838 return peel_typedef_type(t->get_underlying_type()).get();
6839 }
6840
6841 /// Return the leaf pointed-to type node of a @ref pointer_type_def
6842 /// node.
6843 ///
6844 /// If the pointed-to type of a @ref pointer_type_def node is itself a
6845 /// @ref pointer_type_def node, then recursively look at the
6846 /// pointed-to type nodes to get the first one that is not a a @ref
6847 /// pointer_type_def node. This is what a leaf pointed-to type node
6848 /// means.
6849 ///
6850 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
6851 /// *NOT* a @ref pointer_type_def node, then just return the
6852 /// pointed-to type node.
6853 ///
6854 /// And if the type node considered is not a @ref pointer_type_def
6855 /// node, then just return it.
6856 ///
6857 /// @return the leaf pointed-to type node of a @p type.
6858 type_base_sptr
peel_pointer_type(const type_base_sptr & type)6859 peel_pointer_type(const type_base_sptr& type)
6860 {
6861 pointer_type_def_sptr t = is_pointer_type(type);
6862 if (!t)
6863 return type;
6864
6865 if (is_pointer_type(t->get_pointed_to_type()))
6866 return peel_pointer_type(t->get_pointed_to_type());
6867 return t->get_pointed_to_type();
6868 }
6869
6870 /// Return the leaf pointed-to type node of a @ref pointer_type_def
6871 /// node.
6872 ///
6873 /// If the pointed-to type of a @ref pointer_type_def node is itself a
6874 /// @ref pointer_type_def node, then recursively look at the
6875 /// pointed-to type nodes to get the first one that is not a a @ref
6876 /// pointer_type_def node. This is what a leaf pointed-to type node
6877 /// means.
6878 ///
6879 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
6880 /// *NOT* a @ref pointer_type_def node, then just return the
6881 /// pointed-to type node.
6882 ///
6883 /// And if the type node considered is not a @ref pointer_type_def
6884 /// node, then just return it.
6885 ///
6886 /// @return the leaf pointed-to type node of a @p type.
6887 const type_base*
peel_pointer_type(const type_base * type)6888 peel_pointer_type(const type_base* type)
6889 {
6890 const pointer_type_def* t = is_pointer_type(type);
6891 if (!t)
6892 return type;
6893
6894 return peel_pointer_type(t->get_pointed_to_type()).get();
6895 }
6896
6897 /// Return the leaf pointed-to type node of a @ref reference_type_def
6898 /// node.
6899 ///
6900 /// If the pointed-to type of a @ref reference_type_def node is itself
6901 /// a @ref reference_type_def node, then recursively look at the
6902 /// pointed-to type nodes to get the first one that is not a a @ref
6903 /// reference_type_def node. This is what a leaf pointed-to type node
6904 /// means.
6905 ///
6906 /// Otherwise, if the pointed-to type node of @ref reference_type_def
6907 /// is *NOT* a @ref reference_type_def node, then just return the
6908 /// pointed-to type node.
6909 ///
6910 /// And if the type node considered is not a @ref reference_type_def
6911 /// node, then just return it.
6912 ///
6913 /// @return the leaf pointed-to type node of a @p type.
6914 type_base_sptr
peel_reference_type(const type_base_sptr & type)6915 peel_reference_type(const type_base_sptr& type)
6916 {
6917 reference_type_def_sptr t = is_reference_type(type);
6918 if (!t)
6919 return type;
6920
6921 if (is_reference_type(t->get_pointed_to_type()))
6922 return peel_reference_type(t->get_pointed_to_type());
6923 return t->get_pointed_to_type();
6924 }
6925
6926 /// Return the leaf pointed-to type node of a @ref reference_type_def
6927 /// node.
6928 ///
6929 /// If the pointed-to type of a @ref reference_type_def node is itself
6930 /// a @ref reference_type_def node, then recursively look at the
6931 /// pointed-to type nodes to get the first one that is not a a @ref
6932 /// reference_type_def node. This is what a leaf pointed-to type node
6933 /// means.
6934 ///
6935 /// Otherwise, if the pointed-to type node of @ref reference_type_def
6936 /// is *NOT* a @ref reference_type_def node, then just return the
6937 /// pointed-to type node.
6938 ///
6939 /// And if the type node considered is not a @ref reference_type_def
6940 /// node, then just return it.
6941 ///
6942 /// @return the leaf pointed-to type node of a @p type.
6943 const type_base*
peel_reference_type(const type_base * type)6944 peel_reference_type(const type_base* type)
6945 {
6946 const reference_type_def* t = is_reference_type(type);
6947 if (!t)
6948 return type;
6949
6950 return peel_reference_type(t->get_pointed_to_type()).get();
6951 }
6952
6953 /// Return the leaf element type of an array.
6954 ///
6955 /// If the element type is itself an array, then recursively return
6956 /// the element type of that array itself.
6957 ///
6958 /// @param type the array type to consider. If this is not an array
6959 /// type, this type is returned by the function.
6960 ///
6961 /// @return the leaf element type of the array @p type, or, if it's
6962 /// not an array type, then just return @p.
6963 const type_base_sptr
peel_array_type(const type_base_sptr & type)6964 peel_array_type(const type_base_sptr& type)
6965 {
6966 const array_type_def_sptr t = is_array_type(type);
6967 if (!t)
6968 return type;
6969
6970 return peel_array_type(t->get_element_type());
6971 }
6972
6973 /// Return the leaf element type of an array.
6974 ///
6975 /// If the element type is itself an array, then recursively return
6976 /// the element type of that array itself.
6977 ///
6978 /// @param type the array type to consider. If this is not an array
6979 /// type, this type is returned by the function.
6980 ///
6981 /// @return the leaf element type of the array @p type, or, if it's
6982 /// not an array type, then just return @p.
6983 const type_base*
peel_array_type(const type_base * type)6984 peel_array_type(const type_base* type)
6985 {
6986 const array_type_def* t = is_array_type(type);
6987 if (!t)
6988 return type;
6989
6990 return peel_array_type(t->get_element_type()).get();
6991 }
6992
6993 /// Return the leaf underlying type of a qualified type.
6994 ///
6995 /// If the underlying type is itself a qualified type, then
6996 /// recursively return the first underlying type of that qualified
6997 /// type to return the first underlying type that is not a qualified type.
6998 ///
6999 /// If the underlying type is NOT a qualified type, then just return
7000 /// that underlying type.
7001 ///
7002 /// @param type the qualified type to consider.
7003 ///
7004 /// @return the leaf underlying type.
7005 const type_base*
peel_qualified_type(const type_base * type)7006 peel_qualified_type(const type_base* type)
7007 {
7008 const qualified_type_def* t = is_qualified_type(type);
7009 if (!t)
7010 return type;
7011
7012 return peel_qualified_type(t->get_underlying_type().get());
7013 }
7014
7015 /// Return the leaf underlying type of a qualified type.
7016 ///
7017 /// If the underlying type is itself a qualified type, then
7018 /// recursively return the first underlying type of that qualified
7019 /// type to return the first underlying type that is not a qualified type.
7020 ///
7021 /// If the underlying type is NOT a qualified type, then just return
7022 /// that underlying type.
7023 ///
7024 /// @param type the qualified type to consider.
7025 ///
7026 /// @return the leaf underlying type.
7027 const type_base_sptr
peel_qualified_type(const type_base_sptr & type)7028 peel_qualified_type(const type_base_sptr& type)
7029 {
7030 const qualified_type_def_sptr t = is_qualified_type(type);
7031 if (!t)
7032 return type;
7033
7034 return peel_qualified_type(t->get_underlying_type());
7035 }
7036
7037 /// Return the leaf underlying type of a qualified or typedef type.
7038 ///
7039 /// If the underlying type is itself a qualified or typedef type, then
7040 /// recursively return the first underlying type of that qualified or
7041 /// typedef type to return the first underlying type that is not a
7042 /// qualified or typedef type.
7043 ///
7044 /// If the underlying type is NOT a qualified nor a typedef type, then
7045 /// just return that underlying type.
7046 ///
7047 /// @param type the qualified or typedef type to consider.
7048 ///
7049 /// @return the leaf underlying type.
7050 type_base*
peel_qualified_or_typedef_type(const type_base * type)7051 peel_qualified_or_typedef_type(const type_base* type)
7052 {
7053 while (is_typedef(type) || is_qualified_type(type))
7054 {
7055 if (const typedef_decl* t = is_typedef(type))
7056 type = peel_typedef_type(t);
7057
7058 if (const qualified_type_def* t = is_qualified_type(type))
7059 type = peel_qualified_type(t);
7060 }
7061
7062 return const_cast<type_base*>(type);
7063 }
7064
7065 /// Return the leaf underlying type of a qualified or typedef type.
7066 ///
7067 /// If the underlying type is itself a qualified or typedef type, then
7068 /// recursively return the first underlying type of that qualified or
7069 /// typedef type to return the first underlying type that is not a
7070 /// qualified or typedef type.
7071 ///
7072 /// If the underlying type is NOT a qualified nor a typedef type, then
7073 /// just return that underlying type.
7074 ///
7075 /// @param type the qualified or typedef type to consider.
7076 ///
7077 /// @return the leaf underlying type.
7078 type_base_sptr
peel_qualified_or_typedef_type(const type_base_sptr & t)7079 peel_qualified_or_typedef_type(const type_base_sptr &t)
7080 {
7081 type_base_sptr type = t;
7082 while (is_typedef(type) || is_qualified_type(type))
7083 {
7084 if (typedef_decl_sptr t = is_typedef(type))
7085 type = peel_typedef_type(t);
7086
7087 if (qualified_type_def_sptr t = is_qualified_type(type))
7088 type = peel_qualified_type(t);
7089 }
7090
7091 return type;
7092 }
7093
7094 /// Return the leaf underlying or pointed-to type node of a @ref
7095 /// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7096 /// or @ref array_type_def node.
7097 ///
7098 /// @param type the type to peel.
7099 ///
7100 /// @return the leaf underlying or pointed-to type node of @p type.
7101 type_base_sptr
peel_typedef_pointer_or_reference_type(const type_base_sptr type)7102 peel_typedef_pointer_or_reference_type(const type_base_sptr type)
7103 {
7104 type_base_sptr typ = type;
7105 while (is_typedef(typ)
7106 || is_pointer_type(typ)
7107 || is_reference_type(typ)
7108 || is_array_type(typ))
7109 {
7110 if (typedef_decl_sptr t = is_typedef(typ))
7111 typ = peel_typedef_type(t);
7112
7113 if (pointer_type_def_sptr t = is_pointer_type(typ))
7114 typ = peel_pointer_type(t);
7115
7116 if (reference_type_def_sptr t = is_reference_type(typ))
7117 typ = peel_reference_type(t);
7118
7119 if (const array_type_def_sptr t = is_array_type(typ))
7120 typ = peel_array_type(t);
7121 }
7122
7123 return typ;
7124 }
7125
7126 /// Return the leaf underlying or pointed-to type node of a @ref
7127 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7128 /// node.
7129 ///
7130 /// @param type the type to peel.
7131 ///
7132 /// @return the leaf underlying or pointed-to type node of @p type.
7133 type_base*
peel_typedef_pointer_or_reference_type(const type_base * type)7134 peel_typedef_pointer_or_reference_type(const type_base* type)
7135 {
7136 while (is_typedef(type)
7137 || is_pointer_type(type)
7138 || is_reference_type(type)
7139 || is_array_type(type))
7140 {
7141 if (const typedef_decl* t = is_typedef(type))
7142 type = peel_typedef_type(t);
7143
7144 if (const pointer_type_def* t = is_pointer_type(type))
7145 type = peel_pointer_type(t);
7146
7147 if (const reference_type_def* t = is_reference_type(type))
7148 type = peel_reference_type(t);
7149
7150 if (const array_type_def* t = is_array_type(type))
7151 type = peel_array_type(t);
7152 }
7153
7154 return const_cast<type_base*>(type);
7155 }
7156
7157 /// Return the leaf underlying or pointed-to type node of a @ref
7158 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7159 /// node.
7160 ///
7161 /// @param type the type to peel.
7162 ///
7163 /// @return the leaf underlying or pointed-to type node of @p type.
7164 type_base*
peel_typedef_pointer_or_reference_type(const type_base * type,bool peel_qual_type)7165 peel_typedef_pointer_or_reference_type(const type_base* type,
7166 bool peel_qual_type)
7167 {
7168 while (is_typedef(type)
7169 || is_pointer_type(type)
7170 || is_reference_type(type)
7171 || is_array_type(type)
7172 || (peel_qual_type && is_qualified_type(type)))
7173 {
7174 if (const typedef_decl* t = is_typedef(type))
7175 type = peel_typedef_type(t);
7176
7177 if (const pointer_type_def* t = is_pointer_type(type))
7178 type = peel_pointer_type(t);
7179
7180 if (const reference_type_def* t = is_reference_type(type))
7181 type = peel_reference_type(t);
7182
7183 if (const array_type_def* t = is_array_type(type))
7184 type = peel_array_type(t);
7185
7186 if (peel_qual_type)
7187 if (const qualified_type_def* t = is_qualified_type(type))
7188 type = peel_qualified_type(t);
7189 }
7190
7191 return const_cast<type_base*>(type);
7192 }
7193
7194 /// Return the leaf underlying or pointed-to type node of a, @ref
7195 /// pointer_type_def, @ref reference_type_def or @ref
7196 /// qualified_type_def type node.
7197 ///
7198 /// @param type the type to peel.
7199 ///
7200 /// @param peel_qualified_type if true, also peel qualified types.
7201 ///
7202 /// @return the leaf underlying or pointed-to type node of @p type.
7203 type_base*
peel_pointer_or_reference_type(const type_base * type,bool peel_qual_type)7204 peel_pointer_or_reference_type(const type_base *type,
7205 bool peel_qual_type)
7206 {
7207 while (is_pointer_type(type)
7208 || is_reference_type(type)
7209 || is_array_type(type)
7210 || (peel_qual_type && is_qualified_type(type)))
7211 {
7212 if (const pointer_type_def* t = is_pointer_type(type))
7213 type = peel_pointer_type(t);
7214
7215 if (const reference_type_def* t = is_reference_type(type))
7216 type = peel_reference_type(t);
7217
7218 if (const array_type_def* t = is_array_type(type))
7219 type = peel_array_type(t);
7220
7221 if (peel_qual_type)
7222 if (const qualified_type_def* t = is_qualified_type(type))
7223 type = peel_qualified_type(t);
7224 }
7225
7226 return const_cast<type_base*>(type);
7227 }
7228
7229 /// Clone an array type.
7230 ///
7231 /// Note that the element type of the new array is shared witht the
7232 /// old one.
7233 ///
7234 /// @param array the array type to clone.
7235 ///
7236 /// @return a newly built array type. Note that it needs to be added
7237 /// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7238 /// bound to the one of that scope. Otherwise, its lifetime is bound
7239 /// to the lifetime of its containing shared pointer.
7240 array_type_def_sptr
clone_array(const array_type_def_sptr & array)7241 clone_array(const array_type_def_sptr& array)
7242 {
7243 vector<array_type_def::subrange_sptr> subranges;
7244
7245 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7246 array->get_subranges().begin();
7247 i != array->get_subranges().end();
7248 ++i)
7249 {
7250 array_type_def::subrange_sptr subrange
7251 (new array_type_def::subrange_type(array->get_environment(),
7252 (*i)->get_name(),
7253 (*i)->get_lower_bound(),
7254 (*i)->get_upper_bound(),
7255 (*i)->get_underlying_type(),
7256 (*i)->get_location(),
7257 (*i)->get_language()));
7258 subrange->is_infinite((*i)->is_infinite());
7259 if (scope_decl *scope = (*i)->get_scope())
7260 add_decl_to_scope(subrange, scope);
7261 subranges.push_back(subrange);
7262 }
7263
7264 array_type_def_sptr result
7265 (new array_type_def(array->get_element_type(),
7266 subranges, array->get_location()));
7267
7268 return result;
7269 }
7270
7271 /// Clone a typedef type.
7272 ///
7273 /// Note that the underlying type of the newly constructed typedef is
7274 /// shared with the old one.
7275 ///
7276 /// @param t the typedef to clone.
7277 ///
7278 /// @return the newly constructed typedef. Note that it needs to be
7279 /// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7280 /// to be bound to the one of that scope. Otherwise, its lifetime is
7281 /// bound to the lifetime of its containing shared pointer.
7282 typedef_decl_sptr
clone_typedef(const typedef_decl_sptr & t)7283 clone_typedef(const typedef_decl_sptr& t)
7284 {
7285 if (!t)
7286 return t;
7287
7288 typedef_decl_sptr result
7289 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7290 t->get_location(), t->get_linkage_name(),
7291 t->get_visibility()));
7292 return result;
7293 }
7294
7295 /// Clone a qualifiend type.
7296 ///
7297 /// Note that underlying type of the newly constructed qualified type
7298 /// is shared with the old one.
7299 ///
7300 /// @param t the qualified type to clone.
7301 ///
7302 /// @return the newly constructed qualified type. Note that it needs
7303 /// to be added to a scope (e.g, using add_decl_to_scope) for its
7304 /// lifetime to be bound to the one of that scope. Otherwise, its
7305 /// lifetime is bound to the lifetime of its containing shared
7306 /// pointer.
7307 qualified_type_def_sptr
clone_qualified_type(const qualified_type_def_sptr & t)7308 clone_qualified_type(const qualified_type_def_sptr& t)
7309 {
7310 if (!t)
7311 return t;
7312
7313 qualified_type_def_sptr result
7314 (new qualified_type_def(t->get_underlying_type(),
7315 t->get_cv_quals(), t->get_location()));
7316
7317 return result;
7318 }
7319
7320 /// Clone a typedef, an array or a qualified tree.
7321 ///
7322 /// @param type the typedef, array or qualified tree to clone. any
7323 /// order.
7324 ///
7325 /// @return the cloned type, or NULL if @type was neither a typedef,
7326 /// array nor a qualified type.
7327 static type_base_sptr
clone_typedef_array_qualified_type(type_base_sptr type)7328 clone_typedef_array_qualified_type(type_base_sptr type)
7329 {
7330 if (!type)
7331 return type;
7332
7333 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7334 type_base_sptr result;
7335
7336 if (typedef_decl_sptr t = is_typedef(type))
7337 result = clone_typedef(is_typedef(t));
7338 else if (qualified_type_def_sptr t = is_qualified_type(type))
7339 result = clone_qualified_type(t);
7340 else if (array_type_def_sptr t = is_array_type(type))
7341 result = clone_array(t);
7342 else
7343 return type_base_sptr();
7344
7345 if (scope)
7346 add_decl_to_scope(is_decl(result), scope);
7347
7348 return result;
7349 }
7350
7351 /// Clone a type tree made of an array or a typedef of array.
7352 ///
7353 /// Note that this can be a tree which root node is a typedef an which
7354 /// sub-tree can be any arbitrary combination of typedef, qualified
7355 /// type and arrays.
7356 ///
7357 /// @param t the array or typedef of qualified array to consider.
7358 ///
7359 /// @return a clone of @p t.
7360 type_base_sptr
clone_array_tree(const type_base_sptr t)7361 clone_array_tree(const type_base_sptr t)
7362 {
7363 ABG_ASSERT(is_typedef_of_array(t) || is_array_type(t));
7364
7365 scope_decl* scope = is_decl(t)->get_scope();
7366 type_base_sptr result = clone_typedef_array_qualified_type(t);
7367 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7368
7369 type_base_sptr subtree;
7370 if (typedef_decl_sptr type = is_typedef(result))
7371 {
7372 type_base_sptr s =
7373 clone_typedef_array_qualified_type(type->get_underlying_type());
7374 if (s)
7375 {
7376 subtree = s;
7377 type->set_underlying_type(subtree);
7378 }
7379 }
7380 else if (array_type_def_sptr type = is_array_type(result))
7381 {
7382 type_base_sptr s =
7383 clone_typedef_array_qualified_type(type->get_element_type());
7384 if (s)
7385 {
7386 subtree = s;
7387 type->set_element_type(subtree);
7388 }
7389 }
7390 add_decl_to_scope(is_decl(subtree), scope);
7391
7392 for (;;)
7393 {
7394 if (typedef_decl_sptr t = is_typedef(subtree))
7395 {
7396 type_base_sptr s =
7397 clone_typedef_array_qualified_type(t->get_underlying_type());
7398 if (s)
7399 {
7400 scope_decl* scope =
7401 is_decl(t->get_underlying_type())->get_scope();
7402 ABG_ASSERT(scope);
7403 add_decl_to_scope(is_decl(s), scope);
7404 t->set_underlying_type (s);
7405 subtree = s;
7406 }
7407 else
7408 break;
7409 }
7410 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7411 {
7412 type_base_sptr s =
7413 clone_typedef_array_qualified_type(t->get_underlying_type());
7414 if (s)
7415 {
7416 scope_decl* scope =
7417 is_decl(t->get_underlying_type())->get_scope();
7418 ABG_ASSERT(scope);
7419 add_decl_to_scope(is_decl(s), scope);
7420 t->set_underlying_type(s);
7421 subtree = s;
7422 }
7423 else
7424 break;
7425 }
7426 else if (array_type_def_sptr t = is_array_type(subtree))
7427 {
7428 type_base_sptr e = t->get_element_type();
7429 if (is_typedef(e) || is_qualified_type(e))
7430 {
7431 type_base_sptr s =
7432 clone_typedef_array_qualified_type(e);
7433 if (s)
7434 {
7435 scope_decl* scope = is_decl(e)->get_scope();
7436 ABG_ASSERT(scope);
7437 add_decl_to_scope(is_decl(s), scope);
7438 t->set_element_type(s);
7439 }
7440 else
7441 break;
7442 }
7443 break;
7444 }
7445 else
7446 break;
7447 }
7448 return result;
7449 }
7450
7451 /// Update the qualified name of a given sub-tree.
7452 ///
7453 /// @param d the sub-tree for which to update the qualified name.
7454 static void
update_qualified_name(decl_base * d)7455 update_qualified_name(decl_base * d)
7456 {
7457 ::qualified_name_setter setter;
7458 d->traverse(setter);
7459 }
7460
7461 /// Update the qualified name of a given sub-tree.
7462 ///
7463 /// @param d the sub-tree for which to update the qualified name.
7464 static void
update_qualified_name(decl_base_sptr d)7465 update_qualified_name(decl_base_sptr d)
7466 {return update_qualified_name(d.get());}
7467
7468 // <scope_decl stuff>
7469
7470 /// Hash a type by returning the pointer value of its canonical type.
7471 ///
7472 /// @param l the type to hash.
7473 ///
7474 /// @return the the pointer value of the canonical type of @p l.
7475 size_t
operator ()(const type_base_sptr & l) const7476 canonical_type_hash::operator()(const type_base_sptr& l) const
7477 {return operator()(l.get());}
7478
7479 /// Hash a (canonical) type by returning its pointer value
7480 ///
7481 /// @param l the canonical type to hash.
7482 ///
7483 /// @return the pointer value of the canonical type of @p l.
7484 size_t
operator ()(const type_base * l) const7485 canonical_type_hash::operator()(const type_base *l) const
7486 {return reinterpret_cast<size_t>(l);}
7487
7488 struct scope_decl::priv
7489 {
7490 declarations members_;
7491 declarations sorted_members_;
7492 type_base_sptrs_type member_types_;
7493 type_base_sptrs_type sorted_member_types_;
7494 scopes member_scopes_;
7495 canonical_type_sptr_set_type canonical_types_;
7496 type_base_sptrs_type sorted_canonical_types_;
7497 }; // end struct scope_decl::priv
7498
7499 /// Constructor of the @ref scope_decl type.
7500 ///
7501 /// @param the environment to use for the new instance.
7502 ///
7503 /// @param the name of the scope decl.
7504 ///
7505 /// @param locus the source location where the scope_decl is defined.
7506 ///
7507 /// @param vis the visibility of the declaration.
scope_decl(const environment & env,const string & name,const location & locus,visibility vis)7508 scope_decl::scope_decl(const environment& env,
7509 const string& name,
7510 const location& locus,
7511 visibility vis)
7512 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7513 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7514 priv_(new priv)
7515 {}
7516
7517 /// Constructor of the @ref scope_decl type.
7518 ///
7519 /// @param the environment to use for the new instance.
7520 ///
7521 /// @param l the source location where the scope_decl is defined.
7522 ///
7523 /// @param vis the visibility of the declaration.
scope_decl(const environment & env,location & l)7524 scope_decl::scope_decl(const environment& env, location& l)
7525 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7526 decl_base(env, "", l),
7527 priv_(new priv)
7528 {}
7529
7530 /// @eturn the set of canonical types of the the current scope.
7531 canonical_type_sptr_set_type&
get_canonical_types()7532 scope_decl::get_canonical_types()
7533 {return priv_->canonical_types_;}
7534
7535 /// @eturn the set of canonical types of the the current scope.
7536 const canonical_type_sptr_set_type&
get_canonical_types() const7537 scope_decl::get_canonical_types() const
7538 {return const_cast<scope_decl*>(this)->get_canonical_types();}
7539
7540 /// Return a vector of sorted canonical types of the current scope.
7541 ///
7542 /// The types are sorted "almost topologically". That means, they are
7543 /// sorted using the lexicographic order of the string representing
7544 /// the location their definition point. If a type doesn't have a
7545 /// location, then its pretty representation is used.
7546 ///
7547 /// @return a vector of sorted canonical types of the current scope.
7548 const type_base_sptrs_type&
get_sorted_canonical_types() const7549 scope_decl::get_sorted_canonical_types() const
7550 {
7551 if (priv_->sorted_canonical_types_.empty())
7552 {
7553 for (canonical_type_sptr_set_type::const_iterator e =
7554 get_canonical_types().begin();
7555 e != get_canonical_types().end();
7556 ++e)
7557 priv_->sorted_canonical_types_.push_back(*e);
7558
7559 type_topo_comp comp;
7560 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7561 priv_->sorted_canonical_types_.end(),
7562 comp);
7563 }
7564 return priv_->sorted_canonical_types_;
7565 }
7566
7567 /// Getter for the member declarations carried by the current @ref
7568 /// scope_decl.
7569 ///
7570 /// @return the member declarations carried by the current @ref
7571 /// scope_decl.
7572 const scope_decl::declarations&
get_member_decls() const7573 scope_decl::get_member_decls() const
7574 {return priv_->members_;}
7575
7576 /// Getter for the member declarations carried by the current @ref
7577 /// scope_decl.
7578 ///
7579 /// @return the member declarations carried by the current @ref
7580 /// scope_decl.
7581 scope_decl::declarations&
get_member_decls()7582 scope_decl::get_member_decls()
7583 {return priv_->members_;}
7584
7585 /// Getter for the sorted member declarations carried by the current
7586 /// @ref scope_decl.
7587 ///
7588 /// @return the sorted member declarations carried by the current @ref
7589 /// scope_decl. The declarations are sorted topologically.
7590 const scope_decl::declarations&
get_sorted_member_decls() const7591 scope_decl::get_sorted_member_decls() const
7592 {
7593 decl_topo_comp comp;
7594 if (priv_->sorted_members_.empty())
7595 {
7596 for (declarations::const_iterator i = get_member_decls().begin();
7597 i != get_member_decls().end();
7598 ++i)
7599 priv_->sorted_members_.push_back(*i);
7600
7601 std::stable_sort(priv_->sorted_members_.begin(),
7602 priv_->sorted_members_.end(),
7603 comp);
7604 }
7605 return priv_->sorted_members_;
7606 }
7607
7608 /// Getter for the number of anonymous classes contained in this
7609 /// scope.
7610 ///
7611 /// @return the number of anonymous classes contained in this scope.
7612 size_t
get_num_anonymous_member_classes() const7613 scope_decl::get_num_anonymous_member_classes() const
7614 {
7615 int result = 0;
7616 for (declarations::const_iterator it = get_member_decls().begin();
7617 it != get_member_decls().end();
7618 ++it)
7619 if (class_decl_sptr t = is_class_type(*it))
7620 if (t->get_is_anonymous())
7621 ++result;
7622
7623 return result;
7624 }
7625
7626 /// Getter for the number of anonymous unions contained in this
7627 /// scope.
7628 ///
7629 /// @return the number of anonymous unions contained in this scope.
7630 size_t
get_num_anonymous_member_unions() const7631 scope_decl::get_num_anonymous_member_unions() const
7632 {
7633 int result = 0;
7634 for (declarations::const_iterator it = get_member_decls().begin();
7635 it != get_member_decls().end();
7636 ++it)
7637 if (union_decl_sptr t = is_union_type(*it))
7638 if (t->get_is_anonymous())
7639 ++result;
7640
7641 return result;
7642 }
7643
7644 /// Getter for the number of anonymous enums contained in this
7645 /// scope.
7646 ///
7647 /// @return the number of anonymous enums contained in this scope.
7648 size_t
get_num_anonymous_member_enums() const7649 scope_decl::get_num_anonymous_member_enums() const
7650 {
7651 int result = 0;
7652 for (declarations::const_iterator it = get_member_decls().begin();
7653 it != get_member_decls().end();
7654 ++it)
7655 if (enum_type_decl_sptr t = is_enum_type(*it))
7656 if (t->get_is_anonymous())
7657 ++result;
7658
7659 return result;
7660 }
7661
7662 /// Getter for the scopes carried by the current scope.
7663 ///
7664 /// @return the scopes carried by the current scope.
7665 scope_decl::scopes&
get_member_scopes()7666 scope_decl::get_member_scopes()
7667 {return priv_->member_scopes_;}
7668
7669 /// Getter for the scopes carried by the current scope.
7670 ///
7671 /// @return the scopes carried by the current scope.
7672 const scope_decl::scopes&
get_member_scopes() const7673 scope_decl::get_member_scopes() const
7674 {return priv_->member_scopes_;}
7675
7676 /// Test if the current scope is empty.
7677 ///
7678 /// @return true iff the current scope is empty.
7679 bool
is_empty() const7680 scope_decl::is_empty() const
7681 {
7682 return (get_member_decls().empty()
7683 && get_canonical_types().empty());
7684 }
7685
7686 /// Add a member decl to this scope. Note that user code should not
7687 /// use this, but rather use add_decl_to_scope.
7688 ///
7689 /// Note that this function updates the qualified name of the member
7690 /// decl that is added. It also sets the scope of the member. Thus,
7691 /// it ABG_ASSERTs that member should not have its scope set, prior to
7692 /// calling this function.
7693 ///
7694 /// @param member the new member decl to add to this scope.
7695 decl_base_sptr
add_member_decl(const decl_base_sptr & member)7696 scope_decl::add_member_decl(const decl_base_sptr& member)
7697 {
7698 ABG_ASSERT(!has_scope(member));
7699
7700 member->set_scope(this);
7701 priv_->members_.push_back(member);
7702 if (is_type(member))
7703 priv_->member_types_.push_back(is_type(member));
7704
7705 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
7706 priv_->member_scopes_.push_back(m);
7707
7708 update_qualified_name(member);
7709
7710 if (translation_unit* tu = get_translation_unit())
7711 {
7712 if (translation_unit* existing_tu = member->get_translation_unit())
7713 ABG_ASSERT(tu == existing_tu);
7714 else
7715 member->set_translation_unit(tu);
7716 }
7717
7718 maybe_update_types_lookup_map(member);
7719
7720 return member;
7721 }
7722
7723 /// Get the member types of this @ref scope_decl.
7724 ///
7725 /// @return a vector of the member types of this ref class_or_union.
7726 const type_base_sptrs_type&
get_member_types() const7727 scope_decl::get_member_types() const
7728 {return priv_->member_types_;}
7729
7730 /// Find a member type of a given name, inside the current @ref
7731 /// scope_decl.
7732 ///
7733 /// @param name the name of the member type to look for.
7734 ///
7735 /// @return a pointer to the @ref type_base that represents the member
7736 /// type of name @p name, for the current scope.
7737 type_base_sptr
find_member_type(const string & name) const7738 scope_decl::find_member_type(const string& name) const
7739 {
7740 for (auto t : get_member_types())
7741 if (get_type_name(t, /*qualified*/false) == name)
7742 return t;
7743 return type_base_sptr();
7744 }
7745
7746 /// Insert a member type.
7747 ///
7748 /// @param t the type to insert in the @ref scope_decl type.
7749 ///
7750 /// @param an iterator right before which @p t has to be inserted.
7751 void
insert_member_type(type_base_sptr t,declarations::iterator before)7752 scope_decl::insert_member_type(type_base_sptr t,
7753 declarations::iterator before)
7754 {
7755 decl_base_sptr d = get_type_declaration(t);
7756 ABG_ASSERT(d);
7757 ABG_ASSERT(!has_scope(d));
7758
7759 priv_->member_types_.push_back(t);
7760 insert_member_decl(d, before);
7761 }
7762
7763 /// Add a member type to the current instance of class_or_union.
7764 ///
7765 /// @param t the member type to add. It must not have been added to a
7766 /// scope, otherwise this will violate an ABG_ASSERTion.
7767 void
add_member_type(type_base_sptr t)7768 scope_decl::add_member_type(type_base_sptr t)
7769 {insert_member_type(t, get_member_decls().end());}
7770
7771 /// Add a member type to the current instance of class_or_union.
7772 ///
7773 /// @param t the type to be added as a member type to the current
7774 /// instance of class_or_union. An instance of class_or_union::member_type
7775 /// will be created out of @p t and and added to the the class.
7776 ///
7777 /// @param a the access specifier for the member type to be created.
7778 type_base_sptr
add_member_type(type_base_sptr t,access_specifier a)7779 scope_decl::add_member_type(type_base_sptr t, access_specifier a)
7780 {
7781 decl_base_sptr d = get_type_declaration(t);
7782 ABG_ASSERT(d);
7783 ABG_ASSERT(!is_member_decl(d));
7784 add_member_type(t);
7785 set_member_access_specifier(d, a);
7786 return t;
7787 }
7788
7789 /// Remove a member type from the current @ref class_or_union scope.
7790 ///
7791 /// @param t the type to remove.
7792 void
remove_member_type(type_base_sptr t)7793 scope_decl::remove_member_type(type_base_sptr t)
7794 {
7795 for (auto i = priv_->member_types_.begin();
7796 i != priv_->member_types_.end();
7797 ++i)
7798 {
7799 if (*((*i)) == *t)
7800 {
7801 priv_->member_types_.erase(i);
7802 return;
7803 }
7804 }
7805 }
7806
7807 /// Get the sorted member types of this @ref scope_decl
7808 ///
7809 /// @return a vector of the sorted member types of this ref
7810 /// class_or_union.
7811 const type_base_sptrs_type&
get_sorted_member_types() const7812 scope_decl::get_sorted_member_types() const
7813 {
7814 if (priv_->sorted_member_types_.empty())
7815 {
7816 for (auto t : get_member_types())
7817 priv_->sorted_member_types_.push_back(t);
7818
7819 type_topo_comp comp;
7820 std::stable_sort(priv_->sorted_member_types_.begin(),
7821 priv_->sorted_member_types_.end(),
7822 comp);
7823 }
7824 return priv_->sorted_member_types_;
7825 }
7826
7827 /// Insert a member decl to this scope, right before an element
7828 /// pointed to by a given iterator. Note that user code should not
7829 /// use this, but rather use insert_decl_into_scope.
7830 ///
7831 /// Note that this function updates the qualified name of the inserted
7832 /// member.
7833 ///
7834 /// @param member the new member decl to add to this scope.
7835 ///
7836 /// @param before an interator pointing to the element before which
7837 /// the new member should be inserted.
7838 decl_base_sptr
insert_member_decl(decl_base_sptr member,declarations::iterator before)7839 scope_decl::insert_member_decl(decl_base_sptr member,
7840 declarations::iterator before)
7841 {
7842 ABG_ASSERT(!member->get_scope());
7843
7844 member->set_scope(this);
7845 priv_->members_.insert(before, member);
7846
7847 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
7848 priv_-> member_scopes_.push_back(m);
7849
7850 update_qualified_name(member);
7851
7852 if (translation_unit* tu = get_translation_unit())
7853 {
7854 if (translation_unit* existing_tu = member->get_translation_unit())
7855 ABG_ASSERT(tu == existing_tu);
7856 else
7857 member->set_translation_unit(tu);
7858 }
7859
7860 maybe_update_types_lookup_map(member);
7861
7862 return member;
7863 }
7864
7865 /// Remove a declaration from the current scope.
7866 ///
7867 /// @param member the declaration to remove from the scope.
7868 void
remove_member_decl(decl_base_sptr member)7869 scope_decl::remove_member_decl(decl_base_sptr member)
7870 {
7871 for (declarations::iterator i = priv_->members_.begin();
7872 i != priv_->members_.end();
7873 ++i)
7874 {
7875 if (**i == *member)
7876 {
7877 priv_->members_.erase(i);
7878 // Do not access i after this point as it's invalided by the
7879 // erase call.
7880 break;
7881 }
7882 }
7883
7884 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
7885 if (scope)
7886 {
7887 for (scopes::iterator i = priv_->member_scopes_.begin();
7888 i != priv_->member_scopes_.end();
7889 ++i)
7890 {
7891 if (**i == *member)
7892 {
7893 priv_->member_scopes_.erase(i);
7894 break;
7895 }
7896 }
7897 }
7898 }
7899
7900 /// Return the hash value for the current instance of scope_decl.
7901 ///
7902 /// This method can trigger the computing of the hash value, if need be.
7903 ///
7904 /// @return the hash value.
7905 size_t
get_hash() const7906 scope_decl::get_hash() const
7907 {
7908 scope_decl::hash hash_scope;
7909 return hash_scope(this);
7910 }
7911
7912 /// Compares two instances of @ref scope_decl.
7913 ///
7914 /// If the two intances are different, set a bitfield to give some
7915 /// insight about the kind of differences there are.
7916 ///
7917 /// @param l the first artifact of the comparison.
7918 ///
7919 /// @param r the second artifact of the comparison.
7920 ///
7921 /// @param k a pointer to a bitfield that gives information about the
7922 /// kind of changes there are between @p l and @p r. This one is set
7923 /// iff @p k is non-null and the function returns false.
7924 ///
7925 /// Please note that setting k to a non-null value does have a
7926 /// negative performance impact because even if @p l and @p r are not
7927 /// equal, the function keeps up the comparison in order to determine
7928 /// the different kinds of ways in which they are different.
7929 ///
7930 /// @return true if @p l equals @p r, false otherwise.
7931 bool
equals(const scope_decl & l,const scope_decl & r,change_kind * k)7932 equals(const scope_decl& l, const scope_decl& r, change_kind* k)
7933 {
7934 bool result = true;
7935
7936 if (!l.decl_base::operator==(r))
7937 {
7938 result = false;
7939 if (k)
7940 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
7941 else
7942 ABG_RETURN_FALSE;
7943 }
7944
7945 scope_decl::declarations::const_iterator i, j;
7946 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
7947 i != l.get_member_decls().end() && j != r.get_member_decls().end();
7948 ++i, ++j)
7949 {
7950 if (**i != **j)
7951 {
7952 result = false;
7953 if (k)
7954 {
7955 *k |= SUBTYPE_CHANGE_KIND;
7956 break;
7957 }
7958 else
7959 ABG_RETURN_FALSE;
7960 }
7961 }
7962
7963 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
7964 {
7965 result = false;
7966 if (k)
7967 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
7968 else
7969 ABG_RETURN_FALSE;
7970 }
7971
7972 ABG_RETURN(result);
7973 }
7974
7975 /// Return true iff both scopes have the same names and have the same
7976 /// member decls.
7977 ///
7978 /// This function doesn't check for equality of the scopes of its
7979 /// arguments.
7980 bool
operator ==(const decl_base & o) const7981 scope_decl::operator==(const decl_base& o) const
7982 {
7983 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
7984 if (!other)
7985 return false;
7986
7987 return equals(*this, *other, 0);
7988 }
7989
7990 /// Equality operator for @ref scope_decl_sptr.
7991 ///
7992 /// @param l the left hand side operand of the equality operator.
7993 ///
7994 /// @pram r the right hand side operand of the equalify operator.
7995 ///
7996 /// @return true iff @p l equals @p r.
7997 bool
operator ==(const scope_decl_sptr & l,const scope_decl_sptr & r)7998 operator==(const scope_decl_sptr& l, const scope_decl_sptr& r)
7999 {
8000 if (!!l != !!r)
8001 return false;
8002 if (l.get() == r.get())
8003 return true;
8004 return *l == *r;
8005 }
8006
8007 /// Inequality operator for @ref scope_decl_sptr.
8008 ///
8009 /// @param l the left hand side operand of the equality operator.
8010 ///
8011 /// @pram r the right hand side operand of the equalify operator.
8012 ///
8013 /// @return true iff @p l equals @p r.
8014 bool
operator !=(const scope_decl_sptr & l,const scope_decl_sptr & r)8015 operator!=(const scope_decl_sptr& l, const scope_decl_sptr& r)
8016 {return !operator==(l, r);}
8017
8018 /// Find a member of the current scope and return an iterator on it.
8019 ///
8020 /// @param decl the scope member to find.
8021 ///
8022 /// @param i the iterator to set to the member @p decl. This is set
8023 /// iff the function returns true.
8024 ///
8025 /// @return true if the member decl was found, false otherwise.
8026 bool
find_iterator_for_member(const decl_base * decl,declarations::iterator & i)8027 scope_decl::find_iterator_for_member(const decl_base* decl,
8028 declarations::iterator& i)
8029 {
8030 if (!decl)
8031 return false;
8032
8033 if (get_member_decls().empty())
8034 {
8035 i = get_member_decls().end();
8036 return false;
8037 }
8038
8039 for (declarations::iterator it = get_member_decls().begin();
8040 it != get_member_decls().end();
8041 ++it)
8042 {
8043 if ((*it).get() == decl)
8044 {
8045 i = it;
8046 return true;
8047 }
8048 }
8049
8050 return false;
8051 }
8052
8053 /// Find a member of the current scope and return an iterator on it.
8054 ///
8055 /// @param decl the scope member to find.
8056 ///
8057 /// @param i the iterator to set to the member @p decl. This is set
8058 /// iff the function returns true.
8059 ///
8060 /// @return true if the member decl was found, false otherwise.
8061 bool
find_iterator_for_member(const decl_base_sptr decl,declarations::iterator & i)8062 scope_decl::find_iterator_for_member(const decl_base_sptr decl,
8063 declarations::iterator& i)
8064 {return find_iterator_for_member(decl.get(), i);}
8065
8066 /// This implements the ir_traversable_base::traverse pure virtual
8067 /// function.
8068 ///
8069 /// @param v the visitor used on the current instance of scope_decl
8070 /// and on its member nodes.
8071 ///
8072 /// @return true if the traversal of the tree should continue, false
8073 /// otherwise.
8074 bool
traverse(ir_node_visitor & v)8075 scope_decl::traverse(ir_node_visitor &v)
8076 {
8077 if (visiting())
8078 return true;
8079
8080 if (v.visit_begin(this))
8081 {
8082 visiting(true);
8083 for (scope_decl::declarations::const_iterator i =
8084 get_member_decls().begin();
8085 i != get_member_decls ().end();
8086 ++i)
8087 if (!(*i)->traverse(v))
8088 break;
8089 visiting(false);
8090 }
8091 return v.visit_end(this);
8092 }
8093
~scope_decl()8094 scope_decl::~scope_decl()
8095 {}
8096
8097 /// Appends a declaration to a given scope, if the declaration
8098 /// doesn't already belong to one.
8099 ///
8100 /// @param decl the declaration to add to the scope
8101 ///
8102 /// @param scope the scope to append the declaration to
8103 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,scope_decl * scope)8104 add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8105 {
8106 ABG_ASSERT(scope);
8107
8108 if (scope && decl && !decl->get_scope())
8109 decl = scope->add_member_decl(decl);
8110
8111 return decl;
8112 }
8113
8114 /// Appends a declaration to a given scope, if the declaration doesn't
8115 /// already belong to a scope.
8116 ///
8117 /// @param decl the declaration to add append to the scope
8118 ///
8119 /// @param scope the scope to append the decl to
8120 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,const scope_decl_sptr & scope)8121 add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8122 {return add_decl_to_scope(decl, scope.get());}
8123
8124 /// Remove a given decl from its scope
8125 ///
8126 /// @param decl the decl to remove from its scope.
8127 void
remove_decl_from_scope(decl_base_sptr decl)8128 remove_decl_from_scope(decl_base_sptr decl)
8129 {
8130 if (!decl)
8131 return;
8132
8133 scope_decl* scope = decl->get_scope();
8134 scope->remove_member_decl(decl);
8135 decl->set_scope(0);
8136 }
8137
8138 /// Inserts a declaration into a given scope, before a given IR child
8139 /// node of the scope.
8140 ///
8141 /// @param decl the declaration to insert into the scope.
8142 ///
8143 /// @param before an iterator pointing to the child IR node before
8144 /// which to insert the declaration.
8145 ///
8146 /// @param scope the scope into which to insert the declaration.
8147 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl * scope)8148 insert_decl_into_scope(decl_base_sptr decl,
8149 scope_decl::declarations::iterator before,
8150 scope_decl* scope)
8151 {
8152 if (scope && decl && !decl->get_scope())
8153 {
8154 decl_base_sptr d = scope->insert_member_decl(decl, before);
8155 decl = d;
8156 }
8157 return decl;
8158 }
8159
8160 /// Inserts a declaration into a given scope, before a given IR child
8161 /// node of the scope.
8162 ///
8163 /// @param decl the declaration to insert into the scope.
8164 ///
8165 /// @param before an iterator pointing to the child IR node before
8166 /// which to insert the declaration.
8167 ///
8168 /// @param scope the scope into which to insert the declaration.
8169 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl_sptr scope)8170 insert_decl_into_scope(decl_base_sptr decl,
8171 scope_decl::declarations::iterator before,
8172 scope_decl_sptr scope)
8173 {return insert_decl_into_scope(decl, before, scope.get());}
8174
8175 /// Constructor of the @ref global_scope type.
8176 ///
8177 /// @param tu the translation unit the scope belongs to.
global_scope(translation_unit * tu)8178 global_scope::global_scope(translation_unit *tu)
8179 : type_or_decl_base(tu->get_environment(),
8180 GLOBAL_SCOPE_DECL
8181 | ABSTRACT_DECL_BASE
8182 | ABSTRACT_SCOPE_DECL),
8183 decl_base(tu->get_environment(), "", location()),
8184 scope_decl(tu->get_environment(), "", location()),
8185 translation_unit_(tu)
8186 {
8187 runtime_type_instance(this);
8188 }
8189
8190 /// return the global scope as seen by a given declaration.
8191 ///
8192 /// @param decl the declaration to consider.
8193 ///
8194 /// @return the global scope of the decl, or a null pointer if the
8195 /// decl is not yet added to a translation_unit.
8196 const global_scope*
get_global_scope(const decl_base & decl)8197 get_global_scope(const decl_base& decl)
8198 {
8199 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8200 return s;
8201
8202 scope_decl* scope = decl.get_scope();
8203 while (scope && !dynamic_cast<global_scope*>(scope))
8204 scope = scope->get_scope();
8205
8206 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8207 }
8208
8209 /// return the global scope as seen by a given declaration.
8210 ///
8211 /// @param decl the declaration to consider.
8212 ///
8213 /// @return the global scope of the decl, or a null pointer if the
8214 /// decl is not yet added to a translation_unit.
8215 const global_scope*
get_global_scope(const decl_base * decl)8216 get_global_scope(const decl_base* decl)
8217 {return get_global_scope(*decl);}
8218
8219 /// Return the global scope as seen by a given declaration.
8220 ///
8221 /// @param decl the declaration to consider.
8222 ///
8223 /// @return the global scope of the decl, or a null pointer if the
8224 /// decl is not yet added to a translation_unit.
8225 const global_scope*
get_global_scope(const shared_ptr<decl_base> decl)8226 get_global_scope(const shared_ptr<decl_base> decl)
8227 {return get_global_scope(decl.get());}
8228
8229 /// Return the a scope S containing a given declaration and that is
8230 /// right under a given scope P.
8231 ///
8232 /// Note that @p scope must come before @p decl in topological
8233 /// order.
8234 ///
8235 /// @param decl the decl for which to find a scope.
8236 ///
8237 /// @param scope the scope under which the resulting scope must be.
8238 ///
8239 /// @return the resulting scope.
8240 const scope_decl*
get_top_most_scope_under(const decl_base * decl,const scope_decl * scope)8241 get_top_most_scope_under(const decl_base* decl,
8242 const scope_decl* scope)
8243 {
8244 if (!decl)
8245 return 0;
8246
8247 if (scope == 0)
8248 return get_global_scope(decl);
8249
8250 // Handle the case where decl is a scope itself.
8251 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8252 if (!s)
8253 s = decl->get_scope();
8254
8255 if (is_global_scope(s))
8256 return scope;
8257
8258 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8259 // same. The caller needs to be prepared to deal with this case.
8260 if (s == scope)
8261 return s;
8262
8263 while (s && !is_global_scope(s) && s->get_scope() != scope)
8264 s = s->get_scope();
8265
8266 if (!s || is_global_scope(s))
8267 // SCOPE must come before decl in topological order, but I don't
8268 // know how to ensure that ...
8269 return scope;
8270 ABG_ASSERT(s);
8271
8272 return s;
8273 }
8274
8275 /// Return the a scope S containing a given declaration and that is
8276 /// right under a given scope P.
8277 ///
8278 /// @param decl the decl for which to find a scope.
8279 ///
8280 /// @param scope the scope under which the resulting scope must be.
8281 ///
8282 /// @return the resulting scope.
8283 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl * scope)8284 get_top_most_scope_under(const decl_base_sptr decl,
8285 const scope_decl* scope)
8286 {return get_top_most_scope_under(decl.get(), scope);}
8287
8288 /// Return the a scope S containing a given declaration and that is
8289 /// right under a given scope P.
8290 ///
8291 /// @param decl the decl for which to find a scope.
8292 ///
8293 /// @param scope the scope under which the resulting scope must be.
8294 ///
8295 /// @return the resulting scope.
8296 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl_sptr scope)8297 get_top_most_scope_under(const decl_base_sptr decl,
8298 const scope_decl_sptr scope)
8299 {return get_top_most_scope_under(decl, scope.get());}
8300
8301 // </scope_decl stuff>
8302
8303
8304 /// Get the string representation of a CV qualifier bitmap.
8305 ///
8306 /// @param cv_quals the bitmap of CV qualifiers to consider.
8307 ///
8308 /// @return the string representation.
8309 string
get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)8310 get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
8311 {
8312 string repr;
8313 if (cv_quals & qualified_type_def::CV_RESTRICT)
8314 repr = "restrict";
8315 if (cv_quals & qualified_type_def::CV_CONST)
8316 {
8317 if (!repr.empty())
8318 repr += ' ';
8319 repr += "const";
8320 }
8321 if (cv_quals & qualified_type_def::CV_VOLATILE)
8322 {
8323 if (!repr.empty())
8324 repr += ' ';
8325 repr += "volatile";
8326 }
8327 return repr;
8328 }
8329
8330 /// Build and return a copy of the name of an ABI artifact that is
8331 /// either a type or a decl.
8332 ///
8333 /// @param tod the ABI artifact to get the name for.
8334 ///
8335 /// @param qualified if yes, return the qualified name of @p tod;
8336 /// otherwise, return the non-qualified name;
8337 ///
8338 /// @return the name of @p tod.
8339 string
get_name(const type_or_decl_base * tod,bool qualified)8340 get_name(const type_or_decl_base *tod, bool qualified)
8341 {
8342 string result;
8343
8344 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8345
8346 if (type_base* t = dynamic_cast<type_base*>(a))
8347 result = get_type_name(t, qualified);
8348 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8349 {
8350 if (qualified)
8351 result = d->get_qualified_name();
8352 else
8353 result = d->get_name();
8354 }
8355 else
8356 // We should never reach this point.
8357 abort();
8358
8359 return result;
8360 }
8361
8362 /// Build and return a copy of the name of an ABI artifact that is
8363 /// either a type of a decl.
8364 ///
8365 /// @param tod the ABI artifact to get the name for.
8366 ///
8367 /// @param qualified if yes, return the qualified name of @p tod;
8368 /// otherwise, return the non-qualified name;
8369 ///
8370 /// @return the name of @p tod.
8371 string
get_name(const type_or_decl_base_sptr & tod,bool qualified)8372 get_name(const type_or_decl_base_sptr& tod, bool qualified)
8373 {return get_name(tod.get(), qualified);}
8374
8375 /// Build and return a qualified name from a name and its scope.
8376 ///
8377 /// The name is supposed to be for an entity that is part of the
8378 /// scope.
8379 ///
8380 /// @param the scope to consider.
8381 ///
8382 /// @param name of the name to consider.
8383 ///
8384 /// @return a copy of the string that represents the qualified name.
8385 string
build_qualified_name(const scope_decl * scope,const string & name)8386 build_qualified_name(const scope_decl* scope, const string& name)
8387 {
8388 if (name.empty())
8389 return "";
8390
8391 string qualified_name;
8392 if (scope)
8393 qualified_name = scope->get_qualified_name();
8394
8395 if (qualified_name.empty())
8396 qualified_name = name;
8397 else
8398 qualified_name = qualified_name + "::" + name;
8399
8400 return qualified_name;
8401 }
8402
8403 /// Build and return the qualified name of a type in its scope.
8404 ///
8405 /// @param scope the scope of the type to consider.
8406 ///
8407 /// @param type the type to consider.
8408 string
build_qualified_name(const scope_decl * scope,const type_base_sptr & type)8409 build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8410 {return build_qualified_name(scope, get_name((type)));}
8411
8412 // </scope_decl stuff>
8413
8414 /// Get the location of the declaration of a given type.
8415 ///
8416 /// @param type the type to consider.
8417 ///
8418 /// @return the location of the declaration of type @p type.
8419 location
get_location(const type_base_sptr & type)8420 get_location(const type_base_sptr& type)
8421 {
8422 if (decl_base_sptr decl = get_type_declaration(type))
8423 return get_location(decl);
8424 return location();
8425 }
8426
8427 /// Get the location of a given declaration.
8428 ///
8429 /// @param decl the declaration to consider.
8430 ///
8431 /// @return the location of the declaration @p decl.
8432 location
get_location(const decl_base_sptr & decl)8433 get_location(const decl_base_sptr& decl)
8434 {
8435 location loc = decl->get_location();
8436 if (!loc)
8437 {
8438 if (class_or_union_sptr c = is_class_or_union_type(decl))
8439 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8440 {
8441 c = is_class_or_union_type(c->get_definition_of_declaration());
8442 loc = c->get_location();
8443 }
8444 }
8445 return loc;
8446 }
8447
8448 /// Get the scope of a given type.
8449 ///
8450 /// @param t the type to consider.
8451 ///
8452 /// @return the scope of type @p t or 0 if the type has no scope yet.
8453 scope_decl*
get_type_scope(type_base * t)8454 get_type_scope(type_base* t)
8455 {
8456 if (!t)
8457 return 0;
8458
8459 decl_base* d = get_type_declaration(t);
8460 if (d)
8461 return d->get_scope();
8462 return 0;
8463 }
8464
8465 /// Get the scope of a given type.
8466 ///
8467 /// @param t the type to consider.
8468 ///
8469 /// @return the scope of type @p t or 0 if the type has no scope yet.
8470 scope_decl*
get_type_scope(const type_base_sptr & t)8471 get_type_scope(const type_base_sptr& t)
8472 {return get_type_scope(t.get());}
8473
8474 /// Get the name of a given type and return a copy of it.
8475 ///
8476 /// @param t the type to consider.
8477 ///
8478 /// @param qualified if true then return the qualified name of the
8479 /// type.
8480 ///
8481 /// @param internal set to true if the call is intended for an
8482 /// internal use (for technical use inside the library itself), false
8483 /// otherwise. If you don't know what this is for, then set it to
8484 /// false.
8485 ///
8486 /// @return a copy of the type name if the type has a name, or the
8487 /// empty string if it does not.
8488 interned_string
get_type_name(const type_base_sptr & t,bool qualified,bool internal)8489 get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8490 {return get_type_name(t.get(), qualified, internal);}
8491
8492 /// Return true iff a decl is for a type type that has a generic
8493 /// anonymous internal type name.
8494 ///
8495 /// @param d the decl to considier.
8496 ///
8497 /// @return true iff @p d is for a type type that has a generic
8498 /// anonymous internal type name.
8499 static bool
has_generic_anonymous_internal_type_name(const decl_base * d)8500 has_generic_anonymous_internal_type_name(const decl_base *d)
8501 {
8502 return is_class_or_union_type(d) || is_enum_type(d);
8503 }
8504
8505 /// Return the generic internal name of an anonymous type.
8506 ///
8507 /// For internal purposes, we want to define a generic name for all
8508 /// anonymous types of a certain kind. For instance, all anonymous
8509 /// structs will be have a generic name of "__anonymous_struct__", all
8510 /// anonymous unions will have a generic name of
8511 /// "__anonymous_union__", etc.
8512 ///
8513 /// That generic name can be used as a hash to put all anonymous types
8514 /// of a certain kind in the same hash table bucket, for instance.
8515 static interned_string
get_generic_anonymous_internal_type_name(const decl_base * d)8516 get_generic_anonymous_internal_type_name(const decl_base *d)
8517 {
8518 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8519
8520 const environment&env = d->get_environment();
8521
8522 interned_string result;
8523 if (is_class_type(d))
8524 result =
8525 env.intern(tools_utils::get_anonymous_struct_internal_name_prefix());
8526 else if (is_union_type(d))
8527 result =
8528 env.intern(tools_utils::get_anonymous_union_internal_name_prefix());
8529 else if (is_enum_type(d))
8530 result =
8531 env.intern(tools_utils::get_anonymous_enum_internal_name_prefix());
8532 else
8533 ABG_ASSERT_NOT_REACHED;
8534
8535 return result;
8536 }
8537
8538 /// Get the internal name for a given integral type.
8539 ///
8540 /// All integral types that have the modifiers 'short, long or long
8541 /// long' have the same internal name. This is so that they can all
8542 /// have the same canonical type if they are of the same size.
8543 /// Otherwise, 'long int' and 'long long int' would have different
8544 /// canonical types even though they are equivalent from an ABI point
8545 /// of view.
8546 ///
8547 /// @param t the integral type to consider
8548 ///
8549 /// @return the internal name for @p t if it's an integral type, or
8550 /// the empty string if @p t is not an integral type.
8551 static string
get_internal_integral_type_name(const type_base * t)8552 get_internal_integral_type_name(const type_base* t)
8553 {
8554 string name;
8555 type_decl *type = is_integral_type(t);
8556
8557 if (!type)
8558 return name;
8559
8560 integral_type int_type;
8561 if (parse_integral_type(type->get_name(), int_type))
8562 name = int_type.to_string(/*internal=*/true);
8563
8564 return name;
8565 }
8566
8567 /// Get the name of a given type and return a copy of it.
8568 ///
8569 /// @param t the type to consider.
8570 ///
8571 /// @param qualified if true then return the qualified name of the
8572 /// type.
8573 ///
8574 /// @param internal set to true if the call is intended for an
8575 /// internal use (for technical use inside the library itself), false
8576 /// otherwise. If you don't know what this is for, then set it to
8577 /// false.
8578 ///
8579 /// @return a copy of the type name if the type has a name, or the
8580 /// empty string if it does not.
8581 interned_string
get_type_name(const type_base * t,bool qualified,bool internal)8582 get_type_name(const type_base* t, bool qualified, bool internal)
8583 {
8584 const decl_base* d = dynamic_cast<const decl_base*>(t);
8585 if (!d)
8586 {
8587 const function_type* fn_type = is_function_type(t);
8588 ABG_ASSERT(fn_type);
8589 return fn_type->get_cached_name(internal);
8590 }
8591
8592 // All anonymous types of a given kind get to have the same internal
8593 // name for internal purpose. This to allow them to be compared
8594 // among themselves during type canonicalization.
8595 if (internal)
8596 {
8597 if (d->get_is_anonymous())
8598 {
8599 string r;
8600 r += get_generic_anonymous_internal_type_name(d);
8601 return t->get_environment().intern(r);
8602 }
8603
8604 if (qualified)
8605 return d->get_qualified_name(internal);
8606
8607 const environment&env = d->get_environment();
8608 return env.intern(get_internal_integral_type_name(t));
8609 }
8610
8611 if (qualified)
8612 return d->get_qualified_name(internal);
8613 return d->get_name();
8614 }
8615
8616 /// Get the name of a given type and return a copy of it.
8617 ///
8618 /// @param t the type to consider.
8619 ///
8620 /// @param qualified if true then return the qualified name of the
8621 /// type.
8622 ///
8623 /// @param internal set to true if the call is intended for an
8624 /// internal use (for technical use inside the library itself), false
8625 /// otherwise. If you don't know what this is for, then set it to
8626 /// false.
8627 ///
8628 /// @return a copy of the type name if the type has a name, or the
8629 /// empty string if it does not.
8630 interned_string
get_type_name(const type_base & t,bool qualified,bool internal)8631 get_type_name(const type_base& t, bool qualified, bool internal)
8632 {return get_type_name(&t, qualified, internal);}
8633
8634 /// Get the name of the pointer to a given type.
8635 ///
8636 /// @param pointed_to_type the pointed-to-type to consider.
8637 ///
8638 /// @param qualified this is true if the resulting name should be of a
8639 /// pointer to a *fully-qualified* pointed-to-type.
8640 ///
8641 /// @param internal true if the name is for libabigail-internal
8642 /// purposes.
8643 ///
8644 /// @return the name (string representation) of the pointer.
8645 interned_string
get_name_of_pointer_to_type(const type_base & pointed_to_type,bool qualified,bool internal)8646 get_name_of_pointer_to_type(const type_base& pointed_to_type,
8647 bool qualified, bool internal)
8648 {
8649 const environment& env = pointed_to_type.get_environment();
8650 string tn = get_type_name(pointed_to_type, qualified, internal);
8651 tn = tn + "*";
8652
8653 return env.intern(tn);
8654 }
8655
8656 /// Get the name of the reference to a given type.
8657 ///
8658 /// @param pointed_to_type the pointed-to-type to consider.
8659 ///
8660 /// @param qualified this is true if the resulting name should be of a
8661 /// reference to a *fully-qualified* pointed-to-type.
8662 ///
8663 /// @param internal true if the name is for libabigail-internal
8664 /// purposes.
8665 ///
8666 /// @return the name (string representation) of the reference.
8667 interned_string
get_name_of_reference_to_type(const type_base & pointed_to_type,bool lvalue_reference,bool qualified,bool internal)8668 get_name_of_reference_to_type(const type_base& pointed_to_type,
8669 bool lvalue_reference,
8670 bool qualified, bool internal)
8671 {
8672 const environment& env = pointed_to_type.get_environment();
8673
8674 string name = get_type_name(pointed_to_type, qualified, internal);
8675 if (lvalue_reference)
8676 name = name + "&";
8677 else
8678 name = name + "&&";
8679
8680 return env.intern(name);
8681 }
8682
8683 /// Get the name of a qualified type, given the underlying type and
8684 /// its qualifiers.
8685 ///
8686 /// @param underlying_type the underlying type to consider.
8687 ///
8688 /// @param quals the CV qualifiers of the name.
8689 ///
8690 /// @param qualified true if we should consider the fully qualified
8691 /// name of @p underlying_type.
8692 ///
8693 /// @param internal true if the result is to be used for
8694 /// libabigail-internal purposes.
8695 ///
8696 /// @return the name (string representation) of the qualified type.
8697 interned_string
get_name_of_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,bool qualified,bool internal)8698 get_name_of_qualified_type(const type_base_sptr& underlying_type,
8699 qualified_type_def::CV quals,
8700 bool qualified, bool internal)
8701 {
8702 const environment& env = underlying_type->get_environment();
8703
8704 string quals_repr = get_string_representation_of_cv_quals(quals);
8705 string name = get_type_name(underlying_type, qualified, internal);
8706
8707 if (quals_repr.empty() && internal)
8708 // We are asked to return the internal name, that might be used
8709 // for type canonicalization. For that canonicalization, we need
8710 // to make a difference between a no-op qualified type which
8711 // underlying type is foo (the qualified type is named "none
8712 // foo"), and the name of foo, which is just "foo".
8713 //
8714 // Please remember that this has to be kept in sync with what is
8715 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
8716 // change this code here, please change that code there too.
8717 quals_repr = "";
8718
8719 if (!quals_repr.empty())
8720 {
8721 if (is_pointer_type(underlying_type)
8722 || is_reference_type(underlying_type)
8723 || is_array_type(underlying_type))
8724 {
8725 name += " ";
8726 name += quals_repr;
8727 }
8728 else
8729 name = quals_repr + " " + name;
8730 }
8731
8732 return env.intern(name);
8733 }
8734
8735 /// Get the name of a given function type and return a copy of it.
8736 ///
8737 /// @param fn_type the function type to consider.
8738 ///
8739 /// @param internal set to true if the call is intended for an
8740 /// internal use (for technical use inside the library itself), false
8741 /// otherwise. If you don't know what this is for, then set it to
8742 /// false.
8743 ///
8744 /// @return a copy of the function type name
8745 interned_string
get_function_type_name(const function_type_sptr & fn_type,bool internal)8746 get_function_type_name(const function_type_sptr& fn_type,
8747 bool internal)
8748 {return get_function_type_name(fn_type.get(), internal);}
8749
8750 /// Get the name of a given function type and return a copy of it.
8751 ///
8752 /// @param fn_type the function type to consider.
8753 ///
8754 /// @param internal set to true if the call is intended for an
8755 /// internal use (for technical use inside the library itself), false
8756 /// otherwise. If you don't know what this is for, then set it to
8757 /// false.
8758 ///
8759 /// @return a copy of the function type name
8760 interned_string
get_function_type_name(const function_type * fn_type,bool internal)8761 get_function_type_name(const function_type* fn_type,
8762 bool internal)
8763 {
8764 ABG_ASSERT(fn_type);
8765
8766 if (const method_type* method = is_method_type(fn_type))
8767 return get_method_type_name(method, internal);
8768
8769 return get_function_type_name(*fn_type, internal);
8770 }
8771
8772 /// Get the name of a given function type and return a copy of it.
8773 ///
8774 /// @param fn_type the function type to consider.
8775 ///
8776 /// @param internal set to true if the call is intended for an
8777 /// internal use (for technical use inside the library itself), false
8778 /// otherwise. If you don't know what this is for, then set it to
8779 /// false.
8780 ///
8781 /// @return a copy of the function type name
8782 interned_string
get_function_type_name(const function_type & fn_type,bool internal)8783 get_function_type_name(const function_type& fn_type,
8784 bool internal)
8785 {
8786 std::ostringstream o;
8787 // When the function name is used for internal purposes (e.g, for
8788 // canonicalization), we want its representation to stay the same,
8789 // regardless of typedefs. So let's strip typedefs from the return
8790 // type.
8791 type_base_sptr return_type =
8792 internal
8793 ? peel_typedef_type(fn_type.get_return_type())
8794 : fn_type.get_return_type();
8795 const environment& env = fn_type.get_environment();
8796
8797 o << get_pretty_representation(return_type, internal);
8798
8799 o << " (";
8800 type_base_sptr type;
8801 for (function_type::parameters::const_iterator i =
8802 fn_type.get_parameters().begin();
8803 i != fn_type.get_parameters().end();
8804 ++i)
8805 {
8806 if (i != fn_type.get_parameters().begin())
8807 o << ", ";
8808 type = (*i)->get_type();
8809 if (internal)
8810 type = peel_typedef_type(type);
8811 o << get_pretty_representation(type, internal);
8812 }
8813 o <<")";
8814
8815 return env.intern(o.str());
8816 }
8817
8818 /// Get the name of a given method type and return a copy of it.
8819 ///
8820 /// @param fn_type the function type to consider.
8821 ///
8822 /// @param internal set to true if the call is intended for an
8823 /// internal use (for technical use inside the library itself), false
8824 /// otherwise. If you don't know what this is for, then set it to
8825 /// false.
8826 ///
8827 /// @return a copy of the function type name
8828 interned_string
get_method_type_name(const method_type_sptr fn_type,bool internal)8829 get_method_type_name(const method_type_sptr fn_type,
8830 bool internal)
8831 {return get_method_type_name(fn_type.get(), internal);}
8832
8833 /// Get the name of a given method type and return a copy of it.
8834 ///
8835 /// @param fn_type the function type to consider.
8836 ///
8837 /// @param internal set to true if the call is intended for an
8838 /// internal use (for technical use inside the library itself), false
8839 /// otherwise. If you don't know what this is for, then set it to
8840 /// false.
8841 ///
8842 /// @return a copy of the function type name
8843 interned_string
get_method_type_name(const method_type * fn_type,bool internal)8844 get_method_type_name(const method_type* fn_type,
8845 bool internal)
8846 {
8847 if (fn_type)
8848 return get_method_type_name(*fn_type, internal);
8849
8850 return interned_string();
8851 }
8852
8853 /// Get the name of a given method type and return a copy of it.
8854 ///
8855 /// @param fn_type the function type to consider.
8856 ///
8857 /// @param internal set to true if the call is intended for an
8858 /// internal use (for technical use inside the library itself), false
8859 /// otherwise. If you don't know what this is for, then set it to
8860 /// false.
8861 ///
8862 /// @return a copy of the function type name
8863 interned_string
get_method_type_name(const method_type & fn_type,bool internal)8864 get_method_type_name(const method_type& fn_type,
8865 bool internal)
8866 {
8867 std::ostringstream o;
8868 // When the function name is used for internal purposes (e.g, for
8869 // canonicalization), we want its representation to stay the same,
8870 // regardless of typedefs. So let's strip typedefs from the return
8871 // type.
8872 type_base_sptr return_type =
8873 internal
8874 ? peel_typedef_type(fn_type.get_return_type())
8875 : fn_type.get_return_type();
8876 const environment& env = fn_type.get_environment();
8877
8878 if (return_type)
8879 o << return_type->get_cached_pretty_representation(internal);
8880 else
8881 // There are still some abixml files out there in which "void"
8882 // can be expressed as an empty type.
8883 o << "void";
8884
8885 class_or_union_sptr class_type = fn_type.get_class_type();
8886 ABG_ASSERT(class_type);
8887
8888 o << " (" << class_type->get_qualified_name(internal) << "::*)"
8889 << " (";
8890
8891 type_base_sptr type;
8892 for (function_type::parameters::const_iterator i =
8893 fn_type.get_parameters().begin();
8894 i != fn_type.get_parameters().end();
8895 ++i)
8896 {
8897 if (i != fn_type.get_parameters().begin())
8898 o << ", ";
8899 type = (*i)->get_type();
8900 if (internal)
8901 type = peel_typedef_type(type);
8902 if (*i)
8903 o << type->get_cached_pretty_representation(internal);
8904 else
8905 // There are still some abixml files out there in which "void"
8906 // can be expressed as an empty type.
8907 o << "void";
8908 }
8909 o <<")";
8910
8911 return env.intern(o.str());
8912 }
8913
8914 /// Build and return a copy of the pretty representation of an ABI
8915 /// artifact that could be either a type of a decl.
8916 ///
8917 /// param tod the ABI artifact to consider.
8918 ///
8919 /// @param internal set to true if the call is intended for an
8920 /// internal use (for technical use inside the library itself), false
8921 /// otherwise. If you don't know what this is for, then set it to
8922 /// false.
8923 ///
8924 /// @return a copy of the pretty representation of an ABI artifact
8925 /// that could be either a type of a decl.
8926 string
get_pretty_representation(const type_or_decl_base * tod,bool internal)8927 get_pretty_representation(const type_or_decl_base* tod, bool internal)
8928 {
8929 string result;
8930
8931 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
8932 result = get_pretty_representation(t, internal);
8933 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
8934 result = get_pretty_representation(d, internal);
8935 else
8936 // We should never reach this point
8937 abort();
8938
8939 return result;
8940 }
8941
8942 /// Build and return a copy of the pretty representation of an ABI
8943 /// artifact that could be either a type of a decl.
8944 ///
8945 /// param tod the ABI artifact to consider.
8946 ///
8947 /// @param internal set to true if the call is intended for an
8948 /// internal use (for technical use inside the library itself), false
8949 /// otherwise. If you don't know what this is for, then set it to
8950 /// false.
8951 ///
8952 /// @return a copy of the pretty representation of an ABI artifact
8953 /// that could be either a type of a decl.
8954 string
get_pretty_representation(const type_or_decl_base_sptr & tod,bool internal)8955 get_pretty_representation(const type_or_decl_base_sptr& tod, bool internal)
8956 {return get_pretty_representation(tod.get(), internal);}
8957
8958 /// Get a copy of the pretty representation of a decl.
8959 ///
8960 /// @param d the decl to consider.
8961 ///
8962 /// @param internal set to true if the call is intended for an
8963 /// internal use (for technical use inside the library itself), false
8964 /// otherwise. If you don't know what this is for, then set it to
8965 /// false.
8966 ///
8967 /// @return the pretty representation of the decl.
8968 string
get_pretty_representation(const decl_base * d,bool internal)8969 get_pretty_representation(const decl_base* d, bool internal)
8970 {
8971 if (!d)
8972 return "";
8973 return d->get_pretty_representation(internal);
8974 }
8975
8976 /// Get a copy of the pretty representation of a type.
8977 ///
8978 /// @param d the type to consider.
8979 ///
8980 /// @param internal set to true if the call is intended for an
8981 /// internal use (for technical use inside the library itself), false
8982 /// otherwise. If you don't know what this is for, then set it to
8983 /// false.
8984 ///
8985 /// @return the pretty representation of the type.
8986 string
get_pretty_representation(const type_base * t,bool internal)8987 get_pretty_representation(const type_base* t, bool internal)
8988 {
8989 if (!t)
8990 return "void";
8991 if (const function_type* fn_type = is_function_type(t))
8992 return get_pretty_representation(fn_type, internal);
8993
8994 const decl_base* d = get_type_declaration(t);
8995 ABG_ASSERT(d);
8996 return get_pretty_representation(d, internal);
8997 }
8998
8999 /// Get a copy of the pretty representation of a decl.
9000 ///
9001 /// @param d the decl to consider.
9002 ///
9003 /// @param internal set to true if the call is intended for an
9004 /// internal use (for technical use inside the library itself), false
9005 /// otherwise. If you don't know what this is for, then set it to
9006 /// false.
9007 ///
9008 /// @return the pretty representation of the decl.
9009 string
get_pretty_representation(const decl_base_sptr & d,bool internal)9010 get_pretty_representation(const decl_base_sptr& d, bool internal)
9011 {return get_pretty_representation(d.get(), internal);}
9012
9013 /// Get a copy of the pretty representation of a type.
9014 ///
9015 /// @param d the type to consider.
9016 ///
9017 /// @param internal set to true if the call is intended for an
9018 /// internal use (for technical use inside the library itself), false
9019 /// otherwise. If you don't know what this is for, then set it to
9020 /// false.
9021 ///
9022 /// @return the pretty representation of the type.
9023 string
get_pretty_representation(const type_base_sptr & t,bool internal)9024 get_pretty_representation(const type_base_sptr& t, bool internal)
9025 {return get_pretty_representation(t.get(), internal);}
9026
9027 /// Get the pretty representation of a function type.
9028 ///
9029 /// @param fn_type the function type to consider.
9030 ///
9031 /// @param internal set to true if the call is intended for an
9032 /// internal use (for technical use inside the library itself), false
9033 /// otherwise. If you don't know what this is for, then set it to
9034 /// false.
9035 ///
9036 /// @return the string represenation of the function type.
9037 string
get_pretty_representation(const function_type_sptr & fn_type,bool internal)9038 get_pretty_representation(const function_type_sptr& fn_type,
9039 bool internal)
9040 {return get_pretty_representation(fn_type.get(), internal);}
9041
9042 /// Get the pretty representation of a function type.
9043 ///
9044 /// @param fn_type the function type to consider.
9045 ///
9046 /// @param internal set to true if the call is intended for an
9047 /// internal use (for technical use inside the library itself), false
9048 /// otherwise. If you don't know what this is for, then set it to
9049 /// false.
9050 ///
9051 /// @return the string represenation of the function type.
9052 string
get_pretty_representation(const function_type * fn_type,bool internal)9053 get_pretty_representation(const function_type* fn_type, bool internal)
9054 {
9055 if (!fn_type)
9056 return "void";
9057
9058 if (const method_type* method = is_method_type(fn_type))
9059 return get_pretty_representation(method, internal);
9060
9061 return get_pretty_representation(*fn_type, internal);
9062 }
9063
9064 /// Get the pretty representation of a function type.
9065 ///
9066 /// @param fn_type the function type to consider.
9067 ///
9068 /// @param internal set to true if the call is intended for an
9069 /// internal use (for technical use inside the library itself), false
9070 /// otherwise. If you don't know what this is for, then set it to
9071 /// false.
9072 ///
9073 /// @return the string represenation of the function type.
9074 string
get_pretty_representation(const function_type & fn_type,bool internal)9075 get_pretty_representation(const function_type& fn_type, bool internal)
9076 {
9077 std::ostringstream o;
9078 o << "function type " << get_function_type_name(fn_type, internal);
9079 return o.str();
9080 }
9081
9082 /// Get the pretty representation of a method type.
9083 ///
9084 /// @param method the method type to consider.
9085 ///
9086 /// @param internal set to true if the call is intended for an
9087 /// internal use (for technical use inside the library itself), false
9088 /// otherwise. If you don't know what this is for, then set it to
9089 /// false.
9090 ///
9091 /// @return the string represenation of the method type.
9092 string
get_pretty_representation(const method_type & method,bool internal)9093 get_pretty_representation(const method_type& method, bool internal)
9094 {
9095 std::ostringstream o;
9096 o << "method type " << get_method_type_name(method, internal);
9097 return o.str();
9098 }
9099
9100 /// Get the pretty representation of a method type.
9101 ///
9102 /// @param method the method type to consider.
9103 ///
9104 /// @param internal set to true if the call is intended for an
9105 /// internal use (for technical use inside the library itself), false
9106 /// otherwise. If you don't know what this is for, then set it to
9107 /// false.
9108 ///
9109 /// @return the string represenation of the method type.
9110 string
get_pretty_representation(const method_type * method,bool internal)9111 get_pretty_representation(const method_type* method, bool internal)
9112 {
9113 if (!method)
9114 return "void";
9115 return get_pretty_representation(*method, internal);
9116 }
9117
9118 /// Get the pretty representation of a method type.
9119 ///
9120 /// @param method the method type to consider.
9121 ///
9122 /// @param internal set to true if the call is intended for an
9123 /// internal use (for technical use inside the library itself), false
9124 /// otherwise. If you don't know what this is for, then set it to
9125 /// false.
9126 ///
9127 /// @return the string represenation of the method type.
9128 string
get_pretty_representation(const method_type_sptr method,bool internal)9129 get_pretty_representation(const method_type_sptr method, bool internal)
9130 {return get_pretty_representation(method.get(), internal);}
9131
9132 /// Get the flat representation of an instance of @ref class_or_union
9133 /// type.
9134 ///
9135 /// The flat representation of a given @ref class_or_union type is the
9136 /// actual definition of the type, for instance:
9137 ///
9138 /// struct foo {int a; char b;}
9139 ///
9140 ///@param cou the instance of @ref class_or_union to consider.
9141 ///
9142 ///@param indent the identation spaces to use in the representation.
9143 ///
9144 ///@param one_line if true, then the flat representation stands on one
9145 ///line. Otherwise, it stands on multiple lines.
9146 ///
9147 ///@return the resulting flat representation.
9148 string
get_class_or_union_flat_representation(const class_or_union & cou,const string & indent,bool one_line,bool internal,bool qualified_names)9149 get_class_or_union_flat_representation(const class_or_union& cou,
9150 const string& indent,
9151 bool one_line,
9152 bool internal,
9153 bool qualified_names)
9154 {
9155 string repr;
9156 string local_indent = " ";
9157
9158 if (class_decl* clazz = is_class_type(&cou))
9159 {
9160 repr = indent;
9161 if (!internal && clazz->is_struct())
9162 repr += "struct";
9163 else
9164 repr += "class";
9165 }
9166 else if (is_union_type(cou))
9167 repr = indent + "union";
9168 else
9169 return "";
9170
9171 repr += " ";
9172
9173 string name = cou.get_qualified_name();
9174
9175 if (!cou.get_is_anonymous())
9176 repr += name;
9177
9178 repr += "{";
9179
9180 if (!one_line)
9181 repr += "\n";
9182
9183 string real_indent;
9184 const class_or_union::data_members &dmems = cou.get_data_members();
9185 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9186 dm != dmems.end();
9187 ++dm)
9188 {
9189 if (dm != dmems.begin())
9190 {
9191 if (one_line)
9192 real_indent = " ";
9193 else
9194 real_indent = "\n" + indent + local_indent;
9195 }
9196
9197 if (var_decl_sptr v = is_anonymous_data_member(*dm))
9198 repr +=
9199 get_class_or_union_flat_representation
9200 (anonymous_data_member_to_class_or_union(*dm),
9201 real_indent, one_line, internal, qualified_names);
9202 else
9203 {
9204 if (one_line)
9205 {
9206 if (dm != dmems.begin())
9207 repr += real_indent;
9208 repr += (*dm)->get_pretty_representation(internal,
9209 qualified_names);
9210 }
9211 else
9212 repr +=
9213 real_indent+ (*dm)->get_pretty_representation(internal,
9214 qualified_names);
9215 }
9216 repr += ";";
9217 }
9218
9219 if (one_line)
9220 repr += "}";
9221 else
9222 repr += indent + "}";
9223
9224 return repr;
9225 }
9226
9227 /// Get the flat representation of an instance of @ref class_or_union
9228 /// type.
9229 ///
9230 /// The flat representation of a given @ref class_or_union type is the
9231 /// actual definition of the type, for instance:
9232 ///
9233 /// struct foo {int a; char b;}
9234 ///
9235 ///@param cou the instance of @ref class_or_union to consider.
9236 ///
9237 ///@param indent the identation spaces to use in the representation.
9238 ///
9239 ///@param one_line if true, then the flat representation stands on one
9240 ///line. Otherwise, it stands on multiple lines.
9241 ///
9242 ///@return the resulting flat representation.
9243 string
get_class_or_union_flat_representation(const class_or_union * cou,const string & indent,bool one_line,bool internal,bool qualified_names)9244 get_class_or_union_flat_representation(const class_or_union* cou,
9245 const string& indent,
9246 bool one_line,
9247 bool internal,
9248 bool qualified_names)
9249 {
9250 if (cou)
9251 return get_class_or_union_flat_representation(*cou, indent, one_line,
9252 internal, qualified_names);
9253 return "";
9254 }
9255
9256 /// Get the flat representation of an instance of @ref class_or_union
9257 /// type.
9258 ///
9259 /// The flat representation of a given @ref class_or_union type is the
9260 /// actual definition of the type, for instance:
9261 ///
9262 /// struct foo {int a; char b;}
9263 ///
9264 ///@param cou the instance of @ref class_or_union to consider.
9265 ///
9266 ///@param indent the identation spaces to use in the representation.
9267 ///
9268 ///@param one_line if true, then the flat representation stands on one
9269 ///line. Otherwise, it stands on multiple lines.
9270 ///
9271 ///@return the resulting flat representation.
9272 string
get_class_or_union_flat_representation(const class_or_union_sptr & cou,const string & indent,bool one_line,bool internal,bool qualified_names)9273 get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9274 const string& indent,
9275 bool one_line,
9276 bool internal,
9277 bool qualified_names)
9278 {return get_class_or_union_flat_representation(cou.get(),
9279 indent,
9280 one_line,
9281 internal,
9282 qualified_names);}
9283
9284 /// Get the textual representation of a type for debugging purposes.
9285 ///
9286 /// If the type is a class/union, this shows the data members, virtual
9287 /// member functions, size, pointer value of its canonical type, etc.
9288 /// Otherwise, this just shows the name of the artifact as returned by
9289 /// type_or_decl_base:get_pretty_representation().
9290 ///
9291 /// @param artifact the artifact to show a debugging representation of.
9292 ///
9293 /// @return a debugging string representation of @p artifact.
9294 string
get_debug_representation(const type_or_decl_base * artifact)9295 get_debug_representation(const type_or_decl_base* artifact)
9296 {
9297 if (!artifact)
9298 return string("");
9299
9300 class_or_union * c = is_class_or_union_type(artifact);
9301 if (c)
9302 {
9303 class_decl *clazz = is_class_type(c);
9304 string name = c->get_qualified_name();
9305 std::ostringstream o;
9306 o << name;
9307
9308 if (clazz)
9309 {
9310 if (!clazz->get_base_specifiers().empty())
9311 o << " :" << std::endl;
9312 for (auto &b : clazz->get_base_specifiers())
9313 {
9314 o << " ";
9315 if (b->get_is_virtual())
9316 o << "virtual ";
9317 o << b->get_base_class()->get_qualified_name()
9318 << std::endl;
9319 }
9320 }
9321 o << std::endl
9322 << "{"
9323 << " // size in bits: " << c->get_size_in_bits() << "\n"
9324 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9325 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9326 << " // translation unit: " << c->get_translation_unit()->get_absolute_path() << std::endl
9327 << " // @: " << std::hex << is_type(c)
9328 << ", @canonical: " << c->get_canonical_type().get() << std::dec
9329 << "\n\n";
9330
9331 for (auto m : c->get_data_members())
9332 {
9333 type_base_sptr t = m->get_type();
9334 t = peel_typedef_pointer_or_reference_type(t);
9335
9336 o << " "
9337 << m->get_pretty_representation(/*internal=*/false,
9338 /*qualified=*/false)
9339 << ";";
9340
9341 if (t && t->get_canonical_type())
9342 o << " // uses canonical type '@"
9343 << std::hex << t->get_canonical_type().get() << std::dec;
9344
9345 o << "'" << std::endl;
9346 }
9347
9348 if (clazz && clazz->has_vtable())
9349 {
9350 o << " // virtual member functions\n\n";
9351 for (auto f : clazz->get_virtual_mem_fns())
9352 o << " " << f->get_pretty_representation(/*internal=*/false,
9353 /*qualified=*/false)
9354 << ";" << std::endl;
9355 }
9356
9357 o << "};" << std::endl;
9358
9359 return o.str();
9360 }
9361 else if (const enum_type_decl* e = is_enum_type(artifact))
9362 {
9363 string name = e->get_qualified_name();
9364 std::ostringstream o;
9365 o << name
9366 << " : "
9367 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9368 true)
9369 << "\n"
9370 << "{\n"
9371 << " // size in bits: " << e->get_size_in_bits() << "\n"
9372 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9373 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9374 << " // translation unit: "
9375 << e->get_translation_unit()->get_absolute_path() << "\n"
9376 << " // @: " << std::hex << is_type(e)
9377 << ", @canonical: " << e->get_canonical_type().get() << std::dec
9378 << "\n\n";
9379
9380 for (const auto &enom : e->get_enumerators())
9381 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9382
9383 o << "};\n";
9384
9385 return o.str();
9386 }
9387 return artifact->get_pretty_representation(/*internal=*/true,
9388 /*qualified=*/true);
9389 }
9390
9391 /// Get a given data member, referred to by its name, of a class type.
9392 ///
9393 /// @param clazz the class to consider.
9394 ///
9395 /// @param member_name name of the data member to get.
9396 ///
9397 /// @return the resulting data member or nullptr if none was found.
9398 var_decl_sptr
get_data_member(class_or_union * clazz,const char * member_name)9399 get_data_member(class_or_union *clazz, const char* member_name)
9400 {
9401 if (!clazz)
9402 return var_decl_sptr();
9403 return clazz->find_data_member(member_name);
9404 }
9405
9406 /// Get a given data member, referred to by its name, of a class type.
9407 ///
9408 /// @param clazz the class to consider.
9409 ///
9410 /// @param member_name name of the data member to get.
9411 ///
9412 /// @return the resulting data member or nullptr if none was found.
9413 var_decl_sptr
get_data_member(type_base * clazz,const char * member_name)9414 get_data_member(type_base *clazz, const char* member_name)
9415 {return get_data_member(is_class_or_union_type(clazz), member_name);}
9416
9417 /// Get the non-artificial (natural) location of a decl.
9418 ///
9419 /// If the decl doesn't have a natural location then return its
9420 /// artificial one.
9421 ///
9422 /// @param decl the decl to consider.
9423 ///
9424 /// @return the natural location @p decl if it has one; otherwise,
9425 /// return its artificial one.
9426 const location&
get_natural_or_artificial_location(const decl_base * decl)9427 get_natural_or_artificial_location(const decl_base* decl)
9428 {
9429 ABG_ASSERT(decl);
9430
9431 if (decl->get_location())
9432 return decl->get_location();
9433 return decl->get_artificial_location();
9434 }
9435
9436 /// Get the artificial location of a decl.
9437 ///
9438 /// If the decl doesn't have an artificial location then return its
9439 /// natural one.
9440 ///
9441 /// @param decl the decl to consider.
9442 ///
9443 /// @return the artificial location @p decl if it has one; otherwise,
9444 /// return its natural one.
9445 const location&
get_artificial_or_natural_location(const decl_base * decl)9446 get_artificial_or_natural_location(const decl_base* decl)
9447 {
9448 ABG_ASSERT(decl);
9449
9450 if (decl->has_artificial_location())
9451 return decl->get_artificial_location();
9452 return decl->get_location();
9453 }
9454
9455 /// Emit a textual representation of an artifact to std error stream
9456 /// for debugging purposes.
9457 ///
9458 /// This is useful to invoke from within a command line debugger like
9459 /// GDB to help make sense of a given ABI artifact.
9460 ///
9461 /// @param artifact the ABI artifact to emit the debugging
9462 /// representation for.
9463 ///
9464 /// @return the artifact @p artifact.
9465 type_or_decl_base*
debug(const type_or_decl_base * artifact)9466 debug(const type_or_decl_base* artifact)
9467 {
9468 std::cerr << get_debug_representation(artifact) << std::endl;
9469 return const_cast<type_or_decl_base*>(artifact);
9470 }
9471
9472 /// Emit a textual representation of an artifact to std error stream
9473 /// for debugging purposes.
9474 ///
9475 /// This is useful to invoke from within a command line debugger like
9476 /// GDB to help make sense of a given ABI artifact.
9477 ///
9478 /// @param artifact the ABI artifact to emit the debugging
9479 /// representation for.
9480 ///
9481 /// @return the artifact @p artifact.
9482 type_base*
debug(const type_base * artifact)9483 debug(const type_base* artifact)
9484 {
9485 debug(static_cast<const type_or_decl_base*>(artifact));
9486 return const_cast<type_base*>(artifact);
9487 }
9488
9489 /// Emit a textual representation of an artifact to std error stream
9490 /// for debugging purposes.
9491 ///
9492 /// This is useful to invoke from within a command line debugger like
9493 /// GDB to help make sense of a given ABI artifact.
9494 ///
9495 /// @param artifact the ABI artifact to emit the debugging
9496 /// representation for.
9497 ///
9498 /// @return the artifact @p artifact.
9499 decl_base*
debug(const decl_base * artifact)9500 debug(const decl_base* artifact)
9501 {
9502 debug(static_cast<const type_or_decl_base*>(artifact));
9503 return const_cast<decl_base*>(artifact);
9504 }
9505
9506 /// Test if two ABI artifacts are equal.
9507 ///
9508 /// This can be useful when used from the command line of a debugger
9509 /// like GDB.
9510 ///
9511 /// @param l the first ABI artifact to consider in the comparison.
9512 ///
9513 /// @param r the second ABI artifact to consider in the comparison.
9514 ///
9515 /// @return true iff @p l equals @p r.
9516 bool
debug_equals(const type_or_decl_base * l,const type_or_decl_base * r)9517 debug_equals(const type_or_decl_base *l, const type_or_decl_base *r)
9518 {
9519 if (!!l != !!r)
9520 return false;
9521 if (!l && !r)
9522 return true;
9523
9524 return (*l == *r);
9525 }
9526
9527 /// By looking at the language of the TU a given ABI artifact belongs
9528 /// to, test if the ONE Definition Rule should apply.
9529 ///
9530 /// To date, it applies to c++, java and ada.
9531 ///
9532 /// @param artifact the ABI artifact to consider.
9533 ///
9534 /// @return true iff the One Definition Rule should apply.
9535 bool
odr_is_relevant(const type_or_decl_base & artifact)9536 odr_is_relevant(const type_or_decl_base& artifact)
9537 {
9538 translation_unit::language l =
9539 artifact.get_translation_unit()->get_language();
9540
9541 if (is_cplus_plus_language(l)
9542 || is_java_language(l)
9543 || is_ada_language(l))
9544 return true;
9545
9546 return false;
9547 }
9548
9549 /// Get the declaration for a given type.
9550 ///
9551 /// @param t the type to consider.
9552 ///
9553 /// @return the declaration for the type to return.
9554 const decl_base*
get_type_declaration(const type_base * t)9555 get_type_declaration(const type_base* t)
9556 {return dynamic_cast<const decl_base*>(t);}
9557
9558 /// Get the declaration for a given type.
9559 ///
9560 /// @param t the type to consider.
9561 ///
9562 /// @return the declaration for the type to return.
9563 decl_base*
get_type_declaration(type_base * t)9564 get_type_declaration(type_base* t)
9565 {return dynamic_cast<decl_base*>(t);}
9566
9567 /// Get the declaration for a given type.
9568 ///
9569 /// @param t the type to consider.
9570 ///
9571 /// @return the declaration for the type to return.
9572 decl_base_sptr
get_type_declaration(const type_base_sptr t)9573 get_type_declaration(const type_base_sptr t)
9574 {return dynamic_pointer_cast<decl_base>(t);}
9575
9576 /// Test if two types are equal modulo a typedef.
9577 ///
9578 /// Type A and B are compatible if
9579 ///
9580 /// - A and B are equal
9581 /// - or if one type is a typedef of the other one.
9582 ///
9583 /// @param type1 the first type to consider.
9584 ///
9585 /// @param type2 the second type to consider.
9586 ///
9587 /// @return true iff @p type1 and @p type2 are compatible.
9588 bool
types_are_compatible(const type_base_sptr type1,const type_base_sptr type2)9589 types_are_compatible(const type_base_sptr type1,
9590 const type_base_sptr type2)
9591 {
9592 if (!type1 || !type2)
9593 return false;
9594
9595 if (type1 == type2)
9596 return true;
9597
9598 // Normally we should strip typedefs entirely, but this is
9599 // potentially costly, especially on binaries with huge changesets
9600 // like the Linux Kernel. So we just get the leaf types for now.
9601 //
9602 // Maybe there should be an option by which users accepts to pay the
9603 // CPU usage toll in exchange for finer filtering?
9604
9605 // type_base_sptr t1 = strip_typedef(type1);
9606 // type_base_sptr t2 = strip_typedef(type2);
9607
9608 type_base_sptr t1 = peel_typedef_type(type1);
9609 type_base_sptr t2 = peel_typedef_type(type2);
9610
9611 return t1 == t2;
9612 }
9613
9614 /// Test if two types are equal modulo a typedef.
9615 ///
9616 /// Type A and B are compatible if
9617 ///
9618 /// - A and B are equal
9619 /// - or if one type is a typedef of the other one.
9620 ///
9621 /// @param type1 the declaration of the first type to consider.
9622 ///
9623 /// @param type2 the declaration of the second type to consider.
9624 ///
9625 /// @return true iff @p type1 and @p type2 are compatible.
9626 bool
types_are_compatible(const decl_base_sptr d1,const decl_base_sptr d2)9627 types_are_compatible(const decl_base_sptr d1,
9628 const decl_base_sptr d2)
9629 {return types_are_compatible(is_type(d1), is_type(d2));}
9630
9631 /// Return the translation unit a declaration belongs to.
9632 ///
9633 /// @param decl the declaration to consider.
9634 ///
9635 /// @return the resulting translation unit, or null if the decl is not
9636 /// yet added to a translation unit.
9637 translation_unit*
get_translation_unit(const decl_base & decl)9638 get_translation_unit(const decl_base& decl)
9639 {return const_cast<translation_unit*>(decl.get_translation_unit());}
9640
9641 /// Return the translation unit a declaration belongs to.
9642 ///
9643 /// @param decl the declaration to consider.
9644 ///
9645 /// @return the resulting translation unit, or null if the decl is not
9646 /// yet added to a translation unit.
9647 translation_unit*
get_translation_unit(const decl_base * decl)9648 get_translation_unit(const decl_base* decl)
9649 {return decl ? get_translation_unit(*decl) : 0;}
9650
9651 /// Return the translation unit a declaration belongs to.
9652 ///
9653 /// @param decl the declaration to consider.
9654 ///
9655 /// @return the resulting translation unit, or null if the decl is not
9656 /// yet added to a translation unit.
9657 translation_unit*
get_translation_unit(const shared_ptr<decl_base> decl)9658 get_translation_unit(const shared_ptr<decl_base> decl)
9659 {return get_translation_unit(decl.get());}
9660
9661 /// Tests whether if a given scope is the global scope.
9662 ///
9663 /// @param scope the scope to consider.
9664 ///
9665 /// @return true iff the current scope is the global one.
9666 bool
is_global_scope(const scope_decl & scope)9667 is_global_scope(const scope_decl& scope)
9668 {return !!dynamic_cast<const global_scope*>(&scope);}
9669
9670 /// Tests whether if a given scope is the global scope.
9671 ///
9672 /// @param scope the scope to consider.
9673 ///
9674 /// @return the @ref global_scope* representing the scope @p scope or
9675 /// 0 if @p scope is not a global scope.
9676 const global_scope*
is_global_scope(const scope_decl * scope)9677 is_global_scope(const scope_decl* scope)
9678 {return dynamic_cast<const global_scope*>(scope);}
9679
9680 /// Tests whether if a given scope is the global scope.
9681 ///
9682 /// @param scope the scope to consider.
9683 ///
9684 /// @return true iff the current scope is the global one.
9685 bool
is_global_scope(const shared_ptr<scope_decl> scope)9686 is_global_scope(const shared_ptr<scope_decl>scope)
9687 {return is_global_scope(scope.get());}
9688
9689 /// Tests whether a given declaration is at global scope.
9690 ///
9691 /// @param decl the decl to consider.
9692 ///
9693 /// @return true iff decl is at global scope.
9694 bool
is_at_global_scope(const decl_base & decl)9695 is_at_global_scope(const decl_base& decl)
9696 {return (is_global_scope(decl.get_scope()));}
9697
9698 /// Tests whether a given declaration is at global scope.
9699 ///
9700 /// @param decl the decl to consider.
9701 ///
9702 /// @return true iff decl is at global scope.
9703 bool
is_at_global_scope(const decl_base_sptr decl)9704 is_at_global_scope(const decl_base_sptr decl)
9705 {return (decl && is_global_scope(decl->get_scope()));}
9706
9707 /// Tests whether a given declaration is at global scope.
9708 ///
9709 /// @param decl the decl to consider.
9710 ///
9711 /// @return true iff decl is at global scope.
9712 bool
is_at_global_scope(const decl_base * decl)9713 is_at_global_scope(const decl_base* decl)
9714 {return is_at_global_scope(*decl);}
9715
9716 /// Tests whether a given decl is at class scope.
9717 ///
9718 /// @param decl the decl to consider.
9719 ///
9720 /// @return true iff decl is at class scope.
9721 class_or_union*
is_at_class_scope(const decl_base_sptr decl)9722 is_at_class_scope(const decl_base_sptr decl)
9723 {return is_at_class_scope(decl.get());}
9724
9725 /// Tests whether a given decl is at class scope.
9726 ///
9727 /// @param decl the decl to consider.
9728 ///
9729 /// @return true iff decl is at class scope.
9730 class_or_union*
is_at_class_scope(const decl_base * decl)9731 is_at_class_scope(const decl_base* decl)
9732 {
9733 if (!decl)
9734 return 0;
9735
9736 return is_at_class_scope(*decl);
9737 }
9738
9739 /// Tests whether a given decl is at class scope.
9740 ///
9741 /// @param decl the decl to consider.
9742 ///
9743 /// @return true iff decl is at class scope.
9744 class_or_union*
is_at_class_scope(const decl_base & decl)9745 is_at_class_scope(const decl_base& decl)
9746 {
9747 scope_decl* scope = decl.get_scope();
9748 if (class_or_union* cl = is_class_type(scope))
9749 return cl;
9750 if (class_or_union* cl = is_union_type(scope))
9751 return cl;
9752 return 0;
9753 }
9754
9755 /// Find a data member inside an anonymous data member.
9756 ///
9757 /// An anonymous data member has a type which is a class or union.
9758 /// This function looks for a data member inside the type of that
9759 /// anonymous data member.
9760 ///
9761 /// @param anon_dm the anonymous data member to consider.
9762 ///
9763 /// @param name the name of the data member to look for.
9764 var_decl_sptr
find_data_member_from_anonymous_data_member(const var_decl_sptr & anon_dm,const string & name)9765 find_data_member_from_anonymous_data_member(const var_decl_sptr& anon_dm,
9766 const string& name)
9767 {
9768 const class_or_union* containing_class_or_union =
9769 anonymous_data_member_to_class_or_union(anon_dm.get());
9770
9771 if (!containing_class_or_union)
9772 return var_decl_sptr();
9773
9774 var_decl_sptr result = containing_class_or_union->find_data_member(name);
9775 return result;
9776 }
9777
9778 /// Tests whether a given decl is at template scope.
9779 ///
9780 /// Note that only template parameters , types that are compositions,
9781 /// and template patterns (function or class) can be at template scope.
9782 ///
9783 /// @param decl the decl to consider.
9784 ///
9785 /// @return true iff the decl is at template scope.
9786 bool
is_at_template_scope(const shared_ptr<decl_base> decl)9787 is_at_template_scope(const shared_ptr<decl_base> decl)
9788 {return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
9789
9790 /// Tests whether a decl is a template parameter.
9791 ///
9792 /// @param decl the decl to consider.
9793 ///
9794 /// @return true iff decl is a template parameter.
9795 bool
is_template_parameter(const shared_ptr<decl_base> decl)9796 is_template_parameter(const shared_ptr<decl_base> decl)
9797 {
9798 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
9799 || dynamic_pointer_cast<non_type_tparameter>(decl)
9800 || dynamic_pointer_cast<template_tparameter>(decl)));
9801 }
9802
9803 /// Test whether a declaration is a @ref function_decl.
9804 ///
9805 /// @param d the declaration to test for.
9806 ///
9807 /// @return a shared pointer to @ref function_decl if @p d is a @ref
9808 /// function_decl. Otherwise, a nil shared pointer.
9809 function_decl*
is_function_decl(const type_or_decl_base * d)9810 is_function_decl(const type_or_decl_base* d)
9811 {return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
9812
9813 /// Test whether a declaration is a @ref function_decl.
9814 ///
9815 /// @param d the declaration to test for.
9816 ///
9817 /// @return true if @p d is a function_decl.
9818 bool
is_function_decl(const type_or_decl_base & d)9819 is_function_decl(const type_or_decl_base& d)
9820 {return is_function_decl(&d);}
9821
9822 /// Test whether a declaration is a @ref function_decl.
9823 ///
9824 /// @param d the declaration to test for.
9825 ///
9826 /// @return a shared pointer to @ref function_decl if @p d is a @ref
9827 /// function_decl. Otherwise, a nil shared pointer.
9828 function_decl_sptr
is_function_decl(const type_or_decl_base_sptr & d)9829 is_function_decl(const type_or_decl_base_sptr& d)
9830 {return dynamic_pointer_cast<function_decl>(d);}
9831
9832 /// Test whether a declaration is a @ref function_decl.
9833 ///
9834 /// @param d the declaration to test for.
9835 ///
9836 /// @return a pointer to @ref function_decl if @p d is a @ref
9837 /// function_decl. Otherwise, a nil shared pointer.
9838 function_decl::parameter*
is_function_parameter(const type_or_decl_base * tod)9839 is_function_parameter(const type_or_decl_base* tod)
9840 {
9841 return dynamic_cast<function_decl::parameter*>
9842 (const_cast<type_or_decl_base*>(tod));
9843 }
9844
9845 /// Test whether an ABI artifact is a @ref function_decl.
9846 ///
9847 /// @param tod the declaration to test for.
9848 ///
9849 /// @return a pointer to @ref function_decl if @p d is a @ref
9850 /// function_decl. Otherwise, a nil shared pointer.
9851 function_decl::parameter_sptr
is_function_parameter(const type_or_decl_base_sptr tod)9852 is_function_parameter(const type_or_decl_base_sptr tod)
9853 {return dynamic_pointer_cast<function_decl::parameter>(tod);}
9854
9855 /// Test if an ABI artifact is a declaration.
9856 ///
9857 /// @param d the artifact to consider.
9858 ///
9859 /// @param return the declaration sub-object of @p d if it's a
9860 /// declaration, or NULL if it is not.
9861 decl_base*
is_decl(const type_or_decl_base * d)9862 is_decl(const type_or_decl_base* d)
9863 {
9864 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
9865 {
9866 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
9867 // The artifact is a decl-only (like a function or a
9868 // variable). That is, it's not a type that also has a
9869 // declaration. In this case, we are in the fast path and we
9870 // have a pointer to the decl sub-object handy. Just return
9871 // it ...
9872 return reinterpret_cast<decl_base*>
9873 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
9874
9875 // ... Otherwise, we are in the slow path, which is that the
9876 // artifact is a type which has a declaration. In that case,
9877 // let's use the slow dynamic_cast because we don't have the
9878 // pointer to the decl sub-object handily present.
9879 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
9880 }
9881 return 0;
9882 }
9883
9884 /// Test if an ABI artifact is a declaration.
9885 ///
9886 /// @param d the artifact to consider.
9887 ///
9888 /// @param return the declaration sub-object of @p d if it's a
9889 /// declaration, or NULL if it is not.
9890 decl_base_sptr
is_decl(const type_or_decl_base_sptr & d)9891 is_decl(const type_or_decl_base_sptr& d)
9892 {return dynamic_pointer_cast<decl_base>(d);}
9893
9894 /// Test if an ABI artifact is a declaration.
9895 ///
9896 /// This is done using a slow path that uses dynamic_cast.
9897 ///
9898 /// @param d the artifact to consider.
9899 ///
9900 /// @param return the declaration sub-object of @p d if it's a
9901 decl_base*
is_decl_slow(const type_or_decl_base * t)9902 is_decl_slow(const type_or_decl_base* t)
9903 {return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
9904
9905 /// Test if an ABI artifact is a declaration.
9906 ///
9907 /// This is done using a slow path that uses dynamic_cast.
9908 ///
9909 /// @param d the artifact to consider.
9910 ///
9911 /// @param return the declaration sub-object of @p d if it's a
9912 decl_base_sptr
is_decl_slow(const type_or_decl_base_sptr & t)9913 is_decl_slow(const type_or_decl_base_sptr& t)
9914 {return dynamic_pointer_cast<decl_base>(t);}
9915
9916 /// Test whether a declaration is a type.
9917 ///
9918 /// @param d the IR artefact to test for.
9919 ///
9920 /// @return true if the artifact is a type, false otherwise.
9921 bool
is_type(const type_or_decl_base & tod)9922 is_type(const type_or_decl_base& tod)
9923 {
9924 if (dynamic_cast<const type_base*>(&tod))
9925 return true;
9926 return false;
9927 }
9928
9929 /// Test whether a declaration is a type.
9930 ///
9931 /// @param d the IR artefact to test for.
9932 ///
9933 /// @return true if the artifact is a type, false otherwise.
9934 type_base*
is_type(const type_or_decl_base * t)9935 is_type(const type_or_decl_base* t)
9936 {
9937 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
9938 return reinterpret_cast<type_base*>
9939 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
9940
9941 return 0;
9942 }
9943
9944 /// Test whether a declaration is a type.
9945 ///
9946 /// @param d the IR artefact to test for.
9947 ///
9948 /// @return true if the artifact is a type, false otherwise.
9949 type_base_sptr
is_type(const type_or_decl_base_sptr & tod)9950 is_type(const type_or_decl_base_sptr& tod)
9951 {return dynamic_pointer_cast<type_base>(tod);}
9952
9953 /// Test whether a declaration is a type.
9954 ///
9955 /// @param d the declaration to test for.
9956 ///
9957 /// @return true if the declaration is a type, false otherwise.
9958
9959 /// Test if a given type is anonymous.
9960 ///
9961 /// Note that this function considers that an anonymous class that is
9962 /// named by a typedef is not anonymous anymore. This is the C idiom:
9963 ///
9964 /// typedef struct {int member;} s_type;
9965 ///
9966 /// The typedef s_type becomes the name of the originally anonymous
9967 /// struct.
9968 ///
9969 /// @param t the type to consider.
9970 ///
9971 /// @return true iff @p t is anonymous.
9972 bool
is_anonymous_type(const type_base * t)9973 is_anonymous_type(const type_base* t)
9974 {
9975 const decl_base* d = get_type_declaration(t);
9976 if (d)
9977 if (d->get_is_anonymous())
9978 {
9979 if (class_or_union *cou = is_class_or_union_type(t))
9980 {
9981 // An anonymous class that is named by a typedef is not
9982 // considered anonymous anymore.
9983 if (!cou->get_naming_typedef())
9984 return true;
9985 }
9986 else
9987 return true;
9988 }
9989 return false;
9990 }
9991
9992 /// Test if a given type is anonymous.
9993 ///
9994 /// @param t the type to consider.
9995 ///
9996 /// @return true iff @p t is anonymous.
9997 bool
is_anonymous_type(const type_base_sptr & t)9998 is_anonymous_type(const type_base_sptr& t)
9999 {return is_anonymous_type(t.get());}
10000
10001 /// Test whether a type is a type_decl (a builtin type).
10002 ///
10003 /// @return the type_decl* for @t if it's type_decl, otherwise, return
10004 /// nil.
10005 const type_decl*
is_type_decl(const type_or_decl_base * t)10006 is_type_decl(const type_or_decl_base* t)
10007 {return dynamic_cast<const type_decl*>(t);}
10008
10009 /// Test whether a type is a type_decl (a builtin type).
10010 ///
10011 /// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10012 /// return nil.
10013 type_decl_sptr
is_type_decl(const type_or_decl_base_sptr & t)10014 is_type_decl(const type_or_decl_base_sptr& t)
10015 {return dynamic_pointer_cast<type_decl>(t);}
10016
10017 /// Test if a type is an integral type.
10018 ///
10019 /// @param t the type to test.
10020 ///
10021 /// @return the integral type @p t can be converted to, or nil if @p
10022 /// is not an integral type.
10023 type_decl*
is_integral_type(const type_or_decl_base * t)10024 is_integral_type(const type_or_decl_base* t)
10025 {
10026 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10027 if (!type)
10028 return nullptr;
10029
10030 integral_type int_type;
10031 if (!parse_integral_type(type->get_name(), int_type))
10032 return nullptr;
10033
10034 return type;
10035 }
10036
10037 /// Test if a type is an integral type.
10038 ///
10039 /// @param t the type to test.
10040 ///
10041 /// @return the integral type @p t can be converted to, or nil if @p
10042 /// is not an integral type.
10043 type_decl_sptr
is_integral_type(const type_or_decl_base_sptr & t)10044 is_integral_type(const type_or_decl_base_sptr& t)
10045 {
10046 const type_decl_sptr type = is_type_decl(t);
10047 if (!type)
10048 return type_decl_sptr();
10049
10050 integral_type int_type;
10051 if (!parse_integral_type(type->get_name(), int_type))
10052 return type_decl_sptr();
10053
10054 return type;
10055 }
10056
10057 /// Test whether a type is a typedef.
10058 ///
10059 /// @param t the type to test for.
10060 ///
10061 /// @return the typedef declaration of the @p t, or NULL if it's not a
10062 /// typedef.
10063 typedef_decl_sptr
is_typedef(const type_or_decl_base_sptr t)10064 is_typedef(const type_or_decl_base_sptr t)
10065 {return dynamic_pointer_cast<typedef_decl>(t);}
10066
10067 /// Test whether a type is a typedef.
10068 ///
10069 /// @param t the declaration of the type to test for.
10070 ///
10071 /// @return the typedef declaration of the @p t, or NULL if it's not a
10072 /// typedef.
10073 const typedef_decl*
is_typedef(const type_base * t)10074 is_typedef(const type_base* t)
10075 {return dynamic_cast<const typedef_decl*>(t);}
10076
10077 /// Test whether a type is a typedef.
10078 ///
10079 /// @param t the declaration of the type to test for.
10080 ///
10081 /// @return the typedef declaration of the @p t, or NULL if it's not a
10082 /// typedef.
10083 typedef_decl*
is_typedef(type_base * t)10084 is_typedef(type_base* t)
10085 {return dynamic_cast<typedef_decl*>(t);}
10086
10087 /// Test if a type is an enum. This function looks through typedefs.
10088 ///
10089 /// @parm t the type to consider.
10090 ///
10091 /// @return the enum_decl if @p t is an @ref enum_decl or null
10092 /// otherwise.
10093 enum_type_decl_sptr
is_compatible_with_enum_type(const type_base_sptr & t)10094 is_compatible_with_enum_type(const type_base_sptr& t)
10095 {
10096 if (!t)
10097 return enum_type_decl_sptr();
10098
10099 // Normally we should strip typedefs entirely, but this is
10100 // potentially costly, especially on binaries with huge changesets
10101 // like the Linux Kernel. So we just get the leaf types for now.
10102 //
10103 // Maybe there should be an option by which users accepts to pay the
10104 // CPU usage toll in exchange for finer filtering?
10105
10106 // type_base_sptr ty = strip_typedef(t);
10107 type_base_sptr ty = peel_typedef_type(t);;
10108 return is_enum_type(ty);
10109 }
10110
10111 /// Test if a type is an enum. This function looks through typedefs.
10112 ///
10113 /// @parm t the type to consider.
10114 ///
10115 /// @return the enum_decl if @p t is an @ref enum_decl or null
10116 /// otherwise.
10117 enum_type_decl_sptr
is_compatible_with_enum_type(const decl_base_sptr & t)10118 is_compatible_with_enum_type(const decl_base_sptr& t)
10119 {return is_compatible_with_enum_type(is_type(t));}
10120
10121 /// Test if a decl is an enum_type_decl
10122 ///
10123 /// @param d the decl to test for.
10124 ///
10125 /// @return the enum_type_decl* if @p d is an enum, nil otherwise.
10126 const enum_type_decl*
is_enum_type(const type_or_decl_base * d)10127 is_enum_type(const type_or_decl_base* d)
10128 {return dynamic_cast<const enum_type_decl*>(d);}
10129
10130 /// Test if a decl is an enum_type_decl
10131 ///
10132 /// @param d the decl to test for.
10133 ///
10134 /// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
10135 enum_type_decl_sptr
is_enum_type(const type_or_decl_base_sptr & d)10136 is_enum_type(const type_or_decl_base_sptr& d)
10137 {return dynamic_pointer_cast<enum_type_decl>(d);}
10138
10139 /// Test if a type is a class. This function looks through typedefs.
10140 ///
10141 /// @parm t the type to consider.
10142 ///
10143 /// @return the class_decl if @p t is a class_decl or null otherwise.
10144 class_decl_sptr
is_compatible_with_class_type(const type_base_sptr & t)10145 is_compatible_with_class_type(const type_base_sptr& t)
10146 {
10147 if (!t)
10148 return class_decl_sptr();
10149
10150 // Normally we should strip typedefs entirely, but this is
10151 // potentially costly, especially on binaries with huge changesets
10152 // like the Linux Kernel. So we just get the leaf types for now.
10153 //
10154 // Maybe there should be an option by which users accepts to pay the
10155 // CPU usage toll in exchange for finer filtering?
10156
10157 // type_base_sptr ty = strip_typedef(t);
10158 type_base_sptr ty = peel_typedef_type(t);
10159 return is_class_type(ty);
10160 }
10161
10162 /// Test if a type is a class. This function looks through typedefs.
10163 ///
10164 /// @parm t the type to consider.
10165 ///
10166 /// @return the class_decl if @p t is a class_decl or null otherwise.
10167 class_decl_sptr
is_compatible_with_class_type(const decl_base_sptr & t)10168 is_compatible_with_class_type(const decl_base_sptr& t)
10169 {return is_compatible_with_class_type(is_type(t));}
10170
10171 /// Test whether a type is a class.
10172 ///
10173 /// @parm t the type to consider.
10174 ///
10175 /// @return true iff @p t is a class_decl.
10176 bool
is_class_type(const type_or_decl_base & t)10177 is_class_type(const type_or_decl_base& t)
10178 {return is_class_type(&t);}
10179
10180 /// Test whether a type is a class.
10181 ///
10182 /// @parm t the type to consider.
10183 ///
10184 /// @return the class_decl if @p t is a class_decl or null otherwise.
10185 class_decl*
is_class_type(const type_or_decl_base * t)10186 is_class_type(const type_or_decl_base* t)
10187 {
10188 if (!t)
10189 return 0;
10190
10191 if (t->kind() & type_or_decl_base::CLASS_TYPE)
10192 return reinterpret_cast<class_decl*>
10193 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10194
10195 return 0;
10196 }
10197
10198 /// Test whether a type is a class.
10199 ///
10200 /// @parm t the type to consider.
10201 ///
10202 /// @return the class_decl if @p t is a class_decl or null otherwise.
10203 class_decl_sptr
is_class_type(const type_or_decl_base_sptr & d)10204 is_class_type(const type_or_decl_base_sptr& d)
10205 {return dynamic_pointer_cast<class_decl>(d);}
10206
10207
10208 /// Test wheter a type is a declaration-only class.
10209 ///
10210 /// @param t the type to considier.
10211 ///
10212 /// @return true iff @p t is a declaration-only class.
10213 bool
is_declaration_only_class_or_union_type(const type_base * t)10214 is_declaration_only_class_or_union_type(const type_base *t)
10215 {
10216 if (const class_or_union *klass = is_class_or_union_type(t))
10217 return klass->get_is_declaration_only();
10218 return false;
10219 }
10220
10221 /// Test wheter a type is a declaration-only class.
10222 ///
10223 /// @param t the type to considier.
10224 ///
10225 /// @return true iff @p t is a declaration-only class.
10226 bool
is_declaration_only_class_type(const type_base_sptr & t)10227 is_declaration_only_class_type(const type_base_sptr& t)
10228 {return is_declaration_only_class_or_union_type(t.get());}
10229
10230 /// Test if a type is a @ref class_or_union.
10231 ///
10232 /// @param t the type to consider.
10233 ///
10234 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
10235 /// nil otherwise.
10236 class_or_union*
is_class_or_union_type(const type_or_decl_base * t)10237 is_class_or_union_type(const type_or_decl_base* t)
10238 {return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
10239
10240 /// Test if a type is a @ref class_or_union.
10241 ///
10242 /// @param t the type to consider.
10243 ///
10244 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
10245 /// nil otherwise.
10246 shared_ptr<class_or_union>
is_class_or_union_type(const shared_ptr<type_or_decl_base> & t)10247 is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
10248 {return dynamic_pointer_cast<class_or_union>(t);}
10249
10250 /// Test if a type is a @ref union_decl.
10251 ///
10252 /// @param t the type to consider.
10253 ///
10254 /// @return true iff @p t is a union_decl.
10255 bool
is_union_type(const type_or_decl_base & t)10256 is_union_type(const type_or_decl_base& t)
10257 {return is_union_type(&t);}
10258
10259 /// Test if a type is a @ref union_decl.
10260 ///
10261 /// @param t the type to consider.
10262 ///
10263 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
10264 /// otherwise.
10265 union_decl*
is_union_type(const type_or_decl_base * t)10266 is_union_type(const type_or_decl_base* t)
10267 {return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
10268
10269 /// Test if a type is a @ref union_decl.
10270 ///
10271 /// @param t the type to consider.
10272 ///
10273 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
10274 /// otherwise.
10275 union_decl_sptr
is_union_type(const shared_ptr<type_or_decl_base> & t)10276 is_union_type(const shared_ptr<type_or_decl_base>& t)
10277 {return dynamic_pointer_cast<union_decl>(t);}
10278
10279 /// Test whether a type is a pointer_type_def.
10280 ///
10281 /// @param t the type to test.
10282 ///
10283 /// @return the @ref pointer_type_def_sptr if @p t is a
10284 /// pointer_type_def, null otherwise.
10285 pointer_type_def*
is_pointer_type(type_or_decl_base * t)10286 is_pointer_type(type_or_decl_base* t)
10287 {
10288 if (!t)
10289 return 0;
10290
10291 if (t->kind() & type_or_decl_base::POINTER_TYPE)
10292 return reinterpret_cast<pointer_type_def*>
10293 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10294
10295 return 0;
10296 }
10297
10298 /// Test whether a type is a pointer_type_def.
10299 ///
10300 /// @param t the type to test.
10301 ///
10302 /// @return the @ref pointer_type_def_sptr if @p t is a
10303 /// pointer_type_def, null otherwise.
10304 const pointer_type_def*
is_pointer_type(const type_or_decl_base * t)10305 is_pointer_type(const type_or_decl_base* t)
10306 {
10307 return is_pointer_type(const_cast<type_or_decl_base*>(t));
10308 }
10309
10310 /// Test whether a type is a pointer_type_def.
10311 ///
10312 /// @param t the type to test.
10313 ///
10314 /// @return the @ref pointer_type_def_sptr if @p t is a
10315 /// pointer_type_def, null otherwise.
10316 pointer_type_def_sptr
is_pointer_type(const type_or_decl_base_sptr & t)10317 is_pointer_type(const type_or_decl_base_sptr &t)
10318 {return dynamic_pointer_cast<pointer_type_def>(t);}
10319
10320 /// Test whether a type is a reference_type_def.
10321 ///
10322 /// @param t the type to test.
10323 ///
10324 /// @return the @ref reference_type_def_sptr if @p t is a
10325 /// reference_type_def, null otherwise.
10326 reference_type_def*
is_reference_type(type_or_decl_base * t)10327 is_reference_type(type_or_decl_base* t)
10328 {return dynamic_cast<reference_type_def*>(t);}
10329
10330 /// Test whether a type is a reference_type_def.
10331 ///
10332 /// @param t the type to test.
10333 ///
10334 /// @return the @ref reference_type_def_sptr if @p t is a
10335 /// reference_type_def, null otherwise.
10336 const reference_type_def*
is_reference_type(const type_or_decl_base * t)10337 is_reference_type(const type_or_decl_base* t)
10338 {return dynamic_cast<const reference_type_def*>(t);}
10339
10340 /// Test whether a type is a reference_type_def.
10341 ///
10342 /// @param t the type to test.
10343 ///
10344 /// @return the @ref reference_type_def_sptr if @p t is a
10345 /// reference_type_def, null otherwise.
10346 reference_type_def_sptr
is_reference_type(const type_or_decl_base_sptr & t)10347 is_reference_type(const type_or_decl_base_sptr& t)
10348 {return dynamic_pointer_cast<reference_type_def>(t);}
10349
10350 /// Test if a type is a pointer to void type.
10351 ///
10352 /// Note that this looks trough typedefs or CV qualifiers to look for
10353 /// the void pointer.
10354 ///
10355 /// @param type the type to consider.
10356 ///
10357 /// @return the actual void pointer if @p is a void pointer or NULL if
10358 /// it's not.
10359 const type_base*
is_void_pointer_type(const type_base * type)10360 is_void_pointer_type(const type_base* type)
10361 {
10362 type = peel_qualified_or_typedef_type(type);
10363
10364 const pointer_type_def * t = is_pointer_type(type);
10365 if (!t)
10366 return 0;
10367
10368 // Look through typedefs in the pointed-to type as well.
10369 type_base * ty = t->get_pointed_to_type().get();
10370 ty = peel_qualified_or_typedef_type(ty);
10371 if (ty->get_environment().is_void_type(ty))
10372 return ty;
10373
10374 return 0;
10375 }
10376
10377 /// Test whether a type is a reference_type_def.
10378 ///
10379 /// @param t the type to test.
10380 ///
10381 /// @return the @ref reference_type_def_sptr if @p t is a
10382 /// reference_type_def, null otherwise.
10383 qualified_type_def*
is_qualified_type(const type_or_decl_base * t)10384 is_qualified_type(const type_or_decl_base* t)
10385 {return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
10386
10387 /// Test whether a type is a qualified_type_def.
10388 ///
10389 /// @param t the type to test.
10390 ///
10391 /// @return the @ref qualified_type_def_sptr if @p t is a
10392 /// qualified_type_def, null otherwise.
10393 qualified_type_def_sptr
is_qualified_type(const type_or_decl_base_sptr & t)10394 is_qualified_type(const type_or_decl_base_sptr& t)
10395 {return dynamic_pointer_cast<qualified_type_def>(t);}
10396
10397 /// Test whether a type is a function_type.
10398 ///
10399 /// @param t the type to test.
10400 ///
10401 /// @return the @ref function_type_sptr if @p t is a
10402 /// function_type, null otherwise.
10403 function_type_sptr
is_function_type(const type_or_decl_base_sptr & t)10404 is_function_type(const type_or_decl_base_sptr& t)
10405 {return dynamic_pointer_cast<function_type>(t);}
10406
10407 /// Test whether a type is a function_type.
10408 ///
10409 /// @param t the type to test.
10410 ///
10411 /// @return the @ref function_type_sptr if @p t is a
10412 /// function_type, null otherwise.
10413 function_type*
is_function_type(type_or_decl_base * t)10414 is_function_type(type_or_decl_base* t)
10415 {return dynamic_cast<function_type*>(t);}
10416
10417 /// Test whether a type is a function_type.
10418 ///
10419 /// @param t the type to test.
10420 ///
10421 /// @return the @ref function_type_sptr if @p t is a
10422 /// function_type, null otherwise.
10423 const function_type*
is_function_type(const type_or_decl_base * t)10424 is_function_type(const type_or_decl_base* t)
10425 {return dynamic_cast<const function_type*>(t);}
10426
10427 /// Test whether a type is a method_type.
10428 ///
10429 /// @param t the type to test.
10430 ///
10431 /// @return the @ref method_type_sptr if @p t is a
10432 /// method_type, null otherwise.
10433 method_type_sptr
is_method_type(const type_or_decl_base_sptr & t)10434 is_method_type(const type_or_decl_base_sptr& t)
10435 {return dynamic_pointer_cast<method_type>(t);}
10436
10437 /// Test whether a type is a method_type.
10438 ///
10439 /// @param t the type to test.
10440 ///
10441 /// @return the @ref method_type_sptr if @p t is a
10442 /// method_type, null otherwise.
10443 const method_type*
is_method_type(const type_or_decl_base * t)10444 is_method_type(const type_or_decl_base* t)
10445 {return dynamic_cast<const method_type*>(t);}
10446
10447 /// Test whether a type is a method_type.
10448 ///
10449 /// @param t the type to test.
10450 ///
10451 /// @return the @ref method_type_sptr if @p t is a
10452 /// method_type, null otherwise.
10453 method_type*
is_method_type(type_or_decl_base * t)10454 is_method_type(type_or_decl_base* t)
10455 {return dynamic_cast<method_type*>(t);}
10456
10457 /// If a class (or union) is a decl-only class, get its definition.
10458 /// Otherwise, just return the initial class.
10459 ///
10460 /// @param the_class the class (or union) to consider.
10461 ///
10462 /// @return either the definition of the class, or the class itself.
10463 class_or_union*
look_through_decl_only_class(class_or_union * the_class)10464 look_through_decl_only_class(class_or_union* the_class)
10465 {return is_class_or_union_type(look_through_decl_only(the_class));}
10466
10467 /// If a class (or union) is a decl-only class, get its definition.
10468 /// Otherwise, just return the initial class.
10469 ///
10470 /// @param the_class the class (or union) to consider.
10471 ///
10472 /// @return either the definition of the class, or the class itself.
10473 class_or_union_sptr
look_through_decl_only_class(const class_or_union & the_class)10474 look_through_decl_only_class(const class_or_union& the_class)
10475 {return is_class_or_union_type(look_through_decl_only(the_class));}
10476
10477 /// If a class (or union) is a decl-only class, get its definition.
10478 /// Otherwise, just return the initial class.
10479 ///
10480 /// @param klass the class (or union) to consider.
10481 ///
10482 /// @return either the definition of the class, or the class itself.
10483 class_or_union_sptr
look_through_decl_only_class(class_or_union_sptr klass)10484 look_through_decl_only_class(class_or_union_sptr klass)
10485 {return is_class_or_union_type(look_through_decl_only(klass));}
10486
10487 /// If an enum is a decl-only enum, get its definition.
10488 /// Otherwise, just return the initial enum.
10489 ///
10490 /// @param the_enum the enum to consider.
10491 ///
10492 /// @return either the definition of the enum, or the enum itself.
10493 enum_type_decl_sptr
look_through_decl_only_enum(const enum_type_decl & the_enum)10494 look_through_decl_only_enum(const enum_type_decl& the_enum)
10495 {return is_enum_type(look_through_decl_only(the_enum));}
10496
10497 /// If an enum is a decl-only enum, get its definition.
10498 /// Otherwise, just return the initial enum.
10499 ///
10500 /// @param enom the enum to consider.
10501 ///
10502 /// @return either the definition of the enum, or the enum itself.
10503 enum_type_decl_sptr
look_through_decl_only_enum(enum_type_decl_sptr enom)10504 look_through_decl_only_enum(enum_type_decl_sptr enom)
10505 {return is_enum_type(look_through_decl_only(enom));}
10506
10507 /// If a decl is decl-only get its definition. Otherwise, just return nil.
10508 ///
10509 /// @param d the decl to consider.
10510 ///
10511 /// @return either the definition of the decl, or nil.
10512 decl_base_sptr
look_through_decl_only(const decl_base & d)10513 look_through_decl_only(const decl_base& d)
10514 {
10515 decl_base_sptr decl;
10516 if (d.get_is_declaration_only())
10517 decl = d.get_definition_of_declaration();
10518
10519 if (!decl)
10520 return decl;
10521
10522 while (decl->get_is_declaration_only()
10523 && decl->get_definition_of_declaration())
10524 decl = decl->get_definition_of_declaration();
10525
10526 return decl;
10527 }
10528
10529 /// If a decl is decl-only enum, get its definition. Otherwise, just
10530 /// return the initial decl.
10531 ///
10532 /// @param d the decl to consider.
10533 ///
10534 /// @return either the definition of the enum, or the decl itself.
10535 decl_base*
look_through_decl_only(decl_base * d)10536 look_through_decl_only(decl_base* d)
10537 {
10538 if (!d)
10539 return d;
10540
10541 decl_base* result = look_through_decl_only(*d).get();
10542 if (!result)
10543 result = d;
10544
10545 return result;
10546 }
10547
10548 /// If a decl is decl-only get its definition. Otherwise, just return nil.
10549 ///
10550 /// @param d the decl to consider.
10551 ///
10552 /// @return either the definition of the decl, or nil.
10553 decl_base_sptr
look_through_decl_only(const decl_base_sptr & d)10554 look_through_decl_only(const decl_base_sptr& d)
10555 {
10556 if (!d)
10557 return d;
10558
10559 decl_base_sptr result = look_through_decl_only(*d);
10560 if (!result)
10561 result = d;
10562
10563 return result;
10564 }
10565
10566 /// If a type is is decl-only, then get its definition. Otherwise,
10567 /// just return the initial type.
10568 ///
10569 /// @param d the decl to consider.
10570 ///
10571 /// @return either the definition of the decl, or the initial type.
10572 type_base*
look_through_decl_only(type_base * t)10573 look_through_decl_only(type_base* t)
10574 {
10575 decl_base* d = is_decl(t);
10576 if (!d)
10577 return t;
10578 d = look_through_decl_only(d);
10579 return is_type(d);
10580 }
10581
10582 /// If a type is is decl-only, then get its definition. Otherwise,
10583 /// just return the initial type.
10584 ///
10585 /// @param d the decl to consider.
10586 ///
10587 /// @return either the definition of the decl, or the initial type.
10588 type_base_sptr
look_through_decl_only(const type_base_sptr & t)10589 look_through_decl_only(const type_base_sptr& t)
10590 {
10591 decl_base_sptr d = is_decl(t);
10592 if (!d)
10593 return t;
10594 d = look_through_decl_only(d);
10595 return is_type(d);
10596 }
10597
10598 /// Tests if a declaration is a variable declaration.
10599 ///
10600 /// @param decl the decl to test.
10601 ///
10602 /// @return the var_decl_sptr iff decl is a variable declaration; nil
10603 /// otherwise.
10604 var_decl*
is_var_decl(const type_or_decl_base * tod)10605 is_var_decl(const type_or_decl_base* tod)
10606 {return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
10607
10608 /// Tests if a declaration is a variable declaration.
10609 ///
10610 /// @param decl the decl to test.
10611 ///
10612 /// @return the var_decl_sptr iff decl is a variable declaration; nil
10613 /// otherwise.
10614 var_decl_sptr
is_var_decl(const type_or_decl_base_sptr & decl)10615 is_var_decl(const type_or_decl_base_sptr& decl)
10616 {return dynamic_pointer_cast<var_decl>(decl);}
10617
10618 /// Tests if a declaration is a namespace declaration.
10619 ///
10620 /// @param d the decalration to consider.
10621 ///
10622 /// @return the namespace declaration if @p d is a namespace.
10623 namespace_decl_sptr
is_namespace(const decl_base_sptr & d)10624 is_namespace(const decl_base_sptr& d)
10625 {return dynamic_pointer_cast<namespace_decl>(d);}
10626
10627 /// Tests if a declaration is a namespace declaration.
10628 ///
10629 /// @param d the decalration to consider.
10630 ///
10631 /// @return the namespace declaration if @p d is a namespace.
10632 namespace_decl*
is_namespace(const decl_base * d)10633 is_namespace(const decl_base* d)
10634 {return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
10635
10636 /// Tests whether a decl is a template parameter composition type.
10637 ///
10638 /// @param decl the declaration to consider.
10639 ///
10640 /// @return true iff decl is a template parameter composition type.
10641 bool
is_template_parm_composition_type(const shared_ptr<decl_base> decl)10642 is_template_parm_composition_type(const shared_ptr<decl_base> decl)
10643 {
10644 return (decl
10645 && is_at_template_scope(decl)
10646 && is_type(decl)
10647 && !is_template_parameter(decl));
10648 }
10649
10650 /// Test whether a decl is the pattern of a function template.
10651 ///
10652 /// @param decl the decl to consider.
10653 ///
10654 /// @return true iff decl is the pattern of a function template.
10655 bool
is_function_template_pattern(const shared_ptr<decl_base> decl)10656 is_function_template_pattern(const shared_ptr<decl_base> decl)
10657 {
10658 return (decl
10659 && dynamic_pointer_cast<function_decl>(decl)
10660 && dynamic_cast<template_decl*>(decl->get_scope()));
10661 }
10662
10663 /// Test if a type is an array_type_def.
10664 ///
10665 /// @param type the type to consider.
10666 ///
10667 /// @return true iff @p type is an array_type_def.
10668 array_type_def*
is_array_type(const type_or_decl_base * type)10669 is_array_type(const type_or_decl_base* type)
10670 {return dynamic_cast<array_type_def*>(const_cast<type_or_decl_base*>(type));}
10671
10672 /// Test if a type is an array_type_def.
10673 ///
10674 /// @param type the type to consider.
10675 ///
10676 /// @return true iff @p type is an array_type_def.
10677 array_type_def_sptr
is_array_type(const type_or_decl_base_sptr & type)10678 is_array_type(const type_or_decl_base_sptr& type)
10679 {return dynamic_pointer_cast<array_type_def>(type);}
10680
10681 /// Tests if the element of a given array is a qualified type.
10682 ///
10683 /// @param array the array type to consider.
10684 ///
10685 /// @return the qualified element of the array iff it's a qualified
10686 /// type. Otherwise, return a nil object.
10687 qualified_type_def_sptr
is_array_of_qualified_element(const array_type_def_sptr & array)10688 is_array_of_qualified_element(const array_type_def_sptr& array)
10689 {
10690 if (!array)
10691 return qualified_type_def_sptr();
10692
10693 return is_qualified_type(array->get_element_type());
10694 }
10695
10696 /// Test if an array type is an array to a qualified element type.
10697 ///
10698 /// @param type the array type to consider.
10699 ///
10700 /// @return true the array @p type iff it's an array to a qualified
10701 /// element type.
10702 array_type_def_sptr
is_array_of_qualified_element(const type_base_sptr & type)10703 is_array_of_qualified_element(const type_base_sptr& type)
10704 {
10705 if (array_type_def_sptr array = is_array_type(type))
10706 if (is_array_of_qualified_element(array))
10707 return array;
10708
10709 return array_type_def_sptr();
10710 }
10711
10712 /// Test if a type is a typedef of an array.
10713 ///
10714 /// Note that the function looks through qualified and typedefs types
10715 /// of the underlying type of the current typedef. In other words, if
10716 /// we are looking at a typedef of a CV-qualified array, or at a
10717 /// typedef of a CV-qualified typedef of an array, this function will
10718 /// still return TRUE.
10719 ///
10720 /// @param t the type to consider.
10721 ///
10722 /// @return true if t is a typedef which underlying type is an array.
10723 /// That array might be either cv-qualified array or a typedef'ed
10724 /// array, or a combination of both.
10725 array_type_def_sptr
is_typedef_of_array(const type_base_sptr & t)10726 is_typedef_of_array(const type_base_sptr& t)
10727 {
10728 array_type_def_sptr result;
10729
10730 if (typedef_decl_sptr typdef = is_typedef(t))
10731 {
10732 type_base_sptr u =
10733 peel_qualified_or_typedef_type(typdef->get_underlying_type());
10734 result = is_array_type(u);
10735 }
10736
10737 return result;
10738 }
10739
10740 /// Test if a type is an array_type_def::subrange_type.
10741 ///
10742 /// @param type the type to consider.
10743 ///
10744 /// @return the array_type_def::subrange_type which @p type is a type
10745 /// of, or nil if it's not of that type.
10746 array_type_def::subrange_type*
is_subrange_type(const type_or_decl_base * type)10747 is_subrange_type(const type_or_decl_base *type)
10748 {
10749 return dynamic_cast<array_type_def::subrange_type*>
10750 (const_cast<type_or_decl_base*>(type));
10751 }
10752
10753 /// Test if a type is an array_type_def::subrange_type.
10754 ///
10755 /// @param type the type to consider.
10756 ///
10757 /// @return the array_type_def::subrange_type which @p type is a type
10758 /// of, or nil if it's not of that type.
10759 array_type_def::subrange_sptr
is_subrange_type(const type_or_decl_base_sptr & type)10760 is_subrange_type(const type_or_decl_base_sptr &type)
10761 {return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
10762
10763 /// Tests whether a decl is a template.
10764 ///
10765 /// @param decl the decl to consider.
10766 ///
10767 /// @return true iff decl is a function template, class template, or
10768 /// template template parameter.
10769 bool
is_template_decl(const shared_ptr<decl_base> decl)10770 is_template_decl(const shared_ptr<decl_base> decl)
10771 {return decl && dynamic_pointer_cast<template_decl>(decl);}
10772
10773 /// This enum describe the kind of entity to lookup, while using the
10774 /// lookup API.
10775 enum lookup_entity_kind
10776 {
10777 LOOKUP_ENTITY_TYPE,
10778 LOOKUP_ENTITY_VAR,
10779 };
10780
10781 /// Find the first relevant delimiter (the "::" string) in a fully
10782 /// qualified C++ type name, starting from a given position. The
10783 /// delimiter returned separates a type name from the name of its
10784 /// context.
10785 ///
10786 /// This is supposed to work correctly on names in cases like this:
10787 ///
10788 /// foo<ns1::name1, ns2::name2>
10789 ///
10790 /// In that case when called with with parameter @p begin set to 0, no
10791 /// delimiter is returned, because the type name in this case is:
10792 /// 'foo<ns1::name1, ns2::name2>'.
10793 ///
10794 /// But in this case:
10795 ///
10796 /// foo<p1, bar::name>::some_type
10797 ///
10798 /// The "::" returned is the one right before 'some_type'.
10799 ///
10800 /// @param fqn the fully qualified name of the type to consider.
10801 ///
10802 /// @param begin the position from which to look for the delimiter.
10803 ///
10804 /// @param delim_pos out parameter. Is set to the position of the
10805 /// delimiter iff the function returned true.
10806 ///
10807 /// @return true iff the function found and returned the delimiter.
10808 static bool
find_next_delim_in_cplus_type(const string & fqn,size_t begin,size_t & delim_pos)10809 find_next_delim_in_cplus_type(const string& fqn,
10810 size_t begin,
10811 size_t& delim_pos)
10812 {
10813 int angle_count = 0;
10814 bool found = false;
10815 size_t i = begin;
10816 for (; i < fqn.size(); ++i)
10817 {
10818 if (fqn[i] == '<')
10819 ++angle_count;
10820 else if (fqn[i] == '>')
10821 --angle_count;
10822 else if (i + 1 < fqn.size()
10823 && !angle_count
10824 && fqn[i] == ':'
10825 && fqn[i+1] == ':')
10826 {
10827 delim_pos = i;
10828 found = true;
10829 break;
10830 }
10831 }
10832 return found;
10833 }
10834
10835 /// Decompose a fully qualified name into the list of its components.
10836 ///
10837 /// @param fqn the fully qualified name to decompose.
10838 ///
10839 /// @param comps the resulting list of component to fill.
10840 void
fqn_to_components(const string & fqn,list<string> & comps)10841 fqn_to_components(const string& fqn,
10842 list<string>& comps)
10843 {
10844 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
10845 do
10846 {
10847 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
10848 comp_end = fqn_size;
10849
10850 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
10851 comps.push_back(comp);
10852
10853 comp_begin = comp_end + 2;
10854 if (comp_begin >= fqn_size)
10855 break;
10856 } while (true);
10857 }
10858
10859 /// Turn a set of qualified name components (that name a type) into a
10860 /// qualified name string.
10861 ///
10862 /// @param comps the name components
10863 ///
10864 /// @return the resulting string, which would be the qualified name of
10865 /// a type.
10866 string
components_to_type_name(const list<string> & comps)10867 components_to_type_name(const list<string>& comps)
10868 {
10869 string result;
10870 for (list<string>::const_iterator c = comps.begin();
10871 c != comps.end();
10872 ++c)
10873 if (c == comps.begin())
10874 result = *c;
10875 else
10876 result += "::" + *c;
10877 return result;
10878 }
10879
10880 /// This predicate returns true if a given container iterator points
10881 /// to the last element of the container, false otherwise.
10882 ///
10883 /// @tparam T the type of the container of the iterator.
10884 ///
10885 /// @param container the container the iterator points into.
10886 ///
10887 /// @param i the iterator to consider.
10888 ///
10889 /// @return true iff the iterator points to the last element of @p
10890 /// container.
10891 template<typename T>
10892 static bool
iterator_is_last(T & container,typename T::const_iterator i)10893 iterator_is_last(T& container,
10894 typename T::const_iterator i)
10895 {
10896 typename T::const_iterator next = i;
10897 ++next;
10898 return (next == container.end());
10899 }
10900
10901 //--------------------------------
10902 // <type and decls lookup stuff>
10903 // ------------------------------
10904
10905 /// Lookup all the type*s* that have a given fully qualified name.
10906 ///
10907 /// @param type_name the fully qualified name of the type to
10908 /// lookup.
10909 ///
10910 /// @param type_map the map to look into.
10911 ///
10912 /// @return the vector containing the types named @p type_name. If
10913 /// the lookup didn't yield any type, then this function returns nil.
10914 static const type_base_wptrs_type*
lookup_types_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)10915 lookup_types_in_map(const interned_string& type_name,
10916 const istring_type_base_wptrs_map_type& type_map)
10917 {
10918 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
10919 if (i != type_map.end())
10920 return &i->second;
10921 return 0;
10922 }
10923
10924 /// Lookup a type (with a given name) in a map that associates a type
10925 /// name to a type. If there are several types with a given name,
10926 /// then try to return the first one that is not decl-only.
10927 /// Otherwise, return the last of such types, that is, the last one
10928 /// that got registered.
10929 ///
10930 /// @tparam TypeKind the type of the type this function is supposed to
10931 /// return.
10932 ///
10933 /// @param type_name the name of the type to lookup.
10934 ///
10935 /// @param type_map the map in which to look.
10936 ///
10937 /// @return a shared_ptr to the type found. If no type was found or
10938 /// if the type found was not of type @p TypeKind then the function
10939 /// returns nil.
10940 template <class TypeKind>
10941 static shared_ptr<TypeKind>
lookup_type_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)10942 lookup_type_in_map(const interned_string& type_name,
10943 const istring_type_base_wptrs_map_type& type_map)
10944 {
10945 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
10946 if (i != type_map.end())
10947 {
10948 // Walk the types that have the name "type_name" and return the
10949 // first one that is not declaration-only ...
10950 for (auto j : i->second)
10951 {
10952 type_base_sptr t(j);
10953 decl_base_sptr d = is_decl(t);
10954 if (d && !d->get_is_declaration_only())
10955 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
10956 }
10957 // ... or return the last type with the name "type_name" that
10958 // was recorded. It's likely to be declaration-only if we
10959 // reached this point.
10960 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
10961 }
10962 return shared_ptr<TypeKind>();
10963 }
10964
10965 /// Lookup a basic type from a translation unit.
10966 ///
10967 /// This is done by looking the type up in the type map that is
10968 /// maintained in the translation unit. So this is as fast as
10969 /// possible.
10970 ///
10971 /// @param type_name the name of the basic type to look for.
10972 ///
10973 /// @param tu the translation unit to look into.
10974 ///
10975 /// @return the basic type found or nil if no basic type was found.
10976 type_decl_sptr
lookup_basic_type(const interned_string & type_name,const translation_unit & tu)10977 lookup_basic_type(const interned_string& type_name, const translation_unit& tu)
10978 {
10979 return lookup_type_in_map<type_decl>(type_name,
10980 tu.get_types().basic_types());
10981 }
10982
10983 /// Lookup a basic type from a translation unit.
10984 ///
10985 /// This is done by looking the type up in the type map that is
10986 /// maintained in the translation unit. So this is as fast as
10987 /// possible.
10988 ///
10989 /// @param type_name the name of the basic type to look for.
10990 ///
10991 /// @param tu the translation unit to look into.
10992 ///
10993 /// @return the basic type found or nil if no basic type was found.
10994 type_decl_sptr
lookup_basic_type(const string & type_name,const translation_unit & tu)10995 lookup_basic_type(const string& type_name, const translation_unit& tu)
10996 {
10997 const environment& env = tu.get_environment();
10998
10999 interned_string s = env.intern(type_name);
11000 return lookup_basic_type(s, tu);
11001 }
11002
11003 /// Lookup a class type from a translation unit.
11004 ///
11005 /// This is done by looking the type up in the type map that is
11006 /// maintained in the translation unit. So this is as fast as
11007 /// possible.
11008 ///
11009 /// @param fqn the fully qualified name of the class type node to look
11010 /// up.
11011 ///
11012 /// @param tu the translation unit to perform lookup from.
11013 ///
11014 /// @return the declaration of the class type IR node found, NULL
11015 /// otherwise.
11016 class_decl_sptr
lookup_class_type(const string & fqn,const translation_unit & tu)11017 lookup_class_type(const string& fqn, const translation_unit& tu)
11018 {
11019 const environment& env = tu.get_environment();
11020 interned_string s = env.intern(fqn);
11021 return lookup_class_type(s, tu);
11022 }
11023
11024 /// Lookup a class type from a translation unit.
11025 ///
11026 /// This is done by looking the type up in the type map that is
11027 /// maintained in the translation unit. So this is as fast as
11028 /// possible.
11029 ///
11030 /// @param type_name the name of the class type to look for.
11031 ///
11032 /// @param tu the translation unit to look into.
11033 ///
11034 /// @return the class type found or nil if no class type was found.
11035 class_decl_sptr
lookup_class_type(const interned_string & type_name,const translation_unit & tu)11036 lookup_class_type(const interned_string& type_name, const translation_unit& tu)
11037 {
11038 return lookup_type_in_map<class_decl>(type_name,
11039 tu.get_types().class_types());
11040 }
11041
11042 /// Lookup a union type from a translation unit.
11043 ///
11044 /// This is done by looking the type up in the type map that is
11045 /// maintained in the translation unit. So this is as fast as
11046 /// possible.
11047 ///
11048 /// @param type_name the name of the union type to look for.
11049 ///
11050 /// @param tu the translation unit to look into.
11051 ///
11052 /// @return the union type found or nil if no union type was found.
11053 union_decl_sptr
lookup_union_type(const interned_string & type_name,const translation_unit & tu)11054 lookup_union_type(const interned_string& type_name, const translation_unit& tu)
11055 {
11056 return lookup_type_in_map<union_decl>(type_name,
11057 tu.get_types().union_types());
11058 }
11059
11060 /// Lookup a union type from a translation unit.
11061 ///
11062 /// This is done by looking the type up in the type map that is
11063 /// maintained in the translation unit. So this is as fast as
11064 /// possible.
11065 ///
11066 /// @param fqn the fully qualified name of the type to lookup.
11067 ///
11068 /// @param tu the translation unit to look into.
11069 ///
11070 /// @return the union type found or nil if no union type was found.
11071 union_decl_sptr
lookup_union_type(const string & fqn,const translation_unit & tu)11072 lookup_union_type(const string& fqn, const translation_unit& tu)
11073 {
11074 const environment& env = tu.get_environment();
11075 interned_string s = env.intern(fqn);
11076 return lookup_union_type(s, tu);
11077 }
11078
11079 /// Lookup a union type in a given corpus, from its location.
11080 ///
11081 /// @param loc the location of the union type to look for.
11082 ///
11083 /// @param corp the corpus to look it from.
11084 ///
11085 /// @return the resulting union_decl.
11086 union_decl_sptr
lookup_union_type_per_location(const interned_string & loc,const corpus & corp)11087 lookup_union_type_per_location(const interned_string &loc, const corpus& corp)
11088 {
11089 const istring_type_base_wptrs_map_type& m =
11090 corp.get_type_per_loc_map().union_types();
11091 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
11092
11093 return result;
11094 }
11095
11096 /// Lookup a union type in a given corpus, from its location.
11097 ///
11098 /// @param loc the location of the union type to look for.
11099 ///
11100 /// @param corp the corpus to look it from.
11101 ///
11102 /// @return the resulting union_decl.
11103 union_decl_sptr
lookup_union_type_per_location(const string & loc,const corpus & corp)11104 lookup_union_type_per_location(const string& loc, const corpus& corp)
11105 {
11106 const environment& env = corp.get_environment();
11107 return lookup_union_type_per_location(env.intern(loc), corp);
11108 }
11109
11110 /// Lookup an enum type from a translation unit.
11111 ///
11112 /// This is done by looking the type up in the type map that is
11113 /// maintained in the translation unit. So this is as fast as
11114 /// possible.
11115 ///
11116 /// @param type_name the name of the enum type to look for.
11117 ///
11118 /// @param tu the translation unit to look into.
11119 ///
11120 /// @return the enum type found or nil if no enum type was found.
11121 enum_type_decl_sptr
lookup_enum_type(const interned_string & type_name,const translation_unit & tu)11122 lookup_enum_type(const interned_string& type_name, const translation_unit& tu)
11123 {
11124 return lookup_type_in_map<enum_type_decl>(type_name,
11125 tu.get_types().enum_types());
11126 }
11127
11128 /// Lookup an enum type from a translation unit.
11129 ///
11130 /// This is done by looking the type up in the type map that is
11131 /// maintained in the translation unit. So this is as fast as
11132 /// possible.
11133 ///
11134 /// @param type_name the name of the enum type to look for.
11135 ///
11136 /// @param tu the translation unit to look into.
11137 ///
11138 /// @return the enum type found or nil if no enum type was found.
11139 enum_type_decl_sptr
lookup_enum_type(const string & type_name,const translation_unit & tu)11140 lookup_enum_type(const string& type_name, const translation_unit& tu)
11141 {
11142 const environment& env = tu.get_environment();
11143 interned_string s = env.intern(type_name);
11144 return lookup_enum_type(s, tu);
11145 }
11146
11147 /// Lookup a typedef type from a translation unit.
11148 ///
11149 /// This is done by looking the type up in the type map that is
11150 /// maintained in the translation unit. So this is as fast as
11151 /// possible.
11152 ///
11153 /// @param type_name the name of the typedef type to look for.
11154 ///
11155 /// @param tu the translation unit to look into.
11156 ///
11157 /// @return the typedef type found or nil if no typedef type was
11158 /// found.
11159 typedef_decl_sptr
lookup_typedef_type(const interned_string & type_name,const translation_unit & tu)11160 lookup_typedef_type(const interned_string& type_name,
11161 const translation_unit& tu)
11162 {
11163 return lookup_type_in_map<typedef_decl>(type_name,
11164 tu.get_types().typedef_types());
11165 }
11166
11167 /// Lookup a typedef type from a translation unit.
11168 ///
11169 /// This is done by looking the type up in the type map that is
11170 /// maintained in the translation unit. So this is as fast as
11171 /// possible.
11172 ///
11173 /// @param type_name the name of the typedef type to look for.
11174 ///
11175 /// @param tu the translation unit to look into.
11176 ///
11177 /// @return the typedef type found or nil if no typedef type was
11178 /// found.
11179 typedef_decl_sptr
lookup_typedef_type(const string & type_name,const translation_unit & tu)11180 lookup_typedef_type(const string& type_name, const translation_unit& tu)
11181 {
11182 const environment& env = tu.get_environment();
11183 interned_string s = env.intern(type_name);
11184 return lookup_typedef_type(s, tu);
11185 }
11186
11187 /// Lookup a qualified type from a translation unit.
11188 ///
11189 /// This is done by looking the type up in the type map that is
11190 /// maintained in the translation unit. So this is as fast as
11191 /// possible.
11192 ///
11193 /// @param type_name the name of the qualified type to look for.
11194 ///
11195 /// @param tu the translation unit to look into.
11196 ///
11197 /// @return the qualified type found or nil if no qualified type was
11198 /// found.
11199 qualified_type_def_sptr
lookup_qualified_type(const interned_string & type_name,const translation_unit & tu)11200 lookup_qualified_type(const interned_string& type_name,
11201 const translation_unit& tu)
11202 {
11203 const type_maps& m = tu.get_types();
11204 return lookup_type_in_map<qualified_type_def>(type_name,
11205 m.qualified_types());
11206 }
11207
11208 /// Lookup a qualified type from a translation unit.
11209 ///
11210 /// This is done by looking the type up in the type map that is
11211 /// maintained in the translation unit. So this is as fast as
11212 /// possible.
11213 ///
11214 /// @param underlying_type the underying type of the qualified type to
11215 /// look up.
11216 ///
11217 /// @param quals the CV-qualifiers of the qualified type to look for.
11218 ///
11219 /// @param tu the translation unit to look into.
11220 ///
11221 /// @return the qualified type found or nil if no qualified type was
11222 /// found.
11223 qualified_type_def_sptr
lookup_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,const translation_unit & tu)11224 lookup_qualified_type(const type_base_sptr& underlying_type,
11225 qualified_type_def::CV quals,
11226 const translation_unit& tu)
11227 {
11228 interned_string type_name = get_name_of_qualified_type(underlying_type,
11229 quals);
11230 return lookup_qualified_type(type_name, tu);
11231 }
11232
11233 /// Lookup a pointer type from a translation unit.
11234 ///
11235 /// This is done by looking the type up in the type map that is
11236 /// maintained in the translation unit. So this is as fast as
11237 /// possible.
11238 ///
11239 /// @param type_name the name of the pointer type to look for.
11240 ///
11241 /// @param tu the translation unit to look into.
11242 ///
11243 /// @return the pointer type found or nil if no pointer type was
11244 /// found.
11245 pointer_type_def_sptr
lookup_pointer_type(const interned_string & type_name,const translation_unit & tu)11246 lookup_pointer_type(const interned_string& type_name,
11247 const translation_unit& tu)
11248 {
11249 const type_maps& m = tu.get_types();
11250 return lookup_type_in_map<pointer_type_def>(type_name,
11251 m.pointer_types());
11252 }
11253
11254 /// Lookup a pointer type from a translation unit.
11255 ///
11256 /// This is done by looking the type up in the type map that is
11257 /// maintained in the translation unit. So this is as fast as
11258 /// possible.
11259 ///
11260 /// @param type_name the name of the pointer type to look for.
11261 ///
11262 /// @param tu the translation unit to look into.
11263 ///
11264 /// @return the pointer type found or nil if no pointer type was
11265 /// found.
11266 pointer_type_def_sptr
lookup_pointer_type(const string & type_name,const translation_unit & tu)11267 lookup_pointer_type(const string& type_name, const translation_unit& tu)
11268 {
11269 const environment& env = tu.get_environment();
11270 interned_string s = env.intern(type_name);
11271 return lookup_pointer_type(s, tu);
11272 }
11273
11274 /// Lookup a pointer type from a translation unit.
11275 ///
11276 /// This is done by looking the type up in the type map that is
11277 /// maintained in the translation unit. So this is as fast as
11278 /// possible.
11279 ///
11280 /// @param pointed_to_type the pointed-to-type of the pointer to look for.
11281 ///
11282 /// @param tu the translation unit to look into.
11283 ///
11284 /// @return the pointer type found or nil if no pointer type was
11285 /// found.
11286 pointer_type_def_sptr
lookup_pointer_type(const type_base_sptr & pointed_to_type,const translation_unit & tu)11287 lookup_pointer_type(const type_base_sptr& pointed_to_type,
11288 const translation_unit& tu)
11289 {
11290 type_base_sptr t = look_through_decl_only(pointed_to_type);
11291 interned_string type_name = get_name_of_pointer_to_type(*t);
11292 return lookup_pointer_type(type_name, tu);
11293 }
11294
11295 /// Lookup a reference type from a translation unit.
11296 ///
11297 /// This is done by looking the type up in the type map that is
11298 /// maintained in the translation unit. So this is as fast as
11299 /// possible.
11300 ///
11301 /// @param type_name the name of the reference type to look for.
11302 ///
11303 /// @param tu the translation unit to look into.
11304 ///
11305 /// @return the reference type found or nil if no reference type was
11306 /// found.
11307 reference_type_def_sptr
lookup_reference_type(const interned_string & type_name,const translation_unit & tu)11308 lookup_reference_type(const interned_string& type_name,
11309 const translation_unit& tu)
11310 {
11311 const type_maps& m = tu.get_types();
11312 return lookup_type_in_map<reference_type_def>(type_name,
11313 m.reference_types());
11314 }
11315
11316 /// Lookup a reference type from a translation unit.
11317 ///
11318 /// This is done by looking the type up in the type map that is
11319 /// maintained in the translation unit. So this is as fast as
11320 /// possible.
11321 ///
11322 /// @param pointed_to_type the pointed-to-type of the reference to
11323 /// look up.
11324 ///
11325 /// @param tu the translation unit to look into.
11326 ///
11327 /// @return the reference type found or nil if no reference type was
11328 /// found.
11329 const reference_type_def_sptr
lookup_reference_type(const type_base_sptr & pointed_to_type,bool lvalue_reference,const translation_unit & tu)11330 lookup_reference_type(const type_base_sptr& pointed_to_type,
11331 bool lvalue_reference,
11332 const translation_unit& tu)
11333 {
11334 interned_string type_name =
11335 get_name_of_reference_to_type(*look_through_decl_only(pointed_to_type),
11336 lvalue_reference);
11337 return lookup_reference_type(type_name, tu);
11338 }
11339
11340 /// Lookup an array type from a translation unit.
11341 ///
11342 /// This is done by looking the type up in the type map that is
11343 /// maintained in the translation unit. So this is as fast as
11344 /// possible.
11345 ///
11346 /// @param type_name the name of the array type to look for.
11347 ///
11348 /// @param tu the translation unit to look into.
11349 ///
11350 /// @return the array type found or nil if no array type was found.
11351 array_type_def_sptr
lookup_array_type(const interned_string & type_name,const translation_unit & tu)11352 lookup_array_type(const interned_string& type_name,
11353 const translation_unit& tu)
11354 {
11355 const type_maps& m = tu.get_types();
11356 return lookup_type_in_map<array_type_def>(type_name,
11357 m.array_types());
11358 }
11359
11360 /// Lookup a function type from a translation unit.
11361 ///
11362 /// This is done by looking the type up in the type map that is
11363 /// maintained in the translation unit. So this is as fast as
11364 /// possible.
11365 ///
11366 /// @param type_name the name of the type to lookup.
11367 ///
11368 /// @param tu the translation unit to look into.
11369 ///
11370 /// @return the function type found, or NULL of none was found.
11371 function_type_sptr
lookup_function_type(const interned_string & type_name,const translation_unit & tu)11372 lookup_function_type(const interned_string& type_name,
11373 const translation_unit& tu)
11374 {
11375 const type_maps& m = tu.get_types();
11376 return lookup_type_in_map<function_type>(type_name,
11377 m.function_types());
11378 }
11379
11380 /// Lookup a function type from a translation unit.
11381 ///
11382 /// This walks all the function types held by the translation unit and
11383 /// compare their sub-type *names*. If the names match then return
11384 /// the function type found in the translation unit.
11385 ///
11386 /// @param t the function type to look for.
11387 ///
11388 /// @param tu the translation unit to look into.
11389 ///
11390 /// @return the function type found, or NULL of none was found.
11391 function_type_sptr
lookup_function_type(const function_type & t,const translation_unit & tu)11392 lookup_function_type(const function_type& t,
11393 const translation_unit& tu)
11394 {
11395 interned_string type_name = get_type_name(t);
11396 return lookup_function_type(type_name, tu);
11397 }
11398
11399 /// Lookup a function type from a translation unit.
11400 ///
11401 /// This is done by looking the type up in the type map that is
11402 /// maintained in the translation unit. So this is as fast as
11403 /// possible.
11404 ///
11405 /// @param t the function type to look for.
11406 ///
11407 /// @param tu the translation unit to look into.
11408 ///
11409 /// @return the function type found, or NULL of none was found.
11410 function_type_sptr
lookup_function_type(const function_type_sptr & t,const translation_unit & tu)11411 lookup_function_type(const function_type_sptr& t,
11412 const translation_unit& tu)
11413 {return lookup_function_type(*t, tu);}
11414
11415 /// Lookup a type in a translation unit.
11416 ///
11417 /// @param fqn the fully qualified name of the type to lookup.
11418 ///
11419 /// @param tu the translation unit to consider.
11420 ///
11421 /// @return the declaration of the type if found, NULL otherwise.
11422 const type_base_sptr
lookup_type(const interned_string & fqn,const translation_unit & tu)11423 lookup_type(const interned_string& fqn,
11424 const translation_unit& tu)
11425 {
11426 type_base_sptr result;
11427 ((result = lookup_typedef_type(fqn, tu))
11428 || (result = lookup_class_type(fqn, tu))
11429 || (result = lookup_union_type(fqn, tu))
11430 || (result = lookup_enum_type(fqn, tu))
11431 || (result = lookup_qualified_type(fqn, tu))
11432 || (result = lookup_pointer_type(fqn, tu))
11433 || (result = lookup_reference_type(fqn, tu))
11434 || (result = lookup_array_type(fqn, tu))
11435 || (result = lookup_function_type(fqn, tu))
11436 || (result = lookup_basic_type(fqn, tu)));
11437
11438 return result;
11439 }
11440
11441 /// Lookup a type in a translation unit, starting from the global
11442 /// namespace.
11443 ///
11444 /// @param fqn the fully qualified name of the type to lookup.
11445 ///
11446 /// @param tu the translation unit to consider.
11447 ///
11448 /// @return the declaration of the type if found, NULL otherwise.
11449 type_base_sptr
lookup_type(const string & fqn,const translation_unit & tu)11450 lookup_type(const string& fqn, const translation_unit& tu)
11451 {
11452 const environment&env = tu.get_environment();
11453 interned_string ifqn = env.intern(fqn);
11454 return lookup_type(ifqn, tu);
11455 }
11456
11457 /// Lookup a type from a translation unit.
11458 ///
11459 /// @param fqn the components of the fully qualified name of the node
11460 /// to look up.
11461 ///
11462 /// @param tu the translation unit to perform lookup from.
11463 ///
11464 /// @return the declaration of the IR node found, NULL otherwise.
11465 const type_base_sptr
lookup_type(const type_base_sptr type,const translation_unit & tu)11466 lookup_type(const type_base_sptr type,
11467 const translation_unit& tu)
11468 {
11469 interned_string type_name = get_type_name(type);
11470 return lookup_type(type_name, tu);
11471 }
11472
11473 /// Lookup a type in a scope.
11474 ///
11475 /// This is really slow as it walks the member types of the scope in
11476 /// sequence to find the type with a given name.
11477 ///
11478 /// If possible, users should prefer looking up types from the
11479 /// enclosing translation unit or even ABI corpus because both the
11480 /// translation unit and the corpus have a map of type, indexed by
11481 /// their name. Looking up a type from those maps is thus much
11482 /// faster.
11483 ///
11484 /// @param fqn the fully qualified name of the type to lookup.
11485 ///
11486 /// @param skope the scope to look into.
11487 ///
11488 /// @return the declaration of the type if found, NULL otherwise.
11489 const type_base_sptr
lookup_type_in_scope(const string & fqn,const scope_decl_sptr & skope)11490 lookup_type_in_scope(const string& fqn,
11491 const scope_decl_sptr& skope)
11492 {
11493 list<string> comps;
11494 fqn_to_components(fqn, comps);
11495 return lookup_type_in_scope(comps, skope);
11496 }
11497
11498 /// Lookup a @ref var_decl in a scope.
11499 ///
11500 /// @param fqn the fuly qualified name of the @var_decl to lookup.
11501 ///
11502 /// @param skope the scope to look into.
11503 ///
11504 /// @return the declaration of the @ref var_decl if found, NULL
11505 /// otherwise.
11506 const decl_base_sptr
lookup_var_decl_in_scope(const string & fqn,const scope_decl_sptr & skope)11507 lookup_var_decl_in_scope(const string& fqn,
11508 const scope_decl_sptr& skope)
11509 {
11510 list<string> comps;
11511 fqn_to_components(fqn, comps);
11512 return lookup_var_decl_in_scope(comps, skope);
11513 }
11514
11515 /// A generic function (template) to get the name of a node, whatever
11516 /// node it is. This has to be specialized for the kind of node we
11517 /// want.
11518 ///
11519 /// Note that a node is a member of a scope.
11520 ///
11521 /// @tparam NodeKind the kind of node to consider.
11522 ///
11523 /// @param node the node to get the name from.
11524 ///
11525 /// @return the name of the node.
11526 template<typename NodeKind>
11527 static const interned_string&
11528 get_node_name(shared_ptr<NodeKind> node);
11529
11530 /// Gets the name of a class_decl node.
11531 ///
11532 /// @param node the decl_base node to get the name from.
11533 ///
11534 /// @return the name of the node.
11535 template<>
11536 const interned_string&
get_node_name(class_decl_sptr node)11537 get_node_name(class_decl_sptr node)
11538 {return node->get_name();}
11539
11540 /// Gets the name of a type_base node.
11541 ///
11542 /// @param node the type_base node to get the name from.
11543 ///
11544 /// @return the name of the node.
11545 template<>
11546 const interned_string&
get_node_name(type_base_sptr node)11547 get_node_name(type_base_sptr node)
11548 {return get_type_declaration(node)->get_name();}
11549
11550 /// Gets the name of a var_decl node.
11551 ///
11552 /// @param node the var_decl node to get the name from.
11553 ///
11554 /// @return the name of the node.
11555 template<>
11556 const interned_string&
get_node_name(var_decl_sptr node)11557 get_node_name(var_decl_sptr node)
11558 {return node->get_name();}
11559
11560 /// Generic function to get the declaration of a given node, whatever
11561 /// it is. There has to be specializations for the kind of the nodes
11562 /// we want to support.
11563 ///
11564 /// @tparam NodeKind the type of the node we are looking at.
11565 ///
11566 /// @return the declaration.
11567 template<typename NodeKind>
11568 static decl_base_sptr
11569 convert_node_to_decl(shared_ptr<NodeKind> node);
11570
11571 /// Lookup a node in a given scope.
11572 ///
11573 /// @tparam the type of the node to lookup.
11574 ///
11575 /// @param fqn the components of the fully qualified name of the node
11576 /// to lookup.
11577 ///
11578 /// @param skope the scope to look into.
11579 ///
11580 /// @return the declaration of the looked up node, or NULL if it
11581 /// wasn't found.
11582 template<typename NodeKind>
11583 static const type_or_decl_base_sptr
lookup_node_in_scope(const list<string> & fqn,const scope_decl_sptr & skope)11584 lookup_node_in_scope(const list<string>& fqn,
11585 const scope_decl_sptr& skope)
11586 {
11587 type_or_decl_base_sptr resulting_decl;
11588 shared_ptr<NodeKind> node;
11589 bool it_is_last = false;
11590 scope_decl_sptr cur_scope = skope, new_scope, scope;
11591
11592 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
11593 {
11594 new_scope.reset();
11595 it_is_last = iterator_is_last(fqn, c);
11596 for (scope_decl::declarations::const_iterator m =
11597 cur_scope->get_member_decls().begin();
11598 m != cur_scope->get_member_decls().end();
11599 ++m)
11600 {
11601 if (!it_is_last)
11602 {
11603 // looking for a scope
11604 scope = dynamic_pointer_cast<scope_decl>(*m);
11605 if (scope && scope->get_name() == *c)
11606 {
11607 new_scope = scope;
11608 break;
11609 }
11610 }
11611 else
11612 {
11613 //looking for a final type.
11614 node = dynamic_pointer_cast<NodeKind>(*m);
11615 if (node && get_node_name(node) == *c)
11616 {
11617 if (class_decl_sptr cl =
11618 dynamic_pointer_cast<class_decl>(node))
11619 if (cl->get_is_declaration_only()
11620 && !cl->get_definition_of_declaration())
11621 continue;
11622 resulting_decl = node;
11623 break;
11624 }
11625 }
11626 }
11627 if (!new_scope && !resulting_decl)
11628 return decl_base_sptr();
11629 cur_scope = new_scope;
11630 }
11631 ABG_ASSERT(resulting_decl);
11632 return resulting_decl;
11633 }
11634
11635 /// lookup a type in a scope.
11636 ///
11637 ///
11638 /// This is really slow as it walks the member types of the scope in
11639 /// sequence to find the type with a given name.
11640 ///
11641 /// If possible, users should prefer looking up types from the
11642 /// enclosing translation unit or even ABI corpus because both the
11643 /// translation unit and the corpus have a map of type, indexed by
11644 /// their name. Looking up a type from those maps is thus much
11645 /// faster.
11646 ///
11647 /// @param comps the components of the fully qualified name of the
11648 /// type to lookup.
11649 ///
11650 /// @param skope the scope to look into.
11651 ///
11652 /// @return the declaration of the type found.
11653 const type_base_sptr
lookup_type_in_scope(const list<string> & comps,const scope_decl_sptr & scope)11654 lookup_type_in_scope(const list<string>& comps,
11655 const scope_decl_sptr& scope)
11656 {return is_type(lookup_node_in_scope<type_base>(comps, scope));}
11657
11658 /// lookup a type in a scope.
11659 ///
11660 /// This is really slow as it walks the member types of the scope in
11661 /// sequence to find the type with a given name.
11662 ///
11663 /// If possible, users should prefer looking up types from the
11664 /// enclosing translation unit or even ABI corpus because both the
11665 /// translation unit and the corpus have a map of type, indexed by
11666 /// their name. Looking up a type from those maps is thus much
11667 /// faster.
11668 ///
11669 /// @param type the type to look for.
11670 ///
11671 /// @param access_path a vector of scopes the path of scopes to follow
11672 /// before reaching the scope into which to look for @p type. Note
11673 /// that the deepest scope (the one immediately containing @p type) is
11674 /// at index 0 of this vector, and the top-most scope is the last
11675 /// element of the vector.
11676 ///
11677 /// @param scope the top-most scope into which to look for @p type.
11678 ///
11679 /// @return the scope found in @p scope, or NULL if it wasn't found.
11680 static const type_base_sptr
lookup_type_in_scope(const type_base & type,const vector<scope_decl * > & access_path,const scope_decl * scope)11681 lookup_type_in_scope(const type_base& type,
11682 const vector<scope_decl*>& access_path,
11683 const scope_decl* scope)
11684 {
11685 vector<scope_decl*> a = access_path;
11686 type_base_sptr result;
11687
11688 scope_decl* first_scope = 0;
11689 if (!a.empty())
11690 {
11691 first_scope = a.back();
11692 ABG_ASSERT(first_scope->get_name() == scope->get_name());
11693 a.pop_back();
11694 }
11695
11696 if (a.empty())
11697 {
11698 interned_string n = get_type_name(type, false);
11699 for (scope_decl::declarations::const_iterator i =
11700 scope->get_member_decls().begin();
11701 i != scope->get_member_decls().end();
11702 ++i)
11703 if (is_type(*i) && (*i)->get_name() == n)
11704 {
11705 result = is_type(*i);
11706 break;
11707 }
11708 }
11709 else
11710 {
11711 first_scope = a.back();
11712 interned_string scope_name, cur_scope_name = first_scope->get_name();
11713 for (scope_decl::scopes::const_iterator i =
11714 scope->get_member_scopes().begin();
11715 i != scope->get_member_scopes().end();
11716 ++i)
11717 {
11718 scope_name = (*i)->get_name();
11719 if (scope_name == cur_scope_name)
11720 {
11721 result = lookup_type_in_scope(type, a, (*i).get());
11722 break;
11723 }
11724 }
11725 }
11726 return result;
11727 }
11728
11729 /// lookup a type in a scope.
11730 ///
11731 /// This is really slow as it walks the member types of the scope in
11732 /// sequence to find the type with a given name.
11733 ///
11734 /// If possible, users should prefer looking up types from the
11735 /// enclosing translation unit or even ABI corpus because both the
11736 /// translation unit and the corpus have a map of type, indexed by
11737 /// their name. Looking up a type from those maps is thus much
11738 /// faster.
11739 ///
11740 /// @param type the type to look for.
11741 ///
11742 /// @param scope the top-most scope into which to look for @p type.
11743 ///
11744 /// @return the scope found in @p scope, or NULL if it wasn't found.
11745 static const type_base_sptr
lookup_type_in_scope(const type_base_sptr type,const scope_decl * scope)11746 lookup_type_in_scope(const type_base_sptr type,
11747 const scope_decl* scope)
11748 {
11749 if (!type || is_function_type(type))
11750 return type_base_sptr();
11751
11752 decl_base_sptr type_decl = get_type_declaration(type);
11753 ABG_ASSERT(type_decl);
11754 vector<scope_decl*> access_path;
11755 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
11756 {
11757 access_path.push_back(s);
11758 if (is_global_scope(s))
11759 break;
11760 }
11761 return lookup_type_in_scope(*type, access_path, scope);
11762 }
11763
11764 /// Lookup a type from a translation unit by walking the scopes of the
11765 /// translation unit in sequence and looking into them.
11766 ///
11767 /// This is really slow as it walks the member types of the scopes in
11768 /// sequence to find the type with a given name.
11769 ///
11770 /// If possible, users should prefer looking up types from the
11771 /// translation unit or even ABI corpus in a more direct way, by using
11772 /// the lookup_type() functins.
11773 ///
11774 ///
11775 /// This is because both the translation unit and the corpus have a
11776 /// map of types, indexed by their name. Looking up a type from those
11777 /// maps is thus much faster. @param fqn the components of the fully
11778 /// qualified name of the node to look up.
11779 ///
11780 /// @param tu the translation unit to perform lookup from.
11781 ///
11782 /// @return the declaration of the IR node found, NULL otherwise.
11783 const type_base_sptr
lookup_type_through_scopes(const type_base_sptr type,const translation_unit & tu)11784 lookup_type_through_scopes(const type_base_sptr type,
11785 const translation_unit& tu)
11786 {
11787 if (function_type_sptr fn_type = is_function_type(type))
11788 return lookup_function_type(fn_type, tu);
11789 return lookup_type_in_scope(type, tu.get_global_scope().get());
11790 }
11791
11792 /// lookup a var_decl in a scope.
11793 ///
11794 /// @param comps the components of the fully qualified name of the
11795 /// var_decl to lookup.
11796 ///
11797 /// @param skope the scope to look into.
11798 const decl_base_sptr
lookup_var_decl_in_scope(const std::list<string> & comps,const scope_decl_sptr & skope)11799 lookup_var_decl_in_scope(const std::list<string>& comps,
11800 const scope_decl_sptr& skope)
11801 {return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
11802
11803 /// Lookup an IR node from a translation unit.
11804 ///
11805 /// @tparam NodeKind the type of the IR node to lookup from the
11806 /// translation unit.
11807 ///
11808 /// @param fqn the components of the fully qualified name of the node
11809 /// to look up.
11810 ///
11811 /// @param tu the translation unit to perform lookup from.
11812 ///
11813 /// @return the declaration of the IR node found, NULL otherwise.
11814 template<typename NodeKind>
11815 static const type_or_decl_base_sptr
lookup_node_in_translation_unit(const list<string> & fqn,const translation_unit & tu)11816 lookup_node_in_translation_unit(const list<string>& fqn,
11817 const translation_unit& tu)
11818 {return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
11819
11820 /// Lookup a type from a translation unit by walking its scopes in
11821 /// sequence and by looking into them.
11822 ///
11823 /// This is much slower than using the lookup_type() function.
11824 ///
11825 /// @param fqn the components of the fully qualified name of the node
11826 /// to look up.
11827 ///
11828 /// @param tu the translation unit to perform lookup from.
11829 ///
11830 /// @return the declaration of the IR node found, NULL otherwise.
11831 type_base_sptr
lookup_type_through_scopes(const list<string> & fqn,const translation_unit & tu)11832 lookup_type_through_scopes(const list<string>& fqn,
11833 const translation_unit& tu)
11834 {return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
11835
11836
11837 /// Lookup a class type from a translation unit by walking its scopes
11838 /// in sequence and by looking into them.
11839 ///
11840 /// This is much slower than using the lookup_class_type() function
11841 /// because it walks all the scopes of the translation unit in
11842 /// sequence and lookup the types to find one that has a given name.
11843 ///
11844 /// @param fqn the components of the fully qualified name of the class
11845 /// type node to look up.
11846 ///
11847 /// @param tu the translation unit to perform lookup from.
11848 ///
11849 /// @return the declaration of the class type IR node found, NULL
11850 /// otherwise.
11851 class_decl_sptr
lookup_class_type_through_scopes(const list<string> & fqn,const translation_unit & tu)11852 lookup_class_type_through_scopes(const list<string>& fqn,
11853 const translation_unit& tu)
11854 {return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
11855
11856 /// Lookup a basic type from all the translation units of a given
11857 /// corpus.
11858 ///
11859 /// @param fqn the components of the fully qualified name of the basic
11860 /// type node to look up.
11861 ///
11862 /// @param tu the translation unit to perform lookup from.
11863 ///
11864 /// @return the declaration of the basic type IR node found, NULL
11865 /// otherwise.
11866 static type_decl_sptr
lookup_basic_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11867 lookup_basic_type_through_translation_units(const interned_string& type_name,
11868 const corpus& abi_corpus)
11869 {
11870 type_decl_sptr result;
11871
11872 for (translation_units::const_iterator tu =
11873 abi_corpus.get_translation_units().begin();
11874 tu != abi_corpus.get_translation_units().end();
11875 ++tu)
11876 if ((result = lookup_basic_type(type_name, **tu)))
11877 break;
11878
11879 return result;
11880 }
11881
11882 /// Lookup a union type from all the translation units of a given
11883 /// corpus.
11884 ///
11885 /// @param fqn the components of the fully qualified name of the union
11886 /// type node to look up.
11887 ///
11888 /// @param tu the translation unit to perform lookup from.
11889 ///
11890 /// @return the declaration of the union type IR node found, NULL
11891 /// otherwise.
11892 static union_decl_sptr
lookup_union_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11893 lookup_union_type_through_translation_units(const interned_string& type_name,
11894 const corpus & abi_corpus)
11895 {
11896 union_decl_sptr result;
11897
11898 for (translation_units::const_iterator tu =
11899 abi_corpus.get_translation_units().begin();
11900 tu != abi_corpus.get_translation_units().end();
11901 ++tu)
11902 if ((result = lookup_union_type(type_name, **tu)))
11903 break;
11904
11905 return result;
11906 }
11907
11908 /// Lookup an enum type from all the translation units of a given
11909 /// corpus.
11910 ///
11911 /// @param fqn the components of the fully qualified name of the enum
11912 /// type node to look up.
11913 ///
11914 /// @param tu the translation unit to perform lookup from.
11915 ///
11916 /// @return the declaration of the enum type IR node found, NULL
11917 /// otherwise.
11918 static enum_type_decl_sptr
lookup_enum_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11919 lookup_enum_type_through_translation_units(const interned_string& type_name,
11920 const corpus & abi_corpus)
11921 {
11922 enum_type_decl_sptr result;
11923
11924 for (translation_units::const_iterator tu =
11925 abi_corpus.get_translation_units().begin();
11926 tu != abi_corpus.get_translation_units().end();
11927 ++tu)
11928 if ((result = lookup_enum_type(type_name, **tu)))
11929 break;
11930
11931 return result;
11932 }
11933
11934 /// Lookup a typedef type definition in all the translation units of a
11935 /// given ABI corpus.
11936 ///
11937 /// @param @param qn the fully qualified name of the typedef type to lookup.
11938 ///
11939 /// @param abi_corpus the ABI corpus which to look the type up in.
11940 ///
11941 /// @return the type definition if any was found, or a NULL pointer.
11942 static typedef_decl_sptr
lookup_typedef_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11943 lookup_typedef_type_through_translation_units(const interned_string& type_name,
11944 const corpus & abi_corpus)
11945 {
11946 typedef_decl_sptr result;
11947
11948 for (translation_units::const_iterator tu =
11949 abi_corpus.get_translation_units().begin();
11950 tu != abi_corpus.get_translation_units().end();
11951 ++tu)
11952 if ((result = lookup_typedef_type(type_name, **tu)))
11953 break;
11954
11955 return result;
11956 }
11957
11958 /// Lookup a qualified type definition in all the translation units of a
11959 /// given ABI corpus.
11960 ///
11961 /// @param @param qn the fully qualified name of the qualified type to
11962 /// lookup.
11963 ///
11964 /// @param abi_corpus the ABI corpus which to look the type up in.
11965 ///
11966 /// @return the type definition if any was found, or a NULL pointer.
11967 static qualified_type_def_sptr
lookup_qualified_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)11968 lookup_qualified_type_through_translation_units(const interned_string& t_name,
11969 const corpus & abi_corpus)
11970 {
11971 qualified_type_def_sptr result;
11972
11973 for (translation_units::const_iterator tu =
11974 abi_corpus.get_translation_units().begin();
11975 tu != abi_corpus.get_translation_units().end();
11976 ++tu)
11977 if ((result = lookup_qualified_type(t_name, **tu)))
11978 break;
11979
11980 return result;
11981 }
11982
11983 /// Lookup a pointer type definition in all the translation units of a
11984 /// given ABI corpus.
11985 ///
11986 /// @param @param qn the fully qualified name of the pointer type to
11987 /// lookup.
11988 ///
11989 /// @param abi_corpus the ABI corpus which to look the type up in.
11990 ///
11991 /// @return the type definition if any was found, or a NULL pointer.
11992 static pointer_type_def_sptr
lookup_pointer_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11993 lookup_pointer_type_through_translation_units(const interned_string& type_name,
11994 const corpus & abi_corpus)
11995 {
11996 pointer_type_def_sptr result;
11997
11998 for (translation_units::const_iterator tu =
11999 abi_corpus.get_translation_units().begin();
12000 tu != abi_corpus.get_translation_units().end();
12001 ++tu)
12002 if ((result = lookup_pointer_type(type_name, **tu)))
12003 break;
12004
12005 return result;
12006 }
12007
12008 /// Lookup a reference type definition in all the translation units of a
12009 /// given ABI corpus.
12010 ///
12011 /// @param @param qn the fully qualified name of the reference type to
12012 /// lookup.
12013 ///
12014 /// @param abi_corpus the ABI corpus which to look the type up in.
12015 ///
12016 /// @return the type definition if any was found, or a NULL pointer.
12017 static reference_type_def_sptr
lookup_reference_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)12018 lookup_reference_type_through_translation_units(const interned_string& t_name,
12019 const corpus & abi_corpus)
12020 {
12021 reference_type_def_sptr result;
12022
12023 for (translation_units::const_iterator tu =
12024 abi_corpus.get_translation_units().begin();
12025 tu != abi_corpus.get_translation_units().end();
12026 ++tu)
12027 if ((result = lookup_reference_type(t_name, **tu)))
12028 break;
12029
12030 return result;
12031 }
12032
12033 /// Lookup a array type definition in all the translation units of a
12034 /// given ABI corpus.
12035 ///
12036 /// @param @param qn the fully qualified name of the array type to
12037 /// lookup.
12038 ///
12039 /// @param abi_corpus the ABI corpus which to look the type up in.
12040 ///
12041 /// @return the type definition if any was found, or a NULL pointer.
12042 static array_type_def_sptr
lookup_array_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12043 lookup_array_type_through_translation_units(const interned_string& type_name,
12044 const corpus & abi_corpus)
12045 {
12046 array_type_def_sptr result;
12047
12048 for (translation_units::const_iterator tu =
12049 abi_corpus.get_translation_units().begin();
12050 tu != abi_corpus.get_translation_units().end();
12051 ++tu)
12052 if ((result = lookup_array_type(type_name, **tu)))
12053 break;
12054
12055 return result;
12056 }
12057
12058 /// Lookup a function type definition in all the translation units of
12059 /// a given ABI corpus.
12060 ///
12061 /// @param @param qn the fully qualified name of the function type to
12062 /// lookup.
12063 ///
12064 /// @param abi_corpus the ABI corpus which to look the type up in.
12065 ///
12066 /// @return the type definition if any was found, or a NULL pointer.
12067 static function_type_sptr
lookup_function_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12068 lookup_function_type_through_translation_units(const interned_string& type_name,
12069 const corpus & abi_corpus)
12070 {
12071 function_type_sptr result;
12072
12073 for (translation_units::const_iterator tu =
12074 abi_corpus.get_translation_units().begin();
12075 tu != abi_corpus.get_translation_units().end();
12076 ++tu)
12077 if ((result = lookup_function_type(type_name, **tu)))
12078 break;
12079
12080 return result;
12081 }
12082
12083 /// Lookup a type definition in all the translation units of a given
12084 /// ABI corpus.
12085 ///
12086 /// @param @param qn the fully qualified name of the type to lookup.
12087 ///
12088 /// @param abi_corpus the ABI corpus which to look the type up in.
12089 ///
12090 /// @return the type definition if any was found, or a NULL pointer.
12091 type_base_sptr
lookup_type_through_translation_units(const string & qn,const corpus & abi_corpus)12092 lookup_type_through_translation_units(const string& qn,
12093 const corpus& abi_corpus)
12094 {
12095 type_base_sptr result;
12096
12097 for (translation_units::const_iterator tu =
12098 abi_corpus.get_translation_units().begin();
12099 tu != abi_corpus.get_translation_units().end();
12100 ++tu)
12101 if ((result = lookup_type(qn, **tu)))
12102 break;
12103
12104 return result;
12105 }
12106
12107 /// Lookup a type from a given translation unit present in a give corpus.
12108 ///
12109 /// @param type_name the name of the type to look for.
12110 ///
12111 /// @parm tu_path the path of the translation unit to consider.
12112 ///
12113 /// @param corp the corpus to consider.
12114 ///
12115 /// @return the resulting type, if any.
12116 type_base_sptr
lookup_type_from_translation_unit(const string & type_name,const string & tu_path,const corpus & corp)12117 lookup_type_from_translation_unit(const string& type_name,
12118 const string& tu_path,
12119 const corpus& corp)
12120 {
12121 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
12122 if (i == corp.priv_->path_tu_map.end())
12123 return type_base_sptr();
12124
12125 translation_unit_sptr tu = i->second;
12126 ABG_ASSERT(tu);
12127
12128 type_base_sptr t = lookup_type(type_name, *tu);
12129 return t;
12130 }
12131
12132 /// Look into an ABI corpus for a function type.
12133 ///
12134 /// @param fn_type the function type to be looked for in the ABI
12135 /// corpus.
12136 ///
12137 /// @param corpus the ABI corpus into which to look for the function
12138 /// type.
12139 ///
12140 /// @return the function type found in the corpus.
12141 function_type_sptr
lookup_or_synthesize_fn_type(const function_type_sptr & fn_t,const corpus & corpus)12142 lookup_or_synthesize_fn_type(const function_type_sptr& fn_t,
12143 const corpus& corpus)
12144 {
12145 ABG_ASSERT(fn_t);
12146
12147 function_type_sptr result;
12148
12149 if ((result = lookup_function_type(fn_t, corpus)))
12150 return result;
12151
12152 for (translation_units::const_iterator i =
12153 corpus.get_translation_units().begin();
12154 i != corpus.get_translation_units().end();
12155 ++i)
12156 if ((result = synthesize_function_type_from_translation_unit(*fn_t,
12157 **i)))
12158 return result;
12159
12160 return result;
12161 }
12162
12163 /// Look into a given corpus to find a type which has the same
12164 /// qualified name as a giventype.
12165 ///
12166 /// If the per-corpus type map is non-empty (because the corpus allows
12167 /// the One Definition Rule) then the type islooked up in that
12168 /// per-corpus type map. Otherwise, the type is looked-up in each
12169 /// translation unit.
12170 ///
12171 /// @param t the type which has the same qualified name as the type we
12172 /// are looking for.
12173 ///
12174 /// @param corp the ABI corpus to look into for the type.
12175 type_decl_sptr
lookup_basic_type(const type_decl & t,const corpus & corp)12176 lookup_basic_type(const type_decl& t, const corpus& corp)
12177 {return lookup_basic_type(t.get_name(), corp);}
12178
12179 /// Look into a given corpus to find a basic type which has a given
12180 /// qualified name.
12181 ///
12182 /// If the per-corpus type map is non-empty (because the corpus allows
12183 /// the One Definition Rule) then the type islooked up in that
12184 /// per-corpus type map. Otherwise, the type is looked-up in each
12185 /// translation unit.
12186 ///
12187 /// @param qualified_name the qualified name of the basic type to look
12188 /// for.
12189 ///
12190 /// @param corp the corpus to look into.
12191 type_decl_sptr
lookup_basic_type(const interned_string & qualified_name,const corpus & corp)12192 lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
12193 {
12194 const istring_type_base_wptrs_map_type& m = corp.get_types().basic_types();
12195 type_decl_sptr result;
12196
12197 if (!m.empty())
12198 result = lookup_type_in_map<type_decl>(qualified_name, m);
12199 else
12200 result = lookup_basic_type_through_translation_units(qualified_name, corp);
12201
12202 return result;
12203 }
12204
12205 /// Lookup a @ref type_decl type from a given corpus, by its location.
12206 ///
12207 /// @param loc the location to consider.
12208 ///
12209 /// @param corp the corpus to consider.
12210 ///
12211 /// @return the resulting basic type, if any.
12212 type_decl_sptr
lookup_basic_type_per_location(const interned_string & loc,const corpus & corp)12213 lookup_basic_type_per_location(const interned_string &loc,
12214 const corpus &corp)
12215 {
12216 const istring_type_base_wptrs_map_type& m =
12217 corp.get_type_per_loc_map().basic_types();
12218 type_decl_sptr result;
12219
12220 result = lookup_type_in_map<type_decl>(loc, m);
12221
12222 return result;
12223 }
12224
12225 /// Lookup a @ref type_decl type from a given corpus, by its location.
12226 ///
12227 /// @param loc the location to consider.
12228 ///
12229 /// @param corp the corpus to consider.
12230 ///
12231 /// @return the resulting basic type, if any.
12232 type_decl_sptr
lookup_basic_type_per_location(const string & loc,const corpus & corp)12233 lookup_basic_type_per_location(const string &loc, const corpus &corp)
12234 {
12235 const environment& env = corp.get_environment();
12236 return lookup_basic_type_per_location(env.intern(loc), corp);
12237 }
12238
12239 /// Look into a given corpus to find a basic type which has a given
12240 /// qualified name.
12241 ///
12242 /// If the per-corpus type map is non-empty (because the corpus allows
12243 /// the One Definition Rule) then the type islooked up in that
12244 /// per-corpus type map. Otherwise, the type is looked-up in each
12245 /// translation unit.
12246 ///
12247 /// @param qualified_name the qualified name of the basic type to look
12248 /// for.
12249 ///
12250 /// @param corp the corpus to look into.
12251 type_decl_sptr
lookup_basic_type(const string & qualified_name,const corpus & corp)12252 lookup_basic_type(const string& qualified_name, const corpus& corp)
12253 {
12254 return lookup_basic_type(corp.get_environment().intern(qualified_name),
12255 corp);
12256 }
12257
12258 /// Look into a given corpus to find a class type which has the same
12259 /// qualified name as a given type.
12260 ///
12261 /// If the per-corpus type map is non-empty (because the corpus allows
12262 /// the One Definition Rule) then the type islooked up in that
12263 /// per-corpus type map. Otherwise, the type is looked-up in each
12264 /// translation unit.
12265 ///
12266 /// @param t the class decl type which has the same qualified name as
12267 /// the type we are looking for.
12268 ///
12269 /// @param corp the corpus to look into.
12270 class_decl_sptr
lookup_class_type(const class_decl & t,const corpus & corp)12271 lookup_class_type(const class_decl& t, const corpus& corp)
12272 {
12273 interned_string s = get_type_name(t);
12274 return lookup_class_type(s, corp);
12275 }
12276
12277 /// Look into a given corpus to find a class type which has a given
12278 /// qualified name.
12279 ///
12280 /// If the per-corpus type map is non-empty (because the corpus allows
12281 /// the One Definition Rule) then the type islooked up in that
12282 /// per-corpus type map. Otherwise, the type is looked-up in each
12283 /// translation unit.
12284 ///
12285 /// @param qualified_name the qualified name of the type to look for.
12286 ///
12287 /// @param corp the corpus to look into.
12288 class_decl_sptr
lookup_class_type(const string & qualified_name,const corpus & corp)12289 lookup_class_type(const string& qualified_name, const corpus& corp)
12290 {
12291 interned_string s = corp.get_environment().intern(qualified_name);
12292 return lookup_class_type(s, corp);
12293 }
12294
12295 /// Look into a given corpus to find a class type which has a given
12296 /// qualified name.
12297 ///
12298 /// If the per-corpus type map is non-empty (because the corpus allows
12299 /// the One Definition Rule) then the type islooked up in that
12300 /// per-corpus type map. Otherwise, the type is looked-up in each
12301 /// translation unit.
12302 ///
12303 /// @param qualified_name the qualified name of the type to look for.
12304 ///
12305 /// @param corp the corpus to look into.
12306 class_decl_sptr
lookup_class_type(const interned_string & qualified_name,const corpus & corp)12307 lookup_class_type(const interned_string& qualified_name, const corpus& corp)
12308 {
12309 const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
12310
12311 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
12312
12313 return result;
12314 }
12315
12316 /// Look into a given corpus to find the class type*s* that have a
12317 /// given qualified name.
12318 ///
12319 /// @param qualified_name the qualified name of the type to look for.
12320 ///
12321 /// @param corp the corpus to look into.
12322 ///
12323 /// @return the vector of class types named @p qualified_name.
12324 const type_base_wptrs_type *
lookup_class_types(const interned_string & qualified_name,const corpus & corp)12325 lookup_class_types(const interned_string& qualified_name, const corpus& corp)
12326 {
12327 const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
12328
12329 return lookup_types_in_map(qualified_name, m);
12330 }
12331
12332 /// Look into a given corpus to find the class type*s* that have a
12333 /// given qualified name and that are declaration-only.
12334 ///
12335 /// @param qualified_name the qualified name of the type to look for.
12336 ///
12337 /// @param corp the corpus to look into.
12338 ///
12339 /// @param result the vector of decl-only class types named @p
12340 /// qualified_name. This is populated iff the function returns true.
12341 ///
12342 /// @return true iff @p result was populated with the decl-only
12343 /// classes named @p qualified_name.
12344 bool
lookup_decl_only_class_types(const interned_string & qualified_name,const corpus & corp,type_base_wptrs_type & result)12345 lookup_decl_only_class_types(const interned_string& qualified_name,
12346 const corpus& corp,
12347 type_base_wptrs_type& result)
12348 {
12349 const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
12350
12351 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
12352 if (!v)
12353 return false;
12354
12355 for (auto type : *v)
12356 {
12357 type_base_sptr t(type);
12358 class_decl_sptr c = is_class_type(t);
12359 if (c->get_is_declaration_only()
12360 && !c->get_definition_of_declaration())
12361 result.push_back(type);
12362 }
12363
12364 return !result.empty();
12365 }
12366
12367 /// Look into a given corpus to find the class type*s* that have a
12368 /// given qualified name.
12369 ///
12370 /// @param qualified_name the qualified name of the type to look for.
12371 ///
12372 /// @param corp the corpus to look into.
12373 ///
12374 /// @return the vector of class types that which name is @p qualified_name.
12375 const type_base_wptrs_type*
lookup_class_types(const string & qualified_name,const corpus & corp)12376 lookup_class_types(const string& qualified_name, const corpus& corp)
12377 {
12378 interned_string s = corp.get_environment().intern(qualified_name);
12379 return lookup_class_types(s, corp);
12380 }
12381
12382 /// Look up a @ref class_decl from a given corpus by its location.
12383 ///
12384 /// @param loc the location to consider.
12385 ///
12386 /// @param corp the corpus to consider.
12387 ///
12388 /// @return the resulting class decl, if any.
12389 class_decl_sptr
lookup_class_type_per_location(const interned_string & loc,const corpus & corp)12390 lookup_class_type_per_location(const interned_string& loc,
12391 const corpus& corp)
12392 {
12393 const istring_type_base_wptrs_map_type& m =
12394 corp.get_type_per_loc_map().class_types();
12395 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
12396
12397 return result;
12398 }
12399
12400 /// Look up a @ref class_decl from a given corpus by its location.
12401 ///
12402 /// @param loc the location to consider.
12403 ///
12404 /// @param corp the corpus to consider.
12405 ///
12406 /// @return the resulting class decl, if any.
12407 class_decl_sptr
lookup_class_type_per_location(const string & loc,const corpus & corp)12408 lookup_class_type_per_location(const string &loc, const corpus &corp)
12409 {
12410 const environment& env = corp.get_environment();
12411 return lookup_class_type_per_location(env.intern(loc), corp);
12412 }
12413
12414 /// Look into a given corpus to find a union type which has a given
12415 /// qualified name.
12416 ///
12417 /// If the per-corpus type map is non-empty (because the corpus allows
12418 /// the One Definition Rule) then the type islooked up in that
12419 /// per-corpus type map. Otherwise, the type is looked-up in each
12420 /// translation unit.
12421 ///
12422 /// @param qualified_name the qualified name of the type to look for.
12423 ///
12424 /// @param corp the corpus to look into.
12425 union_decl_sptr
lookup_union_type(const interned_string & type_name,const corpus & corp)12426 lookup_union_type(const interned_string& type_name, const corpus& corp)
12427 {
12428 const istring_type_base_wptrs_map_type& m = corp.get_types().union_types();
12429
12430 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
12431 if (!result)
12432 result = lookup_union_type_through_translation_units(type_name, corp);
12433
12434 return result;
12435 }
12436
12437 /// Look into a given corpus to find a union type which has a given
12438 /// qualified name.
12439 ///
12440 /// If the per-corpus type map is non-empty (because the corpus allows
12441 /// the One Definition Rule) then the type islooked up in that
12442 /// per-corpus type map. Otherwise, the type is looked-up in each
12443 /// translation unit.
12444 ///
12445 /// @param qualified_name the qualified name of the type to look for.
12446 ///
12447 /// @param corp the corpus to look into.
12448 union_decl_sptr
lookup_union_type(const string & type_name,const corpus & corp)12449 lookup_union_type(const string& type_name, const corpus& corp)
12450 {
12451 interned_string s = corp.get_environment().intern(type_name);
12452 return lookup_union_type(s, corp);
12453 }
12454
12455 /// Look into a given corpus to find an enum type which has the same
12456 /// qualified name as a given enum type.
12457 ///
12458 /// If the per-corpus type map is non-empty (because the corpus allows
12459 /// the One Definition Rule) then the type islooked up in that
12460 /// per-corpus type map. Otherwise, the type is looked-up in each
12461 /// translation unit.
12462 ///
12463 /// @param t the enum type which has the same qualified name as the
12464 /// type we are looking for.
12465 ///
12466 /// @param corp the corpus to look into.
12467 enum_type_decl_sptr
lookup_enum_type(const enum_type_decl & t,const corpus & corp)12468 lookup_enum_type(const enum_type_decl& t, const corpus& corp)
12469 {
12470 interned_string s = get_type_name(t);
12471 return lookup_enum_type(s, corp);
12472 }
12473
12474 /// Look into a given corpus to find an enum type which has a given
12475 /// qualified name.
12476 ///
12477 /// If the per-corpus type map is non-empty (because the corpus allows
12478 /// the One Definition Rule) then the type islooked up in that
12479 /// per-corpus type map. Otherwise, the type is looked-up in each
12480 /// translation unit.
12481 ///
12482 /// @param qualified_name the qualified name of the enum type to look
12483 /// for.
12484 ///
12485 /// @param corp the corpus to look into.
12486 enum_type_decl_sptr
lookup_enum_type(const string & qualified_name,const corpus & corp)12487 lookup_enum_type(const string& qualified_name, const corpus& corp)
12488 {
12489 interned_string s = corp.get_environment().intern(qualified_name);
12490 return lookup_enum_type(s, corp);
12491 }
12492
12493 /// Look into a given corpus to find an enum type which has a given
12494 /// qualified name.
12495 ///
12496 /// If the per-corpus type map is non-empty (because the corpus allows
12497 /// the One Definition Rule) then the type islooked up in that
12498 /// per-corpus type map. Otherwise, the type is looked-up in each
12499 /// translation unit.
12500 ///
12501 /// @param qualified_name the qualified name of the enum type to look
12502 /// for.
12503 ///
12504 /// @param corp the corpus to look into.
12505 enum_type_decl_sptr
lookup_enum_type(const interned_string & qualified_name,const corpus & corp)12506 lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
12507 {
12508 const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
12509
12510 enum_type_decl_sptr result =
12511 lookup_type_in_map<enum_type_decl>(qualified_name, m);
12512 if (!result)
12513 result = lookup_enum_type_through_translation_units(qualified_name, corp);
12514
12515 return result;
12516 }
12517
12518 /// Look into a given corpus to find the enum type*s* that have a
12519 /// given qualified name.
12520 ///
12521 /// @param qualified_name the qualified name of the type to look for.
12522 ///
12523 /// @param corp the corpus to look into.
12524 ///
12525 /// @return the vector of enum types that which name is @p qualified_name.
12526 const type_base_wptrs_type *
lookup_enum_types(const interned_string & qualified_name,const corpus & corp)12527 lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
12528 {
12529 const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
12530
12531 return lookup_types_in_map(qualified_name, m);
12532 }
12533
12534 /// Look into a given corpus to find the enum type*s* that have a
12535 /// given qualified name.
12536 ///
12537 /// @param qualified_name the qualified name of the type to look for.
12538 ///
12539 /// @param corp the corpus to look into.
12540 ///
12541 /// @return the vector of enum types that which name is @p qualified_name.
12542 const type_base_wptrs_type*
lookup_enum_types(const string & qualified_name,const corpus & corp)12543 lookup_enum_types(const string& qualified_name, const corpus& corp)
12544 {
12545 interned_string s = corp.get_environment().intern(qualified_name);
12546 return lookup_enum_types(s, corp);
12547 }
12548
12549 /// Look up an @ref enum_type_decl from a given corpus, by its location.
12550 ///
12551 /// @param loc the location to consider.
12552 ///
12553 /// @param corp the corpus to look the type from.
12554 ///
12555 /// @return the resulting enum type, if any.
12556 enum_type_decl_sptr
lookup_enum_type_per_location(const interned_string & loc,const corpus & corp)12557 lookup_enum_type_per_location(const interned_string &loc, const corpus& corp)
12558 {
12559 const istring_type_base_wptrs_map_type& m =
12560 corp.get_type_per_loc_map().enum_types();
12561 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
12562
12563 return result;
12564 }
12565
12566 /// Look up an @ref enum_type_decl from a given corpus, by its location.
12567 ///
12568 /// @param loc the location to consider.
12569 ///
12570 /// @param corp the corpus to look the type from.
12571 ///
12572 /// @return the resulting enum type, if any.
12573 enum_type_decl_sptr
lookup_enum_type_per_location(const string & loc,const corpus & corp)12574 lookup_enum_type_per_location(const string &loc, const corpus &corp)
12575 {
12576 const environment& env = corp.get_environment();
12577 return lookup_enum_type_per_location(env.intern(loc), corp);
12578 }
12579
12580 /// Look into a given corpus to find a typedef type which has the
12581 /// same qualified name as a given typedef type.
12582 ///
12583 /// If the per-corpus type map is non-empty (because the corpus allows
12584 /// the One Definition Rule) then the type islooked up in that
12585 /// per-corpus type map. Otherwise, the type is looked-up in each
12586 /// translation unit.
12587 ///
12588 /// @param t the typedef type which has the same qualified name as the
12589 /// typedef type we are looking for.
12590 ///
12591 /// @param corp the corpus to look into.
12592 typedef_decl_sptr
lookup_typedef_type(const typedef_decl & t,const corpus & corp)12593 lookup_typedef_type(const typedef_decl& t, const corpus& corp)
12594 {
12595 interned_string s = get_type_name(t);
12596 return lookup_typedef_type(s, corp);
12597 }
12598
12599 /// Look into a given corpus to find a typedef type which has the
12600 /// same qualified name as a given typedef type.
12601 ///
12602 /// If the per-corpus type map is non-empty (because the corpus allows
12603 /// the One Definition Rule) then the type islooked up in that
12604 /// per-corpus type map. Otherwise, the type is looked-up in each
12605 /// translation unit.
12606 ///
12607 /// @param t the typedef type which has the same qualified name as the
12608 /// typedef type we are looking for.
12609 ///
12610 /// @param corp the corpus to look into.
12611 typedef_decl_sptr
lookup_typedef_type(const string & qualified_name,const corpus & corp)12612 lookup_typedef_type(const string& qualified_name, const corpus& corp)
12613 {
12614 interned_string s = corp.get_environment().intern(qualified_name);
12615 return lookup_typedef_type(s, corp);
12616 }
12617
12618 /// Look into a given corpus to find a typedef type which has a
12619 /// given qualified name.
12620 ///
12621 /// If the per-corpus type map is non-empty (because the corpus allows
12622 /// the One Definition Rule) then the type islooked up in that
12623 /// per-corpus type map. Otherwise, the type is looked-up in each
12624 /// translation unit.
12625 ///
12626 /// @param qualified_name the qualified name of the typedef type to
12627 /// look for.
12628 ///
12629 /// @param corp the corpus to look into.
12630 typedef_decl_sptr
lookup_typedef_type(const interned_string & qualified_name,const corpus & corp)12631 lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
12632 {
12633 const istring_type_base_wptrs_map_type& m = corp.get_types().typedef_types();
12634
12635 typedef_decl_sptr result =
12636 lookup_type_in_map<typedef_decl>(qualified_name, m);
12637 if (!result)
12638 result = lookup_typedef_type_through_translation_units(qualified_name,
12639 corp);
12640
12641 return result;
12642 }
12643
12644 /// Lookup a @ref typedef_decl from a corpus, by its location.
12645 ///
12646 /// @param loc the location to consider.
12647 ///
12648 /// @param corp the corpus to consider.
12649 ///
12650 /// @return the typedef_decl found, if any.
12651 typedef_decl_sptr
lookup_typedef_type_per_location(const interned_string & loc,const corpus & corp)12652 lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
12653 {
12654 const istring_type_base_wptrs_map_type& m =
12655 corp.get_type_per_loc_map().typedef_types();
12656 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
12657
12658 return result;
12659 }
12660
12661 /// Lookup a @ref typedef_decl from a corpus, by its location.
12662 ///
12663 /// @param loc the location to consider.
12664 ///
12665 /// @param corp the corpus to consider.
12666 ///
12667 /// @return the typedef_decl found, if any.
12668 typedef_decl_sptr
lookup_typedef_type_per_location(const string & loc,const corpus & corp)12669 lookup_typedef_type_per_location(const string &loc, const corpus &corp)
12670 {
12671 const environment& env = corp.get_environment();
12672 return lookup_typedef_type_per_location(env.intern(loc), corp);
12673 }
12674
12675 /// Look into a corpus to find a class, union or typedef type which
12676 /// has a given qualified name.
12677 ///
12678 /// If the per-corpus type map is non-empty (because the corpus allows
12679 /// the One Definition Rule) then the type islooked up in that
12680 /// per-corpus type map. Otherwise, the type is looked-up in each
12681 /// translation unit.
12682 ///
12683 /// @param qualified_name the name of the type to find.
12684 ///
12685 /// @param corp the corpus to look into.
12686 ///
12687 /// @return the typedef or class type found.
12688 type_base_sptr
lookup_class_or_typedef_type(const string & qualified_name,const corpus & corp)12689 lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
12690 {
12691 type_base_sptr result = lookup_class_type(qualified_name, corp);
12692 if (!result)
12693 result = lookup_union_type(qualified_name, corp);
12694
12695 if (!result)
12696 result = lookup_typedef_type(qualified_name, corp);
12697 return result;
12698 }
12699
12700 /// Look into a corpus to find a class, typedef or enum type which has
12701 /// a given qualified name.
12702 ///
12703 /// If the per-corpus type map is non-empty (because the corpus allows
12704 /// the One Definition Rule) then the type islooked up in that
12705 /// per-corpus type map. Otherwise, the type is looked-up in each
12706 /// translation unit.
12707 ///
12708 /// @param qualified_name the qualified name of the type to look for.
12709 ///
12710 /// @param corp the corpus to look into.
12711 ///
12712 /// @return the typedef, class or enum type found.
12713 type_base_sptr
lookup_class_typedef_or_enum_type(const string & qualified_name,const corpus & corp)12714 lookup_class_typedef_or_enum_type(const string& qualified_name,
12715 const corpus& corp)
12716 {
12717 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
12718 if (!result)
12719 result = lookup_enum_type(qualified_name, corp);
12720
12721 return result;
12722 }
12723
12724 /// Look into a given corpus to find a qualified type which has the
12725 /// same qualified name as a given type.
12726 ///
12727 /// @param t the type which has the same qualified name as the
12728 /// qualified type we are looking for.
12729 ///
12730 /// @param corp the corpus to look into.
12731 ///
12732 /// @return the qualified type found.
12733 qualified_type_def_sptr
lookup_qualified_type(const qualified_type_def & t,const corpus & corp)12734 lookup_qualified_type(const qualified_type_def& t, const corpus& corp)
12735 {
12736 interned_string s = get_type_name(t);
12737 return lookup_qualified_type(s, corp);
12738 }
12739
12740 /// Look into a given corpus to find a qualified type which has a
12741 /// given qualified name.
12742 ///
12743 /// @param qualified_name the qualified name of the type to look for.
12744 ///
12745 /// @param corp the corpus to look into.
12746 ///
12747 /// @return the type found.
12748 qualified_type_def_sptr
lookup_qualified_type(const interned_string & qualified_name,const corpus & corp)12749 lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
12750 {
12751 const istring_type_base_wptrs_map_type& m =
12752 corp.get_types().qualified_types();
12753
12754 qualified_type_def_sptr result =
12755 lookup_type_in_map<qualified_type_def>(qualified_name, m);
12756
12757 if (!result)
12758 result = lookup_qualified_type_through_translation_units(qualified_name,
12759 corp);
12760
12761 return result;
12762 }
12763
12764 /// Look into a given corpus to find a pointer type which has the same
12765 /// qualified name as a given pointer type.
12766 ///
12767 /// @param t the pointer type which has the same qualified name as the
12768 /// type we are looking for.
12769 ///
12770 /// @param corp the corpus to look into.
12771 ///
12772 /// @return the pointer type found.
12773 pointer_type_def_sptr
lookup_pointer_type(const pointer_type_def & t,const corpus & corp)12774 lookup_pointer_type(const pointer_type_def& t, const corpus& corp)
12775 {
12776 interned_string s = get_type_name(t);
12777 return lookup_pointer_type(s, corp);
12778 }
12779
12780 /// Look into a given corpus to find a pointer type which has a given
12781 /// qualified name.
12782 ///
12783 /// If the per-corpus type map is non-empty (because the corpus allows
12784 /// the One Definition Rule) then the type islooked up in that
12785 /// per-corpus type map. Otherwise, the type is looked-up in each
12786 /// translation unit.
12787 ///
12788 /// @param qualified_name the qualified name of the pointer type to
12789 /// look for.
12790 ///
12791 /// @param corp the corpus to look into.
12792 ///
12793 /// @return the pointer type found.
12794 pointer_type_def_sptr
lookup_pointer_type(const interned_string & qualified_name,const corpus & corp)12795 lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
12796 {
12797 const istring_type_base_wptrs_map_type& m = corp.get_types().pointer_types();
12798
12799 pointer_type_def_sptr result =
12800 lookup_type_in_map<pointer_type_def>(qualified_name, m);
12801 if (!result)
12802 result = lookup_pointer_type_through_translation_units(qualified_name,
12803 corp);
12804
12805 return result;
12806 }
12807
12808 /// Look into a given corpus to find a reference type which has the
12809 /// same qualified name as a given reference type.
12810 ///
12811 /// If the per-corpus type map is non-empty (because the corpus allows
12812 /// the One Definition Rule) then the type islooked up in that
12813 /// per-corpus type map. Otherwise, the type is looked-up in each
12814 /// translation unit.
12815 ///
12816 /// @param t the reference type which has the same qualified name as
12817 /// the reference type we are looking for.
12818 ///
12819 /// @param corp the corpus to look into.
12820 ///
12821 /// @return the reference type found.
12822 reference_type_def_sptr
lookup_reference_type(const reference_type_def & t,const corpus & corp)12823 lookup_reference_type(const reference_type_def& t, const corpus& corp)
12824 {
12825 interned_string s = get_type_name(t);
12826 return lookup_reference_type(s, corp);
12827 }
12828
12829 /// Look into a given corpus to find a reference type which has a
12830 /// given qualified name.
12831 ///
12832 /// If the per-corpus type map is non-empty (because the corpus allows
12833 /// the One Definition Rule) then the type islooked up in that
12834 /// per-corpus type map. Otherwise, the type is looked-up in each
12835 /// translation unit.
12836 ///
12837 /// @param qualified_name the qualified name of the reference type to
12838 /// look for.
12839 ///
12840 /// @param corp the corpus to look into.
12841 ///
12842 /// @return the reference type found.
12843 reference_type_def_sptr
lookup_reference_type(const interned_string & qualified_name,const corpus & corp)12844 lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
12845 {
12846 const istring_type_base_wptrs_map_type& m =
12847 corp.get_types().reference_types();
12848
12849 reference_type_def_sptr result =
12850 lookup_type_in_map<reference_type_def>(qualified_name, m);
12851 if (!result)
12852 result = lookup_reference_type_through_translation_units(qualified_name,
12853 corp);
12854
12855 return result;
12856 }
12857
12858 /// Look into a given corpus to find an array type which has a given
12859 /// qualified name.
12860 ///
12861 /// If the per-corpus type map is non-empty (because the corpus allows
12862 /// the One Definition Rule) then the type islooked up in that
12863 /// per-corpus type map. Otherwise, the type is looked-up in each
12864 /// translation unit.
12865 ///
12866 /// @param qualified_name the qualified name of the array type to look
12867 /// for.
12868 ///
12869 /// @param corp the corpus to look into.
12870 ///
12871 /// @return the array type found.
12872 array_type_def_sptr
lookup_array_type(const array_type_def & t,const corpus & corp)12873 lookup_array_type(const array_type_def& t, const corpus& corp)
12874 {
12875 interned_string s = get_type_name(t);
12876 return lookup_array_type(s, corp);
12877 }
12878
12879 /// Look into a given corpus to find an array type which has the same
12880 /// qualified name as a given array type.
12881 ///
12882 /// If the per-corpus type map is non-empty (because the corpus allows
12883 /// the One Definition Rule) then the type islooked up in that
12884 /// per-corpus type map. Otherwise, the type is looked-up in each
12885 /// translation unit.
12886 ///
12887 /// @param t the type which has the same qualified name as the type we
12888 /// are looking for.
12889 ///
12890 /// @param corp the corpus to look into.
12891 ///
12892 /// @return the type found.
12893 array_type_def_sptr
lookup_array_type(const interned_string & qualified_name,const corpus & corp)12894 lookup_array_type(const interned_string& qualified_name, const corpus& corp)
12895 {
12896 const istring_type_base_wptrs_map_type& m = corp.get_types().array_types();
12897
12898 array_type_def_sptr result =
12899 lookup_type_in_map<array_type_def>(qualified_name, m);
12900 if (!result)
12901 result = lookup_array_type_through_translation_units(qualified_name, corp);
12902
12903 return result;
12904 }
12905
12906 /// Look into a given corpus to find a function type which has the same
12907 /// qualified name as a given function type.
12908 ///
12909 /// If the per-corpus type map is non-empty (because the corpus allows
12910 /// the One Definition Rule) then the type islooked up in that
12911 /// per-corpus type map. Otherwise, the type is looked-up in each
12912 /// translation unit.
12913 ///
12914 /// @param t the function type which has the same qualified name as
12915 /// the function type we are looking for.
12916 ///
12917 /// @param corp the corpus to look into.
12918 ///
12919 /// @return the function type found.
12920 function_type_sptr
lookup_function_type(const function_type & t,const corpus & corp)12921 lookup_function_type(const function_type&t, const corpus& corp)
12922 {
12923 interned_string type_name = get_type_name(t);
12924 return lookup_function_type(type_name, corp);
12925 }
12926
12927 /// Look into a given corpus to find a function type which has the same
12928 /// qualified name as a given function type.
12929 ///
12930 /// If the per-corpus type map is non-empty (because the corpus allows
12931 /// the One Definition Rule) then the type islooked up in that
12932 /// per-corpus type map. Otherwise, the type is looked-up in each
12933 /// translation unit.
12934 ///
12935 /// @param t the function type which has the same qualified name as
12936 /// the function type we are looking for.
12937 ///
12938 /// @param corp the corpus to look into.
12939 ///
12940 /// @return the function type found.
12941 function_type_sptr
lookup_function_type(const function_type_sptr & fn_t,const corpus & corpus)12942 lookup_function_type(const function_type_sptr& fn_t,
12943 const corpus& corpus)
12944 {
12945 if (fn_t)
12946 return lookup_function_type(*fn_t, corpus);
12947 return function_type_sptr();
12948 }
12949
12950 /// Look into a given corpus to find a function type which has a given
12951 /// qualified name.
12952 ///
12953 /// If the per-corpus type map is non-empty (because the corpus allows
12954 /// the One Definition Rule) then the type islooked up in that
12955 /// per-corpus type map. Otherwise, the type is looked-up in each
12956 /// translation unit.
12957 ///
12958 /// @param qualified_name the qualified name of the function type to
12959 /// look for.
12960 ///
12961 /// @param corp the corpus to look into.
12962 ///
12963 /// @return the function type found.
12964 function_type_sptr
lookup_function_type(const interned_string & qualified_name,const corpus & corp)12965 lookup_function_type(const interned_string& qualified_name, const corpus& corp)
12966 {
12967 const istring_type_base_wptrs_map_type& m = corp.get_types().function_types();
12968
12969 function_type_sptr result =
12970 lookup_type_in_map<function_type>(qualified_name, m);
12971 if (!result)
12972 result = lookup_function_type_through_translation_units(qualified_name,
12973 corp);
12974
12975 return result;
12976 }
12977
12978 /// Look into a given corpus to find a type which has a given
12979 /// qualified name.
12980 ///
12981 /// If the per-corpus type map is non-empty (because the corpus allows
12982 /// the One Definition Rule) then the type islooked up in that
12983 /// per-corpus type map. Otherwise, the type is looked-up in each
12984 /// translation unit.
12985 ///
12986 /// @param qualified_name the qualified name of the function type to
12987 /// look for.
12988 ///
12989 /// @param corp the corpus to look into.
12990 ///
12991 /// @return the function type found.
12992 type_base_sptr
lookup_type(const interned_string & n,const corpus & corp)12993 lookup_type(const interned_string& n, const corpus& corp)
12994 {
12995 type_base_sptr result;
12996
12997 ((result = lookup_basic_type(n, corp))
12998 || (result = lookup_class_type(n, corp))
12999 || (result = lookup_union_type(n, corp))
13000 || (result = lookup_enum_type(n, corp))
13001 || (result = lookup_typedef_type(n, corp))
13002 || (result = lookup_qualified_type(n, corp))
13003 || (result = lookup_pointer_type(n, corp))
13004 || (result = lookup_reference_type(n, corp))
13005 || (result = lookup_array_type(n, corp))
13006 || (result= lookup_function_type(n, corp)));
13007
13008 return result;
13009 }
13010
13011 /// Lookup a type from a corpus, by its location.
13012 ///
13013 /// @param loc the location to consider.
13014 ///
13015 /// @param corp the corpus to look the type from.
13016 ///
13017 /// @return the resulting type, if any found.
13018 type_base_sptr
lookup_type_per_location(const interned_string & loc,const corpus & corp)13019 lookup_type_per_location(const interned_string& loc, const corpus& corp)
13020 {
13021 // TODO: finish this.
13022
13023 //TODO: when we fully support types indexed by their location, this
13024 //function should return a vector of types because at each location,
13025 //there can be several types that are defined (yay, C and C++,
13026 //*sigh*).
13027
13028 type_base_sptr result;
13029 ((result = lookup_basic_type_per_location(loc, corp))
13030 || (result = lookup_class_type_per_location(loc, corp))
13031 || (result = lookup_union_type_per_location(loc, corp))
13032 || (result = lookup_enum_type_per_location(loc, corp))
13033 || (result = lookup_typedef_type_per_location(loc, corp)));
13034
13035 return result;
13036 }
13037
13038 /// Look into a given corpus to find a type
13039 ///
13040 /// If the per-corpus type map is non-empty (because the corpus allows
13041 /// the One Definition Rule) then the type islooked up in that
13042 /// per-corpus type map. Otherwise, the type is looked-up in each
13043 /// translation unit.
13044 ///
13045 /// @param qualified_name the qualified name of the function type to
13046 /// look for.
13047 ///
13048 /// @param corp the corpus to look into.
13049 ///
13050 /// @return the function type found.
13051 type_base_sptr
lookup_type(const type_base & t,const corpus & corp)13052 lookup_type(const type_base&t, const corpus& corp)
13053 {
13054 interned_string n = get_type_name(t);
13055 return lookup_type(n, corp);
13056 }
13057
13058 /// Look into a given corpus to find a type
13059 ///
13060 /// If the per-corpus type map is non-empty (because the corpus allows
13061 /// the One Definition Rule) then the type islooked up in that
13062 /// per-corpus type map. Otherwise, the type is looked-up in each
13063 /// translation unit.
13064 ///
13065 /// @param qualified_name the qualified name of the function type to
13066 /// look for.
13067 ///
13068 /// @param corp the corpus to look into.
13069 ///
13070 /// @return the function type found.
13071 type_base_sptr
lookup_type(const type_base_sptr & t,const corpus & corp)13072 lookup_type(const type_base_sptr&t, const corpus& corp)
13073 {
13074 if (t)
13075 return lookup_type(*t, corp);
13076 return type_base_sptr();
13077 }
13078
13079 /// Update the map that associates a fully qualified name of a given
13080 /// type to that type.
13081 ///
13082 ///
13083 /// @param type the type we are considering.
13084 ///
13085 /// @param types_map the map to update. It's a map that assciates a
13086 /// fully qualified name of a type to the type itself.
13087 ///
13088 /// @param use_type_name_as_key if true, use the name of the type as
13089 /// the key to look it up later. If false, then use the location of
13090 /// the type as a key to look it up later.
13091 ///
13092 /// @return true iff the type was added to the map.
13093 template<typename TypeKind>
13094 bool
maybe_update_types_lookup_map(const shared_ptr<TypeKind> & type,istring_type_base_wptrs_map_type & types_map,bool use_type_name_as_key=true)13095 maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
13096 istring_type_base_wptrs_map_type& types_map,
13097 bool use_type_name_as_key = true)
13098 {
13099 interned_string s;
13100
13101 if (use_type_name_as_key)
13102 s = get_type_name(type);
13103 else if (location l = type->get_location())
13104 {
13105 string str = l.expand();
13106 s = type->get_environment().intern(str);
13107 }
13108
13109 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
13110 bool result = false;
13111
13112 if (i == types_map.end())
13113 {
13114 types_map[s].push_back(type);
13115 result = true;
13116 }
13117 else
13118 i->second.push_back(type);
13119
13120 return result;
13121 }
13122
13123 /// This is the specialization for type @ref class_decl of the
13124 /// function template:
13125 ///
13126 /// maybe_update_types_lookup_map<T>(scope_decl*,
13127 /// const shared_ptr<T>&,
13128 /// istring_type_base_wptrs_map_type&)
13129 ///
13130 /// @param class_type the type to consider.
13131 ///
13132 /// @param types_map the type map to update.
13133 ///
13134 /// @return true iff the type was added to the map.
13135 template<>
13136 bool
maybe_update_types_lookup_map(const class_decl_sptr & class_type,istring_type_base_wptrs_map_type & map,bool use_type_name_as_key)13137 maybe_update_types_lookup_map<class_decl>(const class_decl_sptr& class_type,
13138 istring_type_base_wptrs_map_type& map,
13139 bool use_type_name_as_key)
13140 {
13141 class_decl_sptr type = class_type;
13142
13143 bool update_qname_map = true;
13144 if (type->get_is_declaration_only())
13145 {
13146 // Let's try to look through decl-only classes to get their
13147 // definition. But if the class doesn't have a definition then
13148 // we'll keep it.
13149 if (class_decl_sptr def =
13150 is_class_type(class_type->get_definition_of_declaration()))
13151 type = def;
13152 }
13153
13154 if (!update_qname_map)
13155 return false;
13156
13157 interned_string s;
13158 if (use_type_name_as_key)
13159 {
13160 string qname = type->get_qualified_name();
13161 s = type->get_environment().intern(qname);
13162 }
13163 else if (location l = type->get_location())
13164 {
13165 string str = l.expand();
13166 s = type->get_environment().intern(str);
13167 }
13168
13169 bool result = false;
13170 istring_type_base_wptrs_map_type::iterator i = map.find(s);
13171 if (i == map.end())
13172 {
13173 map[s].push_back(type);
13174 result = true;
13175 }
13176 else
13177 i->second.push_back(type);
13178
13179 return result;
13180 }
13181
13182 /// This is the specialization for type @ref function_type of the
13183 /// function template:
13184 ///
13185 /// maybe_update_types_lookup_map<T>(scope_decl*,
13186 /// const shared_ptr<T>&,
13187 /// istring_type_base_wptrs_map_type&)
13188 ///
13189 /// @param scope the scope of the type to consider.
13190 ///
13191 /// @param class_type the type to consider.
13192 ///
13193 /// @param types_map the type map to update.
13194 ///
13195 /// @return true iff the type was added to the map.
13196 template<>
13197 bool
maybe_update_types_lookup_map(const function_type_sptr & type,istring_type_base_wptrs_map_type & types_map,bool)13198 maybe_update_types_lookup_map<function_type>
13199 (const function_type_sptr& type,
13200 istring_type_base_wptrs_map_type& types_map,
13201 bool /*use_type_name_as_key*/)
13202 {
13203 bool result = false;
13204 interned_string s = get_type_name(type);
13205 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
13206 if (i == types_map.end())
13207 {
13208 types_map[s].push_back(type);
13209 result = true;
13210 }
13211 else
13212 i->second.push_back(type);
13213
13214 return result;
13215 }
13216
13217 /// Update the map that associates the fully qualified name of a basic
13218 /// type with the type itself.
13219 ///
13220 /// The per-translation unit type map is updated if no type with this
13221 /// name was already existing in that map.
13222 ///
13223 /// If no type with this name did already exist in the per-corpus type
13224 /// map, then that per-corpus type map is updated. Otherwise, that
13225 /// type is erased from that per-corpus map.
13226 ///
13227 /// @param basic_type the basic type to consider.
13228 void
maybe_update_types_lookup_map(const type_decl_sptr & basic_type)13229 maybe_update_types_lookup_map(const type_decl_sptr& basic_type)
13230 {
13231 if (translation_unit *tu = basic_type->get_translation_unit())
13232 maybe_update_types_lookup_map<type_decl>
13233 (basic_type, tu->get_types().basic_types());
13234
13235 if (corpus *type_corpus = basic_type->get_corpus())
13236 {
13237 maybe_update_types_lookup_map<type_decl>
13238 (basic_type,
13239 type_corpus->priv_->get_types().basic_types());
13240
13241 maybe_update_types_lookup_map<type_decl>
13242 (basic_type,
13243 type_corpus->get_type_per_loc_map().basic_types(),
13244 /*use_type_name_as_key*/false);
13245
13246 if (corpus *group = type_corpus->get_group())
13247 {
13248 maybe_update_types_lookup_map<type_decl>
13249 (basic_type,
13250 group->priv_->get_types().basic_types());
13251
13252 maybe_update_types_lookup_map<type_decl>
13253 (basic_type,
13254 group->get_type_per_loc_map().basic_types(),
13255 /*use_type_name_as_key*/false);
13256 }
13257 }
13258
13259 }
13260
13261 /// Update the map that associates the fully qualified name of a class
13262 /// type with the type itself.
13263 ///
13264 /// The per-translation unit type map is updated if no type with this
13265 /// name was already existing in that map.
13266 ///
13267 /// If no type with this name did already exist in the per-corpus type
13268 /// map, then that per-corpus type map is updated. Otherwise, that
13269 /// type is erased from that per-corpus map.
13270 ///
13271 /// @param class_type the class type to consider.
13272 void
maybe_update_types_lookup_map(const class_decl_sptr & class_type)13273 maybe_update_types_lookup_map(const class_decl_sptr& class_type)
13274 {
13275 if (translation_unit *tu = class_type->get_translation_unit())
13276 maybe_update_types_lookup_map<class_decl>
13277 (class_type, tu->get_types().class_types());
13278
13279 if (corpus *type_corpus = class_type->get_corpus())
13280 {
13281 maybe_update_types_lookup_map<class_decl>
13282 (class_type,
13283 type_corpus->priv_->get_types().class_types());
13284
13285 maybe_update_types_lookup_map<class_decl>
13286 (class_type,
13287 type_corpus->get_type_per_loc_map().class_types(),
13288 /*use_type_name_as_key*/false);
13289
13290 if (corpus *group = type_corpus->get_group())
13291 {
13292 maybe_update_types_lookup_map<class_decl>
13293 (class_type,
13294 group->priv_->get_types().class_types());
13295
13296 maybe_update_types_lookup_map<class_decl>
13297 (class_type,
13298 group->get_type_per_loc_map().class_types(),
13299 /*use_type_name_as_key*/false);
13300 }
13301 }
13302 }
13303
13304 /// Update the map that associates the fully qualified name of a union
13305 /// type with the type itself.
13306 ///
13307 /// The per-translation unit type map is updated if no type with this
13308 /// name was already existing in that map.
13309 ///
13310 /// If no type with this name did already exist in the per-corpus type
13311 /// map, then that per-corpus type map is updated. Otherwise, that
13312 /// type is erased from that per-corpus map.
13313 ///
13314 /// @param union_type the union type to consider.
13315 void
maybe_update_types_lookup_map(const union_decl_sptr & union_type)13316 maybe_update_types_lookup_map(const union_decl_sptr& union_type)
13317 {
13318 if (translation_unit *tu = union_type->get_translation_unit())
13319 maybe_update_types_lookup_map<union_decl>
13320 (union_type, tu->get_types().union_types());
13321
13322 if (corpus *type_corpus = union_type->get_corpus())
13323 {
13324 maybe_update_types_lookup_map<union_decl>
13325 (union_type,
13326 type_corpus->priv_->get_types().union_types());
13327
13328 maybe_update_types_lookup_map<union_decl>
13329 (union_type,
13330 type_corpus->get_type_per_loc_map().union_types(),
13331 /*use_type_name_as_key*/false);
13332
13333 if (corpus *group = type_corpus->get_group())
13334 {
13335 maybe_update_types_lookup_map<union_decl>
13336 (union_type,
13337 group->priv_->get_types().union_types());
13338
13339 maybe_update_types_lookup_map<union_decl>
13340 (union_type,
13341 group->get_type_per_loc_map().union_types(),
13342 /*use_type_name_as_key*/false);
13343 }
13344 }
13345 }
13346
13347 /// Update the map that associates the fully qualified name of an enum
13348 /// type with the type itself.
13349 ///
13350 /// The per-translation unit type map is updated if no type with this
13351 /// name was already existing in that map.
13352 ///
13353 /// If no type with this name did already exist in the per-corpus type
13354 /// map, then that per-corpus type map is updated. Otherwise, that
13355 /// type is erased from that per-corpus map.
13356 ///
13357 /// @param enum_type the type to consider.
13358 void
maybe_update_types_lookup_map(const enum_type_decl_sptr & enum_type)13359 maybe_update_types_lookup_map(const enum_type_decl_sptr& enum_type)
13360 {
13361 if (translation_unit *tu = enum_type->get_translation_unit())
13362 maybe_update_types_lookup_map<enum_type_decl>
13363 (enum_type, tu->get_types().enum_types());
13364
13365 if (corpus *type_corpus = enum_type->get_corpus())
13366 {
13367 maybe_update_types_lookup_map<enum_type_decl>
13368 (enum_type,
13369 type_corpus->priv_->get_types().enum_types());
13370
13371 maybe_update_types_lookup_map<enum_type_decl>
13372 (enum_type,
13373 type_corpus->get_type_per_loc_map().enum_types(),
13374 /*use_type_name_as_key*/false);
13375
13376 if (corpus *group = type_corpus->get_group())
13377 {
13378 maybe_update_types_lookup_map<enum_type_decl>
13379 (enum_type,
13380 group->priv_->get_types().enum_types());
13381
13382 maybe_update_types_lookup_map<enum_type_decl>
13383 (enum_type,
13384 group->get_type_per_loc_map().enum_types(),
13385 /*use_type_name_as_key*/false);
13386 }
13387 }
13388
13389 }
13390
13391 /// Update the map that associates the fully qualified name of a
13392 /// typedef type with the type itself.
13393 ///
13394 /// The per-translation unit type map is updated if no type with this
13395 /// name was already existing in that map.
13396 ///
13397 /// If no type with this name did already exist in the per-corpus type
13398 /// map, then that per-corpus type map is updated. Otherwise, that
13399 /// type is erased from that per-corpus map.
13400 ///
13401 /// @param typedef_type the type to consider.
13402 void
maybe_update_types_lookup_map(const typedef_decl_sptr & typedef_type)13403 maybe_update_types_lookup_map(const typedef_decl_sptr& typedef_type)
13404 {
13405 if (translation_unit *tu = typedef_type->get_translation_unit())
13406 maybe_update_types_lookup_map<typedef_decl>
13407 (typedef_type, tu->get_types().typedef_types());
13408
13409 if (corpus *type_corpus = typedef_type->get_corpus())
13410 {
13411 maybe_update_types_lookup_map<typedef_decl>
13412 (typedef_type,
13413 type_corpus->priv_->get_types().typedef_types());
13414
13415 maybe_update_types_lookup_map<typedef_decl>
13416 (typedef_type,
13417 type_corpus->get_type_per_loc_map().typedef_types(),
13418 /*use_type_name_as_key*/false);
13419
13420 if (corpus *group = type_corpus->get_group())
13421 {
13422 maybe_update_types_lookup_map<typedef_decl>
13423 (typedef_type,
13424 group->priv_->get_types().typedef_types());
13425
13426 maybe_update_types_lookup_map<typedef_decl>
13427 (typedef_type,
13428 group->get_type_per_loc_map().typedef_types(),
13429 /*use_type_name_as_key*/false);
13430 }
13431 }
13432 }
13433
13434 /// Update the map that associates the fully qualified name of a
13435 /// qualified type with the type itself.
13436 ///
13437 /// The per-translation unit type map is updated if no type with this
13438 /// name was already existing in that map.
13439 ///
13440 /// If no type with this name did already exist in the per-corpus type
13441 /// map, then that per-corpus type map is updated. Otherwise, that
13442 /// type is erased from that per-corpus map.
13443 ///
13444 /// @param qualified_type the type to consider.
13445 void
maybe_update_types_lookup_map(const qualified_type_def_sptr & qualified_type)13446 maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
13447 {
13448 if (translation_unit *tu = qualified_type->get_translation_unit())
13449 maybe_update_types_lookup_map<qualified_type_def>
13450 (qualified_type, tu->get_types().qualified_types());
13451
13452 if (corpus *type_corpus = qualified_type->get_corpus())
13453 {
13454 maybe_update_types_lookup_map<qualified_type_def>
13455 (qualified_type,
13456 type_corpus->priv_->get_types().qualified_types());
13457
13458 if (corpus *group = type_corpus->get_group())
13459 {
13460 maybe_update_types_lookup_map<qualified_type_def>
13461 (qualified_type,
13462 group->priv_->get_types().qualified_types());
13463 }
13464 }
13465 }
13466
13467 /// Update the map that associates the fully qualified name of a
13468 /// pointer type with the type itself.
13469 ///
13470 /// The per-translation unit type map is updated if no type with this
13471 /// name was already existing in that map.
13472 ///
13473 /// If no type with this name did already exist in the per-corpus type
13474 /// map, then that per-corpus type map is updated. Otherwise, that
13475 /// type is erased from that per-corpus map.
13476 ///
13477 /// @param pointer_type the type to consider.
13478 void
maybe_update_types_lookup_map(const pointer_type_def_sptr & pointer_type)13479 maybe_update_types_lookup_map(const pointer_type_def_sptr& pointer_type)
13480 {
13481 if (translation_unit *tu = pointer_type->get_translation_unit())
13482 maybe_update_types_lookup_map<pointer_type_def>
13483 (pointer_type, tu->get_types().pointer_types());
13484
13485 if (corpus *type_corpus = pointer_type->get_corpus())
13486 {
13487 maybe_update_types_lookup_map<pointer_type_def>
13488 (pointer_type,
13489 type_corpus->priv_->get_types().pointer_types());
13490
13491 if (corpus *group = type_corpus->get_group())
13492 {
13493 maybe_update_types_lookup_map<pointer_type_def>
13494 (pointer_type,
13495 group->priv_->get_types().pointer_types());
13496 }
13497 }
13498 }
13499
13500 /// Update the map that associates the fully qualified name of a
13501 /// reference type with the type itself.
13502 ///
13503 /// The per-translation unit type map is updated if no type with this
13504 /// name was already existing in that map.
13505 ///
13506 /// If no type with this name did already exist in the per-corpus type
13507 /// map, then that per-corpus type map is updated. Otherwise, that
13508 /// type is erased from that per-corpus map.
13509 ///
13510 /// @param reference_type the type to consider.
13511 void
maybe_update_types_lookup_map(const reference_type_def_sptr & reference_type)13512 maybe_update_types_lookup_map(const reference_type_def_sptr& reference_type)
13513 {
13514 if (translation_unit *tu = reference_type->get_translation_unit())
13515 maybe_update_types_lookup_map<reference_type_def>
13516 (reference_type, tu->get_types().reference_types());
13517
13518 if (corpus *type_corpus = reference_type->get_corpus())
13519 {
13520 maybe_update_types_lookup_map<reference_type_def>
13521 (reference_type,
13522 type_corpus->priv_->get_types().reference_types());
13523
13524 if (corpus *group = type_corpus->get_group())
13525 {
13526 maybe_update_types_lookup_map<reference_type_def>
13527 (reference_type,
13528 group->priv_->get_types().reference_types());
13529 }
13530 }
13531 }
13532
13533 /// Update the map that associates the fully qualified name of a type
13534 /// with the type itself.
13535 ///
13536 /// The per-translation unit type map is updated if no type with this
13537 /// name was already existing in that map.
13538 ///
13539 /// If no type with this name did already exist in the per-corpus type
13540 /// map, then that per-corpus type map is updated. Otherwise, that
13541 /// type is erased from that per-corpus map.
13542 ///
13543 /// @param array_type the type to consider.
13544 void
maybe_update_types_lookup_map(const array_type_def_sptr & array_type)13545 maybe_update_types_lookup_map(const array_type_def_sptr& array_type)
13546 {
13547 if (translation_unit *tu = array_type->get_translation_unit())
13548 maybe_update_types_lookup_map<array_type_def>
13549 (array_type, tu->get_types().array_types());
13550
13551 if (corpus *type_corpus = array_type->get_corpus())
13552 {
13553 maybe_update_types_lookup_map<array_type_def>
13554 (array_type,
13555 type_corpus->priv_->get_types().array_types());
13556
13557 maybe_update_types_lookup_map<array_type_def>
13558 (array_type,
13559 type_corpus->get_type_per_loc_map().array_types(),
13560 /*use_type_name_as_key*/false);
13561
13562 if (corpus *group = type_corpus->get_group())
13563 {
13564 maybe_update_types_lookup_map<array_type_def>
13565 (array_type,
13566 group->priv_->get_types().array_types());
13567
13568 maybe_update_types_lookup_map<array_type_def>
13569 (array_type,
13570 group->get_type_per_loc_map().array_types(),
13571 /*use_type_name_as_key*/false);
13572 }
13573 }
13574 }
13575
13576 /// Update the map that associates the fully qualified name of a type
13577 /// with the type itself.
13578 ///
13579 /// The per-translation unit type map is updated if no type with this
13580 /// name was already existing in that map.
13581 ///
13582 /// If no type with this name did already exist in the per-corpus type
13583 /// map, then that per-corpus type map is updated. Otherwise, that
13584 /// type is erased from that per-corpus map.
13585 ///
13586 /// @param subrange_type the type to consider.
13587 void
maybe_update_types_lookup_map(const array_type_def::subrange_sptr & subrange_type)13588 maybe_update_types_lookup_map
13589 (const array_type_def::subrange_sptr& subrange_type)
13590 {
13591 if (translation_unit *tu = subrange_type->get_translation_unit())
13592 maybe_update_types_lookup_map<array_type_def::subrange_type>
13593 (subrange_type, tu->get_types().subrange_types());
13594
13595 if (corpus *type_corpus = subrange_type->get_corpus())
13596 {
13597 maybe_update_types_lookup_map<array_type_def::subrange_type>
13598 (subrange_type,
13599 type_corpus->priv_->get_types().subrange_types());
13600
13601 maybe_update_types_lookup_map<array_type_def::subrange_type>
13602 (subrange_type,
13603 type_corpus->get_type_per_loc_map().subrange_types(),
13604 /*use_type_name_as_key*/false);
13605
13606 if (corpus *group = subrange_type->get_corpus())
13607 {
13608 maybe_update_types_lookup_map<array_type_def::subrange_type>
13609 (subrange_type,
13610 group->priv_->get_types().subrange_types());
13611
13612 maybe_update_types_lookup_map<array_type_def::subrange_type>
13613 (subrange_type,
13614 group->get_type_per_loc_map().subrange_types(),
13615 /*use_type_name_as_key*/false);
13616 }
13617 }
13618 }
13619
13620 /// Update the map that associates the fully qualified name of a
13621 /// function type with the type itself.
13622 ///
13623 /// The per-translation unit type map is updated if no type with this
13624 /// name was already existing in that map.
13625 ///
13626 /// If no type with this name did already exist in the per-corpus type
13627 /// map, then that per-corpus type map is updated. Otherwise, that
13628 /// type is erased from that per-corpus map.
13629 ///
13630 /// @param scope the scope of the function type.
13631 /// @param fn_type the type to consider.
13632 void
maybe_update_types_lookup_map(const function_type_sptr & fn_type)13633 maybe_update_types_lookup_map(const function_type_sptr& fn_type)
13634 {
13635 if (translation_unit *tu = fn_type->get_translation_unit())
13636 maybe_update_types_lookup_map<function_type>
13637 (fn_type, tu->get_types().function_types());
13638
13639 if (corpus *type_corpus = fn_type->get_corpus())
13640 {
13641 maybe_update_types_lookup_map<function_type>
13642 (fn_type,
13643 type_corpus->priv_->get_types().function_types());
13644
13645 if (corpus *group = fn_type->get_corpus())
13646 {
13647 maybe_update_types_lookup_map<function_type>
13648 (fn_type,
13649 group->priv_->get_types().function_types());
13650 }
13651 }
13652 }
13653
13654 /// Update the map that associates the fully qualified name of a type
13655 /// declaration with the type itself.
13656 ///
13657 /// The per-translation unit type map is updated if no type with this
13658 /// name was already existing in that map.
13659 ///
13660 /// If no type with this name did already exist in the per-corpus type
13661 /// map, then that per-corpus type map is updated. Otherwise, that
13662 /// type is erased from that per-corpus map.
13663 ///
13664 /// @param decl the declaration of the type to consider.
13665 void
maybe_update_types_lookup_map(const decl_base_sptr & decl)13666 maybe_update_types_lookup_map(const decl_base_sptr& decl)
13667 {
13668 if (!is_type(decl))
13669 return;
13670
13671 if (type_decl_sptr basic_type = is_type_decl(decl))
13672 maybe_update_types_lookup_map(basic_type);
13673 else if (class_decl_sptr class_type = is_class_type(decl))
13674 maybe_update_types_lookup_map(class_type);
13675 else if (union_decl_sptr union_type = is_union_type(decl))
13676 maybe_update_types_lookup_map(union_type);
13677 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
13678 maybe_update_types_lookup_map(enum_type);
13679 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
13680 maybe_update_types_lookup_map(typedef_type);
13681 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
13682 maybe_update_types_lookup_map(qualified_type);
13683 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
13684 maybe_update_types_lookup_map(pointer_type);
13685 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
13686 maybe_update_types_lookup_map(reference_type);
13687 else if (array_type_def_sptr array_type = is_array_type(decl))
13688 maybe_update_types_lookup_map(array_type);
13689 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
13690 maybe_update_types_lookup_map(subrange_type);
13691 else
13692 ABG_ASSERT_NOT_REACHED;
13693 }
13694
13695 /// Update the map that associates the fully qualified name of a type
13696 /// with the type itself.
13697 ///
13698 /// The per-translation unit type map is updated if no type with this
13699 /// name was already existing in that map.
13700 ///
13701 /// If no type with this name did already exist in the per-corpus type
13702 /// map, then that per-corpus type map is updated. Otherwise, that
13703 /// type is erased from that per-corpus map.
13704 ///
13705 /// @param type the type to consider.
13706 void
maybe_update_types_lookup_map(const type_base_sptr & type)13707 maybe_update_types_lookup_map(const type_base_sptr& type)
13708 {
13709 if (decl_base_sptr decl = get_type_declaration(type))
13710 maybe_update_types_lookup_map(decl);
13711 else
13712 ABG_ASSERT_NOT_REACHED;
13713 }
13714
13715 //--------------------------------
13716 // </type and decls lookup stuff>
13717 // ------------------------------
13718
13719 /// In a translation unit, lookup a given type or synthesize it if
13720 /// it's a qualified type.
13721 ///
13722 /// So this function first looks the type up in the translation unit.
13723 /// If it's found, then OK, it's returned. Otherwise, if it's a
13724 /// qualified, reference or pointer or function type (a composite
13725 /// type), lookup the underlying type, synthesize the type we want
13726 /// from it and return it.
13727 ///
13728 /// If the underlying types is not not found, then give up and return
13729 /// nil.
13730 ///
13731 /// @return the type that was found or the synthesized type.
13732 type_base_sptr
synthesize_type_from_translation_unit(const type_base_sptr & type,translation_unit & tu)13733 synthesize_type_from_translation_unit(const type_base_sptr& type,
13734 translation_unit& tu)
13735 {
13736 type_base_sptr result;
13737
13738 result = lookup_type(type, tu);
13739
13740 if (!result)
13741 {
13742 if (qualified_type_def_sptr qual = is_qualified_type(type))
13743 {
13744 type_base_sptr underlying_type =
13745 synthesize_type_from_translation_unit(qual->get_underlying_type(),
13746 tu);
13747 if (underlying_type)
13748 {
13749 result.reset(new qualified_type_def(underlying_type,
13750 qual->get_cv_quals(),
13751 qual->get_location()));
13752 }
13753 }
13754 else if (pointer_type_def_sptr p = is_pointer_type(type))
13755 {
13756 type_base_sptr pointed_to_type =
13757 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
13758 tu);
13759 if (pointed_to_type)
13760 {
13761 result.reset(new pointer_type_def(pointed_to_type,
13762 p->get_size_in_bits(),
13763 p->get_alignment_in_bits(),
13764 p->get_location()));
13765 }
13766 }
13767 else if (reference_type_def_sptr r = is_reference_type(type))
13768 {
13769 type_base_sptr pointed_to_type =
13770 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
13771 if (pointed_to_type)
13772 {
13773 result.reset(new reference_type_def(pointed_to_type,
13774 r->is_lvalue(),
13775 r->get_size_in_bits(),
13776 r->get_alignment_in_bits(),
13777 r->get_location()));
13778 }
13779 }
13780 else if (function_type_sptr f = is_function_type(type))
13781 result = synthesize_function_type_from_translation_unit(*f, tu);
13782
13783 if (result)
13784 {
13785 add_decl_to_scope(is_decl(result), tu.get_global_scope());
13786 canonicalize(result);
13787 }
13788 }
13789
13790 if (result)
13791 tu.priv_->synthesized_types_.push_back(result);
13792
13793 return result;
13794 }
13795
13796 /// In a translation unit, lookup the sub-types that make up a given
13797 /// function type and if the sub-types are all found, synthesize and
13798 /// return a function_type with them.
13799 ///
13800 /// This function is like lookup_function_type_in_translation_unit()
13801 /// execept that it constructs the function type from the sub-types
13802 /// found in the translation, rather than just looking for the
13803 /// function types held by the translation unit. This can be useful
13804 /// if the translation unit doesnt hold the function type we are
13805 /// looking for (i.e, lookup_function_type_in_translation_unit()
13806 /// returned NULL) but we still want to see if the sub-types of the
13807 /// function types are present in the translation unit.
13808 ///
13809 /// @param fn_type the function type to consider.
13810 ///
13811 /// @param tu the translation unit to look into.
13812 ///
13813 /// @return the resulting synthesized function type if all its
13814 /// sub-types have been found, NULL otherwise.
13815 function_type_sptr
synthesize_function_type_from_translation_unit(const function_type & fn_type,translation_unit & tu)13816 synthesize_function_type_from_translation_unit(const function_type& fn_type,
13817 translation_unit& tu)
13818 {
13819 function_type_sptr nil = function_type_sptr();
13820
13821 const environment& env = tu.get_environment();
13822
13823 type_base_sptr return_type = fn_type.get_return_type();
13824 type_base_sptr result_return_type;
13825 if (!return_type || env.is_void_type(return_type))
13826 result_return_type = env.get_void_type();
13827 else
13828 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
13829 if (!result_return_type)
13830 return nil;
13831
13832 function_type::parameters parms;
13833 type_base_sptr parm_type;
13834 function_decl::parameter_sptr parm;
13835 for (function_type::parameters::const_iterator i =
13836 fn_type.get_parameters().begin();
13837 i != fn_type.get_parameters().end();
13838 ++i)
13839 {
13840 type_base_sptr t = (*i)->get_type();
13841 parm_type = synthesize_type_from_translation_unit(t, tu);
13842 if (!parm_type)
13843 return nil;
13844 parm.reset(new function_decl::parameter(parm_type,
13845 (*i)->get_index(),
13846 (*i)->get_name(),
13847 (*i)->get_location(),
13848 (*i)->get_variadic_marker(),
13849 (*i)->get_is_artificial()));
13850 parms.push_back(parm);
13851 }
13852
13853 class_or_union_sptr class_type;
13854 const method_type* method = is_method_type(&fn_type);
13855 if (method)
13856 {
13857 class_type = is_class_or_union_type
13858 (synthesize_type_from_translation_unit(method->get_class_type(), tu));
13859 ABG_ASSERT(class_type);
13860 }
13861
13862 function_type_sptr result_fn_type;
13863
13864 if (class_type)
13865 result_fn_type.reset(new method_type(result_return_type,
13866 class_type,
13867 parms,
13868 method->get_is_const(),
13869 fn_type.get_size_in_bits(),
13870 fn_type.get_alignment_in_bits()));
13871 else
13872 result_fn_type.reset(new function_type(result_return_type,
13873 parms,
13874 fn_type.get_size_in_bits(),
13875 fn_type.get_alignment_in_bits()));
13876
13877 tu.priv_->synthesized_types_.push_back(result_fn_type);
13878 tu.bind_function_type_life_time(result_fn_type);
13879
13880 canonicalize(result_fn_type);
13881 return result_fn_type;
13882 }
13883
13884 /// Demangle a C++ mangled name and return the resulting string
13885 ///
13886 /// @param mangled_name the C++ mangled name to demangle.
13887 ///
13888 /// @return the resulting mangled name.
13889 string
demangle_cplus_mangled_name(const string & mangled_name)13890 demangle_cplus_mangled_name(const string& mangled_name)
13891 {
13892 if (mangled_name.empty())
13893 return "";
13894
13895 size_t l = 0;
13896 int status = 0;
13897 char * str = abi::__cxa_demangle(mangled_name.c_str(),
13898 NULL, &l, &status);
13899 string demangled_name = mangled_name;
13900 if (str)
13901 {
13902 ABG_ASSERT(status == 0);
13903 demangled_name = str;
13904 free(str);
13905 str = 0;
13906 }
13907 return demangled_name;
13908 }
13909
13910 /// Return either the type given in parameter if it's non-null, or the
13911 /// void type.
13912 ///
13913 /// @param t the type to consider.
13914 ///
13915 /// @param env the environment to use. If NULL, just abort the
13916 /// process.
13917 ///
13918 /// @return either @p t if it is non-null, or the void type.
13919 type_base_sptr
type_or_void(const type_base_sptr t,const environment & env)13920 type_or_void(const type_base_sptr t, const environment& env)
13921 {
13922 type_base_sptr r;
13923
13924 if (t)
13925 r = t;
13926 else
13927 r = type_base_sptr(env.get_void_type());
13928
13929 return r;
13930 }
13931
~global_scope()13932 global_scope::~global_scope()
13933 {
13934 }
13935
13936 static bool
13937 maybe_propagate_canonical_type(const type_base& lhs_type,
13938 const type_base& rhs_type);
13939
13940 /// Test if two types are eligible to the "Linux Kernel Fast Type
13941 /// Comparison Optimization", a.k.a LKFTCO.
13942 ///
13943 /// Two types T1 and T2 (who are presumably of the same name and kind)
13944 /// are eligible to the LKFTCO if they fulfill the following criteria/
13945 ///
13946 /// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
13947 /// either class, union or enums.
13948 ///
13949 /// 2/ They are defined in the same translation unit.
13950 ///
13951 /// @param t1 the first type to consider.
13952 ///
13953 /// @param t2 the second type to consider.
13954 ///
13955 /// @return true iff t1 and t2 are eligible to the LKFTCO.
13956 static bool
types_defined_same_linux_kernel_corpus_public(const type_base & t1,const type_base & t2)13957 types_defined_same_linux_kernel_corpus_public(const type_base& t1,
13958 const type_base& t2)
13959 {
13960 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
13961 string t1_file_path, t2_file_path;
13962
13963 /// If the t1 (and t2) are classes/unions/enums from the same linux
13964 /// kernel corpus, let's move on. Otherwise bail out.
13965 if (!(t1_corpus && t2_corpus
13966 && t1_corpus == t2_corpus
13967 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
13968 && (is_class_or_union_type(&t1)
13969 || is_enum_type(&t1))))
13970 return false;
13971
13972 class_or_union *c1 = 0, *c2 = 0;
13973 c1 = is_class_or_union_type(&t1);
13974 c2 = is_class_or_union_type(&t2);
13975
13976 // Two anonymous class types with no naming typedefs cannot be
13977 // eligible to this optimization.
13978 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
13979 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
13980 return false;
13981
13982 // Two anonymous classes with naming typedefs should have the same
13983 // typedef name.
13984 if (c1
13985 && c2
13986 && c1->get_is_anonymous() && c1->get_naming_typedef()
13987 && c2->get_is_anonymous() && c2->get_naming_typedef())
13988 if (c1->get_naming_typedef()->get_name()
13989 != c2->get_naming_typedef()->get_name())
13990 return false;
13991
13992 // Two anonymous enum types cannot be eligible to this optimization.
13993 if (const enum_type_decl *e1 = is_enum_type(&t1))
13994 if (const enum_type_decl *e2 = is_enum_type(&t2))
13995 if (e1->get_is_anonymous() || e2->get_is_anonymous())
13996 return false;
13997
13998 // Look through declaration-only types. That is, get the associated
13999 // definition type.
14000 c1 = look_through_decl_only_class(c1);
14001 c2 = look_through_decl_only_class(c2);
14002
14003 if (c1 && c2)
14004 {
14005 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
14006 {
14007 if (c1->get_environment().decl_only_class_equals_definition())
14008 // At least one of classes/union is declaration-only.
14009 // Because we are in a context in which a declaration-only
14010 // class/union is equal to all definitions of that
14011 // class/union, we can assume that the two types are
14012 // equal.
14013 return true;
14014 }
14015 }
14016
14017 if (t1.get_size_in_bits() != t2.get_size_in_bits())
14018 return false;
14019
14020 // Look at the file names of the locations of t1 and t2. If they
14021 // are equal, then t1 and t2 are defined in the same file.
14022 {
14023 location l;
14024
14025 if (c1)
14026 l = c1->get_location();
14027 else
14028 l = dynamic_cast<const decl_base&>(t1).get_location();
14029
14030 unsigned line = 0, col = 0;
14031 if (l)
14032 l.expand(t1_file_path, line, col);
14033 if (c2)
14034 l = c2->get_location();
14035 else
14036 l = dynamic_cast<const decl_base&>(t2).get_location();
14037 if (l)
14038 l.expand(t2_file_path, line, col);
14039 }
14040
14041 if (t1_file_path.empty() || t2_file_path.empty())
14042 return false;
14043
14044 if (t1_file_path == t2_file_path)
14045 return true;
14046
14047 return false;
14048 }
14049
14050
14051 /// Compare a type T against a canonical type.
14052 ///
14053 /// This function is called during the canonicalization process of the
14054 /// type T. T is called the "candidate type" because it's in the
14055 /// process of being canonicalized. Meaning, it's going to be
14056 /// compared to a canonical type C. If T equals C, then the canonical
14057 /// type of T is C.
14058 ///
14059 /// The purpose of this function is to allow the debugging of the
14060 /// canonicalization of T, if that debugging is activated by
14061 /// configuring the libabigail package with
14062 /// --enable-debug-type-canonicalization and by running "abidw
14063 /// --debug-tc". In that case, T is going to be compared to C twice:
14064 /// once with canonical equality and once with structural equality.
14065 /// The two comparisons must be equal. Otherwise, the
14066 /// canonicalization process is said to be faulty and this function
14067 /// aborts.
14068 ///
14069 /// This is a sub-routine of type_base::get_canonical_type_for.
14070 ///
14071 /// @param canonical_type the canonical type to compare the candidate
14072 /// type against.
14073 ///
14074 /// @param candidate_type the candidate type to compare against the
14075 /// canonical type.
14076 ///
14077 /// @return true iff @p canonical_type equals @p candidate_type.
14078 ///
14079 static bool
compare_types_during_canonicalization(const type_base_sptr & canonical_type,const type_base_sptr & candidate_type)14080 compare_types_during_canonicalization(const type_base_sptr& canonical_type,
14081 const type_base_sptr& candidate_type)
14082 {
14083 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
14084 const environment&env = canonical_type->get_environment();
14085 if (env.debug_type_canonicalization_is_on())
14086 {
14087 bool canonical_equality = false, structural_equality = false;
14088 env.priv_->use_canonical_type_comparison_ = false;
14089 structural_equality = canonical_type == candidate_type;
14090 env.priv_->use_canonical_type_comparison_ = true;
14091 canonical_equality = canonical_type == candidate_type;
14092 if (canonical_equality != structural_equality)
14093 {
14094 std::cerr << "structural & canonical equality different for type: "
14095 << canonical_type->get_pretty_representation(true, true)
14096 << std::endl;
14097 ABG_ASSERT_NOT_REACHED;
14098 }
14099 return structural_equality;
14100 }
14101 #endif //end WITH_DEBUG_TYPE_CANONICALIZATION
14102 return canonical_type == candidate_type;
14103 }
14104
14105 /// Compute the canonical type for a given instance of @ref type_base.
14106 ///
14107 /// Consider two types T and T'. The canonical type of T, denoted
14108 /// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
14109 /// otherwise, to compare two types, one just needs to compare their
14110 /// canonical types using pointer equality. That makes type
14111 /// comparison faster than the structural comparison performed by the
14112 /// abigail::ir::equals() overloads.
14113 ///
14114 /// If there is not yet any canonical type for @p t, then @p t is its
14115 /// own canonical type. Otherwise, this function returns the
14116 /// canonical type of @p t which is the canonical type that has the
14117 /// same hash value as @p t and that structurally equals @p t. Note
14118 /// that after invoking this function, the life time of the returned
14119 /// canonical time is then equals to the life time of the current
14120 /// process.
14121 ///
14122 /// @param t a smart pointer to instance of @ref type_base we want to
14123 /// compute a canonical type for.
14124 ///
14125 /// @return the canonical type for the current instance of @ref
14126 /// type_base.
14127 type_base_sptr
get_canonical_type_for(type_base_sptr t)14128 type_base::get_canonical_type_for(type_base_sptr t)
14129 {
14130 if (!t)
14131 return t;
14132
14133 environment& env = const_cast<environment&>(t->get_environment());
14134
14135 if (is_non_canonicalized_type(t))
14136 // This type should not be canonicalized!
14137 return type_base_sptr();
14138
14139 if (is_decl(t))
14140 t = is_type(look_through_decl_only(is_decl(t)));
14141
14142 // Look through decl-only types (classes, unions and enums)
14143 bool decl_only_class_equals_definition =
14144 (odr_is_relevant(*t) || env.decl_only_class_equals_definition());
14145
14146 class_or_union_sptr class_or_union = is_class_or_union_type(t);
14147
14148 // In the context of types from C++ or languages where we assume the
14149 // "One Definition Rule", we assume that a declaration-only
14150 // non-anonymous class equals all fully defined classes of the same
14151 // name.
14152 //
14153 // Otherwise, all classes, including declaration-only classes are
14154 // canonicalized and only canonical comparison is going to be used
14155 // in the system.
14156 if (decl_only_class_equals_definition)
14157 if (class_or_union)
14158 if (class_or_union->get_is_declaration_only())
14159 return type_base_sptr();
14160
14161 class_decl_sptr is_class = is_class_type(t);
14162 if (t->get_canonical_type())
14163 return t->get_canonical_type();
14164
14165 // For classes and union, ensure that an anonymous class doesn't
14166 // have a linkage name. If it does in the future, then me must be
14167 // mindful that the linkage name respects the type identity
14168 // constraints which states that "if two linkage names are different
14169 // then the two types are different".
14170 ABG_ASSERT(!class_or_union
14171 || !class_or_union->get_is_anonymous()
14172 || class_or_union->get_linkage_name().empty());
14173
14174 // We want the pretty representation of the type, but for an
14175 // internal use, not for a user-facing purpose.
14176 //
14177 // If two classe types Foo are declared, one as a class and the
14178 // other as a struct, but are otherwise equivalent, we want their
14179 // pretty representation to be the same. Hence the 'internal'
14180 // argument of ir::get_pretty_representation() is set to true here.
14181 // So in this case, the pretty representation of Foo is going to be
14182 // "class Foo", regardless of its struct-ness. This also applies to
14183 // composite types which would have "class Foo" as a sub-type.
14184 string repr = t->get_cached_pretty_representation(/*internal=*/true);
14185
14186 // If 't' already has a canonical type 'inside' its corpus
14187 // (t_corpus), then this variable is going to contain that canonical
14188 // type.
14189 type_base_sptr canonical_type_present_in_corpus;
14190 environment::canonical_types_map_type& types =
14191 env.get_canonical_types_map();
14192
14193 type_base_sptr result;
14194 environment::canonical_types_map_type::iterator i = types.find(repr);
14195 if (i == types.end())
14196 {
14197 vector<type_base_sptr> v;
14198 v.push_back(t);
14199 types[repr] = v;
14200 result = t;
14201 }
14202 else
14203 {
14204 vector<type_base_sptr> &v = i->second;
14205 // Let's compare 't' structurally (i.e, compare its sub-types
14206 // recursively) against the canonical types of the system. If it
14207 // equals a given canonical type C, then it means C is the
14208 // canonical type of 't'. Otherwise, if 't' is different from
14209 // all the canonical types of the system, then it means 't' is a
14210 // canonical type itself.
14211 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
14212 it != v.rend();
14213 ++it)
14214 {
14215 // Before the "*it == it" comparison below is done, let's
14216 // perform on-the-fly-canonicalization. For C types, let's
14217 // consider that an unresolved struct declaration 'struct S'
14218 // is different from a definition 'struct S'. This is
14219 // because normally, at this point all the declarations of
14220 // struct S that are compatible with the definition of
14221 // struct S have already been resolved to that definition,
14222 // during the DWARF parsing. The remaining unresolved
14223 // declaration are thus considered different. With this
14224 // setup we can properly handle cases of two *different*
14225 // struct S being defined in the same binary (in different
14226 // translation units), and a third struct S being only
14227 // declared as an opaque type in a third translation unit of
14228 // its own, with no definition in there. In that case, the
14229 // declaration-only struct S should be left alone and not
14230 // resolved to any of the two definitions of struct S.
14231 bool saved_decl_only_class_equals_definition =
14232 env.decl_only_class_equals_definition();
14233 env.do_on_the_fly_canonicalization(true);
14234 // Compare types by considering that decl-only classes don't
14235 // equal their definition.
14236 env.decl_only_class_equals_definition(false);
14237 env.priv_->allow_type_comparison_results_caching(true);
14238 bool equal = (types_defined_same_linux_kernel_corpus_public(**it, *t)
14239 || compare_types_during_canonicalization(*it, t));
14240 // Restore the state of the on-the-fly-canonicalization and
14241 // the decl-only-class-being-equal-to-a-matching-definition
14242 // flags.
14243 env.priv_->allow_type_comparison_results_caching(false);
14244 env.do_on_the_fly_canonicalization(false);
14245 env.decl_only_class_equals_definition
14246 (saved_decl_only_class_equals_definition);
14247 if (equal)
14248 {
14249 result = *it;
14250 break;
14251 }
14252 }
14253 #ifdef WITH_DEBUG_SELF_COMPARISON
14254 if (env.self_comparison_debug_is_on())
14255 {
14256 // So we are debugging the canonicalization process,
14257 // possibly via the use of 'abidw --debug-abidiff <binary>'.
14258 corpus_sptr corp1, corp2;
14259 env.get_self_comparison_debug_inputs(corp1, corp2);
14260 if (corp1 && corp2 && t->get_corpus() == corp2.get())
14261 {
14262 // If 't' comes from the second corpus, then it *must*
14263 // be equal to its matching canonical type coming from
14264 // the first corpus because the second corpus is the
14265 // abixml representation of the first corpus. In other
14266 // words, all types coming from the second corpus must
14267 // have canonical types coming from the first corpus.
14268 if (result)
14269 {
14270 if (!env.priv_->
14271 check_canonical_type_from_abixml_during_self_comp(t,
14272 result))
14273 // The canonical type of the type re-read from abixml
14274 // type doesn't match the canonical type that was
14275 // initially serialized down.
14276 std::cerr << "error: wrong canonical type for '"
14277 << repr
14278 << "' / type: @"
14279 << std::hex
14280 << t.get()
14281 << "/ canon: @"
14282 << result.get()
14283 << std::endl;
14284 }
14285 else //!result
14286 {
14287 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
14288 string type_id = env.get_type_id_from_pointer(ptr_val);
14289 if (type_id.empty())
14290 type_id = "type-id-<not-found>";
14291 // We are in the case where 't' is different from all
14292 // the canonical types of the same name that come from
14293 // the first corpus.
14294 //
14295 // If 't' indeed comes from the second corpus then this
14296 // clearly is a canonicalization failure.
14297 //
14298 // There was a problem either during the serialization
14299 // of 't' into abixml, or during the de-serialization
14300 // from abixml into abigail::ir. Further debugging is
14301 // needed to determine what that root cause problem is.
14302 //
14303 // Note that the first canonicalization problem of this
14304 // kind must be fixed before looking at the subsequent
14305 // ones, because the later might well just be
14306 // consequences of the former.
14307 std::cerr << "error: wrong induced canonical type for '"
14308 << repr
14309 << "' from second corpus"
14310 << ", ptr: " << std::hex << t.get()
14311 << "type-id: " << type_id
14312 << std::endl;
14313 }
14314 }
14315 }
14316 #endif
14317
14318 if (!result)
14319 {
14320 v.push_back(t);
14321 result = t;
14322 }
14323 }
14324
14325 return result;
14326 }
14327
14328 /// This method is invoked automatically right after the current
14329 /// instance of @ref class_decl has been canonicalized.
14330 void
on_canonical_type_set()14331 type_base::on_canonical_type_set()
14332 {}
14333
14334 /// This is a subroutine of the canonicalize() function.
14335 ///
14336 /// When the canonical type C of type T has just been computed, there
14337 /// can be cases where T has member functions that C doesn't have.
14338 ///
14339 /// This is possible because non virtual member functions are not
14340 /// taken in account when comparing two types.
14341 ///
14342 /// In that case, this function updates C so that it contains the
14343 /// member functions.
14344 ///
14345 /// There can also be cases where C has a method M which is not linked
14346 /// to any underlying symbol, whereas in T, M is to link to an
14347 /// underlying symbol. In that case, this function updates M in C so
14348 /// that it's linked to the same underlying symbol as for M in T.
14349 static void
maybe_adjust_canonical_type(const type_base_sptr & canonical,const type_base_sptr & type)14350 maybe_adjust_canonical_type(const type_base_sptr& canonical,
14351 const type_base_sptr& type)
14352 {
14353 if (!canonical
14354 // If 'type' is *NOT* a newly canonicalized type ...
14355 || type->get_naked_canonical_type()
14356 // ... or if 'type' is it's own canonical type, then get out.
14357 || type.get() == canonical.get())
14358 return;
14359
14360 if (class_decl_sptr cl = is_class_type(type))
14361 {
14362 class_decl_sptr canonical_class = is_class_type(canonical);
14363
14364 if (canonical_class)
14365 {
14366 // Set symbols of member functions that might be missing
14367 // theirs.
14368 for (class_decl::member_functions::const_iterator i =
14369 cl->get_member_functions().begin();
14370 i != cl->get_member_functions().end();
14371 ++i)
14372 if ((*i)->get_symbol())
14373 {
14374 if (method_decl *m = canonical_class->
14375 find_member_function((*i)->get_linkage_name()))
14376 {
14377 elf_symbol_sptr s1 = (*i)->get_symbol();
14378 if (s1 && !m->get_symbol())
14379 // Method 'm' in the canonical type is not
14380 // linked to the underlying symbol of '*i'.
14381 // Let's link it now. have th
14382 m->set_symbol(s1);
14383 }
14384 else
14385 // There is a member function defined and publicly
14386 // exported in the other class, and the canonical
14387 // class doesn't have that member function. Let's
14388 // copy that member function to the canonical class
14389 // then.
14390 copy_member_function (canonical_class, *i);
14391 }
14392 }
14393 }
14394
14395 // If an artificial function type equals a non-artfificial one in
14396 // the system, then the canonical type of both should be deemed
14397 // non-artificial. This is important because only non-artificial
14398 // canonical function types are emitted out into abixml, so if don't
14399 // do this we risk missing to emit some function types.
14400 if (is_function_type(type))
14401 if (type->get_is_artificial() != canonical->get_is_artificial())
14402 canonical->set_is_artificial(false);
14403 }
14404
14405 /// Compute the canonical type of a given type.
14406 ///
14407 /// It means that after invoking this function, comparing the intance
14408 /// instance @ref type_base and another one (on which
14409 /// type_base::enable_canonical_equality() would have been invoked as
14410 /// well) is performed by just comparing the pointer values of the
14411 /// canonical types of both types. That equality comparison is
14412 /// supposedly faster than structural comparison of the types.
14413 ///
14414 /// @param t a smart pointer to the instance of @ref type_base for
14415 /// which to compute the canonical type. After this call,
14416 /// t->get_canonical_type() will return the newly computed canonical
14417 /// type.
14418 ///
14419 /// @return the canonical type computed for @p t.
14420 type_base_sptr
canonicalize(type_base_sptr t)14421 canonicalize(type_base_sptr t)
14422 {
14423 if (!t)
14424 return t;
14425
14426 if (t->get_canonical_type())
14427 return t->get_canonical_type();
14428
14429 type_base_sptr canonical = type_base::get_canonical_type_for(t);
14430 maybe_adjust_canonical_type(canonical, t);
14431
14432 t->priv_->canonical_type = canonical;
14433 t->priv_->naked_canonical_type = canonical.get();
14434
14435 // So this type is now canonicalized.
14436 //
14437 // It means that:
14438 //
14439 // 1/ Either the canonical type was not propagated during the
14440 // comparison of another type that was being canonicalized
14441 //
14442 // 2/ Or the canonical type has been propagated during the
14443 // comparison of another type that was being canonicalized and
14444 // that propagated canonical type has been confirmed, because
14445 // it was depending on a recursive type which comparison
14446 // succeeded.
14447 ABG_ASSERT(!t->priv_->canonical_type_propagated()
14448 || t->priv_->propagated_canonical_type_confirmed());
14449
14450 if (class_decl_sptr cl = is_class_type(t))
14451 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
14452 if ((canonical = d->get_canonical_type()))
14453 {
14454 d->priv_->canonical_type = canonical;
14455 d->priv_->naked_canonical_type = canonical.get();
14456 }
14457
14458 if (canonical)
14459 if (decl_base_sptr d = is_decl_slow(canonical))
14460 {
14461 scope_decl *scope = d->get_scope();
14462 // Add the canonical type to the set of canonical types
14463 // belonging to its scope.
14464 if (scope)
14465 {
14466 if (is_type(scope))
14467 // The scope in question is itself a type (e.g, a class
14468 // or union). Let's call that type ST. We want to add
14469 // 'canonical' to the set of canonical types belonging
14470 // to ST.
14471 if (type_base_sptr c = is_type(scope)->get_canonical_type())
14472 // We want to add 'canonical' to set of canonical
14473 // types belonging to the canonical type of ST. That
14474 // way, just looking at the canonical type of ST is
14475 // enough to get the types that belong to the scope of
14476 // the class of equivalence of ST.
14477 scope = is_scope_decl(is_decl(c)).get();
14478 scope->get_canonical_types().insert(canonical);
14479 }
14480 // else, if the type doesn't have a scope, it's not meant to be
14481 // emitted. This can be the case for the result of the
14482 // function strip_typedef, for instance.
14483 }
14484
14485 t->on_canonical_type_set();
14486 return canonical;
14487 }
14488
14489
14490 /// Set the definition of this declaration-only @ref decl_base.
14491 ///
14492 /// @param d the new definition to set.
14493 void
set_definition_of_declaration(const decl_base_sptr & d)14494 decl_base::set_definition_of_declaration(const decl_base_sptr& d)
14495 {
14496 ABG_ASSERT(get_is_declaration_only());
14497 priv_->definition_of_declaration_ = d;
14498 if (type_base *t = is_type(this))
14499 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
14500 t->priv_->canonical_type = canonical_type;
14501
14502 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
14503 }
14504
14505 /// The constructor of @ref type_base.
14506 ///
14507 /// @param s the size of the type, in bits.
14508 ///
14509 /// @param a the alignment of the type, in bits.
type_base(const environment & e,size_t s,size_t a)14510 type_base::type_base(const environment& e, size_t s, size_t a)
14511 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
14512 priv_(new priv(s, a))
14513 {}
14514
14515 /// Getter of the canonical type of the current instance of @ref
14516 /// type_base.
14517 ///
14518 /// @return a smart pointer to the canonical type of the current
14519 /// intance of @ref type_base, or an empty smart pointer if the
14520 /// current instance of @ref type_base doesn't have any canonical
14521 /// type.
14522 type_base_sptr
get_canonical_type() const14523 type_base::get_canonical_type() const
14524 {return priv_->canonical_type.lock();}
14525
14526 /// Getter of the canonical type pointer.
14527 ///
14528 /// Note that this function doesn't return a smart pointer, but rather
14529 /// the underlying pointer managed by the smart pointer. So it's as
14530 /// fast as possible. This getter is to be used in code paths that
14531 /// are proven to be performance hot spots; especially, when comparing
14532 /// sensitive types like class, function, pointers and reference
14533 /// types. Those are compared extremely frequently and thus, their
14534 /// accessing the canonical type must be fast.
14535 ///
14536 /// @return the canonical type pointer, not managed by a smart
14537 /// pointer.
14538 type_base*
get_naked_canonical_type() const14539 type_base::get_naked_canonical_type() const
14540 {return priv_->naked_canonical_type;}
14541
14542 /// Get the pretty representation of the current type.
14543 ///
14544 /// The pretty representation is retrieved from a cache. If the cache
14545 /// is empty, this function computes the pretty representation, put it
14546 /// in the cache and returns it.
14547 ///
14548 /// Note that if the type is *NOT* canonicalized, the pretty
14549 /// representation is never cached.
14550 ///
14551 /// @param internal if true, then the pretty representation is to be
14552 /// used for purpuses that are internal to the libabigail library
14553 /// itself. If you don't know what this means, then you probably
14554 /// should set this parameter to "false".
14555 const interned_string&
get_cached_pretty_representation(bool internal) const14556 type_base::get_cached_pretty_representation(bool internal) const
14557 {
14558 if (internal)
14559 {
14560 if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
14561 {
14562 string r = ir::get_pretty_representation(this, internal);
14563 priv_->internal_cached_repr_ = get_environment().intern(r);
14564 }
14565 return priv_->internal_cached_repr_;
14566 }
14567
14568 if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
14569 {
14570 string r = ir::get_pretty_representation(this, internal);
14571 priv_->cached_repr_ = get_environment().intern(r);
14572 }
14573
14574 return priv_->cached_repr_;
14575 }
14576
14577 /// Compares two instances of @ref type_base.
14578 ///
14579 /// If the two intances are different, set a bitfield to give some
14580 /// insight about the kind of differences there are.
14581 ///
14582 /// @param l the first artifact of the comparison.
14583 ///
14584 /// @param r the second artifact of the comparison.
14585 ///
14586 /// @param k a pointer to a bitfield that gives information about the
14587 /// kind of changes there are between @p l and @p r. This one is set
14588 /// iff @p is non-null and if the function returns false.
14589 ///
14590 /// Please note that setting k to a non-null value does have a
14591 /// negative performance impact because even if @p l and @p r are not
14592 /// equal, the function keeps up the comparison in order to determine
14593 /// the different kinds of ways in which they are different.
14594 ///
14595 /// @return true if @p l equals @p r, false otherwise.
14596 bool
equals(const type_base & l,const type_base & r,change_kind * k)14597 equals(const type_base& l, const type_base& r, change_kind* k)
14598 {
14599 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
14600 && l.get_alignment_in_bits() == r.get_alignment_in_bits());
14601 if (!result)
14602 if (k)
14603 *k |= LOCAL_TYPE_CHANGE_KIND;
14604 ABG_RETURN(result);
14605 }
14606
14607 /// Return true iff both type declarations are equal.
14608 ///
14609 /// Note that this doesn't test if the scopes of both types are equal.
14610 bool
operator ==(const type_base & other) const14611 type_base::operator==(const type_base& other) const
14612 {return equals(*this, other, 0);}
14613
14614 /// Inequality operator.
14615 ///
14616 ///@param other the instance of @ref type_base to compare the current
14617 /// instance against.
14618 ///
14619 /// @return true iff the current instance is different from @p other.
14620 bool
operator !=(const type_base & other) const14621 type_base::operator!=(const type_base& other) const
14622 {return !operator==(other);}
14623
14624 /// Setter for the size of the type.
14625 ///
14626 /// @param s the new size -- in bits.
14627 void
set_size_in_bits(size_t s)14628 type_base::set_size_in_bits(size_t s)
14629 {priv_->size_in_bits = s;}
14630
14631 /// Getter for the size of the type.
14632 ///
14633 /// @return the size in bits of the type.
14634 size_t
get_size_in_bits() const14635 type_base::get_size_in_bits() const
14636 {return priv_->size_in_bits;}
14637
14638 /// Setter for the alignment of the type.
14639 ///
14640 /// @param a the new alignment -- in bits.
14641 void
set_alignment_in_bits(size_t a)14642 type_base::set_alignment_in_bits(size_t a)
14643 {priv_->alignment_in_bits = a;}
14644
14645 /// Getter for the alignment of the type.
14646 ///
14647 /// @return the alignment of the type in bits.
14648 size_t
get_alignment_in_bits() const14649 type_base::get_alignment_in_bits() const
14650 {return priv_->alignment_in_bits;}
14651
14652 /// Default implementation of traversal for types. This function does
14653 /// nothing. It must be implemented by every single new type that is
14654 /// written.
14655 ///
14656 /// Please look at e.g, class_decl::traverse() for an example of how
14657 /// to implement this.
14658 ///
14659 /// @param v the visitor used to visit the type.
14660 bool
traverse(ir_node_visitor & v)14661 type_base::traverse(ir_node_visitor& v)
14662 {
14663 if (v.type_node_has_been_visited(this))
14664 return true;
14665
14666 v.visit_begin(this);
14667 bool result = v.visit_end(this);
14668 v.mark_type_node_as_visited(this);
14669
14670 return result;
14671 }
14672
~type_base()14673 type_base::~type_base()
14674 {delete priv_;}
14675
14676 // </type_base definitions>
14677
14678 // <integral_type definitions>
14679
14680 /// Bitwise OR operator for integral_type::modifiers_type.
14681 ///
14682 /// @param l the left-hand side operand.
14683 ///
14684 /// @param r the right-hand side operand.
14685 ///
14686 /// @return the result of the bitwise OR.
14687 integral_type::modifiers_type
operator |(integral_type::modifiers_type l,integral_type::modifiers_type r)14688 operator|(integral_type::modifiers_type l, integral_type::modifiers_type r)
14689 {
14690 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
14691 |
14692 static_cast<unsigned>(r));
14693 }
14694
14695 /// Bitwise AND operator for integral_type::modifiers_type.
14696 ///
14697 /// @param l the left-hand side operand.
14698 ///
14699 /// @param r the right-hand side operand.
14700 ///
14701 /// @return the result of the bitwise AND.
14702 integral_type::modifiers_type
operator &(integral_type::modifiers_type l,integral_type::modifiers_type r)14703 operator&(integral_type::modifiers_type l, integral_type::modifiers_type r)
14704 {
14705 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
14706 &
14707 static_cast<unsigned>(r));
14708 }
14709
14710 /// Bitwise one's complement operator for integral_type::modifiers_type.
14711 ///
14712 /// @param l the left-hand side operand.
14713 ///
14714 /// @param r the right-hand side operand.
14715 ///
14716 /// @return the result of the bitwise one's complement operator.
14717 integral_type::modifiers_type
operator ~(integral_type::modifiers_type l)14718 operator~(integral_type::modifiers_type l)
14719 {
14720 return static_cast<integral_type::modifiers_type>(~static_cast<unsigned>(l));
14721 }
14722
14723 /// Bitwise |= operator for integral_type::modifiers_type.
14724 ///
14725 /// @param l the left-hand side operand.
14726 ///
14727 /// @param r the right-hand side operand.
14728 ///
14729 /// @return the result of the bitwise |=.
14730 integral_type::modifiers_type&
operator |=(integral_type::modifiers_type & l,integral_type::modifiers_type r)14731 operator|=(integral_type::modifiers_type& l, integral_type::modifiers_type r)
14732 {
14733 l = l | r;
14734 return l;
14735 }
14736
14737 /// Bitwise &= operator for integral_type::modifiers_type.
14738 ///
14739 /// @param l the left-hand side operand.
14740 ///
14741 /// @param r the right-hand side operand.
14742 ///
14743 /// @return the result of the bitwise &=.
14744 integral_type::modifiers_type&
operator &=(integral_type::modifiers_type & l,integral_type::modifiers_type r)14745 operator&=(integral_type::modifiers_type& l, integral_type::modifiers_type r)
14746 {
14747 l = l & r;
14748 return l;
14749 }
14750
14751 /// Parse a word containing one integral type modifier.
14752 ///
14753 /// A word is considered to be a string of characters that doesn't
14754 /// contain any white space.
14755 ///
14756 /// @param word the word to parse. It is considered to be a string of
14757 /// characters that doesn't contain any white space.
14758 ///
14759 /// @param modifiers out parameter. It's set by this function to the
14760 /// parsed modifier iff the function returned true.
14761 ///
14762 /// @return true iff @word was successfully parsed.
14763 static bool
parse_integral_type_modifier(const string & word,integral_type::modifiers_type & modifiers)14764 parse_integral_type_modifier(const string& word,
14765 integral_type::modifiers_type &modifiers)
14766 {
14767 if (word == "signed")
14768 modifiers |= integral_type::SIGNED_MODIFIER;
14769 else if (word == "unsigned")
14770 modifiers |= integral_type::UNSIGNED_MODIFIER;
14771 else if (word == "short")
14772 modifiers |= integral_type::SHORT_MODIFIER;
14773 else if (word == "long")
14774 modifiers |= integral_type::LONG_MODIFIER;
14775 else if (word == "long long")
14776 modifiers |= integral_type::LONG_LONG_MODIFIER;
14777 else
14778 return false;
14779
14780 return true;
14781 }
14782
14783 /// Parse a base type of an integral type from a string.
14784 ///
14785 /// @param type_name the type name to parse.
14786 ///
14787 /// @param base out parameter. This is set to the resulting base type
14788 /// parsed, iff the function returned true.
14789 ///
14790 /// @return true iff the function could successfully parse the base
14791 /// type.
14792 static bool
parse_base_integral_type(const string & type_name,integral_type::base_type & base)14793 parse_base_integral_type(const string& type_name,
14794 integral_type::base_type& base)
14795 {
14796 if (type_name == "int")
14797 base = integral_type::INT_BASE_TYPE;
14798 else if (type_name == "char")
14799 base = integral_type::CHAR_BASE_TYPE;
14800 else if (type_name == "bool" || type_name == "_Bool")
14801 base = integral_type::BOOL_BASE_TYPE;
14802 else if (type_name == "double")
14803 base = integral_type::DOUBLE_BASE_TYPE;
14804 else if (type_name =="float")
14805 base = integral_type::FLOAT_BASE_TYPE;
14806 else if (type_name == "char16_t")
14807 base = integral_type::CHAR16_T_BASE_TYPE;
14808 else if (type_name == "char32_t")
14809 base = integral_type::CHAR32_T_BASE_TYPE;
14810 else if (type_name == "wchar_t")
14811 base = integral_type::WCHAR_T_BASE_TYPE;
14812 else
14813 return false;
14814
14815 return true;
14816 }
14817
14818 /// Parse an integral type from a string.
14819 ///
14820 /// @param type_name the string containing the integral type to parse.
14821 ///
14822 /// @param base out parameter. Is set by this function to the base
14823 /// type of the integral type, iff the function returned true.
14824 ///
14825 /// @param modifiers out parameter If set by this function to the
14826 /// modifier of the integral type, iff the function returned true.
14827 ///
14828 /// @return true iff the function could parse an integral type from @p
14829 /// type_name.
14830 static bool
parse_integral_type(const string & type_name,integral_type::base_type & base,integral_type::modifiers_type & modifiers)14831 parse_integral_type(const string& type_name,
14832 integral_type::base_type& base,
14833 integral_type::modifiers_type& modifiers)
14834 {
14835 string input = type_name;
14836 string::size_type len = input.length();
14837 string::size_type cur_pos = 0, prev_pos = 0;
14838 string cur_word, prev_word;
14839 bool ok = false;
14840
14841 while (cur_pos < len)
14842 {
14843 if (cur_pos < len && isspace(input[cur_pos]))
14844 do
14845 ++cur_pos;
14846 while (cur_pos < len && isspace(input[cur_pos]));
14847
14848 prev_pos = cur_pos;
14849 cur_pos = input.find(' ', prev_pos);
14850 prev_word = cur_word;
14851 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
14852
14853 if (cur_pos < len
14854 && cur_word == "long"
14855 && prev_word != "long")
14856 {
14857 if (cur_pos < len && isspace(input[cur_pos]))
14858 do
14859 ++cur_pos;
14860 while (cur_pos < len && isspace(input[cur_pos]));
14861 prev_pos = cur_pos;
14862
14863 cur_pos = input.find(' ', prev_pos);
14864 string saved_prev_word = prev_word;
14865 prev_word = cur_word;
14866 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
14867 if (cur_word == "long")
14868 cur_word = "long long";
14869 else
14870 {
14871 cur_pos = prev_pos;
14872 cur_word = prev_word;
14873 prev_word = saved_prev_word;
14874 }
14875 }
14876
14877 if (!parse_integral_type_modifier(cur_word, modifiers))
14878 {
14879 if (!parse_base_integral_type(cur_word, base))
14880 return false;
14881 else
14882 ok = true;
14883 }
14884 else
14885 ok = true;
14886 }
14887
14888 return ok;
14889 }
14890
14891 /// Parse an integral type from a string.
14892 ///
14893 /// @param str the string containing the integral type to parse.
14894 ///
14895 ///@param type the resulting @ref integral_type. Is set to the result
14896 ///of the parse, iff the function returns true.
14897 ///
14898 /// @return true iff the function could parse an integral type from @p
14899 /// str.
14900 bool
parse_integral_type(const string & str,integral_type & type)14901 parse_integral_type(const string& str, integral_type& type)
14902 {
14903 integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
14904 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
14905
14906 if (!parse_integral_type(str, base_type, modifiers))
14907 return false;
14908
14909 // So this is an integral type.
14910 integral_type int_type(base_type, modifiers);
14911 type = int_type;
14912 return true;
14913 }
14914
14915 /// Default constructor of the @ref integral_type.
integral_type()14916 integral_type::integral_type()
14917 : base_(INT_BASE_TYPE),
14918 modifiers_(NO_MODIFIER)
14919 {}
14920
14921 /// Constructor of the @ref integral_type.
14922 ///
14923 /// @param b the base type of the integral type.
14924 ///
14925 /// @param m the modifiers of the integral type.
integral_type(base_type b,modifiers_type m)14926 integral_type::integral_type(base_type b, modifiers_type m)
14927 : base_(b), modifiers_(m)
14928 {}
14929
14930 /// Constructor of the @ref integral_type.
14931 ///
14932 /// @param the name of the integral type to parse to initialize the
14933 /// current instance of @ref integral_type.
integral_type(const string & type_name)14934 integral_type::integral_type(const string& type_name)
14935 : base_(INT_BASE_TYPE),
14936 modifiers_(NO_MODIFIER)
14937 {
14938 bool could_parse = parse_integral_type(type_name, base_, modifiers_);
14939 ABG_ASSERT(could_parse);
14940 }
14941
14942 /// Getter of the base type of the @ref integral_type.
14943 ///
14944 /// @return the base type of the @ref integral_type.
14945 integral_type::base_type
get_base_type() const14946 integral_type::get_base_type() const
14947 {return base_;}
14948
14949 /// Getter of the modifiers bitmap of the @ref integral_type.
14950 ///
14951 /// @return the modifiers bitmap of the @ref integral_type.
14952 integral_type::modifiers_type
get_modifiers() const14953 integral_type::get_modifiers() const
14954 {return modifiers_;}
14955
14956 /// Setter of the modifiers bitmap of the @ref integral_type.
14957 ///
14958 /// @param m the new modifiers.
14959 void
set_modifiers(modifiers_type m)14960 integral_type::set_modifiers(modifiers_type m)
14961 {modifiers_ = m;}
14962
14963 /// Equality operator for the @ref integral_type.
14964 ///
14965 /// @param other the other integral type to compare against.
14966 ///
14967 /// @return true iff @p other equals the current instance of @ref
14968 /// integral_type.
14969 bool
operator ==(const integral_type & other) const14970 integral_type::operator==(const integral_type&other) const
14971 {return base_ == other.base_ && modifiers_ == other.modifiers_;}
14972
14973 /// Return the string representation of the current instance of @ref
14974 /// integral_type.
14975 ///
14976 /// @param internal if true the string representation is to be used
14977 /// for internal purposes. In general, it means it's for type
14978 /// canonicalization purposes.
14979 ///
14980 /// @return the string representation of the current instance of @ref
14981 /// integral_type.
14982 string
to_string(bool internal) const14983 integral_type::to_string(bool internal) const
14984 {
14985 string result;
14986
14987 // Look at modifiers ...
14988 if (modifiers_ & SIGNED_MODIFIER)
14989 result += "signed ";
14990 if (modifiers_ & UNSIGNED_MODIFIER)
14991 result += "unsigned ";
14992 if (!internal)
14993 {
14994 // For canonicalization purposes, we won't emit the "short, long, or
14995 // long long" modifiers. This is because on some platforms, "long
14996 // int" and "long long int" might have the same size. In those
14997 // cases, we want the two types to be equivalent if they have the
14998 // same size. If they don't have the same internal string
14999 // representation, they'd automatically have different canonical
15000 // types and thus be canonically different.
15001 if (modifiers_ & SHORT_MODIFIER)
15002 result += "short ";
15003 if (modifiers_ & LONG_MODIFIER)
15004 result += "long ";
15005 if (modifiers_ & LONG_LONG_MODIFIER)
15006 result += "long long ";
15007 }
15008
15009 // ... and look at base types.
15010 if (base_ == INT_BASE_TYPE)
15011 result += "int";
15012 else if (base_ == CHAR_BASE_TYPE)
15013 result += "char";
15014 else if (base_ == BOOL_BASE_TYPE)
15015 result += "bool";
15016 else if (base_ == DOUBLE_BASE_TYPE)
15017 result += "double";
15018 else if (base_ == FLOAT_BASE_TYPE)
15019 result += "float";
15020 else if (base_ == CHAR16_T_BASE_TYPE)
15021 result += "char16_t";
15022 else if (base_ == CHAR32_T_BASE_TYPE)
15023 result += "char32_t";
15024 else if (base_ == WCHAR_T_BASE_TYPE)
15025 result += "wchar_t";
15026
15027 return result;
15028 }
15029
15030 /// Convert the current instance of @ref integral_type into its string
15031 /// representation.
15032 ///
15033 /// @return the string representation of the current instance of @ref
15034 /// integral_type.
operator string() const15035 integral_type::operator string() const
15036 {return to_string();}
15037
15038 // </integral_type definitions>
15039
15040 //<type_decl definitions>
15041
15042 /// Constructor.
15043 ///
15044 /// @param env the environment we are operating from.
15045 ///
15046 /// @param name the name of the type declaration.
15047 ///
15048 /// @param size_in_bits the size of the current type_decl, in bits.
15049 ///
15050 /// @param alignment_in_bits the alignment of the current typ, in
15051 /// bits.
15052 ///
15053 /// @param locus the source location of the current type declaration.
15054 ///
15055 /// @param linkage_name the linkage_name of the current type declaration.
15056 ///
15057 /// @param vis the visibility of the type declaration.
type_decl(const environment & env,const string & name,size_t size_in_bits,size_t alignment_in_bits,const location & locus,const string & linkage_name,visibility vis)15058 type_decl::type_decl(const environment& env,
15059 const string& name,
15060 size_t size_in_bits,
15061 size_t alignment_in_bits,
15062 const location& locus,
15063 const string& linkage_name,
15064 visibility vis)
15065
15066 : type_or_decl_base(env,
15067 BASIC_TYPE
15068 | ABSTRACT_TYPE_BASE
15069 | ABSTRACT_DECL_BASE),
15070 decl_base(env, name, locus, linkage_name, vis),
15071 type_base(env, size_in_bits, alignment_in_bits)
15072 {
15073 runtime_type_instance(this);
15074
15075 integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
15076 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
15077 integral_type int_type(base_type, modifiers);
15078 if (parse_integral_type(name, int_type))
15079 {
15080 // Convert the integral_type into its canonical string
15081 // representation.
15082 string integral_type_name = int_type;
15083
15084 // Set the name of this type_decl to the canonical string
15085 // representation above
15086 set_name(integral_type_name);
15087 set_qualified_name(get_name());
15088
15089 if (!get_linkage_name().empty())
15090 set_linkage_name(integral_type_name);
15091 }
15092 }
15093
15094 /// Compares two instances of @ref type_decl.
15095 ///
15096 /// If the two intances are different, set a bitfield to give some
15097 /// insight about the kind of differences there are.
15098 ///
15099 /// @param l the first artifact of the comparison.
15100 ///
15101 /// @param r the second artifact of the comparison.
15102 ///
15103 /// @param k a pointer to a bitfield that gives information about the
15104 /// kind of changes there are between @p l and @p r. This one is set
15105 /// iff @p k is non-null and the function returns false.
15106 ///
15107 /// Please note that setting k to a non-null value does have a
15108 /// negative performance impact because even if @p l and @p r are not
15109 /// equal, the function keeps up the comparison in order to determine
15110 /// the different kinds of ways in which they are different.
15111 ///
15112 /// @return true if @p l equals @p r, false otherwise.
15113 bool
equals(const type_decl & l,const type_decl & r,change_kind * k)15114 equals(const type_decl& l, const type_decl& r, change_kind* k)
15115 {
15116 bool result = false;
15117
15118 // Consider the types as decls to compare their decls-related
15119 // properties.
15120 result = equals(static_cast<const decl_base&>(l),
15121 static_cast<const decl_base&>(r),
15122 k);
15123 if (!k && !result)
15124 ABG_RETURN_FALSE;
15125
15126 // Now consider the types a "types' to compare their size-related
15127 // properties.
15128 result &= equals(static_cast<const type_base&>(l),
15129 static_cast<const type_base&>(r),
15130 k);
15131 ABG_RETURN(result);
15132 }
15133
15134 /// Return true if both types equals.
15135 ///
15136 /// This operator re-uses the overload that takes a decl_base.
15137 ///
15138 /// Note that this does not check the scopes of any of the types.
15139 ///
15140 /// @param o the other type_decl to check agains.
15141 bool
operator ==(const type_base & o) const15142 type_decl::operator==(const type_base& o) const
15143 {
15144 const decl_base* other = dynamic_cast<const decl_base*>(&o);
15145 if (!other)
15146 return false;
15147 return *this == *other;
15148 }
15149
15150 /// Return true if both types equals.
15151 ///
15152 /// Note that this does not check the scopes of any of the types.
15153 ///
15154 /// @param o the other type_decl to check against.
15155 bool
operator ==(const decl_base & o) const15156 type_decl::operator==(const decl_base& o) const
15157 {
15158 const type_decl* other = dynamic_cast<const type_decl*>(&o);
15159 if (!other)
15160 return false;
15161 return try_canonical_compare(this, other);
15162 }
15163
15164 /// Return true if both types equals.
15165 ///
15166 /// Note that this does not check the scopes of any of the types.
15167 ///
15168 /// @param o the other type_decl to check against.
15169 ///
15170 /// @return true iff the current isntance equals @p o
15171 bool
operator ==(const type_decl & o) const15172 type_decl::operator==(const type_decl& o) const
15173 {
15174 const decl_base& other = o;
15175 return *this == other;
15176 }
15177
15178 /// Inequality operator.
15179 ///
15180 /// @param o the other type to compare against.
15181 ///
15182 /// @return true iff the current instance is different from @p o.
15183 bool
operator !=(const type_decl & o) const15184 type_decl::operator!=(const type_decl& o) const
15185 {return !operator==(o);}
15186
15187 /// Equality operator for @ref type_decl_sptr.
15188 ///
15189 /// @param l the first operand to compare.
15190 ///
15191 /// @param r the second operand to compare.
15192 ///
15193 /// @return true iff @p l equals @p r.
15194 bool
operator ==(const type_decl_sptr & l,const type_decl_sptr & r)15195 operator==(const type_decl_sptr& l, const type_decl_sptr& r)
15196 {
15197 if (!!l != !!r)
15198 return false;
15199 if (l.get() == r.get())
15200 return true;
15201 return *l == *r;
15202 }
15203
15204 /// Inequality operator for @ref type_decl_sptr.
15205 ///
15206 /// @param l the first operand to compare.
15207 ///
15208 /// @param r the second operand to compare.
15209 ///
15210 /// @return true iff @p l is different from @p r.
15211 bool
operator !=(const type_decl_sptr & l,const type_decl_sptr & r)15212 operator!=(const type_decl_sptr& l, const type_decl_sptr& r)
15213 {return !operator==(l, r);}
15214
15215 /// Implementation for the virtual qualified name builder for @ref
15216 /// type_decl.
15217 ///
15218 /// @param qualified_name the output parameter to hold the resulting
15219 /// qualified name.
15220 ///
15221 /// @param internal set to true if the call is intended for an
15222 /// internal use (for technical use inside the library itself), false
15223 /// otherwise. If you don't know what this is for, then set it to
15224 /// false.
15225 void
get_qualified_name(interned_string & qualified_name,bool internal) const15226 type_decl::get_qualified_name(interned_string& qualified_name,
15227 bool internal) const
15228 {qualified_name = get_qualified_name(internal);}
15229
15230 /// Implementation for the virtual qualified name builder for @ref
15231 /// type_decl.
15232 ///
15233 /// @param qualified_name the output parameter to hold the resulting
15234 /// qualified name.
15235 ///
15236 /// @param internal set to true if the call is intended for an
15237 /// internal use (for technical use inside the library itself), false
15238 /// otherwise. If you don't know what this is for, then set it to
15239 /// false.
15240 const interned_string&
get_qualified_name(bool internal) const15241 type_decl::get_qualified_name(bool internal) const
15242 {
15243 const environment& env = get_environment();
15244
15245
15246 if (internal)
15247 if (is_integral_type(this))
15248 {
15249 if (get_naked_canonical_type())
15250 {
15251 if (decl_base::priv_->internal_qualified_name_.empty())
15252 decl_base::priv_->internal_qualified_name_ =
15253 env.intern(get_internal_integral_type_name(this));
15254 return decl_base::priv_->internal_qualified_name_;
15255 }
15256 else
15257 {
15258 decl_base::priv_->temporary_internal_qualified_name_ =
15259 env.intern(get_internal_integral_type_name(this));
15260 return decl_base::priv_->temporary_internal_qualified_name_;
15261 }
15262 }
15263
15264 return decl_base::get_qualified_name(/*internal=*/false);
15265 }
15266
15267 /// Get the pretty representation of the current instance of @ref
15268 /// type_decl.
15269 ///
15270 /// @param internal set to true if the call is intended to get a
15271 /// representation of the decl (or type) for the purpose of canonical
15272 /// type comparison. This is mainly used in the function
15273 /// type_base::get_canonical_type_for().
15274 ///
15275 /// In other words if the argument for this parameter is true then the
15276 /// call is meant for internal use (for technical use inside the
15277 /// library itself), false otherwise. If you don't know what this is
15278 /// for, then set it to false.
15279 ///
15280 /// @param qualified_name if true, names emitted in the pretty
15281 /// representation are fully qualified.
15282 ///
15283 /// @return the pretty representatin of the @ref type_decl.
15284 string
get_pretty_representation(bool internal,bool qualified_name) const15285 type_decl::get_pretty_representation(bool internal,
15286 bool qualified_name) const
15287 {
15288 if (internal)
15289 if (is_integral_type(this))
15290 return get_internal_integral_type_name(this);
15291
15292 if (qualified_name)
15293 return get_qualified_name(internal);
15294 return get_name();
15295 }
15296
15297 /// This implements the ir_traversable_base::traverse pure virtual
15298 /// function.
15299 ///
15300 /// @param v the visitor used on the current instance.
15301 ///
15302 /// @return true if the entire IR node tree got traversed, false
15303 /// otherwise.
15304 bool
traverse(ir_node_visitor & v)15305 type_decl::traverse(ir_node_visitor& v)
15306 {
15307 if (v.type_node_has_been_visited(this))
15308 return true;
15309
15310 v.visit_begin(this);
15311 bool result = v.visit_end(this);
15312 v.mark_type_node_as_visited(this);
15313
15314 return result;
15315 }
15316
~type_decl()15317 type_decl::~type_decl()
15318 {}
15319 //</type_decl definitions>
15320
15321 // <scope_type_decl definitions>
15322
15323 /// Constructor.
15324 ///
15325 /// @param env the environment we are operating from.
15326 ///
15327 /// @param name the name of the type.
15328 ///
15329 /// @param size_in_bits the size of the type, in bits.
15330 ///
15331 /// @param alignment_in_bits the alignment of the type, in bits.
15332 ///
15333 /// @param locus the source location where the type is defined.
15334 ///
15335 /// @param vis the visibility of the type.
scope_type_decl(const environment & env,const string & name,size_t size_in_bits,size_t alignment_in_bits,const location & locus,visibility vis)15336 scope_type_decl::scope_type_decl(const environment& env,
15337 const string& name,
15338 size_t size_in_bits,
15339 size_t alignment_in_bits,
15340 const location& locus,
15341 visibility vis)
15342 : type_or_decl_base(env,
15343 ABSTRACT_SCOPE_TYPE_DECL
15344 | ABSTRACT_TYPE_BASE
15345 | ABSTRACT_DECL_BASE),
15346 decl_base(env, name, locus, "", vis),
15347 type_base(env, size_in_bits, alignment_in_bits),
15348 scope_decl(env, name, locus)
15349 {}
15350
15351 /// Compares two instances of @ref scope_type_decl.
15352 ///
15353 /// If the two intances are different, set a bitfield to give some
15354 /// insight about the kind of differences there are.
15355 ///
15356 /// @param l the first artifact of the comparison.
15357 ///
15358 /// @param r the second artifact of the comparison.
15359 ///
15360 /// @param k a pointer to a bitfield that gives information about the
15361 /// kind of changes there are between @p l and @p r. This one is set
15362 /// iff @p k is non-null and the function returns false.
15363 ///
15364 /// Please note that setting k to a non-null value does have a
15365 /// negative performance impact because even if @p l and @p r are not
15366 /// equal, the function keeps up the comparison in order to determine
15367 /// the different kinds of ways in which they are different.
15368 ///
15369 /// @return true if @p l equals @p r, false otherwise.
15370 bool
equals(const scope_type_decl & l,const scope_type_decl & r,change_kind * k)15371 equals(const scope_type_decl& l, const scope_type_decl& r, change_kind* k)
15372 {
15373 bool result = equals(static_cast<const scope_decl&>(l),
15374 static_cast<const scope_decl&>(r),
15375 k);
15376
15377 if (!k && !result)
15378 ABG_RETURN_FALSE;
15379
15380 result &= equals(static_cast<const type_base&>(l),
15381 static_cast<const type_base&>(r),
15382 k);
15383
15384 ABG_RETURN(result);
15385 }
15386
15387 /// Equality operator between two scope_type_decl.
15388 ///
15389 /// Note that this function does not consider the scope of the scope
15390 /// types themselves.
15391 ///
15392 /// @return true iff both scope types are equal.
15393 bool
operator ==(const decl_base & o) const15394 scope_type_decl::operator==(const decl_base& o) const
15395 {
15396 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
15397 if (!other)
15398 return false;
15399 return try_canonical_compare(this, other);
15400 }
15401
15402 /// Equality operator between two scope_type_decl.
15403 ///
15404 /// This re-uses the equality operator that takes a decl_base.
15405 ///
15406 /// @param o the other scope_type_decl to compare against.
15407 ///
15408 /// @return true iff both scope types are equal.
15409 bool
operator ==(const type_base & o) const15410 scope_type_decl::operator==(const type_base& o) const
15411 {
15412 const decl_base* other = dynamic_cast<const decl_base*>(&o);
15413 if (!other)
15414 return false;
15415
15416 return *this == *other;
15417 }
15418
15419 /// Traverses an instance of @ref scope_type_decl, visiting all the
15420 /// sub-types and decls that it might contain.
15421 ///
15422 /// @param v the visitor that is used to visit every IR sub-node of
15423 /// the current node.
15424 ///
15425 /// @return true if either
15426 /// - all the children nodes of the current IR node were traversed
15427 /// and the calling code should keep going with the traversing.
15428 /// - or the current IR node is already being traversed.
15429 /// Otherwise, returning false means that the calling code should not
15430 /// keep traversing the tree.
15431 bool
traverse(ir_node_visitor & v)15432 scope_type_decl::traverse(ir_node_visitor& v)
15433 {
15434 if (visiting())
15435 return true;
15436
15437 if (v.type_node_has_been_visited(this))
15438 return true;
15439
15440 if (v.visit_begin(this))
15441 {
15442 visiting(true);
15443 for (scope_decl::declarations::const_iterator i =
15444 get_member_decls().begin();
15445 i != get_member_decls ().end();
15446 ++i)
15447 if (!(*i)->traverse(v))
15448 break;
15449 visiting(false);
15450 }
15451
15452 bool result = v.visit_end(this);
15453 v.mark_type_node_as_visited(this);
15454
15455 return result;
15456 }
15457
~scope_type_decl()15458 scope_type_decl::~scope_type_decl()
15459 {}
15460 // </scope_type_decl definitions>
15461
15462 // <namespace_decl>
15463
15464 /// Constructor.
15465 ///
15466 /// @param the environment we are operatin from.
15467 ///
15468 /// @param name the name of the namespace.
15469 ///
15470 /// @param locus the source location where the namespace is defined.
15471 ///
15472 /// @param vis the visibility of the namespace.
namespace_decl(const environment & env,const string & name,const location & locus,visibility vis)15473 namespace_decl::namespace_decl(const environment& env,
15474 const string& name,
15475 const location& locus,
15476 visibility vis)
15477 // We need to call the constructor of decl_base directly here
15478 // because it is virtually inherited by scope_decl. Note that we
15479 // just implicitely call the default constructor for scope_decl
15480 // here, as what we really want is to initialize the decl_base
15481 // subobject. Wow, virtual inheritance is useful, but setting it
15482 // up is ugly.
15483 : type_or_decl_base(env,
15484 NAMESPACE_DECL
15485 | ABSTRACT_DECL_BASE
15486 | ABSTRACT_SCOPE_DECL),
15487 decl_base(env, name, locus, "", vis),
15488 scope_decl(env, name, locus)
15489 {
15490 runtime_type_instance(this);
15491 }
15492
15493 /// Build and return a copy of the pretty representation of the
15494 /// namespace.
15495 ///
15496 /// @param internal set to true if the call is intended to get a
15497 /// representation of the decl (or type) for the purpose of canonical
15498 /// type comparison. This is mainly used in the function
15499 /// type_base::get_canonical_type_for().
15500 ///
15501 /// In other words if the argument for this parameter is true then the
15502 /// call is meant for internal use (for technical use inside the
15503 /// library itself), false otherwise. If you don't know what this is
15504 /// for, then set it to false.
15505 ///
15506 /// @param qualified_name if true, names emitted in the pretty
15507 /// representation are fully qualified.
15508 ///
15509 /// @return a copy of the pretty representation of the namespace.
15510 string
get_pretty_representation(bool internal,bool qualified_name) const15511 namespace_decl::get_pretty_representation(bool internal,
15512 bool qualified_name) const
15513 {
15514 string r =
15515 "namespace " + scope_decl::get_pretty_representation(internal,
15516 qualified_name);
15517 return r;
15518 }
15519
15520 /// Return true iff both namespaces and their members are equal.
15521 ///
15522 /// Note that this function does not check if the scope of these
15523 /// namespaces are equal.
15524 bool
operator ==(const decl_base & o) const15525 namespace_decl::operator==(const decl_base& o) const
15526 {
15527 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
15528 if (!other)
15529 return false;
15530 return scope_decl::operator==(*other);
15531 }
15532
15533 /// Test if the current namespace_decl is empty or contains empty
15534 /// namespaces itself.
15535 ///
15536 /// @return true iff the current namespace_decl is empty or contains
15537 /// empty itself.
15538 bool
is_empty_or_has_empty_sub_namespaces() const15539 namespace_decl::is_empty_or_has_empty_sub_namespaces() const
15540 {
15541 if (is_empty())
15542 return true;
15543
15544 for (declarations::const_iterator i = get_member_decls().begin();
15545 i != get_member_decls().end();
15546 ++i)
15547 {
15548 if (!is_namespace(*i))
15549 return false;
15550
15551 namespace_decl_sptr ns = is_namespace(*i);
15552 ABG_ASSERT(ns);
15553
15554 if (!ns->is_empty_or_has_empty_sub_namespaces())
15555 return false;
15556 }
15557
15558 return true;
15559 }
15560
15561 /// This implements the ir_traversable_base::traverse pure virtual
15562 /// function.
15563 ///
15564 /// @param v the visitor used on the current instance and on its
15565 /// member nodes.
15566 ///
15567 /// @return true if the entire IR node tree got traversed, false
15568 /// otherwise.
15569 bool
traverse(ir_node_visitor & v)15570 namespace_decl::traverse(ir_node_visitor& v)
15571 {
15572 if (visiting())
15573 return true;
15574
15575 if (v.visit_begin(this))
15576 {
15577 visiting(true);
15578 scope_decl::declarations::const_iterator i;
15579 for (i = get_member_decls().begin();
15580 i != get_member_decls ().end();
15581 ++i)
15582 {
15583 ir_traversable_base_sptr t =
15584 dynamic_pointer_cast<ir_traversable_base>(*i);
15585 if (t)
15586 if (!t->traverse (v))
15587 break;
15588 }
15589 visiting(false);
15590 }
15591 return v.visit_end(this);
15592 }
15593
~namespace_decl()15594 namespace_decl::~namespace_decl()
15595 {
15596 }
15597
15598 // </namespace_decl>
15599
15600 // <qualified_type_def>
15601
15602 /// Type of the private data of qualified_type_def.
15603 class qualified_type_def::priv
15604 {
15605 friend class qualified_type_def;
15606
15607 qualified_type_def::CV cv_quals_;
15608 // Before the type is canonicalized, this is used as a temporary
15609 // internal name.
15610 interned_string temporary_internal_name_;
15611 // Once the type is canonicalized, this is used as the internal
15612 // name.
15613 interned_string internal_name_;
15614 weak_ptr<type_base> underlying_type_;
15615
priv()15616 priv()
15617 : cv_quals_(CV_NONE)
15618 {}
15619
priv(qualified_type_def::CV quals,type_base_sptr t)15620 priv(qualified_type_def::CV quals,
15621 type_base_sptr t)
15622 : cv_quals_(quals),
15623 underlying_type_(t)
15624 {}
15625
priv(qualified_type_def::CV quals)15626 priv(qualified_type_def::CV quals)
15627 : cv_quals_(quals)
15628 {}
15629 };// end class qualified_type_def::priv
15630
15631 /// Build the name of the current instance of qualified type.
15632 ///
15633 /// @param fully_qualified if true, build a fully qualified name.
15634 ///
15635 /// @param internal set to true if the call is intended for an
15636 /// internal use (for technical use inside the library itself), false
15637 /// otherwise. If you don't know what this is for, then set it to
15638 /// false.
15639 ///
15640 /// @return a copy of the newly-built name.
15641 string
build_name(bool fully_qualified,bool internal) const15642 qualified_type_def::build_name(bool fully_qualified, bool internal) const
15643 {
15644 type_base_sptr t = get_underlying_type();
15645 if (!t)
15646 // The qualified type might temporarily have no underlying type,
15647 // especially during the construction of the type, while the
15648 // underlying type is not yet constructed. In that case, let's do
15649 // like if the underlying type is the 'void' type.
15650 t = get_environment().get_void_type();
15651
15652 return get_name_of_qualified_type(t, get_cv_quals(),
15653 fully_qualified,
15654 internal);
15655 }
15656
15657 /// This function is automatically invoked whenever an instance of
15658 /// this type is canonicalized.
15659 ///
15660 /// It's an overload of the virtual type_base::on_canonical_type_set.
15661 ///
15662 /// We put here what is thus meant to be executed only at the point of
15663 /// type canonicalization.
15664 void
on_canonical_type_set()15665 qualified_type_def::on_canonical_type_set()
15666 {clear_qualified_name();}
15667
15668 /// Constructor of the qualified_type_def
15669 ///
15670 /// @param type the underlying type
15671 ///
15672 /// @param quals a bitfield representing the const/volatile qualifiers
15673 ///
15674 /// @param locus the location of the qualified type definition
qualified_type_def(type_base_sptr type,CV quals,const location & locus)15675 qualified_type_def::qualified_type_def(type_base_sptr type,
15676 CV quals,
15677 const location& locus)
15678 : type_or_decl_base(type->get_environment(),
15679 QUALIFIED_TYPE
15680 | ABSTRACT_TYPE_BASE
15681 | ABSTRACT_DECL_BASE),
15682 type_base(type->get_environment(), type->get_size_in_bits(),
15683 type->get_alignment_in_bits()),
15684 decl_base(type->get_environment(), "", locus, "",
15685 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
15686 priv_(new priv(quals, type))
15687 {
15688 runtime_type_instance(this);
15689 interned_string name = type->get_environment().intern(build_name(false));
15690 set_name(name);
15691 }
15692
15693 /// Constructor of the qualified_type_def
15694 ///
15695 /// @param env the environment of the type.
15696 ///
15697 /// @param quals a bitfield representing the const/volatile qualifiers
15698 ///
15699 /// @param locus the location of the qualified type definition
qualified_type_def(const environment & env,CV quals,const location & locus)15700 qualified_type_def::qualified_type_def(const environment& env,
15701 CV quals,
15702 const location& locus)
15703 : type_or_decl_base(env,
15704 QUALIFIED_TYPE
15705 | ABSTRACT_TYPE_BASE
15706 | ABSTRACT_DECL_BASE),
15707 type_base(env, /*size_in_bits=*/0,
15708 /*alignment_in_bits=*/0),
15709 decl_base(env, "", locus, ""),
15710 priv_(new priv(quals))
15711 {
15712 runtime_type_instance(this);
15713 // We don't yet have an underlying type. So for naming purpose,
15714 // let's temporarily pretend the underlying type is 'void'.
15715 interned_string name = env.intern("void");
15716 set_name(name);
15717 }
15718
15719 /// Get the size of the qualified type def.
15720 ///
15721 /// This is an overload for type_base::get_size_in_bits().
15722 ///
15723 /// @return the size of the qualified type.
15724 size_t
get_size_in_bits() const15725 qualified_type_def::get_size_in_bits() const
15726 {
15727 size_t s = 0;
15728 if (type_base_sptr ut = get_underlying_type())
15729 {
15730 // We do have the underlying type properly set, so let's make
15731 // the size of the qualified type match the size of its
15732 // underlying type.
15733 s = ut->get_size_in_bits();
15734 if (s != type_base::get_size_in_bits())
15735 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
15736 }
15737 return type_base::get_size_in_bits();
15738 }
15739
15740 /// Compares two instances of @ref qualified_type_def.
15741 ///
15742 /// If the two intances are different, set a bitfield to give some
15743 /// insight about the kind of differences there are.
15744 ///
15745 /// @param l the first artifact of the comparison.
15746 ///
15747 /// @param r the second artifact of the comparison.
15748 ///
15749 /// @param k a pointer to a bitfield that gives information about the
15750 /// kind of changes there are between @p l and @p r. This one is set
15751 /// iff @p k is non-null and the function returns false.
15752 ///
15753 /// Please note that setting k to a non-null value does have a
15754 /// negative performance impact because even if @p l and @p r are not
15755 /// equal, the function keeps up the comparison in order to determine
15756 /// the different kinds of ways in which they are different.
15757 ///
15758 /// @return true if @p l equals @p r, false otherwise.
15759 bool
equals(const qualified_type_def & l,const qualified_type_def & r,change_kind * k)15760 equals(const qualified_type_def& l, const qualified_type_def& r, change_kind* k)
15761 {
15762 bool result = true;
15763 if (l.get_cv_quals() != r.get_cv_quals())
15764 {
15765 result = false;
15766 if (k)
15767 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
15768 else
15769 ABG_RETURN_FALSE;
15770 }
15771
15772 if (l.get_underlying_type() != r.get_underlying_type())
15773 {
15774 result = false;
15775 if (k)
15776 {
15777 if (!types_have_similar_structure(l.get_underlying_type().get(),
15778 r.get_underlying_type().get()))
15779 // Underlying type changes in which the structure of the
15780 // type changed are considered local changes to the
15781 // qualified type.
15782 *k |= LOCAL_TYPE_CHANGE_KIND;
15783 else
15784 *k |= SUBTYPE_CHANGE_KIND;
15785 }
15786 else
15787 // okay strictly speaking this is not necessary, but I am
15788 // putting it here to maintenance; that is, so that adding
15789 // subsequent clauses needed to compare two qualified types
15790 // later still works.
15791 ABG_RETURN_FALSE;
15792 }
15793
15794 ABG_RETURN(result);
15795 }
15796
15797 /// Equality operator for qualified types.
15798 ///
15799 /// Note that this function does not check for equality of the scopes.
15800 ///
15801 ///@param o the other qualified type to compare against.
15802 ///
15803 /// @return true iff both qualified types are equal.
15804 bool
operator ==(const decl_base & o) const15805 qualified_type_def::operator==(const decl_base& o) const
15806 {
15807 const qualified_type_def* other =
15808 dynamic_cast<const qualified_type_def*>(&o);
15809 if (!other)
15810 return false;
15811 return try_canonical_compare(this, other);
15812 }
15813
15814 /// Equality operator for qualified types.
15815 ///
15816 /// Note that this function does not check for equality of the scopes.
15817 /// Also, this re-uses the equality operator above that takes a
15818 /// decl_base.
15819 ///
15820 ///@param o the other qualified type to compare against.
15821 ///
15822 /// @return true iff both qualified types are equal.
15823 bool
operator ==(const type_base & o) const15824 qualified_type_def::operator==(const type_base& o) const
15825 {
15826 const decl_base* other = dynamic_cast<const decl_base*>(&o);
15827 if (!other)
15828 return false;
15829 return *this == *other;
15830 }
15831
15832 /// Equality operator for qualified types.
15833 ///
15834 /// Note that this function does not check for equality of the scopes.
15835 /// Also, this re-uses the equality operator above that takes a
15836 /// decl_base.
15837 ///
15838 ///@param o the other qualified type to compare against.
15839 ///
15840 /// @return true iff both qualified types are equal.
15841 bool
operator ==(const qualified_type_def & o) const15842 qualified_type_def::operator==(const qualified_type_def& o) const
15843 {
15844 const decl_base* other = dynamic_cast<const decl_base*>(&o);
15845 if (!other)
15846 return false;
15847 return *this == *other;
15848 }
15849
15850 /// Implementation for the virtual qualified name builder for @ref
15851 /// qualified_type_def.
15852 ///
15853 /// @param qualified_name the output parameter to hold the resulting
15854 /// qualified name.
15855 ///
15856 /// @param internal set to true if the call is intended for an
15857 /// internal use (for technical use inside the library itself), false
15858 /// otherwise. If you don't know what this is for, then set it to
15859 /// false.
15860 void
get_qualified_name(interned_string & qualified_name,bool internal) const15861 qualified_type_def::get_qualified_name(interned_string& qualified_name,
15862 bool internal) const
15863 {qualified_name = get_qualified_name(internal);}
15864
15865 /// Implementation of the virtual qualified name builder/getter.
15866 ///
15867 /// @param internal set to true if the call is intended for an
15868 /// internal use (for technical use inside the library itself), false
15869 /// otherwise. If you don't know what this is for, then set it to
15870 /// false.
15871 ///
15872 /// @return the resulting qualified name.
15873 const interned_string&
get_qualified_name(bool internal) const15874 qualified_type_def::get_qualified_name(bool internal) const
15875 {
15876 const environment& env = get_environment();
15877
15878
15879 if (!get_canonical_type())
15880 {
15881 // The type hasn't been canonicalized yet. We want to return a
15882 // temporary name that is not cached because the structure of
15883 // this type (and so its name) can change until its
15884 // canonicalized.
15885 if (internal)
15886 {
15887 // We are asked to return a temporary *internal* name.
15888 // Lets compute it and return a reference to where it's
15889 // stored.
15890 priv_->temporary_internal_name_ =
15891 env.intern(build_name(true, /*internal=*/true));
15892 return priv_->temporary_internal_name_;
15893 }
15894 else
15895 {
15896 // We are asked to return a temporary non-internal name.
15897 set_temporary_qualified_name
15898 (env.intern(build_name(true, /*internal=*/false)));
15899 return peek_temporary_qualified_name();
15900 }
15901 }
15902 else
15903 {
15904 // The type has already been canonicalized. We want to return
15905 // the definitive name and cache it.
15906 if (internal)
15907 {
15908 if (priv_->internal_name_.empty())
15909 priv_->internal_name_ =
15910 env.intern(build_name(/*qualified=*/true,
15911 /*internal=*/true));
15912 return priv_->internal_name_;
15913 }
15914 else
15915 {
15916 if (peek_qualified_name().empty())
15917 set_qualified_name
15918 (env.intern(build_name(/*qualified=*/true,
15919 /*internal=*/false)));
15920 return peek_qualified_name();
15921 }
15922 }
15923 }
15924
15925 /// This implements the ir_traversable_base::traverse pure virtual
15926 /// function.
15927 ///
15928 /// @param v the visitor used on the current instance.
15929 ///
15930 /// @return true if the entire IR node tree got traversed, false
15931 /// otherwise.
15932 bool
traverse(ir_node_visitor & v)15933 qualified_type_def::traverse(ir_node_visitor& v)
15934 {
15935 if (v.type_node_has_been_visited(this))
15936 return true;
15937
15938 if (visiting())
15939 return true;
15940
15941 if (v.visit_begin(this))
15942 {
15943 visiting(true);
15944 if (type_base_sptr t = get_underlying_type())
15945 t->traverse(v);
15946 visiting(false);
15947 }
15948 bool result = v.visit_end(this);
15949 v.mark_type_node_as_visited(this);
15950 return result;
15951 }
15952
~qualified_type_def()15953 qualified_type_def::~qualified_type_def()
15954 {
15955 }
15956
15957 /// Getter of the const/volatile qualifier bit field
15958 qualified_type_def::CV
get_cv_quals() const15959 qualified_type_def::get_cv_quals() const
15960 {return priv_->cv_quals_;}
15961
15962 /// Setter of the const/value qualifiers bit field
15963 void
set_cv_quals(CV cv_quals)15964 qualified_type_def::set_cv_quals(CV cv_quals)
15965 {priv_->cv_quals_ = cv_quals;}
15966
15967 /// Compute and return the string prefix or suffix representing the
15968 /// qualifiers hold by the current instance of @ref
15969 /// qualified_type_def.
15970 ///
15971 /// @return the newly-built cv string.
15972 string
get_cv_quals_string_prefix() const15973 qualified_type_def::get_cv_quals_string_prefix() const
15974 {return get_string_representation_of_cv_quals(priv_->cv_quals_);}
15975
15976 /// Getter of the underlying type
15977 type_base_sptr
get_underlying_type() const15978 qualified_type_def::get_underlying_type() const
15979 {return priv_->underlying_type_.lock();}
15980
15981 /// Setter of the underlying type.
15982 ///
15983 /// @param t the new underlying type.
15984 void
set_underlying_type(const type_base_sptr & t)15985 qualified_type_def::set_underlying_type(const type_base_sptr& t)
15986 {
15987 ABG_ASSERT(t);
15988 priv_->underlying_type_ = t;
15989 // Now we need to update other properties that depend on the new underlying type.
15990 set_size_in_bits(t->get_size_in_bits());
15991 set_alignment_in_bits(t->get_alignment_in_bits());
15992 interned_string name = get_environment().intern(build_name(false));
15993 set_name(name);
15994 if (scope_decl* s = get_scope())
15995 {
15996 // Now that the name has been updated, we need to update the
15997 // lookup maps accordingly.
15998 scope_decl::declarations::iterator i;
15999 if (s->find_iterator_for_member(this, i))
16000 maybe_update_types_lookup_map(*i);
16001 else
16002 ABG_ASSERT_NOT_REACHED;
16003 }
16004 }
16005
16006 /// Non-member equality operator for @ref qualified_type_def
16007 ///
16008 /// @param l the left-hand side of the equality operator
16009 ///
16010 /// @param r the right-hand side of the equality operator
16011 ///
16012 /// @return true iff @p l and @p r equals.
16013 bool
operator ==(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)16014 operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
16015 {
16016 if (l.get() == r.get())
16017 return true;
16018 if (!!l != !!r)
16019 return false;
16020
16021 return *l == *r;
16022 }
16023
16024 /// Non-member inequality operator for @ref qualified_type_def
16025 ///
16026 /// @param l the left-hand side of the equality operator
16027 ///
16028 /// @param r the right-hand side of the equality operator
16029 ///
16030 /// @return true iff @p l and @p r equals.
16031 bool
operator !=(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)16032 operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
16033 {return ! operator==(l, r);}
16034
16035 /// Overloaded bitwise OR operator for cv qualifiers.
16036 qualified_type_def::CV
operator |(qualified_type_def::CV lhs,qualified_type_def::CV rhs)16037 operator|(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
16038 {
16039 return static_cast<qualified_type_def::CV>
16040 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
16041 }
16042
16043 /// Overloaded bitwise |= operator for cv qualifiers.
16044 qualified_type_def::CV&
operator |=(qualified_type_def::CV & l,qualified_type_def::CV r)16045 operator|=(qualified_type_def::CV& l, qualified_type_def::CV r)
16046 {
16047 l = l | r;
16048 return l;
16049 }
16050
16051 /// Overloaded bitwise &= operator for cv qualifiers.
16052 qualified_type_def::CV&
operator &=(qualified_type_def::CV & l,qualified_type_def::CV r)16053 operator&=(qualified_type_def::CV& l, qualified_type_def::CV r)
16054 {
16055 l = l & r;
16056 return l;
16057 }
16058
16059 /// Overloaded bitwise AND operator for CV qualifiers.
16060 qualified_type_def::CV
operator &(qualified_type_def::CV lhs,qualified_type_def::CV rhs)16061 operator&(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
16062 {
16063 return static_cast<qualified_type_def::CV>
16064 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
16065 }
16066
16067 /// Overloaded bitwise inverting operator for CV qualifiers.
16068 qualified_type_def::CV
operator ~(qualified_type_def::CV q)16069 operator~(qualified_type_def::CV q)
16070 {return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
16071
16072 /// Streaming operator for qualified_type_decl::CV
16073 ///
16074 /// @param o the output stream to serialize the cv qualifier to.
16075 ///
16076 /// @param cv the cv qualifier to serialize.
16077 ///
16078 /// @return the output stream used.
16079 std::ostream&
operator <<(std::ostream & o,qualified_type_def::CV cv)16080 operator<<(std::ostream& o, qualified_type_def::CV cv)
16081 {
16082 string str;
16083
16084 switch (cv)
16085 {
16086 case qualified_type_def::CV_NONE:
16087 str = "none";
16088 break;
16089 case qualified_type_def::CV_CONST:
16090 str = "const";
16091 break;
16092 case qualified_type_def::CV_VOLATILE:
16093 str = "volatile";
16094 break;
16095 case qualified_type_def::CV_RESTRICT:
16096 str = "restrict";
16097 break;
16098 }
16099
16100 o << str;
16101 return o;
16102 }
16103
16104 // </qualified_type_def>
16105
16106 //<pointer_type_def definitions>
16107
16108 /// Private data structure of the @ref pointer_type_def.
16109 struct pointer_type_def::priv
16110 {
16111 type_base_wptr pointed_to_type_;
16112 type_base* naked_pointed_to_type_;
16113 interned_string internal_qualified_name_;
16114 interned_string temp_internal_qualified_name_;
16115
privabigail::ir::pointer_type_def::priv16116 priv(const type_base_sptr& t)
16117 : pointed_to_type_(type_or_void(t, t->get_environment())),
16118 naked_pointed_to_type_(t.get())
16119 {}
16120
privabigail::ir::pointer_type_def::priv16121 priv()
16122 : naked_pointed_to_type_()
16123 {}
16124 }; //end struct pointer_type_def
16125
16126 /// This function is automatically invoked whenever an instance of
16127 /// this type is canonicalized.
16128 ///
16129 /// It's an overload of the virtual type_base::on_canonical_type_set.
16130 ///
16131 /// We put here what is thus meant to be executed only at the point of
16132 /// type canonicalization.
16133 void
on_canonical_type_set()16134 pointer_type_def::on_canonical_type_set()
16135 {clear_qualified_name();}
16136
16137
16138 ///Constructor of @ref pointer_type_def.
16139 ///
16140 /// @param pointed_to the pointed-to type.
16141 ///
16142 /// @param size_in_bits the size of the type, in bits.
16143 ///
16144 /// @param align_in_bits the alignment of the type, in bits.
16145 ///
16146 /// @param locus the source location where the type was defined.
pointer_type_def(const type_base_sptr & pointed_to,size_t size_in_bits,size_t align_in_bits,const location & locus)16147 pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
16148 size_t size_in_bits,
16149 size_t align_in_bits,
16150 const location& locus)
16151 : type_or_decl_base(pointed_to->get_environment(),
16152 POINTER_TYPE
16153 | ABSTRACT_TYPE_BASE
16154 | ABSTRACT_DECL_BASE),
16155 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
16156 decl_base(pointed_to->get_environment(), "", locus, ""),
16157 priv_(new priv(pointed_to))
16158 {
16159 runtime_type_instance(this);
16160 try
16161 {
16162 ABG_ASSERT(pointed_to);
16163 const environment& env = pointed_to->get_environment();
16164 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
16165 string name = (pto ? pto->get_name() : string("void")) + "*";
16166 set_name(env.intern(name));
16167 if (pto)
16168 set_visibility(pto->get_visibility());
16169 }
16170 catch (...)
16171 {}
16172 }
16173
16174 ///Constructor of @ref pointer_type_def.
16175 ///
16176 /// @param env the environment of the type.
16177 ///
16178 /// @param size_in_bits the size of the type, in bits.
16179 ///
16180 /// @param align_in_bits the alignment of the type, in bits.
16181 ///
16182 /// @param locus the source location where the type was defined.
pointer_type_def(const environment & env,size_t size_in_bits,size_t alignment_in_bits,const location & locus)16183 pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
16184 size_t alignment_in_bits,
16185 const location& locus)
16186 : type_or_decl_base(env,
16187 POINTER_TYPE
16188 | ABSTRACT_TYPE_BASE
16189 | ABSTRACT_DECL_BASE),
16190 type_base(env, size_in_bits, alignment_in_bits),
16191 decl_base(env, "", locus, ""),
16192 priv_(new priv())
16193 {
16194 runtime_type_instance(this);
16195 string name = string("void") + "*";
16196 set_name(env.intern(name));
16197 }
16198
16199 /// Set the pointed-to type of the pointer.
16200 ///
16201 /// @param t the new pointed-to type.
16202 void
set_pointed_to_type(const type_base_sptr & t)16203 pointer_type_def::set_pointed_to_type(const type_base_sptr& t)
16204 {
16205 ABG_ASSERT(t);
16206 priv_->pointed_to_type_ = t;
16207 priv_->naked_pointed_to_type_ = t.get();
16208
16209 try
16210 {
16211 const environment& env = t->get_environment();
16212 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
16213 string name = (pto ? pto->get_name() : string("void")) + "*";
16214 set_name(env.intern(name));
16215 if (pto)
16216 set_visibility(pto->get_visibility());
16217 }
16218 catch (...)
16219 {}
16220 }
16221
16222 /// Compares two instances of @ref pointer_type_def.
16223 ///
16224 /// If the two intances are different, set a bitfield to give some
16225 /// insight about the kind of differences there are.
16226 ///
16227 /// @param l the first artifact of the comparison.
16228 ///
16229 /// @param r the second artifact of the comparison.
16230 ///
16231 /// @param k a pointer to a bitfield that gives information about the
16232 /// kind of changes there are between @p l and @p r. This one is set
16233 /// iff @p k is non-null and the function returns false.
16234 ///
16235 /// Please note that setting k to a non-null value does have a
16236 /// negative performance impact because even if @p l and @p r are not
16237 /// equal, the function keeps up the comparison in order to determine
16238 /// the different kinds of ways in which they are different.
16239 ///
16240 /// @return true if @p l equals @p r, false otherwise.
16241 bool
equals(const pointer_type_def & l,const pointer_type_def & r,change_kind * k)16242 equals(const pointer_type_def& l, const pointer_type_def& r, change_kind* k)
16243 {
16244 bool result = l.get_pointed_to_type() == r.get_pointed_to_type();
16245 if (!result)
16246 if (k)
16247 {
16248 if (!types_have_similar_structure(&l, &r))
16249 // pointed-to type changes in which the structure of the
16250 // type changed are considered local changes to the pointer
16251 // type.
16252 *k |= LOCAL_TYPE_CHANGE_KIND;
16253 *k |= SUBTYPE_CHANGE_KIND;
16254 }
16255
16256 ABG_RETURN(result);
16257 }
16258
16259 /// Return true iff both instances of pointer_type_def are equal.
16260 ///
16261 /// Note that this function does not check for the scopes of the this
16262 /// types.
16263 bool
operator ==(const decl_base & o) const16264 pointer_type_def::operator==(const decl_base& o) const
16265 {
16266 const pointer_type_def* other = is_pointer_type(&o);
16267 if (!other)
16268 return false;
16269 return try_canonical_compare(this, other);
16270 }
16271
16272 /// Return true iff both instances of pointer_type_def are equal.
16273 ///
16274 /// Note that this function does not check for the scopes of the
16275 /// types.
16276 ///
16277 /// @param other the other type to compare against.
16278 ///
16279 /// @return true iff @p other equals the current instance.
16280 bool
operator ==(const type_base & other) const16281 pointer_type_def::operator==(const type_base& other) const
16282 {
16283 const decl_base* o = is_decl(&other);
16284 if (!o)
16285 return false;
16286 return *this == *o;
16287 }
16288
16289 /// Return true iff both instances of pointer_type_def are equal.
16290 ///
16291 /// Note that this function does not check for the scopes of the
16292 /// types.
16293 ///
16294 /// @param other the other type to compare against.
16295 ///
16296 /// @return true iff @p other equals the current instance.
16297 bool
operator ==(const pointer_type_def & other) const16298 pointer_type_def::operator==(const pointer_type_def& other) const
16299 {
16300 const decl_base& o = other;
16301 return *this == o;
16302 }
16303
16304 /// Getter of the pointed-to type.
16305 ///
16306 /// @return the pointed-to type.
16307 const type_base_sptr
get_pointed_to_type() const16308 pointer_type_def::get_pointed_to_type() const
16309 {return priv_->pointed_to_type_.lock();}
16310
16311 /// Getter of a naked pointer to the pointed-to type.
16312 ///
16313 /// @return a naked pointed to the pointed-to type.
16314 type_base*
get_naked_pointed_to_type() const16315 pointer_type_def::get_naked_pointed_to_type() const
16316 {return priv_->naked_pointed_to_type_;}
16317
16318 /// Build and return the qualified name of the current instance of
16319 /// @ref pointer_type_def.
16320 ///
16321 /// @param qn output parameter. The resulting qualified name.
16322 ///
16323 /// @param internal set to true if the call is intended for an
16324 /// internal use (for technical use inside the library itself), false
16325 /// otherwise. If you don't know what this is for, then set it to
16326 /// false.
16327 void
get_qualified_name(interned_string & qn,bool internal) const16328 pointer_type_def::get_qualified_name(interned_string& qn, bool internal) const
16329 {qn = get_qualified_name(internal);}
16330
16331 /// Build, cache and return the qualified name of the current instance
16332 /// of @ref pointer_type_def. Subsequent invocations of this function
16333 /// return the cached value.
16334 ///
16335 /// Note that this function should work even if the underlying type is
16336 /// momentarily empty.
16337 ///
16338 /// @param internal set to true if the call is intended for an
16339 /// internal use (for technical use inside the library itself), false
16340 /// otherwise. If you don't know what this is for, then set it to
16341 /// false.
16342 ///
16343 /// @return the resulting qualified name.
16344 const interned_string&
get_qualified_name(bool internal) const16345 pointer_type_def::get_qualified_name(bool internal) const
16346 {
16347 type_base* pointed_to_type = get_naked_pointed_to_type();
16348 pointed_to_type = look_through_decl_only(pointed_to_type);
16349
16350 if (internal)
16351 {
16352 if (get_canonical_type())
16353 {
16354 if (priv_->internal_qualified_name_.empty())
16355 if (pointed_to_type)
16356 priv_->internal_qualified_name_ =
16357 get_name_of_pointer_to_type(*pointed_to_type,
16358 /*qualified_name=*/true,
16359 /*internal=*/true);
16360 return priv_->internal_qualified_name_;
16361 }
16362 else
16363 {
16364 // As the type hasn't yet been canonicalized, its structure
16365 // (and so its name) can change. So let's invalidate the
16366 // cache where we store its name at each invocation of this
16367 // function.
16368 if (pointed_to_type)
16369 priv_->temp_internal_qualified_name_ =
16370 get_name_of_pointer_to_type(*pointed_to_type,
16371 /*qualified_name=*/true,
16372 /*internal=*/true);
16373 return priv_->temp_internal_qualified_name_;
16374 }
16375 }
16376 else
16377 {
16378 if (get_naked_canonical_type())
16379 {
16380 if (decl_base::peek_qualified_name().empty())
16381 set_qualified_name
16382 (get_name_of_pointer_to_type(*pointed_to_type,
16383 /*qualified_name=*/true,
16384 /*internal=*/false));
16385 return decl_base::peek_qualified_name();
16386 }
16387 else
16388 {
16389 // As the type hasn't yet been canonicalized, its structure
16390 // (and so its name) can change. So let's invalidate the
16391 // cache where we store its name at each invocation of this
16392 // function.
16393 if (pointed_to_type)
16394 set_qualified_name
16395 (get_name_of_pointer_to_type(*pointed_to_type,
16396 /*qualified_name=*/true,
16397 /*internal=*/false));
16398 return decl_base::peek_qualified_name();
16399 }
16400 }
16401 }
16402
16403 /// This implements the ir_traversable_base::traverse pure virtual
16404 /// function.
16405 ///
16406 /// @param v the visitor used on the current instance.
16407 ///
16408 /// @return true if the entire IR node tree got traversed, false
16409 /// otherwise.
16410 bool
traverse(ir_node_visitor & v)16411 pointer_type_def::traverse(ir_node_visitor& v)
16412 {
16413 if (v.type_node_has_been_visited(this))
16414 return true;
16415
16416 if (visiting())
16417 return true;
16418
16419 if (v.visit_begin(this))
16420 {
16421 visiting(true);
16422 if (type_base_sptr t = get_pointed_to_type())
16423 t->traverse(v);
16424 visiting(false);
16425 }
16426
16427 bool result = v.visit_end(this);
16428 v.mark_type_node_as_visited(this);
16429 return result;
16430 }
16431
~pointer_type_def()16432 pointer_type_def::~pointer_type_def()
16433 {}
16434
16435 /// Turn equality of shared_ptr of @ref pointer_type_def into a deep
16436 /// equality; that is, make it compare the pointed to objects too.
16437 ///
16438 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
16439 /// of the equality.
16440 ///
16441 /// @param r the shared_ptr of @ref pointer_type_def on
16442 /// right-hand-side of the equality.
16443 ///
16444 /// @return true if the @ref pointer_type_def pointed to by the
16445 /// shared_ptrs are equal, false otherwise.
16446 bool
operator ==(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)16447 operator==(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
16448 {
16449 if (l.get() == r.get())
16450 return true;
16451 if (!!l != !!r)
16452 return false;
16453
16454 return *l == *r;
16455 }
16456
16457 /// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
16458 /// equality; that is, make it compare the pointed to objects too.
16459 ///
16460 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
16461 /// of the equality.
16462 ///
16463 /// @param r the shared_ptr of @ref pointer_type_def on
16464 /// right-hand-side of the equality.
16465 ///
16466 /// @return true iff the @ref pointer_type_def pointed to by the
16467 /// shared_ptrs are different.
16468 bool
operator !=(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)16469 operator!=(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
16470 {return !operator==(l, r);}
16471
16472 // </pointer_type_def definitions>
16473
16474 // <reference_type_def definitions>
16475
16476 /// This function is automatically invoked whenever an instance of
16477 /// this type is canonicalized.
16478 ///
16479 /// It's an overload of the virtual type_base::on_canonical_type_set.
16480 ///
16481 /// We put here what is thus meant to be executed only at the point of
16482 /// type canonicalization.
16483 void
on_canonical_type_set()16484 reference_type_def::on_canonical_type_set()
16485 {clear_qualified_name();}
16486
16487 /// Constructor of the reference_type_def type.
16488 ///
16489 /// @param pointed_to the pointed to type.
16490 ///
16491 /// @param lvalue wether the reference is an lvalue reference. If
16492 /// false, the reference is an rvalue one.
16493 ///
16494 /// @param size_in_bits the size of the type, in bits.
16495 ///
16496 /// @param align_in_bits the alignment of the type, in bits.
16497 ///
16498 /// @param locus the source location of the type.
reference_type_def(const type_base_sptr pointed_to,bool lvalue,size_t size_in_bits,size_t align_in_bits,const location & locus)16499 reference_type_def::reference_type_def(const type_base_sptr pointed_to,
16500 bool lvalue,
16501 size_t size_in_bits,
16502 size_t align_in_bits,
16503 const location& locus)
16504 : type_or_decl_base(pointed_to->get_environment(),
16505 REFERENCE_TYPE
16506 | ABSTRACT_TYPE_BASE
16507 | ABSTRACT_DECL_BASE),
16508 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
16509 decl_base(pointed_to->get_environment(), "", locus, ""),
16510 is_lvalue_(lvalue)
16511 {
16512 runtime_type_instance(this);
16513
16514 try
16515 {
16516 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
16517 string name;
16518 if (pto)
16519 {
16520 set_visibility(pto->get_visibility());
16521 name = string(pto->get_name()) + "&";
16522 }
16523 else
16524 name = string(get_type_name(is_function_type(pointed_to),
16525 /*qualified_name=*/true)) + "&";
16526
16527 if (!is_lvalue())
16528 name += "&";
16529 const environment& env = pointed_to->get_environment();
16530 set_name(env.intern(name));
16531
16532 pointed_to_type_ =
16533 type_base_wptr(type_or_void(pointed_to,
16534 pointed_to->get_environment()));
16535 }
16536 catch (...)
16537 {}
16538 }
16539
16540 /// Constructor of the reference_type_def type.
16541 ///
16542 /// This one creates a type that has no pointed-to type, temporarily.
16543 /// This is useful for cases where the underlying type is not yet
16544 /// available. It can be set later using
16545 /// reference_type_def::set_pointed_to_type().
16546 ///
16547 /// @param env the environment of the type.
16548 ///
16549 /// @param lvalue wether the reference is an lvalue reference. If
16550 /// false, the reference is an rvalue one.
16551 ///
16552 /// @param size_in_bits the size of the type, in bits.
16553 ///
16554 /// @param align_in_bits the alignment of the type, in bits.
16555 ///
16556 /// @param locus the source location of the type.
reference_type_def(const environment & env,bool lvalue,size_t size_in_bits,size_t alignment_in_bits,const location & locus)16557 reference_type_def::reference_type_def(const environment& env, bool lvalue,
16558 size_t size_in_bits,
16559 size_t alignment_in_bits,
16560 const location& locus)
16561 : type_or_decl_base(env,
16562 REFERENCE_TYPE
16563 | ABSTRACT_TYPE_BASE
16564 | ABSTRACT_DECL_BASE),
16565 type_base(env, size_in_bits, alignment_in_bits),
16566 decl_base(env, "", locus, ""),
16567 is_lvalue_(lvalue)
16568 {
16569 runtime_type_instance(this);
16570 string name = "void&";
16571 if (!is_lvalue())
16572 name += "&";
16573
16574 set_name(env.intern(name));
16575 pointed_to_type_ = type_base_wptr(env.get_void_type());
16576 }
16577
16578 /// Setter of the pointed_to type of the current reference type.
16579 ///
16580 /// @param pointed_to the new pointed to type.
16581 void
set_pointed_to_type(type_base_sptr & pointed_to_type)16582 reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
16583 {
16584 ABG_ASSERT(pointed_to_type);
16585 pointed_to_type_ = pointed_to_type;
16586
16587 decl_base_sptr pto;
16588 try
16589 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
16590 catch (...)
16591 {}
16592
16593 if (pto)
16594 {
16595 set_visibility(pto->get_visibility());
16596 string name = string(pto->get_name()) + "&";
16597 if (!is_lvalue())
16598 name += "&";
16599 const environment& env = pto->get_environment();
16600 set_name(env.intern(name));
16601 }
16602 }
16603
16604 /// Compares two instances of @ref reference_type_def.
16605 ///
16606 /// If the two intances are different, set a bitfield to give some
16607 /// insight about the kind of differences there are.
16608 ///
16609 /// @param l the first artifact of the comparison.
16610 ///
16611 /// @param r the second artifact of the comparison.
16612 ///
16613 /// @param k a pointer to a bitfield that gives information about the
16614 /// kind of changes there are between @p l and @p r. This one is set
16615 /// iff @p k is non-null and the function returns false.
16616 ///
16617 /// Please note that setting k to a non-null value does have a
16618 /// negative performance impact because even if @p l and @p r are not
16619 /// equal, the function keeps up the comparison in order to determine
16620 /// the different kinds of ways in which they are different.
16621 ///
16622 /// @return true if @p l equals @p r, false otherwise.
16623 bool
equals(const reference_type_def & l,const reference_type_def & r,change_kind * k)16624 equals(const reference_type_def& l, const reference_type_def& r, change_kind* k)
16625 {
16626 if (l.is_lvalue() != r.is_lvalue())
16627 {
16628 if (k)
16629 *k |= LOCAL_TYPE_CHANGE_KIND;
16630 ABG_RETURN_FALSE;
16631 }
16632
16633 // Compare the pointed-to-types modulo the typedefs they might have
16634 bool result = (l.get_pointed_to_type() == r.get_pointed_to_type());
16635 if (!result)
16636 if (k)
16637 {
16638 if (!types_have_similar_structure(&l, &r))
16639 *k |= LOCAL_TYPE_CHANGE_KIND;
16640 *k |= SUBTYPE_CHANGE_KIND;
16641 }
16642 ABG_RETURN(result);
16643 }
16644
16645 /// Equality operator of the @ref reference_type_def type.
16646 ///
16647 /// @param o the other instance of @ref reference_type_def to compare
16648 /// against.
16649 ///
16650 /// @return true iff the two instances are equal.
16651 bool
operator ==(const decl_base & o) const16652 reference_type_def::operator==(const decl_base& o) const
16653 {
16654 const reference_type_def* other =
16655 dynamic_cast<const reference_type_def*>(&o);
16656 if (!other)
16657 return false;
16658 return try_canonical_compare(this, other);
16659 }
16660
16661 /// Equality operator of the @ref reference_type_def type.
16662 ///
16663 /// @param o the other instance of @ref reference_type_def to compare
16664 /// against.
16665 ///
16666 /// @return true iff the two instances are equal.
16667 bool
operator ==(const type_base & o) const16668 reference_type_def::operator==(const type_base& o) const
16669 {
16670 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16671 if (!other)
16672 return false;
16673 return *this == *other;
16674 }
16675
16676 /// Equality operator of the @ref reference_type_def type.
16677 ///
16678 /// @param o the other instance of @ref reference_type_def to compare
16679 /// against.
16680 ///
16681 /// @return true iff the two instances are equal.
16682 bool
operator ==(const reference_type_def & o) const16683 reference_type_def::operator==(const reference_type_def& o) const
16684 {
16685 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16686 if (!other)
16687 return false;
16688 return *this == *other;
16689 }
16690
16691 type_base_sptr
get_pointed_to_type() const16692 reference_type_def::get_pointed_to_type() const
16693 {return pointed_to_type_.lock();}
16694
16695 bool
is_lvalue() const16696 reference_type_def::is_lvalue() const
16697 {return is_lvalue_;}
16698
16699 /// Build and return the qualified name of the current instance of the
16700 /// @ref reference_type_def.
16701 ///
16702 /// @param qn output parameter. Is set to the newly-built qualified
16703 /// name of the current instance of @ref reference_type_def.
16704 ///
16705 /// @param internal set to true if the call is intended for an
16706 /// internal use (for technical use inside the library itself), false
16707 /// otherwise. If you don't know what this is for, then set it to
16708 /// false.
16709 void
get_qualified_name(interned_string & qn,bool internal) const16710 reference_type_def::get_qualified_name(interned_string& qn, bool internal) const
16711 {qn = get_qualified_name(internal);}
16712
16713 /// Build, cache and return the qualified name of the current instance
16714 /// of the @ref reference_type_def. Subsequent invocations of this
16715 /// function return the cached value.
16716 ///
16717 /// @param internal set to true if the call is intended for an
16718 /// internal use (for technical use inside the library itself), false
16719 /// otherwise. If you don't know what this is for, then set it to
16720 /// false.
16721 ///
16722 /// @return the newly-built qualified name of the current instance of
16723 /// @ref reference_type_def.
16724 const interned_string&
get_qualified_name(bool internal) const16725 reference_type_def::get_qualified_name(bool internal) const
16726 {
16727 if (peek_qualified_name().empty()
16728 || !get_canonical_type())
16729 set_qualified_name(get_name_of_reference_to_type
16730 (*look_through_decl_only(get_pointed_to_type()),
16731 is_lvalue(),
16732 /*qualified_name=*/true,
16733 internal));
16734 return peek_qualified_name();
16735 }
16736
16737 /// Get the pretty representation of the current instance of @ref
16738 /// reference_type_def.
16739 ///
16740 /// @param internal set to true if the call is intended to get a
16741 /// representation of the decl (or type) for the purpose of canonical
16742 /// type comparison. This is mainly used in the function
16743 /// type_base::get_canonical_type_for().
16744 ///
16745 /// In other words if the argument for this parameter is true then the
16746 /// call is meant for internal use (for technical use inside the
16747 /// library itself), false otherwise. If you don't know what this is
16748 /// for, then set it to false.
16749 ///
16750 /// @param qualified_name if true, names emitted in the pretty
16751 /// representation are fully qualified.
16752 ///
16753 /// @return the pretty representatin of the @ref reference_type_def.
16754 string
get_pretty_representation(bool internal,bool qualified_name) const16755 reference_type_def::get_pretty_representation(bool internal,
16756 bool qualified_name) const
16757 {
16758 string result =
16759 get_name_of_reference_to_type(*look_through_decl_only
16760 (get_pointed_to_type()),
16761 is_lvalue(),
16762 qualified_name,
16763 internal);
16764
16765 return result;
16766 }
16767
16768 /// This implements the ir_traversable_base::traverse pure virtual
16769 /// function.
16770 ///
16771 /// @param v the visitor used on the current instance.
16772 ///
16773 /// @return true if the entire IR node tree got traversed, false
16774 /// otherwise.
16775 bool
traverse(ir_node_visitor & v)16776 reference_type_def::traverse(ir_node_visitor& v)
16777 {
16778 if (v.type_node_has_been_visited(this))
16779 return true;
16780
16781 if (visiting())
16782 return true;
16783
16784 if (v.visit_begin(this))
16785 {
16786 visiting(true);
16787 if (type_base_sptr t = get_pointed_to_type())
16788 t->traverse(v);
16789 visiting(false);
16790 }
16791
16792 bool result = v.visit_end(this);
16793 v.mark_type_node_as_visited(this);
16794 return result;
16795 }
16796
~reference_type_def()16797 reference_type_def::~reference_type_def()
16798 {}
16799
16800 /// Turn equality of shared_ptr of @ref reference_type_def into a deep
16801 /// equality; that is, make it compare the pointed to objects too.
16802 ///
16803 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
16804 /// of the equality.
16805 ///
16806 /// @param r the shared_ptr of @ref reference_type_def on
16807 /// right-hand-side of the equality.
16808 ///
16809 /// @return true if the @ref reference_type_def pointed to by the
16810 /// shared_ptrs are equal, false otherwise.
16811 bool
operator ==(const reference_type_def_sptr & l,const reference_type_def_sptr & r)16812 operator==(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
16813 {
16814 if (l.get() == r.get())
16815 return true;
16816 if (!!l != !!r)
16817 return false;
16818
16819 return *l == *r;
16820 }
16821
16822 /// Turn inequality of shared_ptr of @ref reference_type_def into a deep
16823 /// equality; that is, make it compare the pointed to objects too.
16824 ///
16825 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
16826 /// of the equality.
16827 ///
16828 /// @param r the shared_ptr of @ref reference_type_def on
16829 /// right-hand-side of the equality.
16830 ///
16831 /// @return true iff the @ref reference_type_def pointed to by the
16832 /// shared_ptrs are different.
16833 bool
operator !=(const reference_type_def_sptr & l,const reference_type_def_sptr & r)16834 operator!=(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
16835 {return !operator==(l, r);}
16836
16837 // </reference_type_def definitions>
16838
16839 // <array_type_def definitions>
16840
16841 // <array_type_def::subrange_type>
16842 array_type_def::subrange_type::~subrange_type() = default;
16843
16844 // <array_type_def::subrante_type::bound_value>
16845
16846 /// Default constructor of the @ref
16847 /// array_type_def::subrange_type::bound_value class.
16848 ///
16849 /// Constructs an unsigned bound_value of value zero.
bound_value()16850 array_type_def::subrange_type::bound_value::bound_value()
16851 : s_(UNSIGNED_SIGNEDNESS)
16852 {
16853 v_.unsigned_ = 0;
16854 }
16855
16856 /// Initialize an unsigned bound_value with a given value.
16857 ///
16858 /// @param v the initial bound value.
bound_value(uint64_t v)16859 array_type_def::subrange_type::bound_value::bound_value(uint64_t v)
16860 : s_(UNSIGNED_SIGNEDNESS)
16861 {
16862 v_.unsigned_ = v;
16863 }
16864
16865 /// Initialize a signed bound_value with a given value.
16866 ///
16867 /// @param v the initial bound value.
bound_value(int64_t v)16868 array_type_def::subrange_type::bound_value::bound_value(int64_t v)
16869 : s_(SIGNED_SIGNEDNESS)
16870 {
16871 v_.signed_ = v;
16872 }
16873
16874 /// Getter of the signedness (unsigned VS signed) of the bound value.
16875 ///
16876 /// @return the signedness of the bound value.
16877 enum array_type_def::subrange_type::bound_value::signedness
get_signedness() const16878 array_type_def::subrange_type::bound_value::get_signedness() const
16879 {return s_;}
16880
16881 /// Setter of the signedness (unsigned VS signed) of the bound value.
16882 ///
16883 /// @param s the new signedness of the bound value.
16884 void
set_signedness(enum signedness s)16885 array_type_def::subrange_type::bound_value::set_signedness(enum signedness s)
16886 { s_ = s;}
16887
16888 /// Getter of the bound value as a signed value.
16889 ///
16890 /// @return the bound value as signed.
16891 int64_t
get_signed_value() const16892 array_type_def::subrange_type::bound_value::get_signed_value() const
16893 {return v_.signed_;
16894 }
16895
16896 /// Getter of the bound value as an unsigned value.
16897 ///
16898 /// @return the bound value as unsigned.
16899 uint64_t
get_unsigned_value()16900 array_type_def::subrange_type::bound_value::get_unsigned_value()
16901 {return v_.unsigned_;}
16902
16903 /// Setter of the bound value as unsigned.
16904 ///
16905 /// @param v the new unsigned value.
16906 void
set_unsigned(uint64_t v)16907 array_type_def::subrange_type::bound_value::set_unsigned(uint64_t v)
16908 {
16909 s_ = UNSIGNED_SIGNEDNESS;
16910 v_.unsigned_ = v;
16911 }
16912
16913 /// Setter of the bound value as signed.
16914 ///
16915 /// @param v the new signed value.
16916 void
set_signed(int64_t v)16917 array_type_def::subrange_type::bound_value::set_signed(int64_t v)
16918 {
16919 s_ = SIGNED_SIGNEDNESS;
16920 v_.signed_ = v;
16921 }
16922
16923 /// Equality operator of the bound value.
16924 ///
16925 /// @param v the other bound value to compare with.
16926 ///
16927 /// @return true iff the current bound value equals @p v.
16928 bool
operator ==(const bound_value & v) const16929 array_type_def::subrange_type::bound_value::operator==(const bound_value& v) const
16930 {
16931 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
16932 }
16933
16934 // </array_type_def::subrante_type::bound_value>
16935
16936 struct array_type_def::subrange_type::priv
16937 {
16938 bound_value lower_bound_;
16939 bound_value upper_bound_;
16940 type_base_wptr underlying_type_;
16941 translation_unit::language language_;
16942 bool infinite_;
16943
privabigail::ir::array_type_def::subrange_type::priv16944 priv(bound_value ub,
16945 translation_unit::language l = translation_unit::LANG_C11)
16946 : upper_bound_(ub), language_(l), infinite_(false)
16947 {}
16948
privabigail::ir::array_type_def::subrange_type::priv16949 priv(bound_value lb, bound_value ub,
16950 translation_unit::language l = translation_unit::LANG_C11)
16951 : lower_bound_(lb), upper_bound_(ub),
16952 language_(l), infinite_(false)
16953 {}
16954
privabigail::ir::array_type_def::subrange_type::priv16955 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
16956 translation_unit::language l = translation_unit::LANG_C11)
16957 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
16958 language_(l), infinite_(false)
16959 {}
16960 };
16961
16962 /// Constructor of an array_type_def::subrange_type type.
16963 ///
16964 /// @param env the environment this type was created from.
16965 ///
16966 /// @param name the name of the subrange type.
16967 ///
16968 /// @param lower_bound the lower bound of the array. This is
16969 /// generally zero (at least for C and C++).
16970 ///
16971 /// @param upper_bound the upper bound of the array.
16972 ///
16973 /// @param underlying_type the underlying type of the subrange type.
16974 ///
16975 /// @param loc the source location where the type is defined.
subrange_type(const environment & env,const string & name,bound_value lower_bound,bound_value upper_bound,const type_base_sptr & utype,const location & loc,translation_unit::language l)16976 array_type_def::subrange_type::subrange_type(const environment& env,
16977 const string& name,
16978 bound_value lower_bound,
16979 bound_value upper_bound,
16980 const type_base_sptr& utype,
16981 const location& loc,
16982 translation_unit::language l)
16983 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
16984 type_base(env,
16985 upper_bound.get_unsigned_value()
16986 - lower_bound.get_unsigned_value(),
16987 0),
16988 decl_base(env, name, loc, ""),
16989 priv_(new priv(lower_bound, upper_bound, utype, l))
16990 {
16991 runtime_type_instance(this);
16992 }
16993
16994 /// Constructor of the array_type_def::subrange_type type.
16995 ///
16996 /// @param env the environment this type is being created in.
16997 ///
16998 /// @param name the name of the subrange type.
16999 ///
17000 /// @param lower_bound the lower bound of the array. This is
17001 /// generally zero (at least for C and C++).
17002 ///
17003 /// @param upper_bound the upper bound of the array.
17004 ///
17005 /// @param loc the source location where the type is defined.
17006 ///
17007 /// @param l the language that generated this subrange.
subrange_type(const environment & env,const string & name,bound_value lower_bound,bound_value upper_bound,const location & loc,translation_unit::language l)17008 array_type_def::subrange_type::subrange_type(const environment& env,
17009 const string& name,
17010 bound_value lower_bound,
17011 bound_value upper_bound,
17012 const location& loc,
17013 translation_unit::language l)
17014 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
17015 type_base(env,
17016 upper_bound.get_unsigned_value()
17017 - lower_bound.get_unsigned_value(), 0),
17018 decl_base(env, name, loc, ""),
17019 priv_(new priv(lower_bound, upper_bound, l))
17020 {
17021 runtime_type_instance(this);
17022 }
17023
17024 /// Constructor of the array_type_def::subrange_type type.
17025 ///
17026 /// @param env the environment this type is being created from.
17027 ///
17028 /// @param name of the name of type.
17029 ///
17030 /// @param upper_bound the upper bound of the array. The lower bound
17031 /// is considered to be zero.
17032 ///
17033 /// @param loc the source location of the type.
17034 ///
17035 /// @param the language that generated this type.
subrange_type(const environment & env,const string & name,bound_value upper_bound,const location & loc,translation_unit::language l)17036 array_type_def::subrange_type::subrange_type(const environment& env,
17037 const string& name,
17038 bound_value upper_bound,
17039 const location& loc,
17040 translation_unit::language l)
17041 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
17042 type_base(env, upper_bound.get_unsigned_value(), 0),
17043 decl_base(env, name, loc, ""),
17044 priv_(new priv(upper_bound, l))
17045 {
17046 runtime_type_instance(this);
17047 }
17048
17049 /// Getter of the underlying type of the subrange, that is, the type
17050 /// that defines the range.
17051 ///
17052 /// @return the underlying type.
17053 type_base_sptr
get_underlying_type() const17054 array_type_def::subrange_type::get_underlying_type() const
17055 {return priv_->underlying_type_.lock();}
17056
17057 /// Setter of the underlying type of the subrange, that is, the type
17058 /// that defines the range.
17059 ///
17060 /// @param u the new underlying type.
17061 void
set_underlying_type(const type_base_sptr & u)17062 array_type_def::subrange_type::set_underlying_type(const type_base_sptr &u)
17063 {
17064 ABG_ASSERT(priv_->underlying_type_.expired());
17065 priv_->underlying_type_ = u;
17066 }
17067
17068 /// Getter of the upper bound of the subrange type.
17069 ///
17070 /// @return the upper bound of the subrange type.
17071 int64_t
get_upper_bound() const17072 array_type_def::subrange_type::get_upper_bound() const
17073 {return priv_->upper_bound_.get_signed_value();}
17074
17075 /// Getter of the lower bound of the subrange type.
17076 ///
17077 /// @return the lower bound of the subrange type.
17078 int64_t
get_lower_bound() const17079 array_type_def::subrange_type::get_lower_bound() const
17080 {return priv_->lower_bound_.get_signed_value();}
17081
17082 /// Setter of the upper bound of the subrange type.
17083 ///
17084 /// @param ub the new value of the upper bound.
17085 void
set_upper_bound(int64_t ub)17086 array_type_def::subrange_type::set_upper_bound(int64_t ub)
17087 {priv_->upper_bound_ = ub;}
17088
17089 /// Setter of the lower bound.
17090 ///
17091 /// @param lb the new value of the lower bound.
17092 void
set_lower_bound(int64_t lb)17093 array_type_def::subrange_type::set_lower_bound(int64_t lb)
17094 {priv_->lower_bound_ = lb;}
17095
17096 /// Getter of the length of the subrange type.
17097 ///
17098 /// Note that a length of zero means the array has an infinite (or
17099 /// rather a non-known) size.
17100 ///
17101 /// @return the length of the subrange type.
17102 uint64_t
get_length() const17103 array_type_def::subrange_type::get_length() const
17104 {
17105 if (is_infinite())
17106 return 0;
17107
17108 ABG_ASSERT(get_upper_bound() >= get_lower_bound());
17109 return get_upper_bound() - get_lower_bound() + 1;
17110 }
17111
17112 /// Test if the length of the subrange type is infinite.
17113 ///
17114 /// @return true iff the length of the subrange type is infinite.
17115 bool
is_infinite() const17116 array_type_def::subrange_type::is_infinite() const
17117 {return priv_->infinite_;}
17118
17119 /// Set the infinite-ness status of the subrange type.
17120 ///
17121 /// @param f true iff the length of the subrange type should be set to
17122 /// being infinite.
17123 void
is_infinite(bool f)17124 array_type_def::subrange_type::is_infinite(bool f)
17125 {priv_->infinite_ = f;}
17126
17127 /// Getter of the language that generated this type.
17128 ///
17129 /// @return the language of this type.
17130 translation_unit::language
get_language() const17131 array_type_def::subrange_type::get_language() const
17132 {return priv_->language_;}
17133
17134 /// Return a string representation of the sub range.
17135 ///
17136 /// @return the string representation of the sub range.
17137 string
as_string() const17138 array_type_def::subrange_type::as_string() const
17139 {
17140 std::ostringstream o;
17141
17142 if (is_ada_language(get_language()))
17143 {
17144 type_base_sptr underlying_type = get_underlying_type();
17145 if (underlying_type)
17146 o << ir::get_pretty_representation(underlying_type, false) << " ";
17147 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
17148 }
17149 else if (is_infinite())
17150 o << "[]";
17151 else
17152 o << "[" << get_length() << "]";
17153
17154 return o.str();
17155 }
17156
17157 /// Return a string representation of a vector of subranges
17158 ///
17159 /// @return the string representation of a vector of sub ranges.
17160 string
vector_as_string(const vector<subrange_sptr> & v)17161 array_type_def::subrange_type::vector_as_string(const vector<subrange_sptr>& v)
17162 {
17163 if (v.empty())
17164 return "[]";
17165
17166 string r;
17167 for (vector<subrange_sptr>::const_iterator i = v.begin();
17168 i != v.end();
17169 ++i)
17170 r += (*i)->as_string();
17171
17172 return r;
17173 }
17174
17175 /// Compares two isntances of @ref array_type_def::subrange_type.
17176 ///
17177 /// If the two intances are different, set a bitfield to give some
17178 /// insight about the kind of differences there are.
17179 ///
17180 /// @param l the first artifact of the comparison.
17181 ///
17182 /// @param r the second artifact of the comparison.
17183 ///
17184 /// @param k a pointer to a bitfield that gives information about the
17185 /// kind of changes there are between @p l and @p r. This one is set
17186 /// iff @p k is non-null and the function returns false.
17187 ///
17188 /// Please note that setting k to a non-null value does have a
17189 /// negative performance impact because even if @p l and @p r are not
17190 /// equal, the function keeps up the comparison in order to determine
17191 /// the different kinds of ways in which they are different.
17192 ///
17193 /// @return true if @p l equals @p r, false otherwise.
17194 bool
equals(const array_type_def::subrange_type & l,const array_type_def::subrange_type & r,change_kind * k)17195 equals(const array_type_def::subrange_type& l,
17196 const array_type_def::subrange_type& r,
17197 change_kind* k)
17198 {
17199 bool result = true;
17200
17201 if (l.get_lower_bound() != r.get_lower_bound()
17202 || l.get_upper_bound() != r.get_upper_bound()
17203 || l.get_name() != r.get_name())
17204 {
17205 result = false;
17206 if (k)
17207 *k |= LOCAL_TYPE_CHANGE_KIND;
17208 else
17209 ABG_RETURN(result);
17210 }
17211
17212 ABG_RETURN(result);
17213 }
17214
17215 /// Equality operator.
17216 ///
17217 /// @param o the other subrange to test against.
17218 ///
17219 /// @return true iff @p o equals the current instance of
17220 /// array_type_def::subrange_type.
17221 bool
operator ==(const decl_base & o) const17222 array_type_def::subrange_type::operator==(const decl_base& o) const
17223 {
17224 const subrange_type* other =
17225 dynamic_cast<const subrange_type*>(&o);
17226 if (!other)
17227 return false;
17228 return try_canonical_compare(this, other);
17229 }
17230
17231 /// Equality operator.
17232 ///
17233 /// @param o the other subrange to test against.
17234 ///
17235 /// @return true iff @p o equals the current instance of
17236 /// array_type_def::subrange_type.
17237 bool
operator ==(const type_base & o) const17238 array_type_def::subrange_type::operator==(const type_base& o) const
17239 {
17240 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17241 if (!other)
17242 return false;
17243 return *this == *other;
17244 }
17245
17246 /// Equality operator.
17247 ///
17248 /// @param o the other subrange to test against.
17249 ///
17250 /// @return true iff @p o equals the current instance of
17251 /// array_type_def::subrange_type.
17252 bool
operator ==(const subrange_type & o) const17253 array_type_def::subrange_type::operator==(const subrange_type& o) const
17254 {
17255 const type_base &t = o;
17256 return operator==(t);
17257 }
17258
17259 /// Inequality operator.
17260 ///
17261 /// @param o the other subrange to test against.
17262 ///
17263 /// @return true iff @p o is different from the current instance of
17264 /// array_type_def::subrange_type.
17265 bool
operator !=(const subrange_type & o) const17266 array_type_def::subrange_type::operator!=(const subrange_type& o) const
17267 {return !operator==(o);}
17268
17269 /// Build a pretty representation for an
17270 /// array_type_def::subrange_type.
17271 ///
17272 /// @param internal set to true if the call is intended to get a
17273 /// representation of the decl (or type) for the purpose of canonical
17274 /// type comparison. This is mainly used in the function
17275 /// type_base::get_canonical_type_for().
17276 ///
17277 /// In other words if the argument for this parameter is true then the
17278 /// call is meant for internal use (for technical use inside the
17279 /// library itself), false otherwise. If you don't know what this is
17280 /// for, then set it to false.
17281 ///
17282 /// @return a copy of the pretty representation of the current
17283 /// instance of typedef_decl.
17284 string
get_pretty_representation(bool,bool) const17285 array_type_def::subrange_type::get_pretty_representation(bool, bool) const
17286 {
17287 string name = get_name();
17288 string repr;
17289
17290 if (name.empty())
17291 repr += "<anonymous range>";
17292 else
17293 repr += "<range " + get_name() + ">";
17294 repr += as_string();
17295
17296 return repr;
17297 }
17298
17299 /// This implements the ir_traversable_base::traverse pure virtual
17300 /// function.
17301 ///
17302 /// @param v the visitor used on the current instance.
17303 ///
17304 /// @return true if the entire IR node tree got traversed, false
17305 /// otherwise.
17306 bool
traverse(ir_node_visitor & v)17307 array_type_def::subrange_type::traverse(ir_node_visitor& v)
17308 {
17309 if (v.type_node_has_been_visited(this))
17310 return true;
17311
17312 if (v.visit_begin(this))
17313 {
17314 visiting(true);
17315 if (type_base_sptr u = get_underlying_type())
17316 u->traverse(v);
17317 visiting(false);
17318 }
17319
17320 bool result = v.visit_end(this);
17321 v.mark_type_node_as_visited(this);
17322 return result;
17323 }
17324
17325 // </array_type_def::subrange_type>
17326
17327 struct array_type_def::priv
17328 {
17329 type_base_wptr element_type_;
17330 subranges_type subranges_;
17331 interned_string temp_internal_qualified_name_;
17332 interned_string internal_qualified_name_;
17333
privabigail::ir::array_type_def::priv17334 priv(type_base_sptr t)
17335 : element_type_(t)
17336 {}
17337
privabigail::ir::array_type_def::priv17338 priv(type_base_sptr t, subranges_type subs)
17339 : element_type_(t), subranges_(subs)
17340 {}
17341
privabigail::ir::array_type_def::priv17342 priv()
17343 {}
17344 };
17345
17346 /// Constructor for the type array_type_def
17347 ///
17348 /// Note how the constructor expects a vector of subrange
17349 /// objects. Parsing of the array information always entails
17350 /// parsing the subrange info as well, thus the class subrange_type
17351 /// is defined inside class array_type_def and also parsed
17352 /// simultaneously.
17353 ///
17354 /// @param e_type the type of the elements contained in the array
17355 ///
17356 /// @param subs a vector of the array's subranges(dimensions)
17357 ///
17358 /// @param locus the source location of the array type definition.
array_type_def(const type_base_sptr e_type,const std::vector<subrange_sptr> & subs,const location & locus)17359 array_type_def::array_type_def(const type_base_sptr e_type,
17360 const std::vector<subrange_sptr>& subs,
17361 const location& locus)
17362 : type_or_decl_base(e_type->get_environment(),
17363 ARRAY_TYPE
17364 | ABSTRACT_TYPE_BASE
17365 | ABSTRACT_DECL_BASE),
17366 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
17367 decl_base(e_type->get_environment(), locus),
17368 priv_(new priv(e_type))
17369 {
17370 runtime_type_instance(this);
17371 append_subranges(subs);
17372 }
17373
17374 /// Constructor for the type array_type_def
17375 ///
17376 /// This constructor builds a temporary array that has no element type
17377 /// associated. Later when the element type is available, it be set
17378 /// with the array_type_def::set_element_type() member function.
17379 ///
17380 /// Note how the constructor expects a vector of subrange
17381 /// objects. Parsing of the array information always entails
17382 /// parsing the subrange info as well, thus the class subrange_type
17383 /// is defined inside class array_type_def and also parsed
17384 /// simultaneously.
17385 ///
17386 /// @param env the environment of the array type.
17387 ///
17388 /// @param subs a vector of the array's subranges(dimensions)
17389 ///
17390 /// @param locus the source location of the array type definition.
array_type_def(const environment & env,const std::vector<subrange_sptr> & subs,const location & locus)17391 array_type_def::array_type_def(const environment& env,
17392 const std::vector<subrange_sptr>& subs,
17393 const location& locus)
17394 : type_or_decl_base(env,
17395 ARRAY_TYPE
17396 | ABSTRACT_TYPE_BASE
17397 | ABSTRACT_DECL_BASE),
17398 type_base(env, 0, 0),
17399 decl_base(env, locus),
17400 priv_(new priv)
17401 {
17402 runtime_type_instance(this);
17403 append_subranges(subs);
17404 }
17405
17406 /// Update the size of the array.
17407 ///
17408 /// This function computes the size of the array and sets it using
17409 /// type_base::set_size_in_bits().
17410 void
update_size()17411 array_type_def::update_size()
17412 {
17413 type_base_sptr e = priv_->element_type_.lock();
17414 if (e)
17415 {
17416 size_t s = e->get_size_in_bits();
17417 if (s)
17418 {
17419 for (const auto &sub : get_subranges())
17420 s *= sub->get_length();
17421 set_size_in_bits(s);
17422 }
17423 set_alignment_in_bits(e->get_alignment_in_bits());
17424 }
17425 }
17426
17427 string
get_subrange_representation() const17428 array_type_def::get_subrange_representation() const
17429 {
17430 string r = subrange_type::vector_as_string(get_subranges());
17431 return r;
17432 }
17433
17434 /// Get the string representation of an @ref array_type_def.
17435 ///
17436 /// @param a the array type to consider.
17437 ///
17438 /// @param internal set to true if the call is intended for an
17439 /// internal use (for technical use inside the library itself), false
17440 /// otherwise. If you don't know what this is for, then set it to
17441 /// false.
17442 static string
get_type_representation(const array_type_def & a,bool internal)17443 get_type_representation(const array_type_def& a, bool internal)
17444 {
17445 type_base_sptr e_type = a.get_element_type();
17446 decl_base_sptr d = get_type_declaration(e_type);
17447 string r;
17448
17449 if (is_ada_language(a.get_language()))
17450 {
17451 std::ostringstream o;
17452 o << "array ("
17453 << a.get_subrange_representation()
17454 << ") of "
17455 << e_type ? e_type->get_pretty_representation(internal):string("void");
17456 }
17457 else
17458 {
17459 if (internal)
17460 r = (e_type
17461 ? get_type_name(e_type,
17462 /*qualified=*/true,
17463 /*internal=*/true)
17464 : string("void"))
17465 + a.get_subrange_representation();
17466 else
17467 r = (e_type
17468 ? get_type_name(e_type, /*qualified=*/true, /*internal=*/false)
17469 : string("void"))
17470 + a.get_subrange_representation();
17471 }
17472
17473 return r;
17474 }
17475
17476 /// Get the pretty representation of the current instance of @ref
17477 /// array_type_def.
17478 ///
17479 /// @param internal set to true if the call is intended to get a
17480 /// representation of the decl (or type) for the purpose of canonical
17481 /// type comparison. This is mainly used in the function
17482 /// type_base::get_canonical_type_for().
17483 ///
17484 /// In other words if the argument for this parameter is true then the
17485 /// call is meant for internal use (for technical use inside the
17486 /// library itself), false otherwise. If you don't know what this is
17487 /// for, then set it to false.
17488 /// @param internal set to true if the call is intended for an
17489 /// internal use (for technical use inside the library itself), false
17490 /// otherwise. If you don't know what this is for, then set it to
17491 /// false.
17492 ///
17493 /// @return the pretty representation of the ABI artifact.
17494 string
get_pretty_representation(bool internal,bool) const17495 array_type_def::get_pretty_representation(bool internal,
17496 bool /*qualified_name*/) const
17497 {return get_type_representation(*this, internal);}
17498
17499 /// Compares two instances of @ref array_type_def.
17500 ///
17501 /// If the two intances are different, set a bitfield to give some
17502 /// insight about the kind of differences there are.
17503 ///
17504 /// @param l the first artifact of the comparison.
17505 ///
17506 /// @param r the second artifact of the comparison.
17507 ///
17508 /// @param k a pointer to a bitfield that gives information about the
17509 /// kind of changes there are between @p l and @p r. This one is set
17510 /// iff @p k is non-null and the function returns false.
17511 ///
17512 /// Please note that setting k to a non-null value does have a
17513 /// negative performance impact because even if @p l and @p r are not
17514 /// equal, the function keeps up the comparison in order to determine
17515 /// the different kinds of ways in which they are different.
17516 ///
17517 /// @return true if @p l equals @p r, false otherwise.
17518 bool
equals(const array_type_def & l,const array_type_def & r,change_kind * k)17519 equals(const array_type_def& l, const array_type_def& r, change_kind* k)
17520 {
17521 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
17522 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
17523
17524 bool result = true;
17525 if (this_subs.size() != other_subs.size())
17526 {
17527 result = false;
17528 if (k)
17529 *k |= LOCAL_TYPE_CHANGE_KIND;
17530 else
17531 ABG_RETURN_FALSE;
17532 }
17533
17534 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
17535 for (i = this_subs.begin(), j = other_subs.begin();
17536 i != this_subs.end() && j != other_subs.end();
17537 ++i, ++j)
17538 if (**i != **j)
17539 {
17540 result = false;
17541 if (k)
17542 {
17543 *k |= LOCAL_TYPE_CHANGE_KIND;
17544 break;
17545 }
17546 else
17547 ABG_RETURN_FALSE;
17548 }
17549
17550 // Compare the element types modulo the typedefs they might have
17551 if (l.get_element_type() != r.get_element_type())
17552 {
17553 result = false;
17554 if (k)
17555 *k |= SUBTYPE_CHANGE_KIND;
17556 else
17557 ABG_RETURN_FALSE;
17558 }
17559
17560 ABG_RETURN(result);
17561 }
17562
17563 /// Test if two variables are equals modulo CV qualifiers.
17564 ///
17565 /// @param l the first array of the comparison.
17566 ///
17567 /// @param r the second array of the comparison.
17568 ///
17569 /// @return true iff @p l equals @p r or, if they are different, the
17570 /// difference between the too is just a matter of CV qualifiers.
17571 bool
equals_modulo_cv_qualifier(const array_type_def * l,const array_type_def * r)17572 equals_modulo_cv_qualifier(const array_type_def* l, const array_type_def* r)
17573 {
17574 if (l == r)
17575 return true;
17576
17577 if (!l || !r)
17578 ABG_RETURN_FALSE;
17579
17580 l = is_array_type(peel_qualified_or_typedef_type(l));
17581 r = is_array_type(peel_qualified_or_typedef_type(r));
17582
17583 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
17584 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
17585
17586 if (this_subs.size() != other_subs.size())
17587 ABG_RETURN_FALSE;
17588
17589 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
17590 for (i = this_subs.begin(), j = other_subs.begin();
17591 i != this_subs.end() && j != other_subs.end();
17592 ++i, ++j)
17593 if (**i != **j)
17594 ABG_RETURN_FALSE;
17595
17596 type_base *first_element_type =
17597 peel_qualified_or_typedef_type(l->get_element_type().get());
17598 type_base *second_element_type =
17599 peel_qualified_or_typedef_type(r->get_element_type().get());
17600
17601 if (*first_element_type != *second_element_type)
17602 ABG_RETURN_FALSE;
17603
17604 return true;
17605 }
17606
17607 /// Get the language of the array.
17608 ///
17609 /// @return the language of the array.
17610 translation_unit::language
get_language() const17611 array_type_def::get_language() const
17612 {
17613 const std::vector<subrange_sptr>& subranges =
17614 get_subranges();
17615
17616 if (subranges.empty())
17617 return translation_unit::LANG_C11;
17618 return subranges.front()->get_language();
17619 }
17620
17621 bool
operator ==(const decl_base & o) const17622 array_type_def::operator==(const decl_base& o) const
17623 {
17624 const array_type_def* other =
17625 dynamic_cast<const array_type_def*>(&o);
17626 if (!other)
17627 return false;
17628 return try_canonical_compare(this, other);
17629 }
17630
17631 bool
operator ==(const type_base & o) const17632 array_type_def::operator==(const type_base& o) const
17633 {
17634 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17635 if (!other)
17636 return false;
17637 return *this == *other;
17638 }
17639
17640 /// Getter of the type of an array element.
17641 ///
17642 /// @return the type of an array element.
17643 const type_base_sptr
get_element_type() const17644 array_type_def::get_element_type() const
17645 {return priv_->element_type_.lock();}
17646
17647 /// Setter of the type of array element.
17648 ///
17649 /// Beware that after using this function, one might want to
17650 /// re-compute the canonical type of the array, if one has already
17651 /// been computed.
17652 ///
17653 /// The intended use of this method is to permit in-place adjustment
17654 /// of the element type's qualifiers. In particular, the size of the
17655 /// element type should not be changed.
17656 ///
17657 /// @param element_type the new element type to set.
17658 void
set_element_type(const type_base_sptr & element_type)17659 array_type_def::set_element_type(const type_base_sptr& element_type)
17660 {
17661 priv_->element_type_ = element_type;
17662 update_size();
17663 set_name(get_environment().intern(get_pretty_representation()));
17664 }
17665
17666 /// Append subranges from the vector @param subs to the current
17667 /// vector of subranges.
17668 void
append_subranges(const std::vector<subrange_sptr> & subs)17669 array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
17670 {
17671
17672 for (const auto &sub : subs)
17673 priv_->subranges_.push_back(sub);
17674
17675 update_size();
17676 set_name(get_environment().intern(get_pretty_representation()));
17677 }
17678
17679 /// @return true if one of the sub-ranges of the array is infinite, or
17680 /// if the array has no sub-range at all, also meaning that the size
17681 /// of the array is infinite.
17682 bool
is_infinite() const17683 array_type_def::is_infinite() const
17684 {
17685 if (priv_->subranges_.empty())
17686 return true;
17687
17688 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
17689 priv_->subranges_.begin();
17690 i != priv_->subranges_.end();
17691 ++i)
17692 if ((*i)->is_infinite())
17693 return true;
17694
17695 return false;
17696 }
17697
17698 int
get_dimension_count() const17699 array_type_def::get_dimension_count() const
17700 {return priv_->subranges_.size();}
17701
17702 /// Build and return the qualified name of the current instance of the
17703 /// @ref array_type_def.
17704 ///
17705 /// @param qn output parameter. Is set to the newly-built qualified
17706 /// name of the current instance of @ref array_type_def.
17707 ///
17708 /// @param internal set to true if the call is intended for an
17709 /// internal use (for technical use inside the library itself), false
17710 /// otherwise. If you don't know what this is for, then set it to
17711 /// false.
17712 void
get_qualified_name(interned_string & qn,bool internal) const17713 array_type_def::get_qualified_name(interned_string& qn, bool internal) const
17714 {qn = get_qualified_name(internal);}
17715
17716 /// Compute the qualified name of the array.
17717 ///
17718 /// @param internal set to true if the call is intended for an
17719 /// internal use (for technical use inside the library itself), false
17720 /// otherwise. If you don't know what this is for, then set it to
17721 /// false.
17722 ///
17723 /// @return the resulting qualified name.
17724 const interned_string&
get_qualified_name(bool internal) const17725 array_type_def::get_qualified_name(bool internal) const
17726 {
17727 const environment& env = get_environment();
17728
17729
17730 if (internal)
17731 {
17732 if (get_canonical_type())
17733 {
17734 if (priv_->internal_qualified_name_.empty())
17735 priv_->internal_qualified_name_ =
17736 env.intern(get_type_representation(*this, /*internal=*/true));
17737 return priv_->internal_qualified_name_;
17738 }
17739 else
17740 {
17741 priv_->temp_internal_qualified_name_ =
17742 env.intern(get_type_representation(*this, /*internal=*/true));
17743 return priv_->temp_internal_qualified_name_;
17744 }
17745 }
17746 else
17747 {
17748 if (get_canonical_type())
17749 {
17750 if (decl_base::peek_qualified_name().empty())
17751 set_qualified_name(env.intern(get_type_representation
17752 (*this, /*internal=*/false)));
17753 return decl_base::peek_qualified_name();
17754 }
17755 else
17756 {
17757 set_temporary_qualified_name(env.intern(get_type_representation
17758 (*this,
17759 /*internal=*/false)));
17760 return decl_base::peek_temporary_qualified_name();
17761 }
17762 }
17763 }
17764
17765 /// This implements the ir_traversable_base::traverse pure virtual
17766 /// function.
17767 ///
17768 /// @param v the visitor used on the current instance.
17769 ///
17770 /// @return true if the entire IR node tree got traversed, false
17771 /// otherwise.
17772 bool
traverse(ir_node_visitor & v)17773 array_type_def::traverse(ir_node_visitor& v)
17774 {
17775 if (v.type_node_has_been_visited(this))
17776 return true;
17777
17778 if (visiting())
17779 return true;
17780
17781 if (v.visit_begin(this))
17782 {
17783 visiting(true);
17784 if (type_base_sptr t = get_element_type())
17785 t->traverse(v);
17786 visiting(false);
17787 }
17788
17789 bool result = v.visit_end(this);
17790 v.mark_type_node_as_visited(this);
17791 return result;
17792 }
17793
17794 const location&
get_location() const17795 array_type_def::get_location() const
17796 {return decl_base::get_location();}
17797
17798 /// Get the array's subranges
17799 const std::vector<array_type_def::subrange_sptr>&
get_subranges() const17800 array_type_def::get_subranges() const
17801 {return priv_->subranges_;}
17802
~array_type_def()17803 array_type_def::~array_type_def()
17804 {}
17805
17806 // </array_type_def definitions>
17807
17808 // <enum_type_decl definitions>
17809
17810 class enum_type_decl::priv
17811 {
17812 type_base_sptr underlying_type_;
17813 enumerators enumerators_;
17814
17815 friend class enum_type_decl;
17816
17817 priv();
17818
17819 public:
priv(type_base_sptr underlying_type,enumerators & enumerators)17820 priv(type_base_sptr underlying_type,
17821 enumerators& enumerators)
17822 : underlying_type_(underlying_type),
17823 enumerators_(enumerators)
17824 {}
17825 }; // end class enum_type_decl::priv
17826
17827 /// Constructor.
17828 ///
17829 /// @param name the name of the type declaration.
17830 ///
17831 /// @param locus the source location where the type was defined.
17832 ///
17833 /// @param underlying_type the underlying type of the enum.
17834 ///
17835 /// @param enums the enumerators of this enum type.
17836 ///
17837 /// @param linkage_name the linkage name of the enum.
17838 ///
17839 /// @param vis the visibility of the enum type.
enum_type_decl(const string & name,const location & locus,type_base_sptr underlying_type,enumerators & enums,const string & linkage_name,visibility vis)17840 enum_type_decl::enum_type_decl(const string& name,
17841 const location& locus,
17842 type_base_sptr underlying_type,
17843 enumerators& enums,
17844 const string& linkage_name,
17845 visibility vis)
17846 : type_or_decl_base(underlying_type->get_environment(),
17847 ENUM_TYPE
17848 | ABSTRACT_TYPE_BASE
17849 | ABSTRACT_DECL_BASE),
17850 type_base(underlying_type->get_environment(),
17851 underlying_type->get_size_in_bits(),
17852 underlying_type->get_alignment_in_bits()),
17853 decl_base(underlying_type->get_environment(),
17854 name, locus, linkage_name, vis),
17855 priv_(new priv(underlying_type, enums))
17856 {
17857 runtime_type_instance(this);
17858 for (enumerators::iterator e = get_enumerators().begin();
17859 e != get_enumerators().end();
17860 ++e)
17861 e->set_enum_type(this);
17862 }
17863
17864 /// Return the underlying type of the enum.
17865 type_base_sptr
get_underlying_type() const17866 enum_type_decl::get_underlying_type() const
17867 {return priv_->underlying_type_;}
17868
17869 /// @return the list of enumerators of the enum.
17870 const enum_type_decl::enumerators&
get_enumerators() const17871 enum_type_decl::get_enumerators() const
17872 {return priv_->enumerators_;}
17873
17874 /// @return the list of enumerators of the enum.
17875 enum_type_decl::enumerators&
get_enumerators()17876 enum_type_decl::get_enumerators()
17877 {return priv_->enumerators_;}
17878
17879 /// Get the pretty representation of the current instance of @ref
17880 /// enum_type_decl.
17881 ///
17882 /// @param internal set to true if the call is intended to get a
17883 /// representation of the decl (or type) for the purpose of canonical
17884 /// type comparison. This is mainly used in the function
17885 /// type_base::get_canonical_type_for().
17886 ///
17887 /// In other words if the argument for this parameter is true then the
17888 /// call is meant for internal use (for technical use inside the
17889 /// library itself), false otherwise. If you don't know what this is
17890 /// for, then set it to false.
17891 ///
17892 /// @param qualified_name if true, names emitted in the pretty
17893 /// representation are fully qualified.
17894 ///
17895 /// @return the pretty representation of the enum type.
17896 string
get_pretty_representation(bool internal,bool qualified_name) const17897 enum_type_decl::get_pretty_representation(bool internal,
17898 bool qualified_name) const
17899 {
17900 string r = "enum ";
17901
17902 if (internal && get_is_anonymous())
17903 r += get_type_name(this, qualified_name, /*internal=*/true);
17904 else
17905 r += decl_base::get_pretty_representation(internal,
17906 qualified_name);
17907 return r;
17908 }
17909
17910 /// This implements the ir_traversable_base::traverse pure virtual
17911 /// function.
17912 ///
17913 /// @param v the visitor used on the current instance.
17914 ///
17915 /// @return true if the entire IR node tree got traversed, false
17916 /// otherwise.
17917 bool
traverse(ir_node_visitor & v)17918 enum_type_decl::traverse(ir_node_visitor &v)
17919 {
17920 if (v.type_node_has_been_visited(this))
17921 return true;
17922
17923 if (visiting())
17924 return true;
17925
17926 if (v.visit_begin(this))
17927 {
17928 visiting(true);
17929 if (type_base_sptr t = get_underlying_type())
17930 t->traverse(v);
17931 visiting(false);
17932 }
17933
17934 bool result = v.visit_end(this);
17935 v.mark_type_node_as_visited(this);
17936 return result;
17937 }
17938
17939 /// Destructor for the enum type declaration.
~enum_type_decl()17940 enum_type_decl::~enum_type_decl()
17941 {}
17942
17943 /// Test if two enums differ, but not by a name change.
17944 ///
17945 /// @param l the first enum to consider.
17946 ///
17947 /// @param r the second enum to consider.
17948 ///
17949 /// @return true iff @p l differs from @p r by anything but a name
17950 /// change.
17951 bool
enum_has_non_name_change(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)17952 enum_has_non_name_change(const enum_type_decl& l,
17953 const enum_type_decl& r,
17954 change_kind* k)
17955 {
17956 bool result = false;
17957 if (*l.get_underlying_type() != *r.get_underlying_type())
17958 {
17959 result = true;
17960 if (k)
17961 *k |= SUBTYPE_CHANGE_KIND;
17962 else
17963 return true;
17964 }
17965
17966 enum_type_decl::enumerators::const_iterator i, j;
17967 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
17968 i != l.get_enumerators().end() && j != r.get_enumerators().end();
17969 ++i, ++j)
17970 if (*i != *j)
17971 {
17972 result = true;
17973 if (k)
17974 {
17975 *k |= LOCAL_TYPE_CHANGE_KIND;
17976 break;
17977 }
17978 else
17979 return true;
17980 }
17981
17982 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
17983 {
17984 result = true;
17985 if (k)
17986 *k |= LOCAL_TYPE_CHANGE_KIND;
17987 else
17988 return true;
17989 }
17990
17991 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
17992 interned_string qn_r = l.get_environment().intern(r.get_qualified_name());
17993 interned_string qn_l = l.get_environment().intern(l.get_qualified_name());
17994 string n_l = l.get_name();
17995 string n_r = r.get_name();
17996 local_r.set_qualified_name(qn_l);
17997 local_r.set_name(n_l);
17998
17999 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
18000 {
18001 result = true;
18002 if (k)
18003 {
18004 if (!l.decl_base::operator==(r))
18005 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18006 if (!l.type_base::operator==(r))
18007 *k |= LOCAL_TYPE_CHANGE_KIND;
18008 }
18009 else
18010 {
18011 local_r.set_name(n_r);
18012 local_r.set_qualified_name(qn_r);
18013 return true;
18014 }
18015 }
18016 local_r.set_qualified_name(qn_r);
18017 local_r.set_name(n_r);
18018
18019 return result;
18020 }
18021
18022 /// Test if a given enumerator is found present in an enum.
18023 ///
18024 /// This is a subroutine of the equals function for enums.
18025 ///
18026 /// @param enr the enumerator to consider.
18027 ///
18028 /// @param enom the enum to consider.
18029 ///
18030 /// @return true iff the enumerator @p enr is present in the enum @p
18031 /// enom.
18032 static bool
is_enumerator_present_in_enum(const enum_type_decl::enumerator & enr,const enum_type_decl & enom)18033 is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr,
18034 const enum_type_decl &enom)
18035 {
18036 for (const auto &e : enom.get_enumerators())
18037 if (e == enr)
18038 return true;
18039 return false;
18040 }
18041
18042 /// Check if two enumerators values are equal.
18043 ///
18044 /// This function doesn't check if the names of the enumerators are
18045 /// equal or not.
18046 ///
18047 /// @param enr the first enumerator to consider.
18048 ///
18049 /// @param enl the second enumerator to consider.
18050 ///
18051 /// @return true iff @p enr has the same value as @p enl.
18052 static bool
enumerators_values_are_equal(const enum_type_decl::enumerator & enr,const enum_type_decl::enumerator & enl)18053 enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
18054 const enum_type_decl::enumerator &enl)
18055 {return enr.get_value() == enl.get_value();}
18056
18057 /// Detect if a given enumerator value is present in an enum.
18058 ///
18059 /// This function looks inside the enumerators of a given enum and
18060 /// detect if the enum contains at least one enumerator or a given
18061 /// value. The function also detects if the enumerator value we are
18062 /// looking at is present in the enum with a different name. An
18063 /// enumerator with the same value but with a different name is named
18064 /// a "redundant enumerator". The function returns the set of
18065 /// enumerators that are redundant with the value we are looking at.
18066 ///
18067 /// @param enr the enumerator to consider.
18068 ///
18069 /// @param enom the enum to consider.
18070 ///
18071 /// @param redundant_enrs if the function returns true, then this
18072 /// vector is filled with enumerators that are redundant with the
18073 /// value of @p enr.
18074 ///
18075 /// @return true iff the function detects that @p enom contains
18076 /// enumerators with the same value as @p enr.
18077 static bool
is_enumerator_value_present_in_enum(const enum_type_decl::enumerator & enr,const enum_type_decl & enom,vector<enum_type_decl::enumerator> & redundant_enrs)18078 is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
18079 const enum_type_decl &enom,
18080 vector<enum_type_decl::enumerator>& redundant_enrs)
18081 {
18082 bool found = false;
18083 for (const auto &e : enom.get_enumerators())
18084 if (enumerators_values_are_equal(e, enr))
18085 {
18086 found = true;
18087 if (e != enr)
18088 redundant_enrs.push_back(e);
18089 }
18090
18091 return found;
18092 }
18093
18094 /// Check if an enumerator value is redundant in a given enum.
18095 ///
18096 /// Given an enumerator value, this function detects if an enum
18097 /// contains at least one enumerator with the the same value but with
18098 /// a different name.
18099 ///
18100 /// @param enr the enumerator to consider.
18101 ///
18102 /// @param enom the enum to consider.
18103 ///
18104 /// @return true iff @p enr is a redundant enumerator in enom.
18105 static bool
is_enumerator_value_redundant(const enum_type_decl::enumerator & enr,const enum_type_decl & enom)18106 is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
18107 const enum_type_decl &enom)
18108 {
18109 vector<enum_type_decl::enumerator> redundant_enrs;
18110 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
18111 {
18112 if (!redundant_enrs.empty())
18113 return true;
18114 }
18115 return false;
18116 }
18117
18118 /// Compares two instances of @ref enum_type_decl.
18119 ///
18120 /// If the two intances are different, set a bitfield to give some
18121 /// insight about the kind of differences there are.
18122 ///
18123 /// @param l the first artifact of the comparison.
18124 ///
18125 /// @param r the second artifact of the comparison.
18126 ///
18127 /// @param k a pointer to a bitfield that gives information about the
18128 /// kind of changes there are between @p l and @p r. This one is set
18129 /// iff @p k is non-null and the function returns false.
18130 ///
18131 /// Please note that setting k to a non-null value does have a
18132 /// negative performance impact because even if @p l and @p r are not
18133 /// equal, the function keeps up the comparison in order to determine
18134 /// the different kinds of ways in which they are different.
18135 ///
18136 /// @return true if @p l equals @p r, false otherwise.
18137 bool
equals(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)18138 equals(const enum_type_decl& l, const enum_type_decl& r, change_kind* k)
18139 {
18140 bool result = true;
18141
18142 //
18143 // Look through decl-only-enum.
18144 //
18145
18146 const enum_type_decl *def1 =
18147 l.get_is_declaration_only()
18148 ? is_enum_type(l.get_naked_definition_of_declaration())
18149 : &l;
18150
18151 const enum_type_decl *def2 =
18152 r.get_is_declaration_only()
18153 ? is_enum_type(r.get_naked_definition_of_declaration())
18154 : &r;
18155
18156 if (!!def1 != !!def2)
18157 {
18158 // One enum is decl-only while the other is not.
18159 // So the two enums are different.
18160 result = false;
18161 if (k)
18162 *k |= SUBTYPE_CHANGE_KIND;
18163 else
18164 ABG_RETURN_FALSE;
18165 }
18166
18167 //
18168 // At this point, both enums have the same state of decl-only-ness.
18169 // So we can compare oranges to oranges.
18170 //
18171
18172 if (!def1)
18173 def1 = &l;
18174 if (!def2)
18175 def2 = &r;
18176
18177 if (def1->get_underlying_type() != def2->get_underlying_type())
18178 {
18179 result = false;
18180 if (k)
18181 *k |= SUBTYPE_CHANGE_KIND;
18182 else
18183 ABG_RETURN_FALSE;
18184 }
18185
18186 if (!(def1->decl_base::operator==(*def2)
18187 && def1->type_base::operator==(*def2)))
18188 {
18189 result = false;
18190 if (k)
18191 {
18192 if (!def1->decl_base::operator==(*def2))
18193 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18194 if (!def1->type_base::operator==(*def2))
18195 *k |= LOCAL_TYPE_CHANGE_KIND;
18196 }
18197 else
18198 ABG_RETURN_FALSE;
18199 }
18200
18201 // Now compare the enumerators. Note that the order of declaration
18202 // of enumerators should not matter in the comparison.
18203 //
18204 // Also if an enumerator value is redundant, that shouldn't impact
18205 // the comparison.
18206 //
18207 // In that case, note that the two enums below are considered equal:
18208 //
18209 // enum foo
18210 // {
18211 // e0 = 0;
18212 // e1 = 1;
18213 // e2 = 2;
18214 // };
18215 //
18216 // enum foo
18217 // {
18218 // e0 = 0;
18219 // e1 = 1;
18220 // e2 = 2;
18221 // e_added = 1; // <-- this value is redundant with the value
18222 // // of the enumerator e1.
18223 // };
18224 //
18225 // Note however that in the case below, the enums are different.
18226 //
18227 // enum foo
18228 // {
18229 // e0 = 0;
18230 // e1 = 1;
18231 // };
18232 //
18233 // enum foo
18234 // {
18235 // e0 = 0;
18236 // e2 = 1; // <-- this enum value is present in the first version
18237 // // of foo, but is not redundant with any enumerator
18238 // // in the second version of of enum foo.
18239 // };
18240 //
18241 // These two enums are considered equal.
18242
18243 for(const auto &e : def1->get_enumerators())
18244 if (!is_enumerator_present_in_enum(e, *def2)
18245 && (!is_enumerator_value_redundant(e, *def2)
18246 || !is_enumerator_value_redundant(e, *def1)))
18247 {
18248 result = false;
18249 if (k)
18250 {
18251 *k |= LOCAL_TYPE_CHANGE_KIND;
18252 break;
18253 }
18254 else
18255 ABG_RETURN_FALSE;
18256 }
18257
18258 for(const auto &e : def2->get_enumerators())
18259 if (!is_enumerator_present_in_enum(e, *def1)
18260 && (!is_enumerator_value_redundant(e, *def1)
18261 || !is_enumerator_value_redundant(e, *def2)))
18262 {
18263 result = false;
18264 if (k)
18265 {
18266 *k |= LOCAL_TYPE_CHANGE_KIND;
18267 break;
18268 }
18269 else
18270 ABG_RETURN_FALSE;
18271 }
18272
18273 ABG_RETURN(result);
18274 }
18275
18276 /// Equality operator.
18277 ///
18278 /// @param o the other enum to test against.
18279 ///
18280 /// @return true iff @p o equals the current instance of enum type
18281 /// decl.
18282 bool
operator ==(const decl_base & o) const18283 enum_type_decl::operator==(const decl_base& o) const
18284 {
18285 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
18286 if (!op)
18287 return false;
18288 return try_canonical_compare(this, op);
18289 }
18290
18291 /// Equality operator.
18292 ///
18293 /// @param o the other enum to test against.
18294 ///
18295 /// @return true iff @p o is equals the current instance of enum type
18296 /// decl.
18297 bool
operator ==(const type_base & o) const18298 enum_type_decl::operator==(const type_base& o) const
18299 {
18300 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18301 if (!other)
18302 return false;
18303 return *this == *other;
18304 }
18305
18306 /// Equality operator for @ref enum_type_decl_sptr.
18307 ///
18308 /// @param l the first operand to compare.
18309 ///
18310 /// @param r the second operand to compare.
18311 ///
18312 /// @return true iff @p l equals @p r.
18313 bool
operator ==(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)18314 operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
18315 {
18316 if (!!l != !!r)
18317 return false;
18318 if (l.get() == r.get())
18319 return true;
18320 decl_base_sptr o = r;
18321 return *l == *o;
18322 }
18323
18324 /// Inequality operator for @ref enum_type_decl_sptr.
18325 ///
18326 /// @param l the first operand to compare.
18327 ///
18328 /// @param r the second operand to compare.
18329 ///
18330 /// @return true iff @p l equals @p r.
18331 bool
operator !=(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)18332 operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
18333 {return !operator==(l, r);}
18334
18335 /// The type of the private data of an @ref
18336 /// enum_type_decl::enumerator.
18337 class enum_type_decl::enumerator::priv
18338 {
18339 string name_;
18340 int64_t value_;
18341 string qualified_name_;
18342 enum_type_decl* enum_type_;
18343
18344 friend class enum_type_decl::enumerator;
18345
18346 public:
18347
priv()18348 priv()
18349 : enum_type_()
18350 {}
18351
priv(const string & name,int64_t value,enum_type_decl * e=0)18352 priv(const string& name,
18353 int64_t value,
18354 enum_type_decl* e = 0)
18355 : name_(name),
18356 value_(value),
18357 enum_type_(e)
18358 {}
18359 }; // end class enum_type_def::enumerator::priv
18360
18361 /// Default constructor of the @ref enum_type_decl::enumerator type.
enumerator()18362 enum_type_decl::enumerator::enumerator()
18363 : priv_(new priv)
18364 {}
18365
18366 enum_type_decl::enumerator::~enumerator() = default;
18367
18368 /// Constructor of the @ref enum_type_decl::enumerator type.
18369 ///
18370 /// @param env the environment we are operating from.
18371 ///
18372 /// @param name the name of the enumerator.
18373 ///
18374 /// @param value the value of the enumerator.
enumerator(const string & name,int64_t value)18375 enum_type_decl::enumerator::enumerator(const string& name,
18376 int64_t value)
18377 : priv_(new priv(name, value))
18378 {}
18379
18380 /// Copy constructor of the @ref enum_type_decl::enumerator type.
18381 ///
18382 /// @param other enumerator to copy.
enumerator(const enumerator & other)18383 enum_type_decl::enumerator::enumerator(const enumerator& other)
18384 : priv_(new priv(other.get_name(),
18385 other.get_value(),
18386 other.get_enum_type()))
18387 {}
18388
18389 /// Assignment operator of the @ref enum_type_decl::enumerator type.
18390 ///
18391 /// @param o
18392 enum_type_decl::enumerator&
operator =(const enumerator & o)18393 enum_type_decl::enumerator::operator=(const enumerator& o)
18394 {
18395 priv_->name_ = o.get_name();
18396 priv_->value_ = o.get_value();
18397 priv_->enum_type_ = o.get_enum_type();
18398 return *this;
18399 }
18400
18401 /// Equality operator
18402 ///
18403 /// @param other the enumerator to compare to the current
18404 /// instance of enum_type_decl::enumerator.
18405 ///
18406 /// @return true if @p other equals the current instance of
18407 /// enum_type_decl::enumerator.
18408 bool
operator ==(const enumerator & other) const18409 enum_type_decl::enumerator::operator==(const enumerator& other) const
18410 {
18411 bool names_equal = true;
18412 names_equal = (get_name() == other.get_name());
18413 return names_equal && (get_value() == other.get_value());
18414 }
18415
18416 /// Inequality operator.
18417 ///
18418 /// @param other the other instance to compare against.
18419 ///
18420 /// @return true iff @p other is different from the current instance.
18421 bool
operator !=(const enumerator & other) const18422 enum_type_decl::enumerator::operator!=(const enumerator& other) const
18423 {return !operator==(other);}
18424
18425 /// Getter for the name of the current instance of
18426 /// enum_type_decl::enumerator.
18427 ///
18428 /// @return a reference to the name of the current instance of
18429 /// enum_type_decl::enumerator.
18430 const string&
get_name() const18431 enum_type_decl::enumerator::get_name() const
18432 {return priv_->name_;}
18433
18434 /// Getter for the qualified name of the current instance of
18435 /// enum_type_decl::enumerator. The first invocation of the method
18436 /// builds the qualified name, caches it and return a reference to the
18437 /// cached qualified name. Subsequent invocations just return the
18438 /// cached value.
18439 ///
18440 /// @param internal set to true if the call is intended for an
18441 /// internal use (for technical use inside the library itself), false
18442 /// otherwise. If you don't know what this is for, then set it to
18443 /// false.
18444 ///
18445 /// @return the qualified name of the current instance of
18446 /// enum_type_decl::enumerator.
18447 const string&
get_qualified_name(bool internal) const18448 enum_type_decl::enumerator::get_qualified_name(bool internal) const
18449 {
18450 if (priv_->qualified_name_.empty())
18451 {
18452 priv_->qualified_name_ =
18453 get_enum_type()->get_qualified_name(internal)
18454 + "::"
18455 + get_name();
18456 }
18457 return priv_->qualified_name_;
18458 }
18459
18460 /// Setter for the name of @ref enum_type_decl::enumerator.
18461 ///
18462 /// @param n the new name.
18463 void
set_name(const string & n)18464 enum_type_decl::enumerator::set_name(const string& n)
18465 {priv_->name_ = n;}
18466
18467 /// Getter for the value of @ref enum_type_decl::enumerator.
18468 ///
18469 /// @return the value of the current instance of
18470 /// enum_type_decl::enumerator.
18471 int64_t
get_value() const18472 enum_type_decl::enumerator::get_value() const
18473 {return priv_->value_;}
18474
18475 /// Setter for the value of @ref enum_type_decl::enumerator.
18476 ///
18477 /// @param v the new value of the enum_type_decl::enumerator.
18478 void
set_value(int64_t v)18479 enum_type_decl::enumerator::set_value(int64_t v)
18480 {priv_->value_= v;}
18481
18482 /// Getter for the enum type that this enumerator is for.
18483 ///
18484 /// @return the enum type that this enumerator is for.
18485 enum_type_decl*
get_enum_type() const18486 enum_type_decl::enumerator::get_enum_type() const
18487 {return priv_->enum_type_;}
18488
18489 /// Setter for the enum type that this enumerator is for.
18490 ///
18491 /// @param e the new enum type.
18492 void
set_enum_type(enum_type_decl * e)18493 enum_type_decl::enumerator::set_enum_type(enum_type_decl* e)
18494 {priv_->enum_type_ = e;}
18495 // </enum_type_decl definitions>
18496
18497 // <typedef_decl definitions>
18498
18499 /// Private data structure of the @ref typedef_decl.
18500 struct typedef_decl::priv
18501 {
18502 type_base_wptr underlying_type_;
18503 string internal_qualified_name_;
18504 string temp_internal_qualified_name_;
18505
privabigail::ir::typedef_decl::priv18506 priv(const type_base_sptr& t)
18507 : underlying_type_(t)
18508 {}
18509 }; // end struct typedef_decl::priv
18510
18511 /// Constructor of the typedef_decl type.
18512 ///
18513 /// @param name the name of the typedef.
18514 ///
18515 /// @param underlying_type the underlying type of the typedef.
18516 ///
18517 /// @param locus the source location of the typedef declaration.
18518 ///
18519 /// @param linkage_name the mangled name of the typedef.
18520 ///
18521 /// @param vis the visibility of the typedef type.
typedef_decl(const string & name,const type_base_sptr underlying_type,const location & locus,const string & linkage_name,visibility vis)18522 typedef_decl::typedef_decl(const string& name,
18523 const type_base_sptr underlying_type,
18524 const location& locus,
18525 const string& linkage_name,
18526 visibility vis)
18527 : type_or_decl_base(underlying_type->get_environment(),
18528 TYPEDEF_TYPE
18529 | ABSTRACT_TYPE_BASE
18530 | ABSTRACT_DECL_BASE),
18531 type_base(underlying_type->get_environment(),
18532 underlying_type->get_size_in_bits(),
18533 underlying_type->get_alignment_in_bits()),
18534 decl_base(underlying_type->get_environment(),
18535 name, locus, linkage_name, vis),
18536 priv_(new priv(underlying_type))
18537 {
18538 runtime_type_instance(this);
18539 }
18540
18541 /// Constructor of the typedef_decl type.
18542 ///
18543 /// @param name the name of the typedef.
18544 ///
18545 /// @param env the environment of the current typedef.
18546 ///
18547 /// @param locus the source location of the typedef declaration.
18548 ///
18549 /// @param mangled_name the mangled name of the typedef.
18550 ///
18551 /// @param vis the visibility of the typedef type.
typedef_decl(const string & name,const environment & env,const location & locus,const string & mangled_name,visibility vis)18552 typedef_decl::typedef_decl(const string& name,
18553 const environment& env,
18554 const location& locus,
18555 const string& mangled_name,
18556 visibility vis)
18557 : type_or_decl_base(env,
18558 TYPEDEF_TYPE
18559 | ABSTRACT_TYPE_BASE
18560 | ABSTRACT_DECL_BASE),
18561 type_base(env, /*size_in_bits=*/0,
18562 /*alignment_in_bits=*/0),
18563 decl_base(env, name, locus, mangled_name, vis),
18564 priv_(new priv(nullptr))
18565 {
18566 runtime_type_instance(this);
18567 }
18568
18569 /// Return the size of the typedef.
18570 ///
18571 /// This function looks at the size of the underlying type and ensures
18572 /// that it's the same as the size of the typedef.
18573 ///
18574 /// @return the size of the typedef.
18575 size_t
get_size_in_bits() const18576 typedef_decl::get_size_in_bits() const
18577 {
18578 if (!get_underlying_type())
18579 return 0;
18580 size_t s = get_underlying_type()->get_size_in_bits();
18581 if (s != type_base::get_size_in_bits())
18582 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
18583 return type_base::get_size_in_bits();
18584 }
18585
18586 /// Return the alignment of the typedef.
18587 ///
18588 /// This function looks at the alignment of the underlying type and
18589 /// ensures that it's the same as the alignment of the typedef.
18590 ///
18591 /// @return the size of the typedef.
18592 size_t
get_alignment_in_bits() const18593 typedef_decl::get_alignment_in_bits() const
18594 {
18595 if (!get_underlying_type())
18596 return 0;
18597 size_t s = get_underlying_type()->get_alignment_in_bits();
18598 if (s != type_base::get_alignment_in_bits())
18599 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
18600 return type_base::get_alignment_in_bits();
18601 }
18602
18603 /// Compares two instances of @ref typedef_decl.
18604 ///
18605 /// If the two intances are different, set a bitfield to give some
18606 /// insight about the kind of differences there are.
18607 ///
18608 /// @param l the first artifact of the comparison.
18609 ///
18610 /// @param r the second artifact of the comparison.
18611 ///
18612 /// @param k a pointer to a bitfield that gives information about the
18613 /// kind of changes there are between @p l and @p r. This one is set
18614 /// iff @p k is non-null and the function returns false.
18615 ///
18616 /// Please note that setting k to a non-null value does have a
18617 /// negative performance impact because even if @p l and @p r are not
18618 /// equal, the function keeps up the comparison in order to determine
18619 /// the different kinds of ways in which they are different.
18620 ///
18621 /// @return true if @p l equals @p r, false otherwise.
18622 bool
equals(const typedef_decl & l,const typedef_decl & r,change_kind * k)18623 equals(const typedef_decl& l, const typedef_decl& r, change_kind* k)
18624 {
18625 bool result = true;
18626
18627 // No need to go further if the types have different names or
18628 // different size / alignment.
18629 if (!(l.decl_base::operator==(r)))
18630 {
18631 result = false;
18632 if (k)
18633 *k |= LOCAL_TYPE_CHANGE_KIND;
18634 else
18635 ABG_RETURN_FALSE;
18636 }
18637
18638 if (*l.get_underlying_type() != *r.get_underlying_type())
18639 {
18640 // Changes to the underlying type of a typedef are considered
18641 // local, a bit like for pointers.
18642 result = false;
18643 if (k)
18644 *k |= LOCAL_TYPE_CHANGE_KIND;
18645 else
18646 ABG_RETURN_FALSE;
18647 }
18648
18649 ABG_RETURN(result);
18650 }
18651
18652 /// Equality operator
18653 ///
18654 /// @param o the other typedef_decl to test against.
18655 bool
operator ==(const decl_base & o) const18656 typedef_decl::operator==(const decl_base& o) const
18657 {
18658 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
18659 if (!other)
18660 return false;
18661 return try_canonical_compare(this, other);
18662 }
18663
18664 /// Equality operator
18665 ///
18666 /// @param o the other typedef_decl to test against.
18667 ///
18668 /// @return true if the current instance of @ref typedef_decl equals
18669 /// @p o.
18670 bool
operator ==(const type_base & o) const18671 typedef_decl::operator==(const type_base& o) const
18672 {
18673 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18674 if (!other)
18675 return false;
18676 return *this == *other;
18677 }
18678
18679 /// Build a pretty representation for a typedef_decl.
18680 ///
18681 /// @param internal set to true if the call is intended to get a
18682 /// representation of the decl (or type) for the purpose of canonical
18683 /// type comparison. This is mainly used in the function
18684 /// type_base::get_canonical_type_for().
18685 ///
18686 /// In other words if the argument for this parameter is true then the
18687 /// call is meant for internal use (for technical use inside the
18688 /// library itself), false otherwise. If you don't know what this is
18689 /// for, then set it to false.
18690
18691 /// @param qualified_name if true, names emitted in the pretty
18692 /// representation are fully qualified.
18693 ///
18694 /// @return a copy of the pretty representation of the current
18695 /// instance of typedef_decl.
18696 string
get_pretty_representation(bool internal,bool qualified_name) const18697 typedef_decl::get_pretty_representation(bool internal,
18698 bool qualified_name) const
18699 {
18700
18701 string result = "typedef ";
18702 if (qualified_name)
18703 result += get_qualified_name(internal);
18704 else
18705 result += get_name();
18706
18707 return result;
18708 }
18709
18710 /// Getter of the underlying type of the typedef.
18711 ///
18712 /// @return the underlying_type.
18713 type_base_sptr
get_underlying_type() const18714 typedef_decl::get_underlying_type() const
18715 {return priv_->underlying_type_.lock();}
18716
18717 /// Setter ofthe underlying type of the typedef.
18718 ///
18719 /// @param t the new underlying type of the typedef.
18720 void
set_underlying_type(const type_base_sptr & t)18721 typedef_decl::set_underlying_type(const type_base_sptr& t)
18722 {
18723 priv_->underlying_type_ = t;
18724 set_size_in_bits(t->get_size_in_bits());
18725 set_alignment_in_bits(t->get_alignment_in_bits());
18726 }
18727
18728 /// This implements the ir_traversable_base::traverse pure virtual
18729 /// function.
18730 ///
18731 /// @param v the visitor used on the current instance.
18732 ///
18733 /// @return true if the entire IR node tree got traversed, false
18734 /// otherwise.
18735 bool
traverse(ir_node_visitor & v)18736 typedef_decl::traverse(ir_node_visitor& v)
18737 {
18738 if (v.type_node_has_been_visited(this))
18739 return true;
18740
18741 if (visiting())
18742 return true;
18743
18744 if (v.visit_begin(this))
18745 {
18746 visiting(true);
18747 if (type_base_sptr t = get_underlying_type())
18748 t->traverse(v);
18749 visiting(false);
18750 }
18751
18752 bool result = v.visit_end(this);
18753 v.mark_type_node_as_visited(this);
18754 return result;
18755 }
18756
~typedef_decl()18757 typedef_decl::~typedef_decl()
18758 {}
18759 // </typedef_decl definitions>
18760
18761 // <var_decl definitions>
18762
18763 struct var_decl::priv
18764 {
18765 type_base_wptr type_;
18766 type_base* naked_type_;
18767 decl_base::binding binding_;
18768 elf_symbol_sptr symbol_;
18769 interned_string id_;
18770
privabigail::ir::var_decl::priv18771 priv()
18772 : naked_type_(),
18773 binding_(decl_base::BINDING_GLOBAL)
18774 {}
18775
privabigail::ir::var_decl::priv18776 priv(type_base_sptr t,
18777 decl_base::binding b)
18778 : type_(t),
18779 naked_type_(t.get()),
18780 binding_(b)
18781 {}
18782 }; // end struct var_decl::priv
18783
18784 /// Constructor of the @ref var_decl type.
18785 ///
18786 /// @param name the name of the variable declaration
18787 ///
18788 /// @param type the type of the variable declaration
18789 ///
18790 /// @param locus the source location where the variable was defined.
18791 ///
18792 /// @param linkage_name the linkage name of the variable.
18793 ///
18794 /// @param vis the visibility of of the variable.
18795 ///
18796 /// @param bind the binding kind of the variable.
var_decl(const string & name,type_base_sptr type,const location & locus,const string & linkage_name,visibility vis,binding bind)18797 var_decl::var_decl(const string& name,
18798 type_base_sptr type,
18799 const location& locus,
18800 const string& linkage_name,
18801 visibility vis,
18802 binding bind)
18803 : type_or_decl_base(type->get_environment(),
18804 VAR_DECL | ABSTRACT_DECL_BASE),
18805 decl_base(type->get_environment(), name, locus, linkage_name, vis),
18806 priv_(new priv(type, bind))
18807 {
18808 runtime_type_instance(this);
18809 }
18810
18811 /// Getter of the type of the variable.
18812 ///
18813 /// @return the type of the variable.
18814 const type_base_sptr
get_type() const18815 var_decl::get_type() const
18816 {return priv_->type_.lock();}
18817
18818 /// Getter of the type of the variable.
18819 ///
18820 /// This getter returns a bare pointer, as opposed to a smart pointer.
18821 /// It's to be used on performance sensitive code paths identified by
18822 /// careful profiling.
18823 ///
18824 /// @return the type of the variable, as a bare pointer.
18825 const type_base*
get_naked_type() const18826 var_decl::get_naked_type() const
18827 {return priv_->naked_type_;}
18828
18829 /// Getter of the binding of the variable.
18830 ///
18831 /// @return the biding of the variable.
18832 decl_base::binding
get_binding() const18833 var_decl::get_binding() const
18834 {return priv_->binding_;}
18835
18836 /// Setter of the binding of the variable.
18837 ///
18838 /// @param b the new binding value.
18839 void
set_binding(decl_base::binding b)18840 var_decl::set_binding(decl_base::binding b)
18841 {priv_->binding_ = b;}
18842
18843 /// Sets the underlying ELF symbol for the current variable.
18844 ///
18845 /// And underlyin$g ELF symbol for the current variable might exist
18846 /// only if the corpus that this variable originates from was
18847 /// constructed from an ELF binary file.
18848 ///
18849 /// Note that comparing two variables that have underlying ELF symbols
18850 /// involves comparing their underlying elf symbols. The decl name
18851 /// for the variable thus becomes irrelevant in the comparison.
18852 ///
18853 /// @param sym the new ELF symbol for this variable decl.
18854 void
set_symbol(const elf_symbol_sptr & sym)18855 var_decl::set_symbol(const elf_symbol_sptr& sym)
18856 {
18857 priv_->symbol_ = sym;
18858 // The variable id cache that depends on the symbol must be
18859 // invalidated because the symbol changed.
18860 priv_->id_ = get_environment().intern("");
18861 }
18862
18863 /// Gets the the underlying ELF symbol for the current variable,
18864 /// that was set using var_decl::set_symbol(). Please read the
18865 /// documentation for that member function for more information about
18866 /// "underlying ELF symbols".
18867 ///
18868 /// @return sym the underlying ELF symbol for this variable decl, if
18869 /// one exists.
18870 const elf_symbol_sptr&
get_symbol() const18871 var_decl::get_symbol() const
18872 {return priv_->symbol_;}
18873
18874 /// Create a new var_decl that is a clone of the current one.
18875 ///
18876 /// @return the cloned var_decl.
18877 var_decl_sptr
clone() const18878 var_decl::clone() const
18879 {
18880 var_decl_sptr v(new var_decl(get_name(),
18881 get_type(),
18882 get_location(),
18883 get_linkage_name(),
18884 get_visibility(),
18885 get_binding()));
18886
18887 v->set_symbol(get_symbol());
18888
18889 if (is_member_decl(*this))
18890 {
18891 class_or_union* scope = is_class_or_union_type(get_scope());
18892 scope->add_data_member(v, get_member_access_specifier(*this),
18893 get_data_member_is_laid_out(*this),
18894 get_member_is_static(*this),
18895 get_data_member_offset(*this));
18896 }
18897 else
18898 add_decl_to_scope(v, get_scope());
18899
18900 return v;
18901 }
18902 /// Setter of the scope of the current var_decl.
18903 ///
18904 /// Note that the decl won't hold a reference on the scope. It's
18905 /// rather the scope that holds a reference on its members.
18906 ///
18907 /// @param scope the new scope.
18908 void
set_scope(scope_decl * scope)18909 var_decl::set_scope(scope_decl* scope)
18910 {
18911 if (!get_context_rel())
18912 set_context_rel(new dm_context_rel(scope));
18913 else
18914 get_context_rel()->set_scope(scope);
18915 }
18916
18917 /// Compares two instances of @ref var_decl.
18918 ///
18919 /// If the two intances are different, set a bitfield to give some
18920 /// insight about the kind of differences there are.
18921 ///
18922 /// @param l the first artifact of the comparison.
18923 ///
18924 /// @param r the second artifact of the comparison.
18925 ///
18926 /// @param k a pointer to a bitfield that gives information about the
18927 /// kind of changes there are between @p l and @p r. This one is set
18928 /// iff @p k is non-null and the function returns false.
18929 ///
18930 /// Please note that setting k to a non-null value does have a
18931 /// negative performance impact because even if @p l and @p r are not
18932 /// equal, the function keeps up the comparison in order to determine
18933 /// the different kinds of ways in which they are different.
18934 ///
18935 /// @return true if @p l equals @p r, false otherwise.
18936 bool
equals(const var_decl & l,const var_decl & r,change_kind * k)18937 equals(const var_decl& l, const var_decl& r, change_kind* k)
18938 {
18939 bool result = true;
18940
18941 // First test types of variables. This should be fast because in
18942 // the general case, most types should be canonicalized.
18943 if (*l.get_naked_type() != *r.get_naked_type())
18944 {
18945 result = false;
18946 if (k)
18947 {
18948 if (!types_have_similar_structure(l.get_naked_type(),
18949 r.get_naked_type()))
18950 *k |= (LOCAL_TYPE_CHANGE_KIND);
18951 else
18952 *k |= SUBTYPE_CHANGE_KIND;
18953 }
18954 else
18955 ABG_RETURN_FALSE;
18956 }
18957
18958 // If there are underlying elf symbols for these variables,
18959 // compare them. And then compare the other parts.
18960 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
18961 if (!!s0 != !!s1)
18962 {
18963 result = false;
18964 if (k)
18965 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18966 else
18967 ABG_RETURN_FALSE;
18968 }
18969 else if (s0 && s0 != s1)
18970 {
18971 result = false;
18972 if (k)
18973 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18974 else
18975 ABG_RETURN_FALSE;
18976 }
18977 bool symbols_are_equal = (s0 && s1 && result);
18978
18979 if (symbols_are_equal)
18980 {
18981 // The variables have underlying elf symbols that are equal, so
18982 // now, let's compare the decl_base part of the variables w/o
18983 // considering their decl names.
18984 const environment& env = l.get_environment();
18985 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
18986 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
18987 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
18988 bool decl_bases_different = !l.decl_base::operator==(r);
18989 const_cast<var_decl&>(l).set_qualified_name(n1);
18990 const_cast<var_decl&>(r).set_qualified_name(n2);
18991
18992 if (decl_bases_different)
18993 {
18994 result = false;
18995 if (k)
18996 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18997 else
18998 ABG_RETURN_FALSE;
18999 }
19000 }
19001 else
19002 if (!l.decl_base::operator==(r))
19003 {
19004 result = false;
19005 if (k)
19006 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19007 else
19008 ABG_RETURN_FALSE;
19009 }
19010
19011 const dm_context_rel* c0 =
19012 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
19013 const dm_context_rel* c1 =
19014 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
19015 ABG_ASSERT(c0 && c1);
19016
19017 if (*c0 != *c1)
19018 {
19019 result = false;
19020 if (k)
19021 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19022 else
19023 ABG_RETURN_FALSE;
19024 }
19025
19026 ABG_RETURN(result);
19027 }
19028
19029 /// Comparison operator of @ref var_decl.
19030 ///
19031 /// @param o the instance of @ref var_decl to compare against.
19032 ///
19033 /// @return true iff the current instance of @ref var_decl equals @p o.
19034 bool
operator ==(const decl_base & o) const19035 var_decl::operator==(const decl_base& o) const
19036 {
19037 const var_decl* other = dynamic_cast<const var_decl*>(&o);
19038 if (!other)
19039 return false;
19040
19041 return equals(*this, *other, 0);
19042 }
19043
19044 /// Return an ID that tries to uniquely identify the variable inside a
19045 /// program or a library.
19046 ///
19047 /// So if the variable has an underlying elf symbol, the ID is the
19048 /// concatenation of the symbol name and its version. Otherwise, the
19049 /// ID is the linkage name if its non-null. Otherwise, it's the
19050 /// pretty representation of the variable.
19051 ///
19052 /// @return the ID.
19053 interned_string
get_id() const19054 var_decl::get_id() const
19055 {
19056 if (priv_->id_.empty())
19057 {
19058 string repr = get_name();
19059 string sym_str;
19060 if (elf_symbol_sptr s = get_symbol())
19061 sym_str = s->get_id_string();
19062 else if (!get_linkage_name().empty())
19063 sym_str = get_linkage_name();
19064
19065 const environment& env = get_type()->get_environment();
19066 priv_->id_ = env.intern(repr);
19067 if (!sym_str.empty())
19068 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
19069 }
19070 return priv_->id_;
19071 }
19072
19073 /// Return the hash value for the current instance.
19074 ///
19075 /// @return the hash value.
19076 size_t
get_hash() const19077 var_decl::get_hash() const
19078 {
19079 var_decl::hash hash_var;
19080 return hash_var(this);
19081 }
19082
19083 /// Get the qualified name of a given variable or data member.
19084 ///
19085 ///
19086 /// Note that if the current instance of @ref var_decl is an anonymous
19087 /// data member, then the qualified name is actually the flat
19088 /// representation (the definition) of the type of the anonymous data
19089 /// member. We chose the flat representation because otherwise, the
19090 /// name of an *anonymous* data member is empty, by construction, e.g:
19091 ///
19092 /// struct foo {
19093 /// int a;
19094 /// union {
19095 /// char b;
19096 /// char c;
19097 /// }; // <---- this data member is anonymous.
19098 /// int d;
19099 /// }
19100 ///
19101 /// The string returned for the anonymous member here is going to be:
19102 ///
19103 /// "union {char b; char c}"
19104 ///
19105 /// @param internal if true then this is for a purpose to the library,
19106 /// otherwise, it's for being displayed to users.
19107 ///
19108 /// @return the resulting qualified name.
19109 const interned_string&
get_qualified_name(bool internal) const19110 var_decl::get_qualified_name(bool internal) const
19111 {
19112 if (is_anonymous_data_member(this)
19113 && decl_base::get_qualified_name().empty())
19114 {
19115 // Display the anonymous data member in a way that makes sense.
19116 string r = get_pretty_representation(internal);
19117 set_qualified_name(get_environment().intern(r));
19118 }
19119
19120 return decl_base::get_qualified_name(internal);
19121 }
19122
19123 /// Build and return the pretty representation of this variable.
19124 ///
19125 /// @param internal set to true if the call is intended to get a
19126 /// representation of the decl (or type) for the purpose of canonical
19127 /// type comparison. This is mainly used in the function
19128 /// type_base::get_canonical_type_for().
19129 ///
19130 /// In other words if the argument for this parameter is true then the
19131 /// call is meant for internal use (for technical use inside the
19132 /// library itself), false otherwise. If you don't know what this is
19133 /// for, then set it to false.
19134 ///
19135 /// @param qualified_name if true, names emitted in the pretty
19136 /// representation are fully qualified.
19137 ///
19138 /// @return a copy of the pretty representation of this variable.
19139 string
get_pretty_representation(bool internal,bool qualified_name) const19140 var_decl::get_pretty_representation(bool internal, bool qualified_name) const
19141 {
19142 string result;
19143
19144 if (is_member_decl(this) && get_member_is_static(this))
19145 result = "static ";
19146
19147 // Detect if the current instance of var_decl is a member of
19148 // an anonymous class or union.
19149 bool member_of_anonymous_class = false;
19150 if (class_or_union* scope = is_at_class_scope(this))
19151 if (scope->get_is_anonymous())
19152 member_of_anonymous_class = true;
19153
19154 if (array_type_def_sptr t = is_array_type(get_type()))
19155 {
19156 string name;
19157 if (member_of_anonymous_class || !qualified_name)
19158 name = get_name();
19159 else
19160 name = get_qualified_name(internal);
19161
19162 type_base_sptr et = t->get_element_type();
19163 ABG_ASSERT(et);
19164 decl_base_sptr decl = get_type_declaration(et);
19165 ABG_ASSERT(decl);
19166 result += decl->get_qualified_name(internal)
19167 + " " + name + t->get_subrange_representation();
19168 }
19169 else
19170 {
19171 if (/*The current var_decl is to be used as an anonymous data
19172 member. */
19173 get_name().empty())
19174 {
19175 // Display the anonymous data member in a way that
19176 // makes sense.
19177 result +=
19178 get_class_or_union_flat_representation
19179 (is_class_or_union_type(get_type()),
19180 "", /*one_line=*/true, internal);
19181 }
19182 else if (data_member_has_anonymous_type(this))
19183 {
19184 result += get_class_or_union_flat_representation
19185 (is_class_or_union_type(get_type()),
19186 "", /*one_line=*/true, internal);
19187 result += " ";
19188 if (!internal
19189 && (member_of_anonymous_class || !qualified_name))
19190 // It doesn't make sense to name the member of an
19191 // anonymous class or union like:
19192 // "__anonymous__::data_member_name". So let's just use
19193 // its non-qualified name.
19194 result += get_name();
19195 else
19196 result += get_qualified_name(internal);
19197 }
19198 else
19199 {
19200 result +=
19201 get_type_declaration(get_type())->get_qualified_name(internal)
19202 + " ";
19203
19204 if (!internal
19205 && (member_of_anonymous_class || !qualified_name))
19206 // It doesn't make sense to name the member of an
19207 // anonymous class or union like:
19208 // "__anonymous__::data_member_name". So let's just use
19209 // its non-qualified name.
19210 result += get_name();
19211 else
19212 result += get_qualified_name(internal);
19213 }
19214 }
19215 return result;
19216 }
19217
19218 /// Get a name that is valid even for an anonymous data member.
19219 ///
19220 /// If the current @ref var_decl is an anonymous data member, then
19221 /// return its pretty representation. As of now, that pretty
19222 /// representation is actually its flat representation as returned by
19223 /// get_class_or_union_flat_representation().
19224 ///
19225 /// Otherwise, just return the name of the current @ref var_decl.
19226 ///
19227 /// @param qualified if true, return the qualified name. This doesn't
19228 /// have an effet if the current @ref var_decl represents an anonymous
19229 /// data member.
19230 string
get_anon_dm_reliable_name(bool qualified) const19231 var_decl::get_anon_dm_reliable_name(bool qualified) const
19232 {
19233 string name;
19234 if (is_anonymous_data_member(this))
19235 // This function is used in the comparison engine to determine
19236 // which anonymous data member was deleted. So it's not involved
19237 // in type comparison or canonicalization. We don't want to use
19238 // the 'internal' version of the pretty presentation.
19239 name = get_pretty_representation(/*internal=*/false, qualified);
19240 else
19241 name = get_name();
19242
19243 return name;
19244 }
19245
19246 /// This implements the ir_traversable_base::traverse pure virtual
19247 /// function.
19248 ///
19249 /// @param v the visitor used on the current instance.
19250 ///
19251 /// @return true if the entire IR node tree got traversed, false
19252 /// otherwise.
19253 bool
traverse(ir_node_visitor & v)19254 var_decl::traverse(ir_node_visitor& v)
19255 {
19256 if (visiting())
19257 return true;
19258
19259 if (v.visit_begin(this))
19260 {
19261 visiting(true);
19262 if (type_base_sptr t = get_type())
19263 t->traverse(v);
19264 visiting(false);
19265 }
19266 return v.visit_end(this);
19267 }
19268
~var_decl()19269 var_decl::~var_decl()
19270 {}
19271
19272 // </var_decl definitions>
19273
19274 /// This function is automatically invoked whenever an instance of
19275 /// this type is canonicalized.
19276 ///
19277 /// It's an overload of the virtual type_base::on_canonical_type_set.
19278 ///
19279 /// We put here what is thus meant to be executed only at the point of
19280 /// type canonicalization.
19281 void
on_canonical_type_set()19282 function_type::on_canonical_type_set()
19283 {
19284 priv_->cached_name_.clear();
19285 priv_->internal_cached_name_.clear();
19286 }
19287
19288 /// The most straightforward constructor for the function_type class.
19289 ///
19290 /// @param return_type the return type of the function type.
19291 ///
19292 /// @param parms the list of parameters of the function type.
19293 /// Stricto sensu, we just need a list of types; we are using a list
19294 /// of parameters (where each parameter also carries the name of the
19295 /// parameter and its source location) to try and provide better
19296 /// diagnostics whenever it makes sense. If it appears that this
19297 /// wasts too many resources, we can fall back to taking just a
19298 /// vector of types here.
19299 ///
19300 /// @param size_in_bits the size of this type, in bits.
19301 ///
19302 /// @param alignment_in_bits the alignment of this type, in bits.
19303 ///
19304 /// @param size_in_bits the size of this type.
function_type(type_base_sptr return_type,const parameters & parms,size_t size_in_bits,size_t alignment_in_bits)19305 function_type::function_type(type_base_sptr return_type,
19306 const parameters& parms,
19307 size_t size_in_bits,
19308 size_t alignment_in_bits)
19309 : type_or_decl_base(return_type->get_environment(),
19310 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
19311 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
19312 priv_(new priv(parms, return_type))
19313 {
19314 runtime_type_instance(this);
19315
19316 for (parameters::size_type i = 0, j = 1;
19317 i < priv_->parms_.size();
19318 ++i, ++j)
19319 {
19320 if (i == 0 && priv_->parms_[i]->get_is_artificial())
19321 // If the first parameter is artificial, then it certainly
19322 // means that this is a member function, and the first
19323 // parameter is the implicit this pointer. In that case, set
19324 // the index of that implicit parameter to zero. Otherwise,
19325 // the index of the first parameter starts at one.
19326 j = 0;
19327 priv_->parms_[i]->set_index(j);
19328 }
19329 }
19330
19331 /// A constructor for a function_type that takes no parameters.
19332 ///
19333 /// @param return_type the return type of this function_type.
19334 ///
19335 /// @param size_in_bits the size of this type, in bits.
19336 ///
19337 /// @param alignment_in_bits the alignment of this type, in bits.
function_type(type_base_sptr return_type,size_t size_in_bits,size_t alignment_in_bits)19338 function_type::function_type(type_base_sptr return_type,
19339 size_t size_in_bits, size_t alignment_in_bits)
19340 : type_or_decl_base(return_type->get_environment(),
19341 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
19342 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
19343 priv_(new priv(return_type))
19344 {
19345 runtime_type_instance(this);
19346 }
19347
19348 /// A constructor for a function_type that takes no parameter and
19349 /// that has no return_type yet. These missing parts can (and must)
19350 /// be added later.
19351 ///
19352 /// @param env the environment we are operating from.
19353 ///
19354 /// @param size_in_bits the size of this type, in bits.
19355 ///
19356 /// @param alignment_in_bits the alignment of this type, in bits.
function_type(const environment & env,size_t size_in_bits,size_t alignment_in_bits)19357 function_type::function_type(const environment& env,
19358 size_t size_in_bits,
19359 size_t alignment_in_bits)
19360 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
19361 type_base(env, size_in_bits, alignment_in_bits),
19362 priv_(new priv)
19363 {
19364 runtime_type_instance(this);
19365 }
19366
19367 /// Getter for the return type of the current instance of @ref
19368 /// function_type.
19369 ///
19370 /// @return the return type.
19371 type_base_sptr
get_return_type() const19372 function_type::get_return_type() const
19373 {return priv_->return_type_.lock();}
19374
19375 /// Setter of the return type of the current instance of @ref
19376 /// function_type.
19377 ///
19378 /// @param t the new return type to set.
19379 void
set_return_type(type_base_sptr t)19380 function_type::set_return_type(type_base_sptr t)
19381 {priv_->return_type_ = t;}
19382
19383 /// Getter for the set of parameters of the current intance of @ref
19384 /// function_type.
19385 ///
19386 /// @return the parameters of the current instance of @ref
19387 /// function_type.
19388 const function_decl::parameters&
get_parameters() const19389 function_type::get_parameters() const
19390 {return priv_->parms_;}
19391
19392 /// Get the Ith parameter of the vector of parameters of the current
19393 /// instance of @ref function_type.
19394 ///
19395 /// Note that the first parameter is at index 0. That parameter is
19396 /// the first parameter that comes after the possible implicit "this"
19397 /// parameter, when the current instance @ref function_type is for a
19398 /// member function. Otherwise, if the current instance of @ref
19399 /// function_type is for a non-member function, the parameter at index
19400 /// 0 is the first parameter of the function.
19401 ///
19402 ///
19403 /// @param i the index of the parameter to return. If i is greater
19404 /// than the index of the last parameter, then this function returns
19405 /// an empty parameter (smart) pointer.
19406 ///
19407 /// @return the @p i th parameter that is not implicit.
19408 const function_decl::parameter_sptr
get_parm_at_index_from_first_non_implicit_parm(size_t i) const19409 function_type::get_parm_at_index_from_first_non_implicit_parm(size_t i) const
19410 {
19411 parameter_sptr result;
19412 if (dynamic_cast<const method_type*>(this))
19413 {
19414 if (i + 1 < get_parameters().size())
19415 result = get_parameters()[i + 1];
19416 }
19417 else
19418 {
19419 if (i < get_parameters().size())
19420 result = get_parameters()[i];
19421 }
19422 return result;
19423 }
19424
19425 /// Setter for the parameters of the current instance of @ref
19426 /// function_type.
19427 ///
19428 /// @param p the new vector of parameters to set.
19429 void
set_parameters(const parameters & p)19430 function_type::set_parameters(const parameters &p)
19431 {
19432 priv_->parms_ = p;
19433 for (parameters::size_type i = 0, j = 1;
19434 i < priv_->parms_.size();
19435 ++i, ++j)
19436 {
19437 if (i == 0 && priv_->parms_[i]->get_is_artificial())
19438 // If the first parameter is artificial, then it certainly
19439 // means that this is a member function, and the first
19440 // parameter is the implicit this pointer. In that case, set
19441 // the index of that implicit parameter to zero. Otherwise,
19442 // the index of the first parameter starts at one.
19443 j = 0;
19444 priv_->parms_[i]->set_index(j);
19445 }
19446 }
19447
19448 /// Append a new parameter to the vector of parameters of the current
19449 /// instance of @ref function_type.
19450 ///
19451 /// @param parm the parameter to append.
19452 void
append_parameter(parameter_sptr parm)19453 function_type::append_parameter(parameter_sptr parm)
19454 {
19455 parm->set_index(priv_->parms_.size());
19456 priv_->parms_.push_back(parm);
19457 }
19458
19459 /// Test if the current instance of @ref function_type is for a
19460 /// variadic function.
19461 ///
19462 /// A variadic function is a function that takes a variable number of
19463 /// arguments.
19464 ///
19465 /// @return true iff the current instance of @ref function_type is for
19466 /// a variadic function.
19467 bool
is_variadic() const19468 function_type::is_variadic() const
19469 {
19470 return (!priv_->parms_.empty()
19471 && priv_->parms_.back()->get_variadic_marker());
19472 }
19473
19474 /// Compare two function types.
19475 ///
19476 /// In case these function types are actually method types, this
19477 /// function avoids comparing two parameters (of the function types)
19478 /// if the types of the parameters are actually the types of the
19479 /// classes of the method types. This prevents infinite recursion
19480 /// during the comparison of two classes that are structurally
19481 /// identical.
19482 ///
19483 /// This is a subroutine of the equality operator of function_type.
19484 ///
19485 /// @param lhs the first function type to consider
19486 ///
19487 /// @param rhs the second function type to consider
19488 ///
19489 /// @param k a pointer to a bitfield set by the function to give
19490 /// information about the kind of changes carried by @p lhs and @p
19491 /// rhs. It is set iff @p k is non-null and the function returns
19492 /// false.
19493 ///
19494 /// Please note that setting k to a non-null value does have a
19495 /// negative performance impact because even if @p l and @p r are not
19496 /// equal, the function keeps up the comparison in order to determine
19497 /// the different kinds of ways in which they are different.
19498 ///
19499 ///@return true if lhs == rhs, false otherwise.
19500 bool
equals(const function_type & l,const function_type & r,change_kind * k)19501 equals(const function_type& l,
19502 const function_type& r,
19503 change_kind* k)
19504 {
19505 #define RETURN(value) return return_comparison_result(l, r, value)
19506
19507 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
19508
19509 {
19510 // First of all, let's see if these two function types haven't
19511 // already been compared. If so, and if the result of the
19512 // comparison has been cached, let's just re-use it, rather than
19513 // comparing them all over again.
19514 bool cached_result = false;
19515 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
19516 cached_result))
19517 return cached_result;
19518 }
19519
19520 mark_types_as_being_compared(l, r);
19521
19522 bool result = true;
19523
19524 if (!l.type_base::operator==(r))
19525 {
19526 result = false;
19527 if (k)
19528 *k |= LOCAL_TYPE_CHANGE_KIND;
19529 else
19530 RETURN(result);
19531 }
19532
19533 class_or_union* l_class = 0, *r_class = 0;
19534 if (const method_type* m = dynamic_cast<const method_type*>(&l))
19535 l_class = m->get_class_type().get();
19536
19537 if (const method_type* m = dynamic_cast<const method_type*>(&r))
19538 r_class = m->get_class_type().get();
19539
19540 // Compare the names of the class of the method
19541
19542 if (!!l_class != !!r_class)
19543 {
19544 result = false;
19545 if (k)
19546 *k |= LOCAL_TYPE_CHANGE_KIND;
19547 else
19548 RETURN(result);
19549 }
19550 else if (l_class
19551 && (l_class->get_qualified_name()
19552 != r_class->get_qualified_name()))
19553 {
19554 result = false;
19555 if (k)
19556 *k |= LOCAL_TYPE_CHANGE_KIND;
19557 else
19558 RETURN(result);
19559 }
19560
19561 // Then compare the return type; Beware if it's t's a class type
19562 // that is the same as the method class name; we can recurse for
19563 // ever in that case.
19564
19565 decl_base* l_return_type_decl =
19566 get_type_declaration(l.get_return_type()).get();
19567 decl_base* r_return_type_decl =
19568 get_type_declaration(r.get_return_type()).get();
19569 bool compare_result_types = true;
19570 string l_rt_name = l_return_type_decl
19571 ? l_return_type_decl->get_qualified_name()
19572 : string();
19573 string r_rt_name = r_return_type_decl
19574 ? r_return_type_decl->get_qualified_name()
19575 : string();
19576
19577 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
19578 ||
19579 (r_class && (r_class->get_qualified_name() == r_rt_name)))
19580 compare_result_types = false;
19581
19582 if (compare_result_types)
19583 {
19584 // Let's not consider typedefs when comparing return types to
19585 // avoid spurious changes.
19586 //
19587 // TODO: We should also do this for parameter types, or rather,
19588 // we should teach the equality operators in the IR, at some
19589 // point, to peel typedefs off.
19590 if (peel_typedef_type(l.get_return_type())
19591 !=
19592 peel_typedef_type(r.get_return_type()))
19593 {
19594 result = false;
19595 if (k)
19596 {
19597 if (!types_have_similar_structure(l.get_return_type(),
19598 r.get_return_type()))
19599 *k |= LOCAL_TYPE_CHANGE_KIND;
19600 else
19601 *k |= SUBTYPE_CHANGE_KIND;
19602 }
19603 else
19604 RETURN(result);
19605 }
19606 }
19607 else
19608 if (l_rt_name != r_rt_name)
19609 {
19610 result = false;
19611 if (k)
19612 *k |= SUBTYPE_CHANGE_KIND;
19613 else
19614 RETURN(result);
19615 }
19616
19617 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
19618 for (i = l.get_first_parm(), j = r.get_first_parm();
19619 i != l.get_parameters().end() && j != r.get_parameters().end();
19620 ++i, ++j)
19621 {
19622 if (**i != **j)
19623 {
19624 result = false;
19625 if (k)
19626 {
19627 if (!types_have_similar_structure((*i)->get_type(),
19628 (*j)->get_type()))
19629 *k |= LOCAL_TYPE_CHANGE_KIND;
19630 else
19631 *k |= SUBTYPE_CHANGE_KIND;
19632 }
19633 else
19634 RETURN(result);
19635 }
19636 }
19637
19638 if ((i != l.get_parameters().end()
19639 || j != r.get_parameters().end()))
19640 {
19641 result = false;
19642 if (k)
19643 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19644 else
19645 RETURN(result);
19646 }
19647
19648 // We are done comparing these two types and we have a full
19649 // understanding of how they might be different, if they are. Let's
19650 // cache the result of this comparison -- in case we are asked in a
19651 // very near future to compare them again.
19652 //
19653 // TODO: If further profiling shows its necessity, maybe we should
19654 // perform this caching also on the earlier return points of this
19655 // function. That would basically mean to redefine the RETURN macro
19656 // to make it perform this caching for us.
19657 l.get_environment().priv_->cache_type_comparison_result(l, r, result);
19658
19659 RETURN(result);
19660 #undef RETURN
19661 }
19662
19663 /// Get the first parameter of the function.
19664 ///
19665 /// If the function is a non-static member function, the parameter
19666 /// returned is the first one following the implicit 'this' parameter.
19667 ///
19668 /// @return the first non implicit parameter of the function.
19669 function_type::parameters::const_iterator
get_first_non_implicit_parm() const19670 function_type::get_first_non_implicit_parm() const
19671 {
19672 if (get_parameters().empty())
19673 return get_parameters().end();
19674
19675 bool is_method = dynamic_cast<const method_type*>(this);
19676
19677 parameters::const_iterator i = get_parameters().begin();
19678
19679 if (is_method)
19680 ++i;
19681
19682 return i;
19683 }
19684
19685 /// Get the first parameter of the function.
19686 ///
19687 /// Note that if the function is a non-static member function, the
19688 /// parameter returned is the implicit 'this' parameter.
19689 ///
19690 /// @return the first parameter of the function.
19691 function_type::parameters::const_iterator
get_first_parm() const19692 function_type::get_first_parm() const
19693 {return get_parameters().begin();}
19694
19695 /// Get the name of the current @ref function_type.
19696 ///
19697 /// The name is retrieved from a cache. If the cache is empty, this
19698 /// function computes the name of the type, stores it in the cache and
19699 /// returns it. Subsequent invocation of the function are going to
19700 /// just hit the cache.
19701 ///
19702 /// Note that if the type is *NOT* canonicalized then function type
19703 /// name is never cached.
19704 ///
19705 /// @param internal if true then it means the function type name is
19706 /// going to be used for purposes that are internal to libabigail
19707 /// itself. If you don't know what this is then you probably should
19708 /// set this parameter to 'false'.
19709 ///
19710 /// @return the name of the function type.
19711 const interned_string&
get_cached_name(bool internal) const19712 function_type::get_cached_name(bool internal) const
19713 {
19714 if (internal)
19715 {
19716 if (get_naked_canonical_type())
19717 {
19718 if (priv_->internal_cached_name_.empty())
19719 priv_->internal_cached_name_ =
19720 get_function_type_name(this, /*internal=*/true);
19721 return priv_->internal_cached_name_;
19722 }
19723 else
19724 {
19725 priv_->temp_internal_cached_name_ =
19726 get_function_type_name(this,
19727 /*internal=*/true);
19728 return priv_->temp_internal_cached_name_;
19729 }
19730 }
19731 else
19732 {
19733 if (get_naked_canonical_type())
19734 {
19735 if (priv_->cached_name_.empty())
19736 priv_->cached_name_ =
19737 get_function_type_name(this, /*internal=*/false);
19738 return priv_->cached_name_;
19739 }
19740 else
19741 {
19742 priv_->cached_name_ =
19743 get_function_type_name(this, /*internal=*/false);
19744 return priv_->cached_name_;
19745 }
19746 }
19747 }
19748
19749 /// Equality operator for function_type.
19750 ///
19751 /// @param o the other function_type to compare against.
19752 ///
19753 /// @return true iff the two function_type are equal.
19754 bool
operator ==(const type_base & other) const19755 function_type::operator==(const type_base& other) const
19756 {
19757 const function_type* o = dynamic_cast<const function_type*>(&other);
19758 if (!o)
19759 return false;
19760 return try_canonical_compare(this, o);
19761 }
19762
19763 /// Return a copy of the pretty representation of the current @ref
19764 /// function_type.
19765 ///
19766 /// @param internal set to true if the call is intended to get a
19767 /// representation of the decl (or type) for the purpose of canonical
19768 /// type comparison. This is mainly used in the function
19769 /// type_base::get_canonical_type_for().
19770 ///
19771 /// In other words if the argument for this parameter is true then the
19772 /// call is meant for internal use (for technical use inside the
19773 /// library itself), false otherwise. If you don't know what this is
19774 /// for, then set it to false.
19775 ///
19776 /// @return a copy of the pretty representation of the current @ref
19777 /// function_type.
19778 string
get_pretty_representation(bool internal,bool) const19779 function_type::get_pretty_representation(bool internal,
19780 bool /*qualified_name*/) const
19781 {return ir::get_pretty_representation(this, internal);}
19782
19783 /// Traverses an instance of @ref function_type, visiting all the
19784 /// sub-types and decls that it might contain.
19785 ///
19786 /// @param v the visitor that is used to visit every IR sub-node of
19787 /// the current node.
19788 ///
19789 /// @return true if either
19790 /// - all the children nodes of the current IR node were traversed
19791 /// and the calling code should keep going with the traversing.
19792 /// - or the current IR node is already being traversed.
19793 /// Otherwise, returning false means that the calling code should not
19794 /// keep traversing the tree.
19795 bool
traverse(ir_node_visitor & v)19796 function_type::traverse(ir_node_visitor& v)
19797 {
19798 // TODO: should we allow the walker to avoid visiting function type
19799 // twice? I think that if we do, then ir_node_visitor needs an
19800 // option to specifically disallow this feature for function types.
19801
19802 if (visiting())
19803 return true;
19804
19805 if (v.visit_begin(this))
19806 {
19807 visiting(true);
19808 bool keep_going = true;
19809
19810 if (type_base_sptr t = get_return_type())
19811 {
19812 if (!t->traverse(v))
19813 keep_going = false;
19814 }
19815
19816 if (keep_going)
19817 for (parameters::const_iterator i = get_parameters().begin();
19818 i != get_parameters().end();
19819 ++i)
19820 if (type_base_sptr parm_type = (*i)->get_type())
19821 if (!parm_type->traverse(v))
19822 break;
19823
19824 visiting(false);
19825 }
19826 return v.visit_end(this);
19827 }
19828
~function_type()19829 function_type::~function_type()
19830 {}
19831 // </function_type>
19832
19833 // <method_type>
19834
19835 struct method_type::priv
19836 {
19837 class_or_union_wptr class_type_;
19838 bool is_const;
19839
privabigail::ir::method_type::priv19840 priv()
19841 : is_const()
19842 {}
19843 }; // end struct method_type::priv
19844
19845 /// Constructor for instances of method_type.
19846 ///
19847 /// Instances of method_decl must be of type method_type.
19848 ///
19849 /// @param return_type the type of the return value of the method.
19850 ///
19851 /// @param class_type the base type of the method type. That is, the
19852 /// type of the class the method belongs to.
19853 ///
19854 /// @param p the vector of the parameters of the method.
19855 ///
19856 /// @param is_const whether this method type is for a const method.
19857 /// Note that const-ness is a property of the method *type* and of the
19858 /// relationship between a method *declaration* and its scope.
19859 ///
19860 /// @param size_in_bits the size of an instance of method_type,
19861 /// expressed in bits.
19862 ///
19863 /// @param alignment_in_bits the alignment of an instance of
19864 /// method_type, expressed in bits.
method_type(type_base_sptr return_type,class_or_union_sptr class_type,const std::vector<function_decl::parameter_sptr> & p,bool is_const,size_t size_in_bits,size_t alignment_in_bits)19865 method_type::method_type (type_base_sptr return_type,
19866 class_or_union_sptr class_type,
19867 const std::vector<function_decl::parameter_sptr>& p,
19868 bool is_const,
19869 size_t size_in_bits,
19870 size_t alignment_in_bits)
19871 : type_or_decl_base(class_type->get_environment(),
19872 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
19873 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
19874 function_type(return_type, p, size_in_bits, alignment_in_bits),
19875 priv_(new priv)
19876 {
19877 runtime_type_instance(this);
19878 set_class_type(class_type);
19879 set_is_const(is_const);
19880 }
19881
19882 /// Constructor of instances of method_type.
19883 ///
19884 ///Instances of method_decl must be of type method_type.
19885 ///
19886 /// @param return_type the type of the return value of the method.
19887 ///
19888 /// @param class_type the type of the class the method belongs to.
19889 /// The actual (dynamic) type of class_type must be a pointer
19890 /// class_type. We are setting it to pointer to type_base here to
19891 /// help client code that is compiled without rtti and thus cannot
19892 /// perform dynamic casts.
19893 ///
19894 /// @param p the vector of the parameters of the method type.
19895 ///
19896 /// @param is_const whether this method type is for a const method.
19897 /// Note that const-ness is a property of the method *type* and of the
19898 /// relationship between a method *declaration* and its scope.
19899 ///
19900 /// @param size_in_bits the size of an instance of method_type,
19901 /// expressed in bits.
19902 ///
19903 /// @param alignment_in_bits the alignment of an instance of
19904 /// method_type, expressed in bits.
method_type(type_base_sptr return_type,type_base_sptr class_type,const std::vector<function_decl::parameter_sptr> & p,bool is_const,size_t size_in_bits,size_t alignment_in_bits)19905 method_type::method_type(type_base_sptr return_type,
19906 type_base_sptr class_type,
19907 const std::vector<function_decl::parameter_sptr>& p,
19908 bool is_const,
19909 size_t size_in_bits,
19910 size_t alignment_in_bits)
19911 : type_or_decl_base(class_type->get_environment(),
19912 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
19913 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
19914 function_type(return_type, p, size_in_bits, alignment_in_bits),
19915 priv_(new priv)
19916 {
19917 runtime_type_instance(this);
19918 set_class_type(is_class_type(class_type));
19919 set_is_const(is_const);
19920 }
19921
19922 /// Constructor of the qualified_type_def
19923 ///
19924 /// @param env the environment we are operating from.
19925 ///
19926 /// @param size_in_bits the size of the type, expressed in bits.
19927 ///
19928 /// @param alignment_in_bits the alignment of the type, expressed in bits
method_type(const environment & env,size_t size_in_bits,size_t alignment_in_bits)19929 method_type::method_type(const environment& env,
19930 size_t size_in_bits,
19931 size_t alignment_in_bits)
19932 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
19933 type_base(env, size_in_bits, alignment_in_bits),
19934 function_type(env, size_in_bits, alignment_in_bits),
19935 priv_(new priv)
19936 {
19937 runtime_type_instance(this);
19938 }
19939
19940 /// Constructor of instances of method_type.
19941 ///
19942 /// When constructed with this constructor, and instane of method_type
19943 /// must set a return type using method_type::set_return_type
19944 ///
19945 /// @param class_typ the base type of the method type. That is, the
19946 /// type of the class (or union) the method belongs to.
19947 ///
19948 /// @param size_in_bits the size of an instance of method_type,
19949 /// expressed in bits.
19950 ///
19951 /// @param alignment_in_bits the alignment of an instance of
19952 /// method_type, expressed in bits.
method_type(class_or_union_sptr class_type,bool is_const,size_t size_in_bits,size_t alignment_in_bits)19953 method_type::method_type(class_or_union_sptr class_type,
19954 bool is_const,
19955 size_t size_in_bits,
19956 size_t alignment_in_bits)
19957 : type_or_decl_base(class_type->get_environment(),
19958 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
19959 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
19960 function_type(class_type->get_environment(),
19961 size_in_bits,
19962 alignment_in_bits),
19963 priv_(new priv)
19964 {
19965 runtime_type_instance(this);
19966 set_class_type(class_type);
19967 set_is_const(is_const);
19968 }
19969
19970 /// Get the class type this method belongs to.
19971 ///
19972 /// @return the class type.
19973 class_or_union_sptr
get_class_type() const19974 method_type::get_class_type() const
19975 {return class_or_union_sptr(priv_->class_type_);}
19976
19977 /// Sets the class type of the current instance of method_type.
19978 ///
19979 /// The class type is the type of the class the method belongs to.
19980 ///
19981 /// @param t the new class type to set.
19982 void
set_class_type(const class_or_union_sptr & t)19983 method_type::set_class_type(const class_or_union_sptr& t)
19984 {
19985 if (!t)
19986 return;
19987
19988 priv_->class_type_ = t;
19989 }
19990
19991 /// Return a copy of the pretty representation of the current @ref
19992 /// method_type.
19993 ///
19994 /// @param internal set to true if the call is intended to get a
19995 /// representation of the decl (or type) for the purpose of canonical
19996 /// type comparison. This is mainly used in the function
19997 /// type_base::get_canonical_type_for().
19998 ///
19999 /// In other words if the argument for this parameter is true then the
20000 /// call is meant for internal use (for technical use inside the
20001 /// library itself), false otherwise. If you don't know what this is
20002 /// for, then set it to false.
20003 ///
20004 /// @return a copy of the pretty representation of the current @ref
20005 /// method_type.
20006 string
get_pretty_representation(bool internal,bool) const20007 method_type::get_pretty_representation(bool internal,
20008 bool /*qualified_name*/) const
20009 {return ir::get_pretty_representation(*this, internal);}
20010
20011 /// Setter of the "is-const" property of @ref method_type.
20012 ///
20013 /// @param the new value of the "is-const" property.
20014 void
set_is_const(bool f)20015 method_type::set_is_const(bool f)
20016 {priv_->is_const = f;}
20017
20018 /// Getter of the "is-const" property of @ref method_type.
20019 ///
20020 /// @return true iff the "is-const" property was set.
20021 bool
get_is_const() const20022 method_type::get_is_const() const
20023 {return priv_->is_const;}
20024
20025 /// The destructor of method_type
~method_type()20026 method_type::~method_type()
20027 {}
20028
20029 // </method_type>
20030
20031 // <function_decl definitions>
20032
20033 struct function_decl::priv
20034 {
20035 bool declared_inline_;
20036 decl_base::binding binding_;
20037 function_type_wptr type_;
20038 function_type* naked_type_;
20039 elf_symbol_sptr symbol_;
20040 interned_string id_;
20041
privabigail::ir::function_decl::priv20042 priv()
20043 : declared_inline_(false),
20044 binding_(decl_base::BINDING_GLOBAL),
20045 naked_type_()
20046 {}
20047
privabigail::ir::function_decl::priv20048 priv(function_type_sptr t,
20049 bool declared_inline,
20050 decl_base::binding binding)
20051 : declared_inline_(declared_inline),
20052 binding_(binding),
20053 type_(t),
20054 naked_type_(t.get())
20055 {}
20056
privabigail::ir::function_decl::priv20057 priv(function_type_sptr t,
20058 bool declared_inline,
20059 decl_base::binding binding,
20060 elf_symbol_sptr s)
20061 : declared_inline_(declared_inline),
20062 binding_(binding),
20063 type_(t),
20064 naked_type_(t.get()),
20065 symbol_(s)
20066 {}
20067 }; // end sruct function_decl::priv
20068
20069 /// Constructor of the @ref function_decl.
20070 ///
20071 /// @param name the name of the function.
20072 ///
20073 /// @param function_type the type of the function.
20074 ///
20075 /// @param declared_inline wether the function is declared inline.
20076 ///
20077 /// @param locus the source location of the function.
20078 ///
20079 /// @param mangled_name the linkage name of the function.
20080 ///
20081 /// @param vis the visibility of the function.
20082 ///
20083 /// @param bind the binding of the function.
function_decl(const string & name,function_type_sptr function_type,bool declared_inline,const location & locus,const string & mangled_name,visibility vis,binding bind)20084 function_decl::function_decl(const string& name,
20085 function_type_sptr function_type,
20086 bool declared_inline,
20087 const location& locus,
20088 const string& mangled_name,
20089 visibility vis,
20090 binding bind)
20091 : type_or_decl_base(function_type->get_environment(),
20092 FUNCTION_DECL | ABSTRACT_DECL_BASE),
20093 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
20094 priv_(new priv(function_type, declared_inline, bind))
20095 {
20096 runtime_type_instance(this);
20097 }
20098
20099 /// Constructor of the function_decl type.
20100 ///
20101 /// This flavour of constructor is for when the pointer to the
20102 /// instance of function_type that the client code has is presented as
20103 /// a pointer to type_base. In that case, this constructor saves the
20104 /// client code from doing a dynamic_cast to get the function_type
20105 /// pointer.
20106 ///
20107 /// @param name the name of the function declaration.
20108 ///
20109 /// @param fn_type the type of the function declaration. The dynamic
20110 /// type of this parameter should be 'pointer to function_type'
20111 ///
20112 /// @param declared_inline whether this function was declared inline
20113 ///
20114 /// @param locus the source location of the function declaration.
20115 ///
20116 /// @param linkage_name the mangled name of the function declaration.
20117 ///
20118 /// @param vis the visibility of the function declaration.
20119 ///
20120 /// @param bind the kind of the binding of the function
20121 /// declaration.
function_decl(const string & name,type_base_sptr fn_type,bool declared_inline,const location & locus,const string & linkage_name,visibility vis,binding bind)20122 function_decl::function_decl(const string& name,
20123 type_base_sptr fn_type,
20124 bool declared_inline,
20125 const location& locus,
20126 const string& linkage_name,
20127 visibility vis,
20128 binding bind)
20129 : type_or_decl_base(fn_type->get_environment(),
20130 FUNCTION_DECL | ABSTRACT_DECL_BASE),
20131 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
20132 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
20133 declared_inline,
20134 bind))
20135 {
20136 runtime_type_instance(this);
20137 }
20138
20139 /// Get the pretty representation of the current instance of @ref function_decl.
20140 ///
20141 /// @param internal set to true if the call is intended to get a
20142 /// representation of the decl (or type) for the purpose of canonical
20143 /// type comparison. This is mainly used in the function
20144 /// type_base::get_canonical_type_for().
20145 ///
20146 /// In other words if the argument for this parameter is true then the
20147 /// call is meant for internal use (for technical use inside the
20148 /// library itself), false otherwise. If you don't know what this is
20149 /// for, then set it to false.
20150 ///
20151 /// @return the pretty representation for a function.
20152 string
get_pretty_representation(bool internal,bool) const20153 function_decl::get_pretty_representation(bool internal,
20154 bool /*qualified_name*/) const
20155 {
20156 const method_decl* mem_fn =
20157 dynamic_cast<const method_decl*>(this);
20158
20159 string result = mem_fn ? "method ": "function ";
20160
20161 if (mem_fn
20162 && is_member_function(mem_fn)
20163 && get_member_function_is_virtual(mem_fn))
20164 result += "virtual ";
20165
20166 decl_base_sptr type;
20167 if ((mem_fn
20168 && is_member_function(mem_fn)
20169 && (get_member_function_is_dtor(*mem_fn)
20170 || get_member_function_is_ctor(*mem_fn))))
20171 /*cdtors do not have return types. */;
20172 else
20173 type = mem_fn
20174 ? get_type_declaration(mem_fn->get_type()->get_return_type())
20175 : get_type_declaration(get_type()->get_return_type());
20176
20177 if (type)
20178 result += type->get_qualified_name(internal) + " ";
20179
20180 result += get_pretty_representation_of_declarator(internal);
20181
20182 return result;
20183 }
20184
20185 /// Compute and return the pretty representation for the part of the
20186 /// function declaration that starts at the declarator. That is, the
20187 /// return type and the other specifiers of the beginning of the
20188 /// function's declaration ar omitted.
20189 ///
20190 /// @param internal set to true if the call is intended to get a
20191 /// representation of the decl (or type) for the purpose of canonical
20192 /// type comparison. This is mainly used in the function
20193 /// type_base::get_canonical_type_for().
20194 ///
20195 /// In other words if the argument for this parameter is true then the
20196 /// call is meant for internal use (for technical use inside the
20197 /// library itself), false otherwise. If you don't know what this is
20198 /// for, then set it to false.
20199 ///
20200 /// @return the pretty representation for the part of the function
20201 /// declaration that starts at the declarator.
20202 string
get_pretty_representation_of_declarator(bool internal) const20203 function_decl::get_pretty_representation_of_declarator (bool internal) const
20204 {
20205 const method_decl* mem_fn =
20206 dynamic_cast<const method_decl*>(this);
20207
20208 string result;
20209
20210 if (mem_fn)
20211 {
20212 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
20213 + "::" + mem_fn->get_name();
20214 }
20215 else
20216 result += get_qualified_name();
20217
20218 result += "(";
20219
20220 parameters::const_iterator i = get_parameters().begin(),
20221 end = get_parameters().end();
20222
20223 // Skip the first parameter if this is a method.
20224 if (mem_fn && i != end)
20225 ++i;
20226 parameter_sptr parm;
20227 parameter_sptr first_parm;
20228 if (i != end)
20229 first_parm = *i;
20230 for (; i != end; ++i)
20231 {
20232 parm = *i;
20233 if (parm.get() != first_parm.get())
20234 result += ", ";
20235 if (parm->get_variadic_marker()
20236 || get_environment().is_variadic_parameter_type(parm->get_type()))
20237 result += "...";
20238 else
20239 {
20240 type_base_sptr type = parm->get_type();
20241 if (internal)
20242 type = peel_typedef_type(type);
20243 result += get_type_name(type, /*qualified=*/true, internal);
20244 }
20245 }
20246 result += ")";
20247
20248 if (mem_fn
20249 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
20250 || is_method_type(mem_fn->get_type())->get_is_const()))
20251 result += " const";
20252
20253 return result;
20254 }
20255
20256 /// Getter for the first non-implicit parameter of a function decl.
20257 ///
20258 /// If the function is a non-static member function, the parameter
20259 /// returned is the first one following the implicit 'this' parameter.
20260 ///
20261 /// @return the first non implicit parm.
20262 function_decl::parameters::const_iterator
get_first_non_implicit_parm() const20263 function_decl::get_first_non_implicit_parm() const
20264 {
20265 if (get_parameters().empty())
20266 return get_parameters().end();
20267
20268 bool is_method = dynamic_cast<const method_decl*>(this);
20269
20270 parameters::const_iterator i = get_parameters().begin();
20271 if (is_method)
20272 ++i;
20273
20274 return i;
20275 }
20276
20277 /// Return the type of the current instance of @ref function_decl.
20278 ///
20279 /// It's either a function_type or method_type.
20280 /// @return the type of the current instance of @ref function_decl.
20281 const shared_ptr<function_type>
get_type() const20282 function_decl::get_type() const
20283 {return priv_->type_.lock();}
20284
20285 /// Fast getter of the type of the current instance of @ref function_decl.
20286 ///
20287 /// Note that this function returns the underlying pointer managed by
20288 /// the smart pointer returned by function_decl::get_type(). It's
20289 /// faster than function_decl::get_type(). This getter is to be used
20290 /// in code paths that are proven to be performance hot spots;
20291 /// especially (for instance) when comparing function types. Those
20292 /// are compared extremely frequently when libabigail is used to
20293 /// handle huge binaries with a lot of functions.
20294 ///
20295 /// @return the type of the current instance of @ref function_decl.
20296 const function_type*
get_naked_type() const20297 function_decl::get_naked_type() const
20298 {return priv_->naked_type_;}
20299
20300 void
set_type(const function_type_sptr & fn_type)20301 function_decl::set_type(const function_type_sptr& fn_type)
20302 {
20303 priv_->type_ = fn_type;
20304 priv_->naked_type_ = fn_type.get();
20305 }
20306
20307 /// This sets the underlying ELF symbol for the current function decl.
20308 ///
20309 /// And underlyin$g ELF symbol for the current function decl might
20310 /// exist only if the corpus that this function decl originates from
20311 /// was constructed from an ELF binary file.
20312 ///
20313 /// Note that comparing two function decls that have underlying ELF
20314 /// symbols involves comparing their underlying elf symbols. The decl
20315 /// name for the function thus becomes irrelevant in the comparison.
20316 ///
20317 /// @param sym the new ELF symbol for this function decl.
20318 void
set_symbol(const elf_symbol_sptr & sym)20319 function_decl::set_symbol(const elf_symbol_sptr& sym)
20320 {
20321 priv_->symbol_ = sym;
20322 // The function id cache that depends on the symbol must be
20323 // invalidated because the symbol changed.
20324 priv_->id_ = get_environment().intern("");
20325 }
20326
20327 /// Gets the the underlying ELF symbol for the current variable,
20328 /// that was set using function_decl::set_symbol(). Please read the
20329 /// documentation for that member function for more information about
20330 /// "underlying ELF symbols".
20331 ///
20332 /// @return sym the underlying ELF symbol for this function decl, if
20333 /// one exists.
20334 const elf_symbol_sptr&
get_symbol() const20335 function_decl::get_symbol() const
20336 {return priv_->symbol_;}
20337
20338 bool
is_declared_inline() const20339 function_decl::is_declared_inline() const
20340 {return priv_->declared_inline_;}
20341
20342 decl_base::binding
get_binding() const20343 function_decl::get_binding() const
20344 {return priv_->binding_;}
20345
20346 /// @return the return type of the current instance of function_decl.
20347 const shared_ptr<type_base>
get_return_type() const20348 function_decl::get_return_type() const
20349 {return get_type()->get_return_type();}
20350
20351 /// @return the parameters of the function.
20352 const std::vector<shared_ptr<function_decl::parameter> >&
get_parameters() const20353 function_decl::get_parameters() const
20354 {return get_type()->get_parameters();}
20355
20356 /// Append a parameter to the type of this function.
20357 ///
20358 /// @param parm the parameter to append.
20359 void
append_parameter(shared_ptr<parameter> parm)20360 function_decl::append_parameter(shared_ptr<parameter> parm)
20361 {get_type()->append_parameter(parm);}
20362
20363 /// Append a vector of parameters to the type of this function.
20364 ///
20365 /// @param parms the vector of parameters to append.
20366 void
append_parameters(std::vector<shared_ptr<parameter>> & parms)20367 function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
20368 {
20369 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
20370 i != parms.end();
20371 ++i)
20372 get_type()->append_parameter(*i);
20373 }
20374
20375 /// Create a new instance of function_decl that is a clone of the
20376 /// current one.
20377 ///
20378 /// @return the new clone.
20379 function_decl_sptr
clone() const20380 function_decl::clone() const
20381 {
20382 function_decl_sptr f;
20383 if (is_member_function(*this))
20384 {
20385 method_decl_sptr
20386 m(new method_decl(get_name(),
20387 get_type(),
20388 is_declared_inline(),
20389 get_location(),
20390 get_linkage_name(),
20391 get_visibility(),
20392 get_binding()));
20393 class_or_union* scope = is_class_or_union_type(get_scope());
20394 ABG_ASSERT(scope);
20395 scope->add_member_function(m, get_member_access_specifier(*this),
20396 get_member_function_is_virtual(*this),
20397 get_member_function_vtable_offset(*this),
20398 get_member_is_static(*this),
20399 get_member_function_is_ctor(*this),
20400 get_member_function_is_dtor(*this),
20401 get_member_function_is_const(*this));
20402 f = m;
20403 }
20404 else
20405 {
20406 f.reset(new function_decl(get_name(),
20407 get_type(),
20408 is_declared_inline(),
20409 get_location(),
20410 get_linkage_name(),
20411 get_visibility(),
20412 get_binding()));
20413 add_decl_to_scope(f, get_scope());
20414 }
20415 f->set_symbol(get_symbol());
20416
20417 return f;
20418 }
20419
20420 /// Compares two instances of @ref function_decl.
20421 ///
20422 /// If the two intances are different, set a bitfield to give some
20423 /// insight about the kind of differences there are.
20424 ///
20425 /// @param l the first artifact of the comparison.
20426 ///
20427 /// @param r the second artifact of the comparison.
20428 ///
20429 /// @param k a pointer to a bitfield that gives information about the
20430 /// kind of changes there are between @p l and @p r. This one is set
20431 /// iff @p k is non-null and the function returns false.
20432 ///
20433 /// Please note that setting k to a non-null value does have a
20434 /// negative performance impact because even if @p l and @p r are not
20435 /// equal, the function keeps up the comparison in order to determine
20436 /// the different kinds of ways in which they are different.
20437 ///
20438 /// @return true if @p l equals @p r, false otherwise.
20439 bool
equals(const function_decl & l,const function_decl & r,change_kind * k)20440 equals(const function_decl& l, const function_decl& r, change_kind* k)
20441 {
20442 bool result = true;
20443
20444 // Compare function types
20445 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
20446 if (t0 == t1 || *t0 == *t1)
20447 ; // the types are equal, let's move on to compare the other
20448 // properties of the functions.
20449 else
20450 {
20451 result = false;
20452 if (k)
20453 {
20454 if (!types_have_similar_structure(t0, t1))
20455 *k |= LOCAL_TYPE_CHANGE_KIND;
20456 else
20457 *k |= SUBTYPE_CHANGE_KIND;
20458 }
20459 else
20460 ABG_RETURN_FALSE;
20461 }
20462
20463 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
20464 if (!!s0 != !!s1)
20465 {
20466 result = false;
20467 if (k)
20468 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20469 else
20470 ABG_RETURN_FALSE;
20471 }
20472 else if (s0 && s0 != s1)
20473 {
20474 if (!elf_symbols_alias(s0, s1))
20475 {
20476 result = false;
20477 if (k)
20478 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20479 else
20480 ABG_RETURN_FALSE;
20481 }
20482 }
20483 bool symbols_are_equal = (s0 && s1 && result);
20484
20485 if (symbols_are_equal)
20486 {
20487 // The functions have underlying elf symbols that are equal,
20488 // so now, let's compare the decl_base part of the functions
20489 // w/o considering their decl names.
20490 interned_string n1 = l.get_name(), n2 = r.get_name();
20491 interned_string ln1 = l.get_linkage_name(), ln2 = r.get_linkage_name();
20492 const_cast<function_decl&>(l).set_name("");
20493 const_cast<function_decl&>(l).set_linkage_name("");
20494 const_cast<function_decl&>(r).set_name("");
20495 const_cast<function_decl&>(r).set_linkage_name("");
20496
20497 bool decl_bases_different = !l.decl_base::operator==(r);
20498
20499 const_cast<function_decl&>(l).set_name(n1);
20500 const_cast<function_decl&>(l).set_linkage_name(ln1);
20501 const_cast<function_decl&>(r).set_name(n2);
20502 const_cast<function_decl&>(r).set_linkage_name(ln2);
20503
20504 if (decl_bases_different)
20505 {
20506 result = false;
20507 if (k)
20508 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20509 else
20510 ABG_RETURN_FALSE;
20511 }
20512 }
20513 else
20514 if (!l.decl_base::operator==(r))
20515 {
20516 result = false;
20517 if (k)
20518 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20519 else
20520 ABG_RETURN_FALSE;
20521 }
20522
20523 // Compare the remaining properties
20524 if (l.is_declared_inline() != r.is_declared_inline()
20525 || l.get_binding() != r.get_binding())
20526 {
20527 result = false;
20528 if (k)
20529 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20530 else
20531 ABG_RETURN_FALSE;
20532 }
20533
20534 if (is_member_function(l) != is_member_function(r))
20535 {
20536 result = false;
20537 if (k)
20538 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20539 else
20540 ABG_RETURN_FALSE;
20541 }
20542
20543 if (is_member_function(l) && is_member_function(r))
20544 {
20545 if (!((get_member_function_is_ctor(l)
20546 == get_member_function_is_ctor(r))
20547 && (get_member_function_is_dtor(l)
20548 == get_member_function_is_dtor(r))
20549 && (get_member_is_static(l)
20550 == get_member_is_static(r))
20551 && (get_member_function_is_const(l)
20552 == get_member_function_is_const(r))
20553 && (get_member_function_is_virtual(l)
20554 == get_member_function_is_virtual(r))
20555 && (get_member_function_vtable_offset(l)
20556 == get_member_function_vtable_offset(r))))
20557 {
20558 result = false;
20559 if (k)
20560 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20561 else
20562 ABG_RETURN_FALSE;
20563 }
20564 }
20565
20566 ABG_RETURN(result);
20567 }
20568
20569 /// Comparison operator for @ref function_decl.
20570 ///
20571 /// @param other the other instance of @ref function_decl to compare
20572 /// against.
20573 ///
20574 /// @return true iff the current instance of @ref function_decl equals
20575 /// @p other.
20576 bool
operator ==(const decl_base & other) const20577 function_decl::operator==(const decl_base& other) const
20578 {
20579 const function_decl* o = dynamic_cast<const function_decl*>(&other);
20580 if (!o)
20581 return false;
20582 return equals(*this, *o, 0);
20583 }
20584
20585 /// Return true iff the function takes a variable number of
20586 /// parameters.
20587 ///
20588 /// @return true if the function taks a variable number
20589 /// of parameters.
20590 bool
is_variadic() const20591 function_decl::is_variadic() const
20592 {
20593 return (!get_parameters().empty()
20594 && get_parameters().back()->get_variadic_marker());
20595 }
20596
20597 /// The virtual implementation of 'get_hash' for a function_decl.
20598 ///
20599 /// This allows decl_base::get_hash to work for function_decls.
20600 ///
20601 /// @return the hash value for function decl.
20602 size_t
get_hash() const20603 function_decl::get_hash() const
20604 {
20605 function_decl::hash hash_fn;
20606 return hash_fn(*this);
20607 }
20608
20609 /// Return an ID that tries to uniquely identify the function inside a
20610 /// program or a library.
20611 ///
20612 /// So if the function has an underlying elf symbol, the ID is the
20613 /// concatenation of the symbol name and its version. Otherwise, the
20614 /// ID is the linkage name if its non-null. Otherwise, it's the
20615 /// pretty representation of the function.
20616 ///
20617 /// @return the ID.
20618 interned_string
get_id() const20619 function_decl::get_id() const
20620 {
20621 if (priv_->id_.empty())
20622 {
20623 const environment& env = get_type()->get_environment();
20624 if (elf_symbol_sptr s = get_symbol())
20625 {
20626 if (s->has_aliases())
20627 // The symbol has several aliases, so let's use a scheme
20628 // that allows all aliased functions to have different
20629 // IDs.
20630 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
20631 else
20632 // Let's use the full symbol name with its version as ID.
20633 priv_->id_ = env.intern(s->get_id_string());
20634 }
20635 else if (!get_linkage_name().empty())
20636 priv_->id_= env.intern(get_linkage_name());
20637 else
20638 priv_->id_ = env.intern(get_pretty_representation());
20639 }
20640 return priv_->id_;
20641 }
20642
20643 /// Test if two function declarations are aliases.
20644 ///
20645 /// Two functions declarations are aliases if their symbols are
20646 /// aliases, in the ELF sense.
20647 ///
20648 /// @param f1 the first function to consider.
20649 ///
20650 /// @param f2 the second function to consider.
20651 ///
20652 /// @return true iff @p f1 is an alias of @p f2
20653 bool
function_decls_alias(const function_decl & f1,const function_decl & f2)20654 function_decls_alias(const function_decl& f1, const function_decl& f2)
20655 {
20656 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
20657
20658 if (!s1 || !s2)
20659 return false;
20660
20661 return elf_symbols_alias(s1, s2);
20662 }
20663
20664 /// This implements the ir_traversable_base::traverse pure virtual
20665 /// function.
20666 ///
20667 /// @param v the visitor used on the current instance.
20668 ///
20669 /// @return true if the entire IR node tree got traversed, false
20670 /// otherwise.
20671 bool
traverse(ir_node_visitor & v)20672 function_decl::traverse(ir_node_visitor& v)
20673 {
20674 if (visiting())
20675 return true;
20676
20677 if (v.visit_begin(this))
20678 {
20679 visiting(true);
20680 if (type_base_sptr t = get_type())
20681 t->traverse(v);
20682 visiting(false);
20683 }
20684 return v.visit_end(this);
20685 }
20686
20687 /// Destructor of the @ref function_decl type.
~function_decl()20688 function_decl::~function_decl()
20689 {delete priv_;}
20690
20691 /// A deep comparison operator for a shared pointer to @ref function_decl
20692 ///
20693 /// This function compares to shared pointers to @ref function_decl by
20694 /// looking at the pointed-to instances of @ref function_dec
20695 /// comparing them too. If the two pointed-to objects are equal then
20696 /// this function returns true.
20697 ///
20698 /// @param l the left-hand side argument of the equality operator.
20699 ///
20700 /// @param r the right-hand side argument of the equality operator.
20701 ///
20702 /// @return true iff @p l equals @p r.
20703 bool
operator ==(const function_decl_sptr & l,const function_decl_sptr & r)20704 operator==(const function_decl_sptr& l, const function_decl_sptr& r)
20705 {
20706 if (l.get() == r.get())
20707 return true;
20708 if (!!l != !!r)
20709 return false;
20710
20711 return *l == *r;
20712 }
20713
20714 /// A deep inequality operator for smart pointers to functions.
20715 ///
20716 /// @param l the left-hand side argument of the inequality operator.
20717 ///
20718 /// @pram r the right-hand side argument of the inequality operator.
20719 ///
20720 /// @return true iff @p is not equal to @p r.
20721 bool
operator !=(const function_decl_sptr & l,const function_decl_sptr & r)20722 operator!=(const function_decl_sptr& l, const function_decl_sptr& r)
20723 {return !operator==(l, r);}
20724
20725 // <function_decl definitions>
20726
20727 // <function_decl::parameter definitions>
20728
20729 struct function_decl::parameter::priv
20730 {
20731 type_base_wptr type_;
20732 unsigned index_;
20733 bool variadic_marker_;
20734
privabigail::ir::function_decl::parameter::priv20735 priv()
20736 : index_(),
20737 variadic_marker_()
20738 {}
20739
privabigail::ir::function_decl::parameter::priv20740 priv(type_base_sptr type,
20741 unsigned index,
20742 bool variadic_marker)
20743 : type_(type),
20744 index_(index),
20745 variadic_marker_(variadic_marker)
20746 {}
20747 };// end struct function_decl::parameter::priv
20748
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic)20749 function_decl::parameter::parameter(const type_base_sptr type,
20750 unsigned index,
20751 const string& name,
20752 const location& loc,
20753 bool is_variadic)
20754 : type_or_decl_base(type->get_environment(),
20755 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
20756 decl_base(type->get_environment(), name, loc),
20757 priv_(new priv(type, index, is_variadic))
20758 {
20759 runtime_type_instance(this);
20760 }
20761
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic,bool is_artificial)20762 function_decl::parameter::parameter(const type_base_sptr type,
20763 unsigned index,
20764 const string& name,
20765 const location& loc,
20766 bool is_variadic,
20767 bool is_artificial)
20768 : type_or_decl_base(type->get_environment(),
20769 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
20770 decl_base(type->get_environment(), name, loc),
20771 priv_(new priv(type, index, is_variadic))
20772 {
20773 runtime_type_instance(this);
20774 set_is_artificial(is_artificial);
20775 }
20776
parameter(const type_base_sptr type,const string & name,const location & loc,bool is_variadic,bool is_artificial)20777 function_decl::parameter::parameter(const type_base_sptr type,
20778 const string& name,
20779 const location& loc,
20780 bool is_variadic,
20781 bool is_artificial)
20782 : type_or_decl_base(type->get_environment(),
20783 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
20784 decl_base(type->get_environment(), name, loc),
20785 priv_(new priv(type, 0, is_variadic))
20786 {
20787 runtime_type_instance(this);
20788 set_is_artificial(is_artificial);
20789 }
20790
parameter(const type_base_sptr type,unsigned index,bool variad)20791 function_decl::parameter::parameter(const type_base_sptr type,
20792 unsigned index,
20793 bool variad)
20794 : type_or_decl_base(type->get_environment(),
20795 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
20796 decl_base(type->get_environment(), "", location()),
20797 priv_(new priv(type, index, variad))
20798 {
20799 runtime_type_instance(this);
20800 }
20801
20802 function_decl::parameter::~parameter() = default;
20803
20804 const type_base_sptr
get_type() const20805 function_decl::parameter::get_type()const
20806 {return priv_->type_.lock();}
20807
20808 /// @return a copy of the type name of the parameter.
20809 interned_string
get_type_name() const20810 function_decl::parameter::get_type_name() const
20811 {
20812 const environment& env = get_environment();
20813
20814 type_base_sptr t = get_type();
20815 string str;
20816 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
20817 str = "...";
20818 else
20819 {
20820 ABG_ASSERT(t);
20821 str = abigail::ir::get_type_name(t);
20822 }
20823 return env.intern(str);
20824 }
20825
20826 /// @return a copy of the pretty representation of the type of the
20827 /// parameter.
20828 const string
get_type_pretty_representation() const20829 function_decl::parameter::get_type_pretty_representation() const
20830 {
20831 type_base_sptr t = get_type();
20832 string str;
20833 if (get_variadic_marker()
20834 || get_environment().is_variadic_parameter_type(t))
20835 str = "...";
20836 else
20837 {
20838 ABG_ASSERT(t);
20839 str += get_type_declaration(t)->get_pretty_representation();
20840 }
20841 return str;
20842 }
20843
20844 /// Get a name uniquely identifying the parameter in the function.
20845 ///
20846 ///@return the unique parm name id.
20847 interned_string
get_name_id() const20848 function_decl::parameter::get_name_id() const
20849 {
20850 const environment& env = get_environment();
20851
20852
20853 std::ostringstream o;
20854 o << "parameter-" << get_index();
20855
20856 return env.intern(o.str());
20857 }
20858
20859 unsigned
get_index() const20860 function_decl::parameter::get_index() const
20861 {return priv_->index_;}
20862
20863 void
set_index(unsigned i)20864 function_decl::parameter::set_index(unsigned i)
20865 {priv_->index_ = i;}
20866
20867
20868 bool
get_variadic_marker() const20869 function_decl::parameter::get_variadic_marker() const
20870 {return priv_->variadic_marker_;}
20871
20872 /// Compares two instances of @ref function_decl::parameter.
20873 ///
20874 /// If the two intances are different, set a bitfield to give some
20875 /// insight about the kind of differences there are.
20876 ///
20877 /// @param l the first artifact of the comparison.
20878 ///
20879 /// @param r the second artifact of the comparison.
20880 ///
20881 /// @param k a pointer to a bitfield that gives information about the
20882 /// kind of changes there are between @p l and @p r. This one is set
20883 /// iff @p k is non-null and the function returns false.
20884 ///
20885 /// Please note that setting k to a non-null value does have a
20886 /// negative performance impact because even if @p l and @p r are not
20887 /// equal, the function keeps up the comparison in order to determine
20888 /// the different kinds of ways in which they are different.
20889 ///
20890 /// @return true if @p l equals @p r, false otherwise.
20891 bool
equals(const function_decl::parameter & l,const function_decl::parameter & r,change_kind * k)20892 equals(const function_decl::parameter& l,
20893 const function_decl::parameter& r,
20894 change_kind* k)
20895 {
20896 bool result = true;
20897
20898 if ((l.get_variadic_marker() != r.get_variadic_marker())
20899 || (l.get_index() != r.get_index())
20900 || (!!l.get_type() != !!r.get_type()))
20901 {
20902 result = false;
20903 if (k)
20904 {
20905 if (l.get_index() != r.get_index())
20906 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20907 if (l.get_variadic_marker() != r.get_variadic_marker()
20908 || !!l.get_type() != !!r.get_type())
20909 *k |= LOCAL_TYPE_CHANGE_KIND;
20910 }
20911 else
20912 ABG_RETURN_FALSE;
20913 }
20914
20915 type_base_sptr l_type = peel_typedef_type(l.get_type());
20916 type_base_sptr r_type = peel_typedef_type(r.get_type());
20917 if (l_type != r_type)
20918 {
20919 result = false;
20920 if (k)
20921 {
20922 if (!types_have_similar_structure(l_type, r_type))
20923 *k |= LOCAL_TYPE_CHANGE_KIND;
20924 else
20925 *k |= SUBTYPE_CHANGE_KIND;
20926 }
20927 else
20928 ABG_RETURN_FALSE;
20929 }
20930
20931 ABG_RETURN(result);
20932 }
20933
20934 bool
operator ==(const parameter & o) const20935 function_decl::parameter::operator==(const parameter& o) const
20936 {return equals(*this, o, 0);}
20937
20938 bool
operator ==(const decl_base & o) const20939 function_decl::parameter::operator==(const decl_base& o) const
20940 {
20941 const function_decl::parameter* p =
20942 dynamic_cast<const function_decl::parameter*>(&o);
20943 if (!p)
20944 return false;
20945 return function_decl::parameter::operator==(*p);
20946 }
20947
20948 /// Non-member equality operator for @ref function_decl::parameter.
20949 ///
20950 /// @param l the left-hand side of the equality operator
20951 ///
20952 /// @param r the right-hand side of the equality operator
20953 ///
20954 /// @return true iff @p l and @p r equals.
20955 bool
operator ==(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)20956 operator==(const function_decl::parameter_sptr& l,
20957 const function_decl::parameter_sptr& r)
20958 {
20959 if (!!l != !!r)
20960 return false;
20961 if (!l)
20962 return true;
20963 return *l == *r;
20964 }
20965
20966 /// Non-member inequality operator for @ref function_decl::parameter.
20967 ///
20968 /// @param l the left-hand side of the equality operator
20969 ///
20970 /// @param r the right-hand side of the equality operator
20971 ///
20972 /// @return true iff @p l and @p r different.
20973 bool
operator !=(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)20974 operator!=(const function_decl::parameter_sptr& l,
20975 const function_decl::parameter_sptr& r)
20976 {return !operator==(l, r);}
20977
20978 /// Traverse the diff sub-tree under the current instance
20979 /// function_decl.
20980 ///
20981 /// @param v the visitor to invoke on each diff node of the sub-tree.
20982 ///
20983 /// @return true if the traversing has to keep going on, false
20984 /// otherwise.
20985 bool
traverse(ir_node_visitor & v)20986 function_decl::parameter::traverse(ir_node_visitor& v)
20987 {
20988 if (visiting())
20989 return true;
20990
20991 if (v.visit_begin(this))
20992 {
20993 visiting(true);
20994 if (type_base_sptr t = get_type())
20995 t->traverse(v);
20996 visiting(false);
20997 }
20998 return v.visit_end(this);
20999 }
21000
21001 /// Get the hash of a decl. If the hash hasn't been computed yet,
21002 /// compute it ans store its value; otherwise, just return the hash.
21003 ///
21004 /// @return the hash of the decl.
21005 size_t
get_hash() const21006 function_decl::parameter::get_hash() const
21007 {
21008 function_decl::parameter::hash hash_fn_parm;
21009 return hash_fn_parm(this);
21010 }
21011
21012 /// Compute the qualified name of the parameter.
21013 ///
21014 /// @param internal set to true if the call is intended for an
21015 /// internal use (for technical use inside the library itself), false
21016 /// otherwise. If you don't know what this is for, then set it to
21017 /// false.
21018 ///
21019 /// @param qn the resulting qualified name.
21020 void
get_qualified_name(interned_string & qualified_name,bool) const21021 function_decl::parameter::get_qualified_name(interned_string& qualified_name,
21022 bool /*internal*/) const
21023 {qualified_name = get_name();}
21024
21025 /// Compute and return a copy of the pretty representation of the
21026 /// current function parameter.
21027 ///
21028 /// @param internal set to true if the call is intended to get a
21029 /// representation of the decl (or type) for the purpose of canonical
21030 /// type comparison. This is mainly used in the function
21031 /// type_base::get_canonical_type_for().
21032 ///
21033 /// In other words if the argument for this parameter is true then the
21034 /// call is meant for internal use (for technical use inside the
21035 /// library itself), false otherwise. If you don't know what this is
21036 /// for, then set it to false.
21037 ///
21038 /// @return a copy of the textual representation of the current
21039 /// function parameter.
21040 string
get_pretty_representation(bool internal,bool) const21041 function_decl::parameter::get_pretty_representation(bool internal,
21042 bool /*qualified_name*/) const
21043 {
21044 const environment& env = get_environment();
21045
21046 string type_repr;
21047 type_base_sptr t = get_type();
21048 if (!t)
21049 type_repr = "void";
21050 else if (env.is_variadic_parameter_type(t))
21051 type_repr = "...";
21052 else
21053 type_repr = ir::get_pretty_representation(t, internal);
21054
21055 string result = type_repr;
21056 string parm_name = get_name_id();
21057
21058 if (!parm_name.empty())
21059 result += " " + parm_name;
21060
21061 return result;
21062 }
21063
21064 // </function_decl::parameter definitions>
21065
21066 // <class_or_union definitions>
21067
21068 /// A Constructor for instances of @ref class_or_union
21069 ///
21070 /// @param env the environment we are operating from.
21071 ///
21072 /// @param name the identifier of the class.
21073 ///
21074 /// @param size_in_bits the size of an instance of @ref
21075 /// class_or_union, expressed in bits
21076 ///
21077 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
21078 /// expressed in bits.
21079 ///
21080 /// @param locus the source location of declaration point this class.
21081 ///
21082 /// @param vis the visibility of instances of @ref class_or_union.
21083 ///
21084 /// @param mem_types the vector of member types of this instance of
21085 /// @ref class_or_union.
21086 ///
21087 /// @param data_members the vector of data members of this instance of
21088 /// @ref class_or_union.
21089 ///
21090 /// @param member_fns the vector of member functions of this instance
21091 /// of @ref class_or_union.
class_or_union(const environment & env,const string & name,size_t size_in_bits,size_t align_in_bits,const location & locus,visibility vis,member_types & mem_types,data_members & data_members,member_functions & member_fns)21092 class_or_union::class_or_union(const environment& env, const string& name,
21093 size_t size_in_bits, size_t align_in_bits,
21094 const location& locus, visibility vis,
21095 member_types& mem_types,
21096 data_members& data_members,
21097 member_functions& member_fns)
21098 : type_or_decl_base(env,
21099 ABSTRACT_TYPE_BASE
21100 | ABSTRACT_DECL_BASE
21101 | ABSTRACT_SCOPE_TYPE_DECL
21102 | ABSTRACT_SCOPE_DECL),
21103 decl_base(env, name, locus, name, vis),
21104 type_base(env, size_in_bits, align_in_bits),
21105 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
21106 priv_(new priv(data_members, member_fns))
21107 {
21108 for (member_types::iterator i = mem_types.begin();
21109 i != mem_types.end();
21110 ++i)
21111 if (!has_scope(get_type_declaration(*i)))
21112 add_decl_to_scope(get_type_declaration(*i), this);
21113
21114 for (data_members::iterator i = data_members.begin();
21115 i != data_members.end();
21116 ++i)
21117 if (!has_scope(*i))
21118 add_decl_to_scope(*i, this);
21119
21120 for (member_functions::iterator i = member_fns.begin();
21121 i != member_fns.end();
21122 ++i)
21123 if (!has_scope(static_pointer_cast<decl_base>(*i)))
21124 add_decl_to_scope(*i, this);
21125 }
21126
21127 /// A constructor for instances of @ref class_or_union.
21128 ///
21129 /// @param env the environment we are operating from.
21130 ///
21131 /// @param name the name of the class.
21132 ///
21133 /// @param size_in_bits the size of an instance of @ref
21134 /// class_or_union, expressed in bits
21135 ///
21136 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
21137 /// expressed in bits.
21138 ///
21139 /// @param locus the source location of declaration point this class.
21140 ///
21141 /// @param vis the visibility of instances of @ref class_or_union.
class_or_union(const environment & env,const string & name,size_t size_in_bits,size_t align_in_bits,const location & locus,visibility vis)21142 class_or_union::class_or_union(const environment& env, const string& name,
21143 size_t size_in_bits, size_t align_in_bits,
21144 const location& locus, visibility vis)
21145 : type_or_decl_base(env,
21146 ABSTRACT_TYPE_BASE
21147 | ABSTRACT_DECL_BASE
21148 | ABSTRACT_SCOPE_TYPE_DECL
21149 | ABSTRACT_SCOPE_DECL),
21150 decl_base(env, name, locus, name, vis),
21151 type_base(env, size_in_bits, align_in_bits),
21152 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
21153 priv_(new priv)
21154 {}
21155
21156 /// Constructor of the @ref class_or_union type.
21157 ///
21158 /// @param env the @ref environment we are operating from.
21159 ///
21160 /// @param name the name of the @ref class_or_union.
21161 ///
21162 /// @param is_declaration_only a boolean saying whether the instance
21163 /// represents a declaration only, or not.
class_or_union(const environment & env,const string & name,bool is_declaration_only)21164 class_or_union::class_or_union(const environment& env, const string& name,
21165 bool is_declaration_only)
21166 : type_or_decl_base(env,
21167 ABSTRACT_TYPE_BASE
21168 | ABSTRACT_DECL_BASE
21169 | ABSTRACT_SCOPE_TYPE_DECL
21170 | ABSTRACT_SCOPE_DECL),
21171 decl_base(env, name, location(), name),
21172 type_base(env, 0, 0),
21173 scope_type_decl(env, name, 0, 0, location()),
21174 priv_(new priv)
21175 {
21176 set_is_declaration_only(is_declaration_only);
21177 }
21178
21179 /// This implements the ir_traversable_base::traverse pure virtual
21180 /// function.
21181 ///
21182 /// @param v the visitor used on the member nodes of the translation
21183 /// unit during the traversal.
21184 ///
21185 /// @return true if the entire IR node tree got traversed, false
21186 /// otherwise.
21187 bool
traverse(ir_node_visitor & v)21188 class_or_union::traverse(ir_node_visitor& v)
21189 {
21190 if (v.type_node_has_been_visited(this))
21191 return true;
21192
21193 if (visiting())
21194 return true;
21195
21196 if (v.visit_begin(this))
21197 {
21198 visiting(true);
21199 bool stop = false;
21200
21201 if (!stop)
21202 for (data_members::const_iterator i = get_data_members().begin();
21203 i != get_data_members().end();
21204 ++i)
21205 if (!(*i)->traverse(v))
21206 {
21207 stop = true;
21208 break;
21209 }
21210
21211 if (!stop)
21212 for (member_functions::const_iterator i= get_member_functions().begin();
21213 i != get_member_functions().end();
21214 ++i)
21215 if (!(*i)->traverse(v))
21216 {
21217 stop = true;
21218 break;
21219 }
21220
21221 if (!stop)
21222 for (member_types::const_iterator i = get_member_types().begin();
21223 i != get_member_types().end();
21224 ++i)
21225 if (!(*i)->traverse(v))
21226 {
21227 stop = true;
21228 break;
21229 }
21230
21231 if (!stop)
21232 for (member_function_templates::const_iterator i =
21233 get_member_function_templates().begin();
21234 i != get_member_function_templates().end();
21235 ++i)
21236 if (!(*i)->traverse(v))
21237 {
21238 stop = true;
21239 break;
21240 }
21241
21242 if (!stop)
21243 for (member_class_templates::const_iterator i =
21244 get_member_class_templates().begin();
21245 i != get_member_class_templates().end();
21246 ++i)
21247 if (!(*i)->traverse(v))
21248 {
21249 stop = true;
21250 break;
21251 }
21252 visiting(false);
21253 }
21254
21255 bool result = v.visit_end(this);
21256 v.mark_type_node_as_visited(this);
21257 return result;
21258 }
21259
21260 /// Destrcutor of the @ref class_or_union type.
~class_or_union()21261 class_or_union::~class_or_union()
21262 {delete priv_;}
21263
21264 /// Add a member declaration to the current instance of class_or_union.
21265 /// The member declaration can be either a member type, data member,
21266 /// member function, or member template.
21267 ///
21268 /// @param d the member declaration to add.
21269 decl_base_sptr
add_member_decl(const decl_base_sptr & d)21270 class_or_union::add_member_decl(const decl_base_sptr& d)
21271 {return insert_member_decl(d);}
21272
21273 /// Remove a given decl from the current @ref class_or_union scope.
21274 ///
21275 /// Note that only type declarations are supported by this method for
21276 /// now. Support for the other kinds of declaration is left as an
21277 /// exercise for the interested reader of the code.
21278 ///
21279 /// @param decl the declaration to remove from this @ref
21280 /// class_or_union scope.
21281 void
remove_member_decl(decl_base_sptr decl)21282 class_or_union::remove_member_decl(decl_base_sptr decl)
21283 {
21284 type_base_sptr t = is_type(decl);
21285
21286 // For now we want to support just removing types from classes. For
21287 // other kinds of IR node, we need more work.
21288 ABG_ASSERT(t);
21289
21290 remove_member_type(t);
21291 }
21292
21293 /// Fixup the members of the type of an anonymous data member.
21294 ///
21295 /// Walk all data members of (the type of) a given anonymous data
21296 /// member and set a particular property of the relationship between
21297 /// each data member and its containing type.
21298 ///
21299 /// That property records the fact that the data member belongs to the
21300 /// anonymous data member we consider.
21301 ///
21302 /// In the future, if there are other properties of this relationship
21303 /// to set in this manner, they ought to be added here.
21304 ///
21305 /// @param anon_dm the anonymous data member to consider.
21306 void
maybe_fixup_members_of_anon_data_member(var_decl_sptr & anon_dm)21307 class_or_union::maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm)
21308 {
21309 class_or_union * anon_dm_type =
21310 anonymous_data_member_to_class_or_union(anon_dm.get());
21311 if (!anon_dm_type)
21312 return;
21313
21314 for (class_or_union::data_members::const_iterator it =
21315 anon_dm_type->get_non_static_data_members().begin();
21316 it != anon_dm_type->get_non_static_data_members().end();
21317 ++it)
21318 {
21319 dm_context_rel *rel =
21320 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
21321 ABG_ASSERT(rel);
21322 rel->set_anonymous_data_member(anon_dm.get());
21323 }
21324 }
21325
21326 /// Getter of the alignment of the @ref class_or_union type.
21327 ///
21328 /// If this @ref class_or_union is a declaration of a definition that
21329 /// is elsewhere, then the size of the definition is returned.
21330 ///
21331 /// @return the alignment of the @ref class_or_union type.
21332 size_t
get_alignment_in_bits() const21333 class_or_union::get_alignment_in_bits() const
21334 {
21335 if (get_is_declaration_only() && get_definition_of_declaration())
21336 return is_class_or_union_type
21337 (get_definition_of_declaration())->get_alignment_in_bits();
21338
21339 return type_base::get_alignment_in_bits();
21340 }
21341
21342 /// Setter of the alignment of the class type.
21343 ///
21344 /// If this class is a declaration of a definition that is elsewhere,
21345 /// then the new alignment is set to the definition.
21346 ///
21347 /// @param s the new alignment.
21348 void
set_alignment_in_bits(size_t a)21349 class_or_union::set_alignment_in_bits(size_t a)
21350 {
21351 if (get_is_declaration_only() && get_definition_of_declaration())
21352 is_class_or_union_type
21353 (get_definition_of_declaration()) ->set_alignment_in_bits(a);
21354 else
21355 type_base::set_alignment_in_bits(a);
21356 }
21357
21358 /// Setter of the size of the @ref class_or_union type.
21359 ///
21360 /// If this @ref class_or_union is a declaration of a definition that
21361 /// is elsewhere, then the new size is set to the definition.
21362 ///
21363 /// @param s the new size.
21364 void
set_size_in_bits(size_t s)21365 class_or_union::set_size_in_bits(size_t s)
21366 {
21367 if (get_is_declaration_only() && get_definition_of_declaration())
21368 is_class_or_union_type
21369 (get_definition_of_declaration())->set_size_in_bits(s);
21370 else
21371 type_base::set_size_in_bits(s);
21372 }
21373
21374 /// Getter of the size of the @ref class_or_union type.
21375 ///
21376 /// If this @ref class_or_union is a declaration of a definition that
21377 /// is elsewhere, then the size of the definition is returned.
21378 ///
21379 /// @return the size of the @ref class_or_union type.
21380 size_t
get_size_in_bits() const21381 class_or_union::get_size_in_bits() const
21382 {
21383 if (get_is_declaration_only() && get_definition_of_declaration())
21384 return is_class_or_union_type
21385 (get_definition_of_declaration())->get_size_in_bits();
21386
21387 return type_base::get_size_in_bits();
21388 }
21389
21390 /// Get the number of anonymous member classes contained in this
21391 /// class.
21392 ///
21393 /// @return the number of anonymous member classes contained in this
21394 /// class.
21395 size_t
get_num_anonymous_member_classes() const21396 class_or_union::get_num_anonymous_member_classes() const
21397 {
21398 int result = 0;
21399 for (member_types::const_iterator it = get_member_types().begin();
21400 it != get_member_types().end();
21401 ++it)
21402 if (class_decl_sptr t = is_class_type(*it))
21403 if (t->get_is_anonymous())
21404 ++result;
21405
21406 return result;
21407 }
21408
21409 /// Get the number of anonymous member unions contained in this class.
21410 ///
21411 /// @return the number of anonymous member unions contained in this
21412 /// class.
21413 size_t
get_num_anonymous_member_unions() const21414 class_or_union::get_num_anonymous_member_unions() const
21415 {
21416 int result = 0;
21417 for (member_types::const_iterator it = get_member_types().begin();
21418 it != get_member_types().end();
21419 ++it)
21420 if (union_decl_sptr t = is_union_type(*it))
21421 if (t->get_is_anonymous())
21422 ++result;
21423
21424 return result;
21425 }
21426
21427 /// Get the number of anonymous member enums contained in this class.
21428 ///
21429 /// @return the number of anonymous member enums contained in this
21430 /// class.
21431 size_t
get_num_anonymous_member_enums() const21432 class_or_union::get_num_anonymous_member_enums() const
21433 {
21434 int result = 0;
21435 for (member_types::const_iterator it = get_member_types().begin();
21436 it != get_member_types().end();
21437 ++it)
21438 if (enum_type_decl_sptr t = is_enum_type(*it))
21439 if (t->get_is_anonymous())
21440 ++result;
21441
21442 return result;
21443 }
21444
21445 /// Add a data member to the current instance of class_or_union.
21446 ///
21447 /// @param v a var_decl to add as a data member. A proper
21448 /// class_or_union::data_member is created from @p v and added to the
21449 /// class_or_union. This var_decl should not have been already added
21450 /// to a scope.
21451 ///
21452 /// @param access the access specifier for the data member.
21453 ///
21454 /// @param is_laid_out whether the data member was laid out. That is,
21455 /// if its offset has been computed. In the pattern of a class
21456 /// template for instance, this would be set to false.
21457 ///
21458 /// @param is_static whether the data memer is static.
21459 ///
21460 /// @param offset_in_bits if @p is_laid_out is true, this is the
21461 /// offset of the data member, expressed (oh, surprise) in bits.
21462 void
add_data_member(var_decl_sptr v,access_specifier access,bool is_laid_out,bool is_static,size_t offset_in_bits)21463 class_or_union::add_data_member(var_decl_sptr v, access_specifier access,
21464 bool is_laid_out, bool is_static,
21465 size_t offset_in_bits)
21466 {
21467 ABG_ASSERT(!has_scope(v));
21468
21469 priv_->data_members_.push_back(v);
21470 scope_decl::add_member_decl(v);
21471 set_data_member_is_laid_out(v, is_laid_out);
21472 set_data_member_offset(v, offset_in_bits);
21473 set_member_access_specifier(v, access);
21474 set_member_is_static(v, is_static);
21475
21476 if (!is_static)
21477 {
21478 // If this is a non-static variable, add it to the set of
21479 // non-static variables, if it's not only in there.
21480 bool is_already_in = false;
21481 for (data_members::const_iterator i =
21482 priv_->non_static_data_members_.begin();
21483 i != priv_->non_static_data_members_.end();
21484 ++i)
21485 if (*i == v)
21486 {
21487 is_already_in = true;
21488 break;
21489 }
21490 if (!is_already_in)
21491 priv_->non_static_data_members_.push_back(v);
21492 }
21493
21494 // If v is an anonymous data member, then fixup its data members.
21495 // For now, the only thing the fixup does is to make the data
21496 // members of the anonymous data member be aware of their containing
21497 // anonymous data member. That is helpful to compute the absolute
21498 // bit offset of each of the members of the anonymous data member.
21499 maybe_fixup_members_of_anon_data_member(v);
21500 }
21501
21502 /// Get the data members of this @ref class_or_union.
21503 ///
21504 /// @return a vector of the data members of this @ref class_or_union.
21505 const class_or_union::data_members&
get_data_members() const21506 class_or_union::get_data_members() const
21507 {return priv_->data_members_;}
21508
21509 /// Find a data member of a given name in the current @ref class_or_union.
21510 ///
21511 /// @param name the name of the data member to find in the current
21512 /// @ref class_or_union.
21513 ///
21514 /// @return a pointer to the @ref var_decl that represents the data
21515 /// member to find inside the current @ref class_or_union.
21516 const var_decl_sptr
find_data_member(const string & name) const21517 class_or_union::find_data_member(const string& name) const
21518 {
21519 for (data_members::const_iterator i = get_data_members().begin();
21520 i != get_data_members().end();
21521 ++i)
21522 if ((*i)->get_name() == name)
21523 return *i;
21524
21525 // We haven't found a data member with the name 'name'. Let's look
21526 // closer again, this time in our anonymous data members.
21527 for (data_members::const_iterator i = get_data_members().begin();
21528 i != get_data_members().end();
21529 ++i)
21530 if (is_anonymous_data_member(*i))
21531 {
21532 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
21533 ABG_ASSERT(type);
21534 if (var_decl_sptr data_member = type->find_data_member(name))
21535 return data_member;
21536 }
21537
21538 return var_decl_sptr();
21539 }
21540
21541 /// Find an anonymous data member in the class.
21542 ///
21543 /// @param v the anonymous data member to find.
21544 ///
21545 /// @return the anonymous data member found, or nil if none was found.
21546 const var_decl_sptr
find_anonymous_data_member(const var_decl_sptr & v) const21547 class_or_union::find_anonymous_data_member(const var_decl_sptr& v) const
21548 {
21549 if (!v->get_name().empty())
21550 return var_decl_sptr();
21551
21552 for (data_members::const_iterator it = get_non_static_data_members().begin();
21553 it != get_non_static_data_members().end();
21554 ++it)
21555 {
21556 if (is_anonymous_data_member(*it))
21557 if ((*it)->get_pretty_representation(/*internal=*/false, true)
21558 == v->get_pretty_representation(/*internal=*/false, true))
21559 return *it;
21560 }
21561
21562 return var_decl_sptr();
21563 }
21564
21565 /// Find a given data member.
21566 ///
21567 /// This function takes a @ref var_decl as an argument. If it has a
21568 /// non-empty name, then it tries to find a data member which has the
21569 /// same name as the argument.
21570 ///
21571 /// If it has an empty name, then the @ref var_decl is considered as
21572 /// an anonymous data member. In that case, this function tries to
21573 /// find an anonymous data member which type equals that of the @ref
21574 /// var_decl argument.
21575 ///
21576 /// @param v this carries either the name of the data member we need
21577 /// to look for, or the type of the anonymous data member we are
21578 /// looking for.
21579 const var_decl_sptr
find_data_member(const var_decl_sptr & v) const21580 class_or_union::find_data_member(const var_decl_sptr& v) const
21581 {
21582 if (!v)
21583 return var_decl_sptr();
21584
21585 if (v->get_name().empty())
21586 return find_anonymous_data_member(v);
21587
21588 return find_data_member(v->get_name());
21589 }
21590
21591
21592 /// Get the non-static data memebers of this @ref class_or_union.
21593 ///
21594 /// @return a vector of the non-static data members of this @ref
21595 /// class_or_union.
21596 const class_or_union::data_members&
get_non_static_data_members() const21597 class_or_union::get_non_static_data_members() const
21598 {return priv_->non_static_data_members_;}
21599
21600 /// Add a member function.
21601 ///
21602 /// @param f the new member function to add.
21603 ///
21604 /// @param a the access specifier to use for the new member function.
21605 ///
21606 /// @param is_static whether the new member function is static.
21607 ///
21608 /// @param is_ctor whether the new member function is a constructor.
21609 ///
21610 /// @param is_dtor whether the new member function is a destructor.
21611 ///
21612 /// @param is_const whether the new member function is const.
21613 void
add_member_function(method_decl_sptr f,access_specifier a,bool is_static,bool is_ctor,bool is_dtor,bool is_const)21614 class_or_union::add_member_function(method_decl_sptr f,
21615 access_specifier a,
21616 bool is_static, bool is_ctor,
21617 bool is_dtor, bool is_const)
21618 {
21619 ABG_ASSERT(!has_scope(f));
21620
21621 scope_decl::add_member_decl(f);
21622
21623 set_member_function_is_ctor(f, is_ctor);
21624 set_member_function_is_dtor(f, is_dtor);
21625 set_member_access_specifier(f, a);
21626 set_member_is_static(f, is_static);
21627 set_member_function_is_const(f, is_const);
21628
21629 priv_->member_functions_.push_back(f);
21630
21631 // Update the map of linkage name -> member functions. It's useful,
21632 // so that class_or_union::find_member_function() can function.
21633 if (!f->get_linkage_name().empty())
21634 priv_->mem_fns_map_[f->get_linkage_name()] = f;
21635 }
21636
21637 /// Get the member functions of this @ref class_or_union.
21638 ///
21639 /// @return a vector of the member functions of this @ref
21640 /// class_or_union.
21641 const class_or_union::member_functions&
get_member_functions() const21642 class_or_union::get_member_functions() const
21643 {return priv_->member_functions_;}
21644
21645 /// Find a method, using its linkage name as a key.
21646 ///
21647 /// @param linkage_name the linkage name of the method to find.
21648 ///
21649 /// @return the method found, or nil if none was found.
21650 const method_decl*
find_member_function(const string & linkage_name) const21651 class_or_union::find_member_function(const string& linkage_name) const
21652 {
21653 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
21654 }
21655
21656 /// Find a method, using its linkage name as a key.
21657 ///
21658 /// @param linkage_name the linkage name of the method to find.
21659 ///
21660 /// @return the method found, or nil if none was found.
21661 method_decl*
find_member_function(const string & linkage_name)21662 class_or_union::find_member_function(const string& linkage_name)
21663 {
21664 string_mem_fn_sptr_map_type::const_iterator i =
21665 priv_->mem_fns_map_.find(linkage_name);
21666 if (i == priv_->mem_fns_map_.end())
21667 return 0;
21668 return i->second.get();
21669 }
21670
21671 /// Find a method, using its linkage name as a key.
21672 ///
21673 /// @param linkage_name the linkage name of the method to find.
21674 ///
21675 /// @return the method found, or nil if none was found.
21676 method_decl_sptr
find_member_function_sptr(const string & linkage_name)21677 class_or_union::find_member_function_sptr(const string& linkage_name)
21678 {
21679 string_mem_fn_sptr_map_type::const_iterator i =
21680 priv_->mem_fns_map_.find(linkage_name);
21681 if (i == priv_->mem_fns_map_.end())
21682 return 0;
21683 return i->second;
21684 }
21685
21686 /// Find a method (member function) using its signature (pretty
21687 /// representation) as a key.
21688 ///
21689 /// @param s the signature of the method.
21690 ///
21691 /// @return the method found, or nil if none was found.
21692 const method_decl*
find_member_function_from_signature(const string & s) const21693 class_or_union::find_member_function_from_signature(const string& s) const
21694 {
21695 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
21696 }
21697
21698 /// Find a method (member function) using its signature (pretty
21699 /// representation) as a key.
21700 ///
21701 /// @param s the signature of the method.
21702 ///
21703 /// @return the method found, or nil if none was found.
21704 method_decl*
find_member_function_from_signature(const string & s)21705 class_or_union::find_member_function_from_signature(const string& s)
21706 {
21707 string_mem_fn_ptr_map_type::const_iterator i =
21708 priv_->signature_2_mem_fn_map_.find(s);
21709 if (i == priv_->signature_2_mem_fn_map_.end())
21710 return 0;
21711 return i->second;
21712 }
21713
21714 /// Get the member function templates of this class.
21715 ///
21716 /// @return a vector of the member function templates of this class.
21717 const member_function_templates&
get_member_function_templates() const21718 class_or_union::get_member_function_templates() const
21719 {return priv_->member_function_templates_;}
21720
21721 /// Get the member class templates of this class.
21722 ///
21723 /// @return a vector of the member class templates of this class.
21724 const member_class_templates&
get_member_class_templates() const21725 class_or_union::get_member_class_templates() const
21726 {return priv_->member_class_templates_;}
21727
21728 /// Append a member function template to the @ref class_or_union.
21729 ///
21730 /// @param m the member function template to append.
21731 void
add_member_function_template(member_function_template_sptr m)21732 class_or_union::add_member_function_template(member_function_template_sptr m)
21733 {
21734 decl_base* c = m->as_function_tdecl()->get_scope();
21735 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
21736 /// error message or something like a structured error.
21737 priv_->member_function_templates_.push_back(m);
21738 if (!c)
21739 scope_decl::add_member_decl(m->as_function_tdecl());
21740 }
21741
21742 /// Append a member class template to the @ref class_or_union.
21743 ///
21744 /// @param m the member function template to append.
21745 void
add_member_class_template(member_class_template_sptr m)21746 class_or_union::add_member_class_template(member_class_template_sptr m)
21747 {
21748 decl_base* c = m->as_class_tdecl()->get_scope();
21749 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
21750 /// error message or something like a structured error.
21751 m->set_scope(this);
21752 priv_->member_class_templates_.push_back(m);
21753 if (!c)
21754 scope_decl::add_member_decl(m->as_class_tdecl());
21755 }
21756
21757 ///@return true iff the current instance has no member.
21758 bool
has_no_member() const21759 class_or_union::has_no_member() const
21760 {
21761 return (get_member_types().empty()
21762 && priv_->data_members_.empty()
21763 && priv_->member_functions_.empty()
21764 && priv_->member_function_templates_.empty()
21765 && priv_->member_class_templates_.empty());
21766 }
21767
21768 /// Insert a data member to this @ref class_or_union type.
21769 ///
21770 /// @param d the data member to insert.
21771 ///
21772 /// @return the decl @p that got inserted.
21773 decl_base_sptr
insert_member_decl(decl_base_sptr d)21774 class_or_union::insert_member_decl(decl_base_sptr d)
21775 {
21776 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
21777 {
21778 add_data_member(v, public_access,
21779 /*is_laid_out=*/false,
21780 /*is_static=*/true,
21781 /*offset_in_bits=*/0);
21782 d = v;
21783 }
21784 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
21785 add_member_function(f, public_access,
21786 /*is_static=*/false,
21787 /*is_ctor=*/false,
21788 /*is_dtor=*/false,
21789 /*is_const=*/false);
21790 else if (member_function_template_sptr f =
21791 dynamic_pointer_cast<member_function_template>(d))
21792 add_member_function_template(f);
21793 else if (member_class_template_sptr c =
21794 dynamic_pointer_cast<member_class_template>(d))
21795 add_member_class_template(c);
21796 else
21797 scope_decl::add_member_decl(d);
21798
21799 return d;
21800 }
21801
21802 /// Equality operator.
21803 ///
21804 /// @param other the other @ref class_or_union to compare against.
21805 ///
21806 /// @return true iff @p other equals the current @ref class_or_union.
21807 bool
operator ==(const decl_base & other) const21808 class_or_union::operator==(const decl_base& other) const
21809 {
21810 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
21811 if (!op)
21812 return false;
21813
21814 // If this is a decl-only type (and thus with no canonical type),
21815 // use the canonical type of the definition, if any.
21816 const class_or_union *l = 0;
21817 if (get_is_declaration_only())
21818 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
21819 if (l == 0)
21820 l = this;
21821
21822 // Likewise for the other class.
21823 const class_or_union *r = 0;
21824 if (op->get_is_declaration_only())
21825 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
21826 if (r == 0)
21827 r = op;
21828
21829 return try_canonical_compare(l, r);
21830 }
21831
21832 /// Equality operator.
21833 ///
21834 /// @param other the other @ref class_or_union to compare against.
21835 ///
21836 /// @return true iff @p other equals the current @ref class_or_union.
21837 bool
operator ==(const type_base & other) const21838 class_or_union::operator==(const type_base& other) const
21839 {
21840 const decl_base* o = dynamic_cast<const decl_base*>(&other);
21841 if (!o)
21842 return false;
21843 return *this == *o;
21844 }
21845
21846 /// Equality operator.
21847 ///
21848 /// @param other the other @ref class_or_union to compare against.
21849 ///
21850 /// @return true iff @p other equals the current @ref class_or_union.
21851 bool
operator ==(const class_or_union & other) const21852 class_or_union::operator==(const class_or_union& other) const
21853 {
21854 const decl_base& o = other;
21855 return class_or_union::operator==(o);
21856 }
21857
21858 /// Dumps a textual representation (to the standard error output) of
21859 /// the content of the set of classes being currently compared using
21860 /// the @ref equal overloads.
21861 ///
21862 /// This function is for debugging purposes.
21863 ///
21864 /// @param c an artifact that belongs to the environment in which the
21865 /// classes of interest are being compared.
21866 void
dump_classes_being_compared(const type_or_decl_base & c)21867 dump_classes_being_compared(const type_or_decl_base& c)
21868 {c.get_environment().priv_->dump_classes_being_compared();}
21869
21870 /// Dumps a textual representation (to the standard error output) of
21871 /// the content of the set of function types being currently compared
21872 /// using the @ref equal overloads.
21873 ///
21874 /// This function is for debugging purposes.
21875 ///
21876 /// @param c an artifact that belongs to the environment in which the
21877 /// function types of interest are being compared.
21878 void
dump_fn_types_being_compared(const type_or_decl_base & t)21879 dump_fn_types_being_compared(const type_or_decl_base& t)
21880 {t.get_environment().priv_->dump_fn_types_being_compared();}
21881
21882 /// Compares two instances of @ref class_or_union.
21883 ///
21884 /// If the two intances are different, set a bitfield to give some
21885 /// insight about the kind of differences there are.
21886 ///
21887 /// @param l the first artifact of the comparison.
21888 ///
21889 /// @param r the second artifact of the comparison.
21890 ///
21891 /// @param k a pointer to a bitfield that gives information about the
21892 /// kind of changes there are between @p l and @p r. This one is set
21893 /// iff it's non-null and if the function returns false.
21894 ///
21895 /// Please note that setting k to a non-null value does have a
21896 /// negative performance impact because even if @p l and @p r are not
21897 /// equal, the function keeps up the comparison in order to determine
21898 /// the different kinds of ways in which they are different.
21899 ///
21900 /// @return true if @p l equals @p r, false otherwise.
21901 bool
equals(const class_or_union & l,const class_or_union & r,change_kind * k)21902 equals(const class_or_union& l, const class_or_union& r, change_kind* k)
21903 {
21904 #define RETURN(value) return return_comparison_result(l, r, value, \
21905 /*propagate_canonical_type=*/false);
21906
21907 // if one of the classes is declaration-only, look through it to
21908 // get its definition.
21909 bool l_is_decl_only = l.get_is_declaration_only();
21910 bool r_is_decl_only = r.get_is_declaration_only();
21911 if (l_is_decl_only || r_is_decl_only)
21912 {
21913 const class_or_union* def1 = l_is_decl_only
21914 ? is_class_or_union_type(l.get_naked_definition_of_declaration())
21915 : &l;
21916
21917 const class_or_union* def2 = r_is_decl_only
21918 ? is_class_or_union_type(r.get_naked_definition_of_declaration())
21919 : &r;
21920
21921 if (!def1 || !def2)
21922 {
21923 if (!l.get_is_anonymous()
21924 && !r.get_is_anonymous()
21925 && l_is_decl_only && r_is_decl_only
21926 && comparison::filtering::is_decl_only_class_with_size_change(l, r))
21927 // The two decl-only classes differ from their size. A
21928 // true decl-only class should not have a size property to
21929 // begin with. This comes from a DWARF oddity and can
21930 // results in a false positive, so let's not consider that
21931 // change.
21932 return true;
21933
21934 if ((l.get_environment().decl_only_class_equals_definition()
21935 || ((odr_is_relevant(l) && !def1)
21936 || (odr_is_relevant(r) && !def2)))
21937 && !is_anonymous_or_typedef_named(l)
21938 && !is_anonymous_or_typedef_named(r))
21939 {
21940 const interned_string& q1 = l.get_scoped_name();
21941 const interned_string& q2 = r.get_scoped_name();
21942 if (q1 == q2)
21943 // Not using RETURN(true) here, because that causes
21944 // performance issues. We don't need to do
21945 // l.priv_->unmark_as_being_compared({l,r}) here because
21946 // we haven't marked l or r as being compared yet, and
21947 // doing so has a peformance cost that shows up on
21948 // performance profiles for *big* libraries.
21949 return true;
21950 else
21951 {
21952 if (k)
21953 *k |= LOCAL_TYPE_CHANGE_KIND;
21954 // Not using RETURN(true) here, because that causes
21955 // performance issues. We don't need to do
21956 // l.priv_->unmark_as_being_compared({l,r}) here because
21957 // we haven't marked l or r as being compared yet, and
21958 // doing so has a peformance cost that shows up on
21959 // performance profiles for *big* libraries.
21960 ABG_RETURN_FALSE;
21961 }
21962 }
21963 else // A decl-only class is considered different from a
21964 // class definition of the same name.
21965 {
21966 if (!!def1 != !!def2)
21967 {
21968 if (k)
21969 *k |= LOCAL_TYPE_CHANGE_KIND;
21970 ABG_RETURN_FALSE;
21971 }
21972
21973 // both definitions are empty
21974 if (!(l.decl_base::operator==(r)
21975 && l.type_base::operator==(r)))
21976 {
21977 if (k)
21978 *k |= LOCAL_TYPE_CHANGE_KIND;
21979 ABG_RETURN_FALSE;
21980 }
21981
21982 return true;
21983 }
21984 }
21985
21986 bool val = *def1 == *def2;
21987 if (!val)
21988 if (k)
21989 *k |= LOCAL_TYPE_CHANGE_KIND;
21990 RETURN(val);
21991 }
21992
21993 // No need to go further if the classes have different names or
21994 // different size / alignment.
21995 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
21996 {
21997 if (k)
21998 *k |= LOCAL_TYPE_CHANGE_KIND;
21999 ABG_RETURN_FALSE;
22000 }
22001
22002 if (types_defined_same_linux_kernel_corpus_public(l, r))
22003 return true;
22004
22005 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
22006
22007 mark_types_as_being_compared(l, r);
22008
22009 bool result = true;
22010
22011 //compare data_members
22012 {
22013 if (l.get_non_static_data_members().size()
22014 != r.get_non_static_data_members().size())
22015 {
22016 result = false;
22017 if (k)
22018 *k |= LOCAL_TYPE_CHANGE_KIND;
22019 else
22020 RETURN(result);
22021 }
22022
22023 for (class_or_union::data_members::const_iterator
22024 d0 = l.get_non_static_data_members().begin(),
22025 d1 = r.get_non_static_data_members().begin();
22026 (d0 != l.get_non_static_data_members().end()
22027 && d1 != r.get_non_static_data_members().end());
22028 ++d0, ++d1)
22029 if (**d0 != **d1)
22030 {
22031 result = false;
22032 if (k)
22033 {
22034 // Report any representation change as being local.
22035 if (!types_have_similar_structure((*d0)->get_type(),
22036 (*d1)->get_type())
22037 || (*d0)->get_type() == (*d1)->get_type())
22038 *k |= LOCAL_TYPE_CHANGE_KIND;
22039 else
22040 *k |= SUBTYPE_CHANGE_KIND;
22041 }
22042 else
22043 RETURN(result);
22044 }
22045 }
22046
22047 // Do not compare member functions. DWARF does not necessarily
22048 // all the member functions, be they virtual or not, in all
22049 // translation units. So we cannot have a clear view of them, per
22050 // class
22051
22052 // compare member function templates
22053 {
22054 if (l.get_member_function_templates().size()
22055 != r.get_member_function_templates().size())
22056 {
22057 result = false;
22058 if (k)
22059 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
22060 else
22061 RETURN(result);
22062 }
22063
22064 for (member_function_templates::const_iterator
22065 fn_tmpl_it0 = l.get_member_function_templates().begin(),
22066 fn_tmpl_it1 = r.get_member_function_templates().begin();
22067 fn_tmpl_it0 != l.get_member_function_templates().end()
22068 && fn_tmpl_it1 != r.get_member_function_templates().end();
22069 ++fn_tmpl_it0, ++fn_tmpl_it1)
22070 if (**fn_tmpl_it0 != **fn_tmpl_it1)
22071 {
22072 result = false;
22073 if (k)
22074 {
22075 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
22076 break;
22077 }
22078 else
22079 RETURN(result);
22080 }
22081 }
22082
22083 // compare member class templates
22084 {
22085 if (l.get_member_class_templates().size()
22086 != r.get_member_class_templates().size())
22087 {
22088 result = false;
22089 if (k)
22090 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
22091 else
22092 RETURN(result);
22093 }
22094
22095 for (member_class_templates::const_iterator
22096 cl_tmpl_it0 = l.get_member_class_templates().begin(),
22097 cl_tmpl_it1 = r.get_member_class_templates().begin();
22098 cl_tmpl_it0 != l.get_member_class_templates().end()
22099 && cl_tmpl_it1 != r.get_member_class_templates().end();
22100 ++cl_tmpl_it0, ++cl_tmpl_it1)
22101 if (**cl_tmpl_it0 != **cl_tmpl_it1)
22102 {
22103 result = false;
22104 if (k)
22105 {
22106 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
22107 break;
22108 }
22109 else
22110 RETURN(result);
22111 }
22112 }
22113
22114 RETURN(result);
22115 #undef RETURN
22116 }
22117
22118
22119 /// Copy a method of a @ref class_or_union into a new @ref
22120 /// class_or_union.
22121 ///
22122 /// @param t the @ref class_or_union into which the method is to be copied.
22123 ///
22124 /// @param method the method to copy into @p t.
22125 ///
22126 /// @return the resulting newly copied method.
22127 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl_sptr & method)22128 copy_member_function(const class_or_union_sptr& t,
22129 const method_decl_sptr& method)
22130 {return copy_member_function(t, method.get());}
22131
22132
22133 /// Copy a method of a @ref class_or_union into a new @ref
22134 /// class_or_union.
22135 ///
22136 /// @param t the @ref class_or_union into which the method is to be copied.
22137 ///
22138 /// @param method the method to copy into @p t.
22139 ///
22140 /// @return the resulting newly copied method.
22141 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl * method)22142 copy_member_function(const class_or_union_sptr& t, const method_decl* method)
22143 {
22144 ABG_ASSERT(t);
22145 ABG_ASSERT(method);
22146
22147 method_type_sptr old_type = method->get_type();
22148 ABG_ASSERT(old_type);
22149 method_type_sptr new_type(new method_type(old_type->get_return_type(),
22150 t,
22151 old_type->get_parameters(),
22152 old_type->get_is_const(),
22153 old_type->get_size_in_bits(),
22154 old_type->get_alignment_in_bits()));
22155 keep_type_alive(new_type);
22156
22157 method_decl_sptr
22158 new_method(new method_decl(method->get_name(),
22159 new_type,
22160 method->is_declared_inline(),
22161 method->get_location(),
22162 method->get_linkage_name(),
22163 method->get_visibility(),
22164 method->get_binding()));
22165 new_method->set_symbol(method->get_symbol());
22166
22167 if (class_decl_sptr class_type = is_class_type(t))
22168 class_type->add_member_function(new_method,
22169 get_member_access_specifier(*method),
22170 get_member_function_is_virtual(*method),
22171 get_member_function_vtable_offset(*method),
22172 get_member_is_static(*method),
22173 get_member_function_is_ctor(*method),
22174 get_member_function_is_dtor(*method),
22175 get_member_function_is_const(*method));
22176 else
22177 t->add_member_function(new_method,
22178 get_member_access_specifier(*method),
22179 get_member_is_static(*method),
22180 get_member_function_is_ctor(*method),
22181 get_member_function_is_dtor(*method),
22182 get_member_function_is_const(*method));
22183 return new_method;
22184 }
22185
22186 // </class_or_union definitions>
22187
22188 /// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
22189 /// @{
22190 ///
22191 /// This optimization is also known as "canonical type propagation".
22192 ///
22193 /// During the canonicalization of a type T (which doesn't yet have a
22194 /// canonical type), T is compared structurally (member-wise) against
22195 /// a type C which already has a canonical type. The comparison
22196 /// expression is C == T.
22197 ///
22198 /// During that structural comparison, if a subtype of C (which also
22199 /// already has a canonical type) is structurally compared to a
22200 /// subtype of T (which doesn't yet have a canonical type) and if they
22201 /// are equal, then we can deduce that the canonical type of the
22202 /// subtype of C is the canonical type of the subtype of C.
22203 ///
22204 /// Thus, we can canonicalize the sub-type of the T, during the
22205 /// canonicalization of T itself. That canonicalization of the
22206 /// sub-type of T is what we call the "on-the-fly canonicalization".
22207 /// It's on the fly because it happens during a comparison -- which
22208 /// itself happens during the canonicalization of T.
22209 ///
22210 /// For now this on-the-fly canonicalization only happens when
22211 /// comparing @ref class_decl and @ref function_type.
22212 ///
22213 /// Note however that there is a case when a type is *NOT* eligible to
22214 /// this canonical type propagation optimization.
22215 ///
22216 /// The reason why a type is deemed NON-eligible to the canonical type
22217 /// propagation optimization is that it "depends" on recursively
22218 /// present type. Let me explain.
22219 ///
22220 /// Suppose we have a type T that has sub-types named ST0 and ST1.
22221 /// Suppose ST1 itself has a sub-type that is T itself. In this case,
22222 /// we say that T is a recursive type, because it has T (itself) as
22223 /// one of its sub-types:
22224 ///
22225 /// <PRE>
22226 /// T
22227 /// +-- ST0
22228 /// |
22229 /// +-- ST1
22230 /// | +
22231 /// | |
22232 /// | +-- T
22233 /// |
22234 /// +-- ST2
22235 /// </PRE>
22236 ///
22237 /// ST1 is said to "depend" on T because it has T as a sub-type. But
22238 /// because T is recursive, then ST1 is said to depend on a recursive
22239 /// type. Notice however that ST0 does not depend on any recursive
22240 /// type.
22241 ///
22242 /// Now suppose we are comparing T to a type T' that has the same
22243 /// structure with sub-types ST0', ST1' and ST2'. During the
22244 /// comparison of ST1 against ST1', their sub-type T is compared
22245 /// against T'. Because T (resp. T') is a recursive type that is
22246 /// already being compared, the comparison of T against T' (as a
22247 /// subtypes of ST1 and ST1') returns true, meaning they are
22248 /// considered equal. This is done so that we don't enter an infinite
22249 /// recursion.
22250 ///
22251 /// That means ST1 is also deemed equal to ST1'. If we are in the
22252 /// course of the canonicalization of T' and thus if T (as well as as
22253 /// all of its sub-types) is already canonicalized, then the canonical
22254 /// type propagation optimization will make us propagate the canonical
22255 /// type of ST1 onto ST1'. So the canonical type of ST1' will be
22256 /// equal to the canonical type of ST1 as a result of that
22257 /// optmization.
22258 ///
22259 /// But then, later down the road, when ST2 is compared against ST2',
22260 /// let's suppose that we find out that they are different. Meaning
22261 /// that ST2 != ST2'. This means that T != T', i.e, the
22262 /// canonicalization of T' failed for now. But most importantly, it
22263 /// means that the propagation of the canonical type of ST1 to ST1'
22264 /// must now be invalidated. Meaning, ST1' must now be considered as
22265 /// not having any canonical type.
22266 ///
22267 /// In other words, during type canonicalization, if ST1' depends on a
22268 /// recursive type T', its propagated canonical type must be
22269 /// invalidated (set to nullptr) if T' appears to be different from T,
22270 /// a.k.a, the canonicalization of T' temporarily failed.
22271 ///
22272 /// This means that any sub-type that depends on recursive types and
22273 /// that has been the target of the canonical type propagation
22274 /// optimization must be tracked. If the dependant recursive type
22275 /// fails its canonicalization, then the sub-type being compared must
22276 /// have its propagated canonical type cleared. In other words, its
22277 /// propagated canonical type must be cancelled.
22278 ///
22279 /// @}
22280
22281
22282 /// If on-the-fly canonicalization is turned on, then this function
22283 /// sets the canonical type of its second parameter to the canonical
22284 /// type of the first parameter.
22285 ///
22286 /// @param lhs_type the type which canonical type to propagate.
22287 ///
22288 /// @param rhs_type the type which canonical type to set.
22289 static bool
maybe_propagate_canonical_type(const type_base & lhs_type,const type_base & rhs_type)22290 maybe_propagate_canonical_type(const type_base& lhs_type,
22291 const type_base& rhs_type)
22292 {
22293 const environment& env = lhs_type.get_environment();
22294 #if WITH_DEBUG_TYPE_CANONICALIZATION
22295 if (!env.priv_->use_canonical_type_comparison_)
22296 return false;
22297 #endif
22298
22299 if (env.do_on_the_fly_canonicalization())
22300 if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
22301 if (!rhs_type.get_canonical_type())
22302 if (env.priv_->propagate_ct(lhs_type, rhs_type))
22303 return true;
22304 return false;
22305 }
22306
22307 // <class_decl definitions>
22308
22309 static void
22310 sort_virtual_member_functions(class_decl::member_functions& mem_fns);
22311
22312 /// The private data for the class_decl type.
22313 struct class_decl::priv
22314 {
22315 base_specs bases_;
22316 unordered_map<string, base_spec_sptr> bases_map_;
22317 member_functions virtual_mem_fns_;
22318 virtual_mem_fn_map_type virtual_mem_fns_map_;
22319 bool is_struct_;
22320
privabigail::ir::class_decl::priv22321 priv()
22322 : is_struct_(false)
22323 {}
22324
privabigail::ir::class_decl::priv22325 priv(bool is_struct, class_decl::base_specs& bases)
22326 : bases_(bases),
22327 is_struct_(is_struct)
22328 {
22329 }
22330
privabigail::ir::class_decl::priv22331 priv(bool is_struct)
22332 : is_struct_(is_struct)
22333 {}
22334 };// end struct class_decl::priv
22335
22336 /// A Constructor for instances of \ref class_decl
22337 ///
22338 /// @param env the environment we are operating from.
22339 ///
22340 /// @param name the identifier of the class.
22341 ///
22342 /// @param size_in_bits the size of an instance of class_decl, expressed
22343 /// in bits
22344 ///
22345 /// @param align_in_bits the alignment of an instance of class_decl,
22346 /// expressed in bits.
22347 ///
22348 /// @param locus the source location of declaration point this class.
22349 ///
22350 /// @param vis the visibility of instances of class_decl.
22351 ///
22352 /// @param bases the vector of base classes for this instance of class_decl.
22353 ///
22354 /// @param mbrs the vector of member types of this instance of
22355 /// class_decl.
22356 ///
22357 /// @param data_mbrs the vector of data members of this instance of
22358 /// class_decl.
22359 ///
22360 /// @param mbr_fns the vector of member functions of this instance of
22361 /// class_decl.
class_decl(const environment & env,const string & name,size_t size_in_bits,size_t align_in_bits,bool is_struct,const location & locus,visibility vis,base_specs & bases,member_types & mbr_types,data_members & data_mbrs,member_functions & mbr_fns)22362 class_decl::class_decl(const environment& env, const string& name,
22363 size_t size_in_bits, size_t align_in_bits,
22364 bool is_struct, const location& locus,
22365 visibility vis, base_specs& bases,
22366 member_types& mbr_types,
22367 data_members& data_mbrs,
22368 member_functions& mbr_fns)
22369 : type_or_decl_base(env,
22370 CLASS_TYPE
22371 | ABSTRACT_TYPE_BASE
22372 | ABSTRACT_DECL_BASE
22373 | ABSTRACT_SCOPE_TYPE_DECL
22374 | ABSTRACT_SCOPE_DECL),
22375 decl_base(env, name, locus, name, vis),
22376 type_base(env, size_in_bits, align_in_bits),
22377 class_or_union(env, name, size_in_bits, align_in_bits,
22378 locus, vis, mbr_types, data_mbrs, mbr_fns),
22379 priv_(new priv(is_struct, bases))
22380 {
22381 runtime_type_instance(this);
22382 }
22383
22384 /// A Constructor for instances of @ref class_decl
22385 ///
22386 /// @param env the environment we are operating from.
22387 ///
22388 /// @param name the identifier of the class.
22389 ///
22390 /// @param size_in_bits the size of an instance of class_decl, expressed
22391 /// in bits
22392 ///
22393 /// @param align_in_bits the alignment of an instance of class_decl,
22394 /// expressed in bits.
22395 ///
22396 /// @param locus the source location of declaration point this class.
22397 ///
22398 /// @param vis the visibility of instances of class_decl.
22399 ///
22400 /// @param bases the vector of base classes for this instance of class_decl.
22401 ///
22402 /// @param mbrs the vector of member types of this instance of
22403 /// class_decl.
22404 ///
22405 /// @param data_mbrs the vector of data members of this instance of
22406 /// class_decl.
22407 ///
22408 /// @param mbr_fns the vector of member functions of this instance of
22409 /// class_decl.
22410 ///
22411 /// @param is_anonymous whether the newly created instance is
22412 /// anonymous.
class_decl(const environment & env,const string & name,size_t size_in_bits,size_t align_in_bits,bool is_struct,const location & locus,visibility vis,base_specs & bases,member_types & mbr_types,data_members & data_mbrs,member_functions & mbr_fns,bool is_anonymous)22413 class_decl::class_decl(const environment& env, const string& name,
22414 size_t size_in_bits, size_t align_in_bits,
22415 bool is_struct, const location& locus,
22416 visibility vis, base_specs& bases,
22417 member_types& mbr_types, data_members& data_mbrs,
22418 member_functions& mbr_fns, bool is_anonymous)
22419 : type_or_decl_base(env,
22420 CLASS_TYPE
22421 | ABSTRACT_TYPE_BASE
22422 | ABSTRACT_DECL_BASE
22423 | ABSTRACT_SCOPE_TYPE_DECL
22424 | ABSTRACT_SCOPE_DECL),
22425 decl_base(env, name, locus,
22426 // If the class is anonymous then by default it won't
22427 // have a linkage name. Also, the anonymous class does
22428 // have an internal-only unique name that is generally
22429 // not taken into account when comparing classes; such a
22430 // unique internal-only name, when used as a linkage
22431 // name might introduce spurious comparison false
22432 // negatives.
22433 /*linkage_name=*/is_anonymous ? string() : name,
22434 vis),
22435 type_base(env, size_in_bits, align_in_bits),
22436 class_or_union(env, name, size_in_bits, align_in_bits,
22437 locus, vis, mbr_types, data_mbrs, mbr_fns),
22438 priv_(new priv(is_struct, bases))
22439 {
22440 runtime_type_instance(this);
22441 set_is_anonymous(is_anonymous);
22442 }
22443
22444 /// A constructor for instances of class_decl.
22445 ///
22446 /// @param env the environment we are operating from.
22447 ///
22448 /// @param name the name of the class.
22449 ///
22450 /// @param size_in_bits the size of an instance of class_decl, expressed
22451 /// in bits
22452 ///
22453 /// @param align_in_bits the alignment of an instance of class_decl,
22454 /// expressed in bits.
22455 ///
22456 /// @param locus the source location of declaration point this class.
22457 ///
22458 /// @param vis the visibility of instances of class_decl.
class_decl(const environment & env,const string & name,size_t size_in_bits,size_t align_in_bits,bool is_struct,const location & locus,visibility vis)22459 class_decl::class_decl(const environment& env, const string& name,
22460 size_t size_in_bits, size_t align_in_bits,
22461 bool is_struct, const location& locus,
22462 visibility vis)
22463 : type_or_decl_base(env,
22464 CLASS_TYPE
22465 | ABSTRACT_TYPE_BASE
22466 | ABSTRACT_DECL_BASE
22467 | ABSTRACT_SCOPE_TYPE_DECL
22468 | ABSTRACT_SCOPE_DECL),
22469 decl_base(env, name, locus, name, vis),
22470 type_base(env, size_in_bits, align_in_bits),
22471 class_or_union(env, name, size_in_bits, align_in_bits,
22472 locus, vis),
22473 priv_(new priv(is_struct))
22474 {
22475 runtime_type_instance(this);
22476 }
22477
22478 /// A constructor for instances of @ref class_decl.
22479 ///
22480 /// @param env the environment we are operating from.
22481 ///
22482 /// @param name the name of the class.
22483 ///
22484 /// @param size_in_bits the size of an instance of class_decl, expressed
22485 /// in bits
22486 ///
22487 /// @param align_in_bits the alignment of an instance of class_decl,
22488 /// expressed in bits.
22489 ///
22490 /// @param locus the source location of declaration point this class.
22491 ///
22492 /// @param vis the visibility of instances of class_decl.
22493 ///
22494 /// @param is_anonymous whether the newly created instance is
22495 /// anonymous.
class_decl(const environment & env,const string & name,size_t size_in_bits,size_t align_in_bits,bool is_struct,const location & locus,visibility vis,bool is_anonymous)22496 class_decl:: class_decl(const environment& env, const string& name,
22497 size_t size_in_bits, size_t align_in_bits,
22498 bool is_struct, const location& locus,
22499 visibility vis, bool is_anonymous)
22500 : type_or_decl_base(env,
22501 CLASS_TYPE
22502 | ABSTRACT_TYPE_BASE
22503 | ABSTRACT_DECL_BASE
22504 | ABSTRACT_SCOPE_TYPE_DECL
22505 | ABSTRACT_SCOPE_DECL),
22506 decl_base(env, name, locus,
22507 // If the class is anonymous then by default it won't
22508 // have a linkage name. Also, the anonymous class does
22509 // have an internal-only unique name that is generally
22510 // not taken into account when comparing classes; such a
22511 // unique internal-only name, when used as a linkage
22512 // name might introduce spurious comparison false
22513 // negatives.
22514 /*linkage_name=*/ is_anonymous ? string() : name,
22515 vis),
22516 type_base(env, size_in_bits, align_in_bits),
22517 class_or_union(env, name, size_in_bits, align_in_bits,
22518 locus, vis),
22519 priv_(new priv(is_struct))
22520 {
22521 runtime_type_instance(this);
22522 set_is_anonymous(is_anonymous);
22523 }
22524
22525 /// A constuctor for instances of class_decl that represent a
22526 /// declaration without definition.
22527 ///
22528 /// @param env the environment we are operating from.
22529 ///
22530 /// @param name the name of the class.
22531 ///
22532 /// @param is_declaration_only a boolean saying whether the instance
22533 /// represents a declaration only, or not.
class_decl(const environment & env,const string & name,bool is_struct,bool is_declaration_only)22534 class_decl::class_decl(const environment& env, const string& name,
22535 bool is_struct, bool is_declaration_only)
22536 : type_or_decl_base(env,
22537 CLASS_TYPE
22538 | ABSTRACT_TYPE_BASE
22539 | ABSTRACT_DECL_BASE
22540 | ABSTRACT_SCOPE_TYPE_DECL
22541 | ABSTRACT_SCOPE_DECL),
22542 decl_base(env, name, location(), name),
22543 type_base(env, 0, 0),
22544 class_or_union(env, name, is_declaration_only),
22545 priv_(new priv(is_struct))
22546 {
22547 runtime_type_instance(this);
22548 }
22549
22550 /// This method is invoked automatically right after the current
22551 /// instance of @ref class_decl has been canonicalized.
22552 ///
22553 /// Currently, the only thing it does is to sort the virtual member
22554 /// functions vector.
22555 void
on_canonical_type_set()22556 class_decl::on_canonical_type_set()
22557 {
22558 sort_virtual_mem_fns();
22559
22560 for (class_decl::virtual_mem_fn_map_type::iterator i =
22561 priv_->virtual_mem_fns_map_.begin();
22562 i != priv_->virtual_mem_fns_map_.end();
22563 ++i)
22564 sort_virtual_member_functions(i->second);
22565 }
22566
22567 /// Set the "is-struct" flag of the class.
22568 ///
22569 /// @param f the new value of the flag.
22570 void
is_struct(bool f)22571 class_decl::is_struct(bool f)
22572 {priv_->is_struct_ = f;}
22573
22574 /// Test if the class is a struct.
22575 ///
22576 /// @return true iff the class is a struct.
22577 bool
is_struct() const22578 class_decl::is_struct() const
22579 {return priv_->is_struct_;}
22580
22581 /// Add a base specifier to this class.
22582 ///
22583 /// @param b the new base specifier.
22584 void
add_base_specifier(base_spec_sptr b)22585 class_decl::add_base_specifier(base_spec_sptr b)
22586 {
22587 priv_->bases_.push_back(b);
22588 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
22589 }
22590
22591 /// Get the base specifiers for this class.
22592 ///
22593 /// @return a vector of the base specifiers.
22594 const class_decl::base_specs&
get_base_specifiers() const22595 class_decl::get_base_specifiers() const
22596 {return priv_->bases_;}
22597
22598 /// Find a base class of a given qualified name for the current class.
22599 ///
22600 /// @param qualified_name the qualified name of the base class to look for.
22601 ///
22602 /// @return a pointer to the @ref class_decl that represents the base
22603 /// class of name @p qualified_name, if found.
22604 class_decl_sptr
find_base_class(const string & qualified_name) const22605 class_decl::find_base_class(const string& qualified_name) const
22606 {
22607 unordered_map<string, base_spec_sptr>::iterator i =
22608 priv_->bases_map_.find(qualified_name);
22609
22610 if (i != priv_->bases_map_.end())
22611 return i->second->get_base_class();
22612
22613 return class_decl_sptr();
22614 }
22615
22616 /// Get the virtual member functions of this class.
22617 ///
22618 /// @param return a vector of the virtual member functions of this
22619 /// class.
22620 const class_decl::member_functions&
get_virtual_mem_fns() const22621 class_decl::get_virtual_mem_fns() const
22622 {return priv_->virtual_mem_fns_;}
22623
22624 /// Get the map that associates a virtual table offset to the virtual
22625 /// member functions with that virtual table offset.
22626 ///
22627 /// Usually, there should be a 1:1 mapping between a given vtable
22628 /// offset and virtual member functions of that vtable offset. But
22629 /// because of some implementation details, there can be several C++
22630 /// destructor functions that are *generated* by compilers, for a
22631 /// given destructor that is defined in the source code. If the
22632 /// destructor is virtual then those generated functions have some
22633 /// DWARF attributes in common with the constructor that the user
22634 /// actually defined in its source code. Among those attributes are
22635 /// the vtable offset of the destructor.
22636 ///
22637 /// @return the map that associates a virtual table offset to the
22638 /// virtual member functions with that virtual table offset.
22639 const class_decl::virtual_mem_fn_map_type&
get_virtual_mem_fns_map() const22640 class_decl::get_virtual_mem_fns_map() const
22641 {return priv_->virtual_mem_fns_map_;}
22642
22643 /// Sort the virtual member functions by their virtual index.
22644 void
sort_virtual_mem_fns()22645 class_decl::sort_virtual_mem_fns()
22646 {sort_virtual_member_functions(priv_->virtual_mem_fns_);}
22647
22648 /// Getter of the pretty representation of the current instance of
22649 /// @ref class_decl.
22650 ///
22651 /// @param internal set to true if the call is intended to get a
22652 /// representation of the decl (or type) for the purpose of canonical
22653 /// type comparison. This is mainly used in the function
22654 /// type_base::get_canonical_type_for().
22655 ///
22656 /// In other words if the argument for this parameter is true then the
22657 /// call is meant for internal use (for technical use inside the
22658 /// library itself), false otherwise. If you don't know what this is
22659 /// for, then set it to false.
22660 ///
22661 /// @param qualified_name if true, names emitted in the pretty
22662 /// representation are fully qualified.
22663 ///
22664 /// @return the pretty representaion for a class_decl.
22665 string
get_pretty_representation(bool internal,bool qualified_name) const22666 class_decl::get_pretty_representation(bool internal,
22667 bool qualified_name) const
22668 {
22669 string cl = "class ";
22670 if (!internal && is_struct())
22671 cl = "struct ";
22672
22673 // When computing the pretty representation for internal purposes,
22674 // if an anonymous class is named by a typedef, then consider that
22675 // it has a name, which is the typedef name.
22676 if (get_is_anonymous())
22677 {
22678 if (internal && !get_name().empty())
22679 return cl + get_type_name(this, qualified_name, /*internal=*/true);
22680 return get_class_or_union_flat_representation(this, "",
22681 /*one_line=*/true,
22682 internal);
22683
22684 }
22685
22686 string result = cl;
22687 if (qualified_name)
22688 result += get_qualified_name(internal);
22689 else
22690 result += get_name();
22691
22692 return result;
22693 }
22694
22695 decl_base_sptr
insert_member_decl(decl_base_sptr d)22696 class_decl::insert_member_decl(decl_base_sptr d)
22697 {
22698 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
22699 add_member_function(f, public_access,
22700 /*is_virtual=*/false,
22701 /*vtable_offset=*/0,
22702 /*is_static=*/false,
22703 /*is_ctor=*/false,
22704 /*is_dtor=*/false,
22705 /*is_const=*/false);
22706 else
22707 d = class_or_union::insert_member_decl(d);
22708
22709 return d;
22710 }
22711
22712 /// The private data structure of class_decl::base_spec.
22713 struct class_decl::base_spec::priv
22714 {
22715 class_decl_wptr base_class_;
22716 long offset_in_bits_;
22717 bool is_virtual_;
22718
privabigail::ir::class_decl::base_spec::priv22719 priv(const class_decl_sptr& cl,
22720 long offset_in_bits,
22721 bool is_virtual)
22722 : base_class_(cl),
22723 offset_in_bits_(offset_in_bits),
22724 is_virtual_(is_virtual)
22725 {}
22726 };
22727
22728 /// Constructor for base_spec instances.
22729 ///
22730 /// @param base the base class to consider
22731 ///
22732 /// @param a the access specifier of the base class.
22733 ///
22734 /// @param offset_in_bits if positive or null, represents the offset
22735 /// of the base in the layout of its containing type.. If negative,
22736 /// means that the current base is not laid out in its containing type.
22737 ///
22738 /// @param is_virtual if true, means that the current base class is
22739 /// virtual in it's containing type.
base_spec(const class_decl_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)22740 class_decl::base_spec::base_spec(const class_decl_sptr& base,
22741 access_specifier a,
22742 long offset_in_bits,
22743 bool is_virtual)
22744 : type_or_decl_base(base->get_environment(),
22745 ABSTRACT_DECL_BASE),
22746 decl_base(base->get_environment(), base->get_name(), base->get_location(),
22747 base->get_linkage_name(), base->get_visibility()),
22748 member_base(a),
22749 priv_(new priv(base, offset_in_bits, is_virtual))
22750 {
22751 runtime_type_instance(this);
22752 set_qualified_name(base->get_qualified_name());
22753 }
22754
22755 /// Get the base class referred to by the current base class
22756 /// specifier.
22757 ///
22758 /// @return the base class.
22759 class_decl_sptr
get_base_class() const22760 class_decl::base_spec::get_base_class() const
22761 {return priv_->base_class_.lock();}
22762
22763 /// Getter of the "is-virtual" proprerty of the base class specifier.
22764 ///
22765 /// @return true iff this specifies a virtual base class.
22766 bool
get_is_virtual() const22767 class_decl::base_spec::get_is_virtual() const
22768 {return priv_->is_virtual_;}
22769
22770 /// Getter of the offset of the base.
22771 ///
22772 /// @return the offset of the base.
22773 long
get_offset_in_bits() const22774 class_decl::base_spec::get_offset_in_bits() const
22775 {return priv_->offset_in_bits_;}
22776
22777 /// Calculate the hash value for a class_decl::base_spec.
22778 ///
22779 /// @return the hash value.
22780 size_t
get_hash() const22781 class_decl::base_spec::get_hash() const
22782 {
22783 base_spec::hash h;
22784 return h(*this);
22785 }
22786
22787 /// Traverses an instance of @ref class_decl::base_spec, visiting all
22788 /// the sub-types and decls that it might contain.
22789 ///
22790 /// @param v the visitor that is used to visit every IR sub-node of
22791 /// the current node.
22792 ///
22793 /// @return true if either
22794 /// - all the children nodes of the current IR node were traversed
22795 /// and the calling code should keep going with the traversing.
22796 /// - or the current IR node is already being traversed.
22797 /// Otherwise, returning false means that the calling code should not
22798 /// keep traversing the tree.
22799 bool
traverse(ir_node_visitor & v)22800 class_decl::base_spec::traverse(ir_node_visitor& v)
22801 {
22802 if (visiting())
22803 return true;
22804
22805 if (v.visit_begin(this))
22806 {
22807 visiting(true);
22808 get_base_class()->traverse(v);
22809 visiting(false);
22810 }
22811
22812 return v.visit_end(this);
22813 }
22814
22815 /// Constructor for base_spec instances.
22816 ///
22817 /// Note that this constructor is for clients that don't support RTTI
22818 /// and that have a base class of type_base, but of dynamic type
22819 /// class_decl.
22820 ///
22821 /// @param base the base class to consider. Must be a pointer to an
22822 /// instance of class_decl
22823 ///
22824 /// @param a the access specifier of the base class.
22825 ///
22826 /// @param offset_in_bits if positive or null, represents the offset
22827 /// of the base in the layout of its containing type.. If negative,
22828 /// means that the current base is not laid out in its containing type.
22829 ///
22830 /// @param is_virtual if true, means that the current base class is
22831 /// virtual in it's containing type.
base_spec(const type_base_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)22832 class_decl::base_spec::base_spec(const type_base_sptr& base,
22833 access_specifier a,
22834 long offset_in_bits,
22835 bool is_virtual)
22836 : type_or_decl_base(base->get_environment(),
22837 ABSTRACT_DECL_BASE),
22838 decl_base(base->get_environment(), get_type_declaration(base)->get_name(),
22839 get_type_declaration(base)->get_location(),
22840 get_type_declaration(base)->get_linkage_name(),
22841 get_type_declaration(base)->get_visibility()),
22842 member_base(a),
22843 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
22844 offset_in_bits,
22845 is_virtual))
22846 {
22847 runtime_type_instance(this);
22848 }
22849
22850 class_decl::base_spec::~base_spec() = default;
22851
22852 /// Compares two instances of @ref class_decl::base_spec.
22853 ///
22854 /// If the two intances are different, set a bitfield to give some
22855 /// insight about the kind of differences there are.
22856 ///
22857 /// @param l the first artifact of the comparison.
22858 ///
22859 /// @param r the second artifact of the comparison.
22860 ///
22861 /// @param k a pointer to a bitfield that gives information about the
22862 /// kind of changes there are between @p l and @p r. This one is set
22863 /// iff @p k is non-null and the function returns false.
22864 ///
22865 /// Please note that setting k to a non-null value does have a
22866 /// negative performance impact because even if @p l and @p r are not
22867 /// equal, the function keeps up the comparison in order to determine
22868 /// the different kinds of ways in which they are different.
22869 ///
22870 /// @return true if @p l equals @p r, false otherwise.
22871 bool
equals(const class_decl::base_spec & l,const class_decl::base_spec & r,change_kind * k)22872 equals(const class_decl::base_spec& l,
22873 const class_decl::base_spec& r,
22874 change_kind* k)
22875 {
22876 if (!l.member_base::operator==(r))
22877 {
22878 if (k)
22879 *k |= LOCAL_TYPE_CHANGE_KIND;
22880 ABG_RETURN_FALSE;
22881 }
22882
22883 ABG_RETURN((*l.get_base_class() == *r.get_base_class()));
22884 }
22885
22886 /// Comparison operator for @ref class_decl::base_spec.
22887 ///
22888 /// @param other the instance of @ref class_decl::base_spec to compare
22889 /// against.
22890 ///
22891 /// @return true if the current instance of @ref class_decl::base_spec
22892 /// equals @p other.
22893 bool
operator ==(const decl_base & other) const22894 class_decl::base_spec::operator==(const decl_base& other) const
22895 {
22896 const class_decl::base_spec* o =
22897 dynamic_cast<const class_decl::base_spec*>(&other);
22898
22899 if (!o)
22900 return false;
22901
22902 return equals(*this, *o, 0);
22903 }
22904
22905 /// Comparison operator for @ref class_decl::base_spec.
22906 ///
22907 /// @param other the instance of @ref class_decl::base_spec to compare
22908 /// against.
22909 ///
22910 /// @return true if the current instance of @ref class_decl::base_spec
22911 /// equals @p other.
22912 bool
operator ==(const member_base & other) const22913 class_decl::base_spec::operator==(const member_base& other) const
22914 {
22915 const class_decl::base_spec* o =
22916 dynamic_cast<const class_decl::base_spec*>(&other);
22917 if (!o)
22918 return false;
22919
22920 return operator==(static_cast<const decl_base&>(*o));
22921 }
22922
~mem_fn_context_rel()22923 mem_fn_context_rel::~mem_fn_context_rel()
22924 {
22925 }
22926
22927 /// A constructor for instances of method_decl.
22928 ///
22929 /// @param name the name of the method.
22930 ///
22931 /// @param type the type of the method.
22932 ///
22933 /// @param declared_inline whether the method was
22934 /// declared inline or not.
22935 ///
22936 /// @param locus the source location of the method.
22937 ///
22938 /// @param linkage_name the mangled name of the method.
22939 ///
22940 /// @param vis the visibility of the method.
22941 ///
22942 /// @param bind the binding of the method.
method_decl(const string & name,method_type_sptr type,bool declared_inline,const location & locus,const string & linkage_name,visibility vis,binding bind)22943 method_decl::method_decl(const string& name,
22944 method_type_sptr type,
22945 bool declared_inline,
22946 const location& locus,
22947 const string& linkage_name,
22948 visibility vis,
22949 binding bind)
22950 : type_or_decl_base(type->get_environment(),
22951 METHOD_DECL
22952 | ABSTRACT_DECL_BASE
22953 |FUNCTION_DECL),
22954 decl_base(type->get_environment(), name, locus, linkage_name, vis),
22955 function_decl(name, static_pointer_cast<function_type>(type),
22956 declared_inline, locus, linkage_name, vis, bind)
22957 {
22958 runtime_type_instance(this);
22959 set_context_rel(new mem_fn_context_rel(0));
22960 set_member_function_is_const(*this, type->get_is_const());
22961 }
22962
22963 /// A constructor for instances of method_decl.
22964 ///
22965 /// @param name the name of the method.
22966 ///
22967 /// @param type the type of the method. Must be an instance of
22968 /// method_type.
22969 ///
22970 /// @param declared_inline whether the method was
22971 /// declared inline or not.
22972 ///
22973 /// @param locus the source location of the method.
22974 ///
22975 /// @param linkage_name the mangled name of the method.
22976 ///
22977 /// @param vis the visibility of the method.
22978 ///
22979 /// @param bind the binding of the method.
method_decl(const string & name,function_type_sptr type,bool declared_inline,const location & locus,const string & linkage_name,visibility vis,binding bind)22980 method_decl::method_decl(const string& name,
22981 function_type_sptr type,
22982 bool declared_inline,
22983 const location& locus,
22984 const string& linkage_name,
22985 visibility vis,
22986 binding bind)
22987 : type_or_decl_base(type->get_environment(),
22988 METHOD_DECL
22989 | ABSTRACT_DECL_BASE
22990 | FUNCTION_DECL),
22991 decl_base(type->get_environment(), name, locus, linkage_name, vis),
22992 function_decl(name, static_pointer_cast<function_type>
22993 (dynamic_pointer_cast<method_type>(type)),
22994 declared_inline, locus, linkage_name, vis, bind)
22995 {
22996 runtime_type_instance(this);
22997 set_context_rel(new mem_fn_context_rel(0));
22998 }
22999
23000 /// A constructor for instances of method_decl.
23001 ///
23002 /// @param name the name of the method.
23003 ///
23004 /// @param type the type of the method. Must be an instance of
23005 /// method_type.
23006 ///
23007 /// @param declared_inline whether the method was
23008 /// declared inline or not.
23009 ///
23010 /// @param locus the source location of the method.
23011 ///
23012 /// @param linkage_name the mangled name of the method.
23013 ///
23014 /// @param vis the visibility of the method.
23015 ///
23016 /// @param bind the binding of the method.
method_decl(const string & name,type_base_sptr type,bool declared_inline,const location & locus,const string & linkage_name,visibility vis,binding bind)23017 method_decl::method_decl(const string& name,
23018 type_base_sptr type,
23019 bool declared_inline,
23020 const location& locus,
23021 const string& linkage_name,
23022 visibility vis,
23023 binding bind)
23024 : type_or_decl_base(type->get_environment(),
23025 METHOD_DECL
23026 | ABSTRACT_DECL_BASE
23027 | FUNCTION_DECL),
23028 decl_base(type->get_environment(), name, locus, linkage_name, vis),
23029 function_decl(name, static_pointer_cast<function_type>
23030 (dynamic_pointer_cast<method_type>(type)),
23031 declared_inline, locus, linkage_name, vis, bind)
23032 {
23033 runtime_type_instance(this);
23034 set_context_rel(new mem_fn_context_rel(0));
23035 }
23036
23037 /// Set the linkage name of the method.
23038 ///
23039 /// @param l the new linkage name of the method.
23040 void
set_linkage_name(const string & l)23041 method_decl::set_linkage_name(const string& l)
23042 {
23043 decl_base::set_linkage_name(l);
23044 // Update the linkage_name -> member function map of the containing
23045 // class declaration.
23046 if (!l.empty())
23047 {
23048 method_type_sptr t = get_type();
23049 class_or_union_sptr cl = t->get_class_type();
23050 method_decl_sptr m(this, sptr_utils::noop_deleter());
23051 cl->priv_->mem_fns_map_[l] = m;
23052 }
23053 }
23054
~method_decl()23055 method_decl::~method_decl()
23056 {}
23057
23058 const method_type_sptr
get_type() const23059 method_decl::get_type() const
23060 {
23061 method_type_sptr result;
23062 if (function_decl::get_type())
23063 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
23064 return result;
23065 }
23066
23067 /// Set the containing class of a method_decl.
23068 ///
23069 /// @param scope the new containing class_decl.
23070 void
set_scope(scope_decl * scope)23071 method_decl::set_scope(scope_decl* scope)
23072 {
23073 if (!get_context_rel())
23074 set_context_rel(new mem_fn_context_rel(scope));
23075 else
23076 get_context_rel()->set_scope(scope);
23077 }
23078
23079 /// Equality operator for @ref method_decl_sptr.
23080 ///
23081 /// This is a deep equality operator, as it compares the @ref
23082 /// method_decl that is pointed-to by the smart pointer.
23083 ///
23084 /// @param l the left-hand side argument of the equality operator.
23085 ///
23086 /// @param r the righ-hand side argument of the equality operator.
23087 ///
23088 /// @return true iff @p l equals @p r.
23089 bool
operator ==(const method_decl_sptr & l,const method_decl_sptr & r)23090 operator==(const method_decl_sptr& l, const method_decl_sptr& r)
23091 {
23092 if (l.get() == r.get())
23093 return true;
23094 if (!!l != !!r)
23095 return false;
23096
23097 return *l == *r;
23098 }
23099
23100 /// Inequality operator for @ref method_decl_sptr.
23101 ///
23102 /// This is a deep equality operator, as it compares the @ref
23103 /// method_decl that is pointed-to by the smart pointer.
23104 ///
23105 /// @param l the left-hand side argument of the equality operator.
23106 ///
23107 /// @param r the righ-hand side argument of the equality operator.
23108 ///
23109 /// @return true iff @p l differs from @p r.
23110 bool
operator !=(const method_decl_sptr & l,const method_decl_sptr & r)23111 operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
23112 {return !operator==(l, r);}
23113
23114 /// Test if a function_decl is actually a method_decl.
23115 ///
23116 ///@param d the @ref function_decl to consider.
23117 ///
23118 /// @return the method_decl sub-object of @p d if inherits
23119 /// a method_decl type.
23120 method_decl*
is_method_decl(const type_or_decl_base * d)23121 is_method_decl(const type_or_decl_base *d)
23122 {
23123 return dynamic_cast<method_decl*>
23124 (const_cast<type_or_decl_base*>(d));
23125 }
23126
23127 /// Test if a function_decl is actually a method_decl.
23128 ///
23129 ///@param d the @ref function_decl to consider.
23130 ///
23131 /// @return the method_decl sub-object of @p d if inherits
23132 /// a method_decl type.
23133 method_decl*
is_method_decl(const type_or_decl_base & d)23134 is_method_decl(const type_or_decl_base&d)
23135 {return is_method_decl(&d);}
23136
23137 /// Test if a function_decl is actually a method_decl.
23138 ///
23139 ///@param d the @ref function_decl to consider.
23140 ///
23141 /// @return the method_decl sub-object of @p d if inherits
23142 /// a method_decl type.
23143 method_decl_sptr
is_method_decl(const type_or_decl_base_sptr & d)23144 is_method_decl(const type_or_decl_base_sptr& d)
23145 {return dynamic_pointer_cast<method_decl>(d);}
23146
23147 /// A "less than" functor to sort a vector of instances of
23148 /// method_decl that are virtual.
23149 struct virtual_member_function_less_than
23150 {
23151 /// The less than operator. First, it sorts the methods by their
23152 /// vtable index. If they have the same vtable index, it sorts them
23153 /// by the name of their ELF symbol. If they don't have elf
23154 /// symbols, it sorts them by considering their pretty
23155 /// representation.
23156 ///
23157 /// Note that this method expects virtual methods.
23158 ///
23159 /// @param f the first method to consider.
23160 ///
23161 /// @param s the second method to consider.
23162 ///
23163 /// @return true if method @p is less than method @s.
23164 bool
operator ()abigail::ir::virtual_member_function_less_than23165 operator()(const method_decl& f,
23166 const method_decl& s)
23167 {
23168 ABG_ASSERT(get_member_function_is_virtual(f));
23169 ABG_ASSERT(get_member_function_is_virtual(s));
23170
23171 ssize_t f_offset = get_member_function_vtable_offset(f);
23172 ssize_t s_offset = get_member_function_vtable_offset(s);
23173 if (f_offset != s_offset) return f_offset < s_offset;
23174
23175 string fn, sn;
23176
23177 // If the functions have symbols, then compare their symbol-id
23178 // string.
23179 elf_symbol_sptr f_sym = f.get_symbol();
23180 elf_symbol_sptr s_sym = s.get_symbol();
23181 if ((!f_sym) != (!s_sym)) return !f_sym;
23182 if (f_sym && s_sym)
23183 {
23184 fn = f_sym->get_id_string();
23185 sn = s_sym->get_id_string();
23186 if (fn != sn) return fn < sn;
23187 }
23188
23189 // Try the linkage names (important for destructors).
23190 fn = f.get_linkage_name();
23191 sn = s.get_linkage_name();
23192 if (fn != sn) return fn < sn;
23193
23194 // None of the functions have symbols or linkage names that
23195 // distinguish them, so compare their pretty representation.
23196 fn = f.get_pretty_representation();
23197 sn = s.get_pretty_representation();
23198 if (fn != sn) return fn < sn;
23199
23200 /// If it's just the file paths that are different then sort them
23201 /// too.
23202 string fn_filepath, sn_filepath;
23203 unsigned line = 0, column = 0;
23204 location fn_loc = f.get_location(), sn_loc = s.get_location();
23205 if (fn_loc)
23206 fn_loc.expand(fn_filepath, line, column);
23207 if (sn_loc)
23208 sn_loc.expand(sn_filepath, line, column);
23209 return fn_filepath < sn_filepath;
23210 }
23211
23212 /// The less than operator. First, it sorts the methods by their
23213 /// vtable index. If they have the same vtable index, it sorts them
23214 /// by the name of their ELF symbol. If they don't have elf
23215 /// symbols, it sorts them by considering their pretty
23216 /// representation.
23217 ///
23218 /// Note that this method expects to take virtual methods.
23219 ///
23220 /// @param f the first method to consider.
23221 ///
23222 /// @param s the second method to consider.
23223 bool
operator ()abigail::ir::virtual_member_function_less_than23224 operator()(const method_decl_sptr f,
23225 const method_decl_sptr s)
23226 {return operator()(*f, *s);}
23227 }; // end struct virtual_member_function_less_than
23228
23229 /// Sort a vector of instances of virtual member functions.
23230 ///
23231 /// @param mem_fns the vector of member functions to sort.
23232 static void
sort_virtual_member_functions(class_decl::member_functions & mem_fns)23233 sort_virtual_member_functions(class_decl::member_functions& mem_fns)
23234 {
23235 virtual_member_function_less_than lt;
23236 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
23237 }
23238
23239 /// Add a member function to the current instance of @ref class_or_union.
23240 ///
23241 /// @param f a method_decl to add to the current class. This function
23242 /// should not have been already added to a scope.
23243 ///
23244 /// @param access the access specifier for the member function to add.
23245 ///
23246 /// @param is_virtual if this is true then it means the function @p f
23247 /// is a virtual function. That also means that the current instance
23248 /// of @ref class_or_union is actually an instance of @ref class_decl.
23249 ///
23250 /// @param vtable_offset the offset of the member function in the
23251 /// virtual table. This parameter is taken into account only if @p
23252 /// is_virtual is true.
23253 ///
23254 /// @param is_static whether the member function is static.
23255 ///
23256 /// @param is_ctor whether the member function is a constructor.
23257 ///
23258 /// @param is_dtor whether the member function is a destructor.
23259 ///
23260 /// @param is_const whether the member function is const.
23261 void
add_member_function(method_decl_sptr f,access_specifier a,bool is_virtual,size_t vtable_offset,bool is_static,bool is_ctor,bool is_dtor,bool is_const)23262 class_or_union::add_member_function(method_decl_sptr f,
23263 access_specifier a,
23264 bool is_virtual,
23265 size_t vtable_offset,
23266 bool is_static, bool is_ctor,
23267 bool is_dtor, bool is_const)
23268 {
23269 add_member_function(f, a, is_static, is_ctor,
23270 is_dtor, is_const);
23271
23272 if (class_decl* klass = is_class_type(this))
23273 {
23274 set_member_function_is_virtual(f, is_virtual);
23275 if (is_virtual)
23276 {
23277 set_member_function_vtable_offset(f, vtable_offset);
23278 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
23279 }
23280 }
23281 }
23282
23283 /// When a virtual member function has seen its virtualness set by
23284 /// set_member_function_is_virtual(), this function ensures that the
23285 /// member function is added to the specific vectors and maps of
23286 /// virtual member function of its class.
23287 ///
23288 /// @param method the method to fixup.
23289 void
fixup_virtual_member_function(method_decl_sptr method)23290 fixup_virtual_member_function(method_decl_sptr method)
23291 {
23292 if (!method || !get_member_function_is_virtual(method))
23293 return;
23294
23295 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
23296
23297 class_decl::member_functions::const_iterator m;
23298 for (m = klass->priv_->virtual_mem_fns_.begin();
23299 m != klass->priv_->virtual_mem_fns_.end();
23300 ++m)
23301 if (m->get() == method.get())
23302 break;
23303 if (m == klass->priv_->virtual_mem_fns_.end())
23304 klass->priv_->virtual_mem_fns_.push_back(method);
23305
23306 // Build or udpate the map that associates a vtable offset to the
23307 // number of virtual member functions that "point" to it.
23308 ssize_t voffset = get_member_function_vtable_offset(method);
23309 if (voffset == -1)
23310 return;
23311
23312 class_decl::virtual_mem_fn_map_type::iterator i =
23313 klass->priv_->virtual_mem_fns_map_.find(voffset);
23314 if (i == klass->priv_->virtual_mem_fns_map_.end())
23315 {
23316 class_decl::member_functions virtual_mem_fns_at_voffset;
23317 virtual_mem_fns_at_voffset.push_back(method);
23318 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
23319 }
23320 else
23321 {
23322 for (m = i->second.begin() ; m != i->second.end(); ++m)
23323 if (m->get() == method.get())
23324 break;
23325 if (m == i->second.end())
23326 i->second.push_back(method);
23327 }
23328 }
23329
23330 /// Return true iff the class has no entity in its scope.
23331 bool
has_no_base_nor_member() const23332 class_decl::has_no_base_nor_member() const
23333 {return priv_->bases_.empty() && has_no_member();}
23334
23335 /// Test if the current instance of @ref class_decl has virtual member
23336 /// functions.
23337 ///
23338 /// @return true iff the current instance of @ref class_decl has
23339 /// virtual member functions.
23340 bool
has_virtual_member_functions() const23341 class_decl::has_virtual_member_functions() const
23342 {return !get_virtual_mem_fns().empty();}
23343
23344 /// Test if the current instance of @ref class_decl has at least one
23345 /// virtual base.
23346 ///
23347 /// @return true iff the current instance of @ref class_decl has a
23348 /// virtual member function.
23349 bool
has_virtual_bases() const23350 class_decl::has_virtual_bases() const
23351 {
23352 for (base_specs::const_iterator b = get_base_specifiers().begin();
23353 b != get_base_specifiers().end();
23354 ++b)
23355 if ((*b)->get_is_virtual()
23356 || (*b)->get_base_class()->has_virtual_bases())
23357 return true;
23358
23359 return false;
23360 }
23361
23362 /// Test if the current instance has a vtable.
23363 ///
23364 /// This is only valid for a C++ program.
23365 ///
23366 /// Basically this function checks if the class has either virtual
23367 /// functions, or virtual bases.
23368 bool
has_vtable() const23369 class_decl::has_vtable() const
23370 {
23371 if (has_virtual_member_functions()
23372 || has_virtual_bases())
23373 return true;
23374 return false;
23375 }
23376
23377 /// Get the highest vtable offset of all the virtual methods of the
23378 /// class.
23379 ///
23380 /// @return the highest vtable offset of all the virtual methods of
23381 /// the class.
23382 ssize_t
get_biggest_vtable_offset() const23383 class_decl::get_biggest_vtable_offset() const
23384 {
23385 ssize_t offset = -1;
23386 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
23387 get_virtual_mem_fns_map().begin();
23388 e != get_virtual_mem_fns_map().end();
23389 ++e)
23390 if (e->first > offset)
23391 offset = e->first;
23392
23393 return offset;
23394 }
23395
23396 /// Return the hash value for the current instance.
23397 ///
23398 /// @return the hash value.
23399 size_t
get_hash() const23400 class_decl::get_hash() const
23401 {
23402 class_decl::hash hash_class;
23403 return hash_class(this);
23404 }
23405
23406 /// Test if two methods are equal without taking their symbol or
23407 /// linkage name into account.
23408 ///
23409 /// @param f the first method.
23410 ///
23411 /// @param s the second method.
23412 ///
23413 /// @return true iff @p f equals @p s without taking their linkage
23414 /// name or symbol into account.
23415 static bool
methods_equal_modulo_elf_symbol(const method_decl_sptr & f,const method_decl_sptr & s)23416 methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
23417 const method_decl_sptr& s)
23418 {
23419 method_decl_sptr first = f, second = s;
23420 elf_symbol_sptr saved_first_elf_symbol =
23421 first->get_symbol();
23422 elf_symbol_sptr saved_second_elf_symbol =
23423 second->get_symbol();
23424 interned_string saved_first_linkage_name =
23425 first->get_linkage_name();
23426 interned_string saved_second_linkage_name =
23427 second->get_linkage_name();
23428
23429 first->set_symbol(elf_symbol_sptr());
23430 first->set_linkage_name("");
23431 second->set_symbol(elf_symbol_sptr());
23432 second->set_linkage_name("");
23433
23434 bool equal = *first == *second;
23435
23436 first->set_symbol(saved_first_elf_symbol);
23437 first->set_linkage_name(saved_first_linkage_name);
23438 second->set_symbol(saved_second_elf_symbol);
23439 second->set_linkage_name(saved_second_linkage_name);
23440
23441 return equal;
23442 }
23443
23444 /// Test if a given method is equivalent to at least of other method
23445 /// that is in a vector of methods.
23446 ///
23447 /// Note that "equivalent" here means being equal without taking the
23448 /// linkage name or the symbol of the methods into account.
23449 ///
23450 /// This is a sub-routine of the 'equals' function that compares @ref
23451 /// class_decl.
23452 ///
23453 /// @param method the method to compare.
23454 ///
23455 /// @param fns the vector of functions to compare @p method against.
23456 ///
23457 /// @return true iff @p is equivalent to at least one method in @p
23458 /// fns.
23459 static bool
method_matches_at_least_one_in_vector(const method_decl_sptr & method,const class_decl::member_functions & fns)23460 method_matches_at_least_one_in_vector(const method_decl_sptr& method,
23461 const class_decl::member_functions& fns)
23462 {
23463 for (class_decl::member_functions::const_iterator i = fns.begin();
23464 i != fns.end();
23465 ++i)
23466 // Note that the comparison must be done in this order: method ==
23467 // *i This is to keep the consistency of the comparison. It's
23468 // important especially when doing type canonicalization. The
23469 // already canonicalize type is the left operand, and the type
23470 // being canonicalized is the right operand. This comes from the
23471 // code in type_base::get_canonical_type_for().
23472 if (methods_equal_modulo_elf_symbol(method, *i))
23473 return true;
23474
23475 return false;
23476 }
23477
23478 /// Cancel the canonical type that was propagated.
23479 ///
23480 /// If we are in the process of comparing a type for the purpose of
23481 /// canonicalization, and if that type has been the target of the
23482 /// canonical type propagation optimization, then clear the propagated
23483 /// canonical type. See @ref OnTheFlyCanonicalization for more about
23484 /// the canonical type optimization
23485 ///
23486 /// @param t the type to consider.
23487 static bool
maybe_cancel_propagated_canonical_type(const class_or_union & t)23488 maybe_cancel_propagated_canonical_type(const class_or_union& t)
23489 {
23490 const environment& env = t.get_environment();
23491 if (env.do_on_the_fly_canonicalization())
23492 if (is_type(&t)->priv_->canonical_type_propagated())
23493 {
23494 is_type(&t)->priv_->clear_propagated_canonical_type();
23495 env.priv_->remove_from_types_with_non_confirmed_propagated_ct(&t);
23496 return true;
23497 }
23498 return false;
23499 }
23500
23501 /// Compares two instances of @ref class_decl.
23502 ///
23503 /// If the two intances are different, set a bitfield to give some
23504 /// insight about the kind of differences there are.
23505 ///
23506 /// @param l the first artifact of the comparison.
23507 ///
23508 /// @param r the second artifact of the comparison.
23509 ///
23510 /// @param k a pointer to a bitfield that gives information about the
23511 /// kind of changes there are between @p l and @p r. This one is set
23512 /// iff @p k is non-null and the function returns false.
23513 ///
23514 /// Please note that setting k to a non-null value does have a
23515 /// negative performance impact because even if @p l and @p r are not
23516 /// equal, the function keeps up the comparison in order to determine
23517 /// the different kinds of ways in which they are different.
23518 ///
23519 /// @return true if @p l equals @p r, false otherwise.
23520 bool
equals(const class_decl & l,const class_decl & r,change_kind * k)23521 equals(const class_decl& l, const class_decl& r, change_kind* k)
23522 {
23523 {
23524 // First of all, let's see if these two types haven't already been
23525 // compared. If so, and if the result of the comparison has been
23526 // cached, let's just re-use it, rather than comparing them all
23527 // over again.
23528 bool result = false;
23529 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
23530 return result;
23531 }
23532
23533 // if one of the classes is declaration-only then we take a fast
23534 // path here.
23535 if (l.get_is_declaration_only() || r.get_is_declaration_only())
23536 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
23537 static_cast<const class_or_union&>(r),
23538 k));
23539
23540 bool had_canonical_type = !!r.get_naked_canonical_type();
23541 bool result = true;
23542 if (!equals(static_cast<const class_or_union&>(l),
23543 static_cast<const class_or_union&>(r),
23544 k))
23545 {
23546 result = false;
23547 if (!k)
23548 ABG_RETURN(result);
23549 }
23550
23551 // If comparing the class_or_union 'part' of the type led to
23552 // canonical type propagation, then cancel that because it's too
23553 // early to do that at this point. We still need to compare bases
23554 // virtual members.
23555 if (!had_canonical_type)
23556 maybe_cancel_propagated_canonical_type(r);
23557
23558 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
23559
23560 mark_types_as_being_compared(l, r);
23561
23562 #define RETURN(value) return return_comparison_result(l, r, value);
23563
23564 // Compare bases.
23565 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
23566 {
23567 result = false;
23568 if (k)
23569 *k |= LOCAL_TYPE_CHANGE_KIND;
23570 else
23571 RETURN(result);
23572 }
23573
23574 for (class_decl::base_specs::const_iterator
23575 b0 = l.get_base_specifiers().begin(),
23576 b1 = r.get_base_specifiers().begin();
23577 (b0 != l.get_base_specifiers().end()
23578 && b1 != r.get_base_specifiers().end());
23579 ++b0, ++b1)
23580 if (*b0 != *b1)
23581 {
23582 result = false;
23583 if (k)
23584 {
23585 if (!types_have_similar_structure((*b0)->get_base_class().get(),
23586 (*b1)->get_base_class().get()))
23587 *k |= LOCAL_TYPE_CHANGE_KIND;
23588 else
23589 *k |= SUBTYPE_CHANGE_KIND;
23590 break;
23591 }
23592 RETURN(result);
23593 }
23594
23595 // Compare virtual member functions
23596
23597 // We look at the map that associates a given vtable offset to a
23598 // vector of virtual member functions that point to that offset.
23599 //
23600 // This is because there are cases where several functions can
23601 // point to the same virtual table offset.
23602 //
23603 // This is usually the case for virtual destructors. Even though
23604 // there can be only one virtual destructor declared in source
23605 // code, there are actually potentially up to three generated
23606 // functions for that destructor. Some of these generated
23607 // functions can be clones of other functions that are among those
23608 // generated ones. In any cases, they all have the same
23609 // properties, including the vtable offset property.
23610
23611 // So, there should be the same number of different vtable
23612 // offsets, the size of two maps must be equals.
23613 if (l.get_virtual_mem_fns_map().size()
23614 != r.get_virtual_mem_fns_map().size())
23615 {
23616 result = false;
23617 if (k)
23618 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23619 else
23620 RETURN(result);
23621 }
23622
23623 // Then, each virtual member function of a given vtable offset in
23624 // the first class type, must match an equivalent virtual member
23625 // function of a the same vtable offset in the second class type.
23626 //
23627 // By "match", I mean that the two virtual member function should
23628 // be equal if we don't take into account their symbol name or
23629 // their linkage name. This is because two destructor functions
23630 // clones (for instance) might have different linkage name, but
23631 // are still equivalent if their other properties are the same.
23632 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
23633 l.get_virtual_mem_fns_map().begin();
23634 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
23635 ++first_v_fn_entry)
23636 {
23637 unsigned voffset = first_v_fn_entry->first;
23638 const class_decl::member_functions& first_vfns =
23639 first_v_fn_entry->second;
23640
23641 const class_decl::virtual_mem_fn_map_type::const_iterator
23642 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
23643
23644 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
23645 {
23646 result = false;
23647 if (k)
23648 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23649 RETURN(result);
23650 }
23651
23652 const class_decl::member_functions& second_vfns =
23653 second_v_fn_entry->second;
23654
23655 bool matches = false;
23656 for (class_decl::member_functions::const_iterator i =
23657 first_vfns.begin();
23658 i != first_vfns.end();
23659 ++i)
23660 if (method_matches_at_least_one_in_vector(*i, second_vfns))
23661 {
23662 matches = true;
23663 break;
23664 }
23665
23666 if (!matches)
23667 {
23668 result = false;
23669 if (k)
23670 *k |= SUBTYPE_CHANGE_KIND;
23671 else
23672 RETURN(result);
23673 }
23674 }
23675
23676 // We are done comparing these two types and we have a full
23677 // understanding of how they might be different, if they are. Let's
23678 // cache the result of this comparison -- in case we are asked in a
23679 // very near future to compare them again.
23680 //
23681 // TODO: If further profiling shows its necessity, maybe we should
23682 // perform this caching also on the earlier return points of this
23683 // function. That would basically mean to redefine the RETURN macro
23684 // to make it perform this caching for us.
23685 l.get_environment().priv_->cache_type_comparison_result(l, r, result);
23686
23687 RETURN(result);
23688 #undef RETURN
23689 }
23690
23691 /// Copy a method of a class into a new class.
23692 ///
23693 /// @param klass the class into which the method is to be copied.
23694 ///
23695 /// @param method the method to copy into @p klass.
23696 ///
23697 /// @return the resulting newly copied method.
23698 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl_sptr & f)23699 copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
23700 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
23701
23702 /// Copy a method of a class into a new class.
23703 ///
23704 /// @param klass the class into which the method is to be copied.
23705 ///
23706 /// @param method the method to copy into @p klass.
23707 ///
23708 /// @return the resulting newly copied method.
23709 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl * f)23710 copy_member_function(const class_decl_sptr& clazz, const method_decl* f)
23711 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
23712
23713 /// Comparison operator for @ref class_decl.
23714 ///
23715 /// @param other the instance of @ref class_decl to compare against.
23716 ///
23717 /// @return true iff the current instance of @ref class_decl equals @p
23718 /// other.
23719 bool
operator ==(const decl_base & other) const23720 class_decl::operator==(const decl_base& other) const
23721 {
23722 const class_decl* op = is_class_type(&other);
23723 if (!op)
23724 return false;
23725
23726 // If this is a decl-only type (and thus with no canonical type),
23727 // use the canonical type of the definition, if any.
23728 const class_decl *l = 0;
23729 if (get_is_declaration_only())
23730 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
23731 if (l == 0)
23732 l = this;
23733
23734 ABG_ASSERT(l);
23735
23736 // Likewise for the other type.
23737 const class_decl *r = 0;
23738 if (op->get_is_declaration_only())
23739 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
23740 if (r == 0)
23741 r = op;
23742
23743 ABG_ASSERT(r);
23744
23745 return try_canonical_compare(l, r);
23746 }
23747
23748 /// Equality operator for class_decl.
23749 ///
23750 /// Re-uses the equality operator that takes a decl_base.
23751 ///
23752 /// @param other the other class_decl to compare against.
23753 ///
23754 /// @return true iff the current instance equals the other one.
23755 bool
operator ==(const type_base & other) const23756 class_decl::operator==(const type_base& other) const
23757 {
23758 const decl_base* o = is_decl(&other);
23759 if (!o)
23760 return false;
23761 return *this == *o;
23762 }
23763
23764 /// Comparison operator for @ref class_decl.
23765 ///
23766 /// @param other the instance of @ref class_decl to compare against.
23767 ///
23768 /// @return true iff the current instance of @ref class_decl equals @p
23769 /// other.
23770 bool
operator ==(const class_decl & other) const23771 class_decl::operator==(const class_decl& other) const
23772 {
23773 const decl_base& o = other;
23774 return *this == o;
23775 }
23776
23777 /// Turn equality of shared_ptr of class_decl into a deep equality;
23778 /// that is, make it compare the pointed to objects too.
23779 ///
23780 /// @param l the shared_ptr of class_decl on left-hand-side of the
23781 /// equality.
23782 ///
23783 /// @param r the shared_ptr of class_decl on right-hand-side of the
23784 /// equality.
23785 ///
23786 /// @return true if the class_decl pointed to by the shared_ptrs are
23787 /// equal, false otherwise.
23788 bool
operator ==(const class_decl_sptr & l,const class_decl_sptr & r)23789 operator==(const class_decl_sptr& l, const class_decl_sptr& r)
23790 {
23791 if (l.get() == r.get())
23792 return true;
23793 if (!!l != !!r)
23794 return false;
23795
23796 return *l == *r;
23797 }
23798
23799 /// Turn inequality of shared_ptr of class_decl into a deep equality;
23800 /// that is, make it compare the pointed to objects too.
23801 ///
23802 /// @param l the shared_ptr of class_decl on left-hand-side of the
23803 /// equality.
23804 ///
23805 /// @param r the shared_ptr of class_decl on right-hand-side of the
23806 /// equality.
23807 ///
23808 /// @return true if the class_decl pointed to by the shared_ptrs are
23809 /// different, false otherwise.
23810 bool
operator !=(const class_decl_sptr & l,const class_decl_sptr & r)23811 operator!=(const class_decl_sptr& l, const class_decl_sptr& r)
23812 {return !operator==(l, r);}
23813
23814 /// Turn equality of shared_ptr of class_or_union into a deep
23815 /// equality; that is, make it compare the pointed to objects too.
23816 ///
23817 /// @param l the left-hand-side operand of the operator
23818 ///
23819 /// @param r the right-hand-side operand of the operator.
23820 ///
23821 /// @return true iff @p l equals @p r.
23822 bool
operator ==(const class_or_union_sptr & l,const class_or_union_sptr & r)23823 operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
23824 {
23825 if (l.get() == r.get())
23826 return true;
23827 if (!!l != !!r)
23828 return false;
23829
23830 return *l == *r;
23831 }
23832
23833 /// Turn inequality of shared_ptr of class_or_union into a deep
23834 /// equality; that is, make it compare the pointed to objects too.
23835 ///
23836 /// @param l the left-hand-side operand of the operator
23837 ///
23838 /// @param r the right-hand-side operand of the operator.
23839 ///
23840 /// @return true iff @p l is different from @p r.
23841 bool
operator !=(const class_or_union_sptr & l,const class_or_union_sptr & r)23842 operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
23843 {return !operator==(l, r);}
23844
23845 /// This implements the ir_traversable_base::traverse pure virtual
23846 /// function.
23847 ///
23848 /// @param v the visitor used on the current instance and on its
23849 /// members.
23850 ///
23851 /// @return true if the entire IR node tree got traversed, false
23852 /// otherwise.
23853 bool
traverse(ir_node_visitor & v)23854 class_decl::traverse(ir_node_visitor& v)
23855 {
23856 if (v.type_node_has_been_visited(this))
23857 return true;
23858
23859 if (visiting())
23860 return true;
23861
23862 if (v.visit_begin(this))
23863 {
23864 visiting(true);
23865 bool stop = false;
23866
23867 for (base_specs::const_iterator i = get_base_specifiers().begin();
23868 i != get_base_specifiers().end();
23869 ++i)
23870 {
23871 if (!(*i)->traverse(v))
23872 {
23873 stop = true;
23874 break;
23875 }
23876 }
23877
23878 if (!stop)
23879 for (data_members::const_iterator i = get_data_members().begin();
23880 i != get_data_members().end();
23881 ++i)
23882 if (!(*i)->traverse(v))
23883 {
23884 stop = true;
23885 break;
23886 }
23887
23888 if (!stop)
23889 for (member_functions::const_iterator i= get_member_functions().begin();
23890 i != get_member_functions().end();
23891 ++i)
23892 if (!(*i)->traverse(v))
23893 {
23894 stop = true;
23895 break;
23896 }
23897
23898 if (!stop)
23899 for (member_types::const_iterator i = get_member_types().begin();
23900 i != get_member_types().end();
23901 ++i)
23902 if (!(*i)->traverse(v))
23903 {
23904 stop = true;
23905 break;
23906 }
23907
23908 if (!stop)
23909 for (member_function_templates::const_iterator i =
23910 get_member_function_templates().begin();
23911 i != get_member_function_templates().end();
23912 ++i)
23913 if (!(*i)->traverse(v))
23914 {
23915 stop = true;
23916 break;
23917 }
23918
23919 if (!stop)
23920 for (member_class_templates::const_iterator i =
23921 get_member_class_templates().begin();
23922 i != get_member_class_templates().end();
23923 ++i)
23924 if (!(*i)->traverse(v))
23925 {
23926 stop = true;
23927 break;
23928 }
23929 visiting(false);
23930 }
23931
23932 bool result = v.visit_end(this);
23933 v.mark_type_node_as_visited(this);
23934 return result;
23935 }
23936
23937 /// Destructor of the @ref class_decl type.
~class_decl()23938 class_decl::~class_decl()
23939 {delete priv_;}
23940
~context_rel()23941 context_rel::~context_rel()
23942 {}
23943
23944 bool
operator ==(const member_base & o) const23945 member_base::operator==(const member_base& o) const
23946 {
23947 return (get_access_specifier() == o.get_access_specifier()
23948 && get_is_static() == o.get_is_static());
23949 }
23950
23951 /// Equality operator for smart pointers to @ref
23952 /// class_decl::base_specs.
23953 ///
23954 /// This compares the pointed-to objects.
23955 ///
23956 /// @param l the first instance to consider.
23957 ///
23958 /// @param r the second instance to consider.
23959 ///
23960 /// @return true iff @p l equals @p r.
23961 bool
operator ==(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)23962 operator==(const class_decl::base_spec_sptr& l,
23963 const class_decl::base_spec_sptr& r)
23964 {
23965 if (l.get() == r.get())
23966 return true;
23967 if (!!l != !!r)
23968 return false;
23969
23970 return *l == static_cast<const decl_base&>(*r);
23971 }
23972
23973 /// Inequality operator for smart pointers to @ref
23974 /// class_decl::base_specs.
23975 ///
23976 /// This compares the pointed-to objects.
23977 ///
23978 /// @param l the first instance to consider.
23979 ///
23980 /// @param r the second instance to consider.
23981 ///
23982 /// @return true iff @p l is different from @p r.
23983 bool
operator !=(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)23984 operator!=(const class_decl::base_spec_sptr& l,
23985 const class_decl::base_spec_sptr& r)
23986 {return !operator==(l, r);}
23987
23988 /// Test if an ABI artifact is a class base specifier.
23989 ///
23990 /// @param tod the ABI artifact to consider.
23991 ///
23992 /// @return a pointer to the @ref class_decl::base_spec sub-object of
23993 /// @p tod iff it's a class base specifier.
23994 class_decl::base_spec*
is_class_base_spec(const type_or_decl_base * tod)23995 is_class_base_spec(const type_or_decl_base* tod)
23996 {
23997 return dynamic_cast<class_decl::base_spec*>
23998 (const_cast<type_or_decl_base*>(tod));
23999 }
24000
24001 /// Test if an ABI artifact is a class base specifier.
24002 ///
24003 /// @param tod the ABI artifact to consider.
24004 ///
24005 /// @return a pointer to the @ref class_decl::base_spec sub-object of
24006 /// @p tod iff it's a class base specifier.
24007 class_decl::base_spec_sptr
is_class_base_spec(type_or_decl_base_sptr tod)24008 is_class_base_spec(type_or_decl_base_sptr tod)
24009 {return dynamic_pointer_cast<class_decl::base_spec>(tod);}
24010
24011 bool
operator ==(const member_base & other) const24012 member_function_template::operator==(const member_base& other) const
24013 {
24014 try
24015 {
24016 const member_function_template& o =
24017 dynamic_cast<const member_function_template&>(other);
24018
24019 if (!(is_constructor() == o.is_constructor()
24020 && is_const() == o.is_const()
24021 && member_base::operator==(o)))
24022 return false;
24023
24024 if (function_tdecl_sptr ftdecl = as_function_tdecl())
24025 {
24026 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
24027 if (other_ftdecl)
24028 return ftdecl->function_tdecl::operator==(*other_ftdecl);
24029 }
24030 }
24031 catch(...)
24032 {}
24033 return false;
24034 }
24035
24036 /// Equality operator for smart pointers to @ref
24037 /// member_function_template. This is compares the
24038 /// pointed-to instances.
24039 ///
24040 /// @param l the first instance to consider.
24041 ///
24042 /// @param r the second instance to consider.
24043 ///
24044 /// @return true iff @p l equals @p r.
24045 bool
operator ==(const member_function_template_sptr & l,const member_function_template_sptr & r)24046 operator==(const member_function_template_sptr& l,
24047 const member_function_template_sptr& r)
24048 {
24049 if (l.get() == r.get())
24050 return true;
24051 if (!!l != !!r)
24052 return false;
24053
24054 return *l == *r;
24055 }
24056
24057 /// Inequality operator for smart pointers to @ref
24058 /// member_function_template. This is compares the pointed-to
24059 /// instances.
24060 ///
24061 /// @param l the first instance to consider.
24062 ///
24063 /// @param r the second instance to consider.
24064 ///
24065 /// @return true iff @p l equals @p r.
24066 bool
operator !=(const member_function_template_sptr & l,const member_function_template_sptr & r)24067 operator!=(const member_function_template_sptr& l,
24068 const member_function_template_sptr& r)
24069 {return !operator==(l, r);}
24070
24071 /// This implements the ir_traversable_base::traverse pure virtual
24072 /// function.
24073 ///
24074 /// @param v the visitor used on the current instance and on its
24075 /// underlying function template.
24076 ///
24077 /// @return true if the entire IR node tree got traversed, false
24078 /// otherwise.
24079 bool
traverse(ir_node_visitor & v)24080 member_function_template::traverse(ir_node_visitor& v)
24081 {
24082 if (visiting())
24083 return true;
24084
24085 if (v.visit_begin(this))
24086 {
24087 visiting(true);
24088 if (function_tdecl_sptr f = as_function_tdecl())
24089 f->traverse(v);
24090 visiting(false);
24091 }
24092 return v.visit_end(this);
24093 }
24094
24095 /// Equality operator of the the @ref member_class_template class.
24096 ///
24097 /// @param other the other @ref member_class_template to compare against.
24098 ///
24099 /// @return true iff the current instance equals @p other.
24100 bool
operator ==(const member_base & other) const24101 member_class_template::operator==(const member_base& other) const
24102 {
24103 try
24104 {
24105 const member_class_template& o =
24106 dynamic_cast<const member_class_template&>(other);
24107
24108 if (!member_base::operator==(o))
24109 return false;
24110
24111 return as_class_tdecl()->class_tdecl::operator==(o);
24112 }
24113 catch(...)
24114 {return false;}
24115 }
24116
24117 /// Comparison operator for the @ref member_class_template
24118 /// type.
24119 ///
24120 /// @param other the other instance of @ref
24121 /// member_class_template to compare against.
24122 ///
24123 /// @return true iff the two instances are equal.
24124 bool
operator ==(const member_class_template & other) const24125 member_class_template::operator==(const member_class_template& other) const
24126 {
24127 const decl_base* o = dynamic_cast<const decl_base*>(&other);
24128 return *this == *o;
24129 }
24130
24131 /// Comparison operator for the @ref member_class_template
24132 /// type.
24133 ///
24134 /// @param l the first argument of the operator.
24135 ///
24136 /// @param r the second argument of the operator.
24137 ///
24138 /// @return true iff the two instances are equal.
24139 bool
operator ==(const member_class_template_sptr & l,const member_class_template_sptr & r)24140 operator==(const member_class_template_sptr& l,
24141 const member_class_template_sptr& r)
24142 {
24143 if (l.get() == r.get())
24144 return true;
24145 if (!!l != !!r)
24146 return false;
24147
24148 return *l == *r;
24149 }
24150
24151 /// Inequality operator for the @ref member_class_template
24152 /// type.
24153 ///
24154 /// @param l the first argument of the operator.
24155 ///
24156 /// @param r the second argument of the operator.
24157 ///
24158 /// @return true iff the two instances are equal.
24159 bool
operator !=(const member_class_template_sptr & l,const member_class_template_sptr & r)24160 operator!=(const member_class_template_sptr& l,
24161 const member_class_template_sptr& r)
24162 {return !operator==(l, r);}
24163
24164 /// This implements the ir_traversable_base::traverse pure virtual
24165 /// function.
24166 ///
24167 /// @param v the visitor used on the current instance and on the class
24168 /// pattern of the template.
24169 ///
24170 /// @return true if the entire IR node tree got traversed, false
24171 /// otherwise.
24172 bool
traverse(ir_node_visitor & v)24173 member_class_template::traverse(ir_node_visitor& v)
24174 {
24175 if (visiting())
24176 return true;
24177
24178 if (v.visit_begin(this))
24179 {
24180 visiting(true);
24181 if (class_tdecl_sptr t = as_class_tdecl())
24182 t->traverse(v);
24183 visiting(false);
24184 }
24185 return v.visit_end(this);
24186 }
24187
24188 /// Streaming operator for class_decl::access_specifier.
24189 ///
24190 /// @param o the output stream to serialize the access specifier to.
24191 ///
24192 /// @param a the access specifier to serialize.
24193 ///
24194 /// @return the output stream.
24195 std::ostream&
operator <<(std::ostream & o,access_specifier a)24196 operator<<(std::ostream& o, access_specifier a)
24197 {
24198 string r;
24199
24200 switch (a)
24201 {
24202 case no_access:
24203 r = "none";
24204 break;
24205 case private_access:
24206 r = "private";
24207 break;
24208 case protected_access:
24209 r = "protected";
24210 break;
24211 case public_access:
24212 r= "public";
24213 break;
24214 };
24215 o << r;
24216 return o;
24217 }
24218
24219 /// Sets the static-ness property of a class member.
24220 ///
24221 /// @param d the class member to set the static-ness property for.
24222 /// Note that this must be a class member otherwise the function
24223 /// aborts the current process.
24224 ///
24225 /// @param s this must be true if the member is to be static, false
24226 /// otherwise.
24227 void
set_member_is_static(decl_base & d,bool s)24228 set_member_is_static(decl_base& d, bool s)
24229 {
24230 ABG_ASSERT(is_member_decl(d));
24231
24232 context_rel* c = d.get_context_rel();
24233 ABG_ASSERT(c);
24234
24235 c->set_is_static(s);
24236
24237 scope_decl* scope = d.get_scope();
24238
24239 if (class_or_union* cl = is_class_or_union_type(scope))
24240 {
24241 if (var_decl* v = is_var_decl(&d))
24242 {
24243 if (s)
24244 // remove from the non-static data members
24245 for (class_decl::data_members::iterator i =
24246 cl->priv_->non_static_data_members_.begin();
24247 i != cl->priv_->non_static_data_members_.end();
24248 ++i)
24249 {
24250 if ((*i)->get_name() == v->get_name())
24251 {
24252 cl->priv_->non_static_data_members_.erase(i);
24253 break;
24254 }
24255 }
24256 else
24257 {
24258 bool is_already_in_non_static_data_members = false;
24259 for (class_or_union::data_members::iterator i =
24260 cl->priv_->non_static_data_members_.begin();
24261 i != cl->priv_->non_static_data_members_.end();
24262 ++i)
24263 {
24264 if ((*i)->get_name() == v->get_name())
24265 {
24266 is_already_in_non_static_data_members = true;
24267 break;
24268 }
24269 }
24270 if (!is_already_in_non_static_data_members)
24271 {
24272 var_decl_sptr var;
24273 // add to non-static data members.
24274 for (class_or_union::data_members::const_iterator i =
24275 cl->priv_->data_members_.begin();
24276 i != cl->priv_->data_members_.end();
24277 ++i)
24278 {
24279 if ((*i)->get_name() == v->get_name())
24280 {
24281 var = *i;
24282 break;
24283 }
24284 }
24285 ABG_ASSERT(var);
24286 cl->priv_->non_static_data_members_.push_back(var);
24287 }
24288 }
24289 }
24290 }
24291 }
24292
24293 /// Sets the static-ness property of a class member.
24294 ///
24295 /// @param d the class member to set the static-ness property for.
24296 /// Note that this must be a class member otherwise the function
24297 /// aborts the current process.
24298 ///
24299 /// @param s this must be true if the member is to be static, false
24300 /// otherwise.
24301 void
set_member_is_static(const decl_base_sptr & d,bool s)24302 set_member_is_static(const decl_base_sptr& d, bool s)
24303 {set_member_is_static(*d, s);}
24304
24305 // </class_decl>
24306
24307 // <union_decl>
24308
24309 /// Constructor for the @ref union_decl type.
24310 ///
24311 /// @param env the @ref environment we are operating from.
24312 ///
24313 /// @param name the name of the union type.
24314 ///
24315 /// @param size_in_bits the size of the union, in bits.
24316 ///
24317 /// @param locus the location of the type.
24318 ///
24319 /// @param vis the visibility of instances of @ref union_decl.
24320 ///
24321 /// @param mbr_types the member types of the union.
24322 ///
24323 /// @param data_mbrs the data members of the union.
24324 ///
24325 /// @param member_fns the member functions of the union.
union_decl(const environment & env,const string & name,size_t size_in_bits,const location & locus,visibility vis,member_types & mbr_types,data_members & data_mbrs,member_functions & member_fns)24326 union_decl::union_decl(const environment& env, const string& name,
24327 size_t size_in_bits, const location& locus,
24328 visibility vis, member_types& mbr_types,
24329 data_members& data_mbrs, member_functions& member_fns)
24330 : type_or_decl_base(env,
24331 UNION_TYPE
24332 | ABSTRACT_TYPE_BASE
24333 | ABSTRACT_DECL_BASE),
24334 decl_base(env, name, locus, name, vis),
24335 type_base(env, size_in_bits, 0),
24336 class_or_union(env, name, size_in_bits, 0,
24337 locus, vis, mbr_types, data_mbrs, member_fns)
24338 {
24339 runtime_type_instance(this);
24340 }
24341
24342 /// Constructor for the @ref union_decl type.
24343 ///
24344 /// @param env the @ref environment we are operating from.
24345 ///
24346 /// @param name the name of the union type.
24347 ///
24348 /// @param size_in_bits the size of the union, in bits.
24349 ///
24350 /// @param locus the location of the type.
24351 ///
24352 /// @param vis the visibility of instances of @ref union_decl.
24353 ///
24354 /// @param mbr_types the member types of the union.
24355 ///
24356 /// @param data_mbrs the data members of the union.
24357 ///
24358 /// @param member_fns the member functions of the union.
24359 ///
24360 /// @param is_anonymous whether the newly created instance is
24361 /// anonymous.
union_decl(const environment & env,const string & name,size_t size_in_bits,const location & locus,visibility vis,member_types & mbr_types,data_members & data_mbrs,member_functions & member_fns,bool is_anonymous)24362 union_decl::union_decl(const environment& env, const string& name,
24363 size_t size_in_bits, const location& locus,
24364 visibility vis, member_types& mbr_types,
24365 data_members& data_mbrs, member_functions& member_fns,
24366 bool is_anonymous)
24367 : type_or_decl_base(env,
24368 UNION_TYPE
24369 | ABSTRACT_TYPE_BASE
24370 | ABSTRACT_DECL_BASE),
24371 decl_base(env, name, locus,
24372 // If the class is anonymous then by default it won't
24373 // have a linkage name. Also, the anonymous class does
24374 // have an internal-only unique name that is generally
24375 // not taken into account when comparing classes; such a
24376 // unique internal-only name, when used as a linkage
24377 // name might introduce spurious comparison false
24378 // negatives.
24379 /*linkage_name=*/is_anonymous ? string() : name,
24380 vis),
24381 type_base(env, size_in_bits, 0),
24382 class_or_union(env, name, size_in_bits, 0,
24383 locus, vis, mbr_types, data_mbrs, member_fns)
24384 {
24385 runtime_type_instance(this);
24386 set_is_anonymous(is_anonymous);
24387 }
24388
24389 /// Constructor for the @ref union_decl type.
24390 ///
24391 /// @param env the @ref environment we are operating from.
24392 ///
24393 /// @param name the name of the union type.
24394 ///
24395 /// @param size_in_bits the size of the union, in bits.
24396 ///
24397 /// @param locus the location of the type.
24398 ///
24399 /// @param vis the visibility of instances of @ref union_decl.
union_decl(const environment & env,const string & name,size_t size_in_bits,const location & locus,visibility vis)24400 union_decl::union_decl(const environment& env, const string& name,
24401 size_t size_in_bits, const location& locus,
24402 visibility vis)
24403 : type_or_decl_base(env,
24404 UNION_TYPE
24405 | ABSTRACT_TYPE_BASE
24406 | ABSTRACT_DECL_BASE
24407 | ABSTRACT_SCOPE_TYPE_DECL
24408 | ABSTRACT_SCOPE_DECL),
24409 decl_base(env, name, locus, name, vis),
24410 type_base(env, size_in_bits, 0),
24411 class_or_union(env, name, size_in_bits,
24412 0, locus, vis)
24413 {
24414 runtime_type_instance(this);
24415 }
24416
24417 /// Constructor for the @ref union_decl type.
24418 ///
24419 /// @param env the @ref environment we are operating from.
24420 ///
24421 /// @param name the name of the union type.
24422 ///
24423 /// @param size_in_bits the size of the union, in bits.
24424 ///
24425 /// @param locus the location of the type.
24426 ///
24427 /// @param vis the visibility of instances of @ref union_decl.
24428 ///
24429 /// @param is_anonymous whether the newly created instance is
24430 /// anonymous.
union_decl(const environment & env,const string & name,size_t size_in_bits,const location & locus,visibility vis,bool is_anonymous)24431 union_decl::union_decl(const environment& env, const string& name,
24432 size_t size_in_bits, const location& locus,
24433 visibility vis, bool is_anonymous)
24434 : type_or_decl_base(env,
24435 UNION_TYPE
24436 | ABSTRACT_TYPE_BASE
24437 | ABSTRACT_DECL_BASE
24438 | ABSTRACT_SCOPE_TYPE_DECL
24439 | ABSTRACT_SCOPE_DECL),
24440 decl_base(env, name, locus,
24441 // If the class is anonymous then by default it won't
24442 // have a linkage name. Also, the anonymous class does
24443 // have an internal-only unique name that is generally
24444 // not taken into account when comparing classes; such a
24445 // unique internal-only name, when used as a linkage
24446 // name might introduce spurious comparison false
24447 // negatives.
24448 /*linkage_name=*/is_anonymous ? string() : name,
24449 vis),
24450 type_base(env, size_in_bits, 0),
24451 class_or_union(env, name, size_in_bits,
24452 0, locus, vis)
24453 {
24454 runtime_type_instance(this);
24455 set_is_anonymous(is_anonymous);
24456 }
24457
24458 /// Constructor for the @ref union_decl type.
24459 ///
24460 /// @param env the @ref environment we are operating from.
24461 ///
24462 /// @param name the name of the union type.
24463 ///
24464 /// @param is_declaration_only a boolean saying whether the instance
24465 /// represents a declaration only, or not.
union_decl(const environment & env,const string & name,bool is_declaration_only)24466 union_decl::union_decl(const environment& env,
24467 const string& name,
24468 bool is_declaration_only)
24469 : type_or_decl_base(env,
24470 UNION_TYPE
24471 | ABSTRACT_TYPE_BASE
24472 | ABSTRACT_DECL_BASE
24473 | ABSTRACT_SCOPE_TYPE_DECL
24474 | ABSTRACT_SCOPE_DECL),
24475 decl_base(env, name, location(), name),
24476 type_base(env, 0, 0),
24477 class_or_union(env, name, is_declaration_only)
24478 {
24479 runtime_type_instance(this);
24480 }
24481
24482 /// Getter of the pretty representation of the current instance of
24483 /// @ref union_decl.
24484 ///
24485 /// @param internal set to true if the call is intended to get a
24486 /// representation of the decl (or type) for the purpose of canonical
24487 /// type comparison. This is mainly used in the function
24488 /// type_base::get_canonical_type_for().
24489 ///
24490 /// In other words if the argument for this parameter is true then the
24491 /// call is meant for internal use (for technical use inside the
24492 /// library itself), false otherwise. If you don't know what this is
24493 /// for, then set it to false.
24494 ///
24495 /// @param qualified_name if true, names emitted in the pretty
24496 /// representation are fully qualified.
24497 ///
24498 /// @return the pretty representaion for a union_decl.
24499 string
get_pretty_representation(bool internal,bool qualified_name) const24500 union_decl::get_pretty_representation(bool internal,
24501 bool qualified_name) const
24502 {
24503 string repr;
24504 if (get_is_anonymous())
24505 {
24506 if (internal && !get_name().empty())
24507 repr = string("union ") +
24508 get_type_name(this, qualified_name, /*internal=*/true);
24509 else
24510 repr = get_class_or_union_flat_representation(this, "",
24511 /*one_line=*/true,
24512 internal);
24513 }
24514 else
24515 {
24516 repr = "union ";
24517 if (qualified_name)
24518 repr += get_qualified_name(internal);
24519 else
24520 repr += get_name();
24521 }
24522
24523 return repr;
24524 }
24525
24526 /// Comparison operator for @ref union_decl.
24527 ///
24528 /// @param other the instance of @ref union_decl to compare against.
24529 ///
24530 /// @return true iff the current instance of @ref union_decl equals @p
24531 /// other.
24532 bool
operator ==(const decl_base & other) const24533 union_decl::operator==(const decl_base& other) const
24534 {
24535 const union_decl* op = dynamic_cast<const union_decl*>(&other);
24536 if (!op)
24537 return false;
24538 return try_canonical_compare(this, op);
24539 }
24540
24541 /// Equality operator for union_decl.
24542 ///
24543 /// Re-uses the equality operator that takes a decl_base.
24544 ///
24545 /// @param other the other union_decl to compare against.
24546 ///
24547 /// @return true iff the current instance equals the other one.
24548 bool
operator ==(const type_base & other) const24549 union_decl::operator==(const type_base& other) const
24550 {
24551 const decl_base *o = dynamic_cast<const decl_base*>(&other);
24552 if (!o)
24553 return false;
24554 return *this == *o;
24555 }
24556
24557 /// Comparison operator for @ref union_decl.
24558 ///
24559 /// @param other the instance of @ref union_decl to compare against.
24560 ///
24561 /// @return true iff the current instance of @ref union_decl equals @p
24562 /// other.
24563 bool
operator ==(const union_decl & other) const24564 union_decl::operator==(const union_decl& other) const
24565 {
24566 const decl_base& o = other;
24567 return *this == o;
24568 }
24569
24570 /// This implements the ir_traversable_base::traverse pure virtual
24571 /// function.
24572 ///
24573 /// @param v the visitor used on the current instance and on its
24574 /// members.
24575 ///
24576 /// @return true if the entire IR node tree got traversed, false
24577 /// otherwise.
24578 bool
traverse(ir_node_visitor & v)24579 union_decl::traverse(ir_node_visitor& v)
24580 {
24581 if (v.type_node_has_been_visited(this))
24582 return true;
24583
24584 if (visiting())
24585 return true;
24586
24587 if (v.visit_begin(this))
24588 {
24589 visiting(true);
24590 bool stop = false;
24591
24592 if (!stop)
24593 for (data_members::const_iterator i = get_data_members().begin();
24594 i != get_data_members().end();
24595 ++i)
24596 if (!(*i)->traverse(v))
24597 {
24598 stop = true;
24599 break;
24600 }
24601
24602 if (!stop)
24603 for (member_functions::const_iterator i= get_member_functions().begin();
24604 i != get_member_functions().end();
24605 ++i)
24606 if (!(*i)->traverse(v))
24607 {
24608 stop = true;
24609 break;
24610 }
24611
24612 if (!stop)
24613 for (member_types::const_iterator i = get_member_types().begin();
24614 i != get_member_types().end();
24615 ++i)
24616 if (!(*i)->traverse(v))
24617 {
24618 stop = true;
24619 break;
24620 }
24621
24622 if (!stop)
24623 for (member_function_templates::const_iterator i =
24624 get_member_function_templates().begin();
24625 i != get_member_function_templates().end();
24626 ++i)
24627 if (!(*i)->traverse(v))
24628 {
24629 stop = true;
24630 break;
24631 }
24632
24633 if (!stop)
24634 for (member_class_templates::const_iterator i =
24635 get_member_class_templates().begin();
24636 i != get_member_class_templates().end();
24637 ++i)
24638 if (!(*i)->traverse(v))
24639 {
24640 stop = true;
24641 break;
24642 }
24643 visiting(false);
24644 }
24645
24646 bool result = v.visit_end(this);
24647 v.mark_type_node_as_visited(this);
24648 return result;
24649 }
24650
24651 /// Destructor of the @ref union_decl type.
~union_decl()24652 union_decl::~union_decl()
24653 {}
24654
24655 /// Compares two instances of @ref union_decl.
24656 ///
24657 /// If the two intances are different, set a bitfield to give some
24658 /// insight about the kind of differences there are.
24659 ///
24660 /// @param l the first artifact of the comparison.
24661 ///
24662 /// @param r the second artifact of the comparison.
24663 ///
24664 /// @param k a pointer to a bitfield that gives information about the
24665 /// kind of changes there are between @p l and @p r. This one is set
24666 /// iff @p k is non-null and the function returns false.
24667 ///
24668 /// Please note that setting k to a non-null value does have a
24669 /// negative performance impact because even if @p l and @p r are not
24670 /// equal, the function keeps up the comparison in order to determine
24671 /// the different kinds of ways in which they are different.
24672 ///
24673 /// @return true if @p l equals @p r, false otherwise.
24674 bool
equals(const union_decl & l,const union_decl & r,change_kind * k)24675 equals(const union_decl& l, const union_decl& r, change_kind* k)
24676 {
24677 {
24678 // First of all, let's see if these two types haven't already been
24679 // compared. If so, and if the result of the comparison has been
24680 // cached, let's just re-use it, rather than comparing them all
24681 // over again.
24682 bool result = false;
24683 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
24684 return result;
24685 }
24686
24687 #define RETURN(value) \
24688 return return_comparison_result(l, r, value);
24689
24690 bool result = equals(static_cast<const class_or_union&>(l),
24691 static_cast<const class_or_union&>(r),
24692 k);
24693
24694 mark_types_as_being_compared(l, r);
24695
24696 // We are done comparing these two types and we have a full
24697 // understanding of how they might be different, if they are. Let's
24698 // cache the result of this comparison -- in case we are asked in a
24699 // very near future to compare them again.
24700 //
24701 // TODO: If further profiling shows its necessity, maybe we should
24702 // perform this caching also on the earlier return points of this
24703 // function. That would basically mean to redefine the RETURN macro
24704 // to make it perform this caching for us.
24705 l.get_environment().priv_->cache_type_comparison_result(l, r, result);
24706
24707 RETURN(result);
24708 }
24709
24710 /// Copy a method of a @ref union_decl into a new @ref
24711 /// union_decl.
24712 ///
24713 /// @param t the @ref union_decl into which the method is to be copied.
24714 ///
24715 /// @param method the method to copy into @p t.
24716 ///
24717 /// @return the resulting newly copied method.
24718 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl_sptr & f)24719 copy_member_function(const union_decl_sptr& union_type,
24720 const method_decl_sptr& f)
24721 {return copy_member_function(union_type, f.get());}
24722
24723 /// Copy a method of a @ref union_decl into a new @ref
24724 /// union_decl.
24725 ///
24726 /// @param t the @ref union_decl into which the method is to be copied.
24727 ///
24728 /// @param method the method to copy into @p t.
24729 ///
24730 /// @return the resulting newly copied method.
24731 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl * f)24732 copy_member_function(const union_decl_sptr& union_type,
24733 const method_decl* f)
24734 {
24735 const class_or_union_sptr t = union_type;
24736 return copy_member_function(t, f);
24737 }
24738
24739 /// Turn equality of shared_ptr of union_decl into a deep equality;
24740 /// that is, make it compare the pointed to objects too.
24741 ///
24742 /// @param l the left-hand-side operand of the operator
24743 ///
24744 /// @param r the right-hand-side operand of the operator.
24745 ///
24746 /// @return true iff @p l equals @p r.
24747 bool
operator ==(const union_decl_sptr & l,const union_decl_sptr & r)24748 operator==(const union_decl_sptr& l, const union_decl_sptr& r)
24749 {
24750 if (l.get() == r.get())
24751 return true;
24752 if (!!l != !!r)
24753 return false;
24754
24755 return *l == *r;
24756 }
24757
24758 /// Turn inequality of shared_ptr of union_decl into a deep equality;
24759 /// that is, make it compare the pointed to objects too.
24760 ///
24761 /// @param l the left-hand-side operand of the operator
24762 ///
24763 /// @param r the right-hand-side operand of the operator.
24764 ///
24765 /// @return true iff @p l is different from @p r.
24766 bool
operator !=(const union_decl_sptr & l,const union_decl_sptr & r)24767 operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
24768 {return !operator==(l, r);}
24769 // </union_decl>
24770
24771 // <template_decl stuff>
24772
24773 /// Data type of the private data of the @template_decl type.
24774 class template_decl::priv
24775 {
24776 friend class template_decl;
24777
24778 std::list<template_parameter_sptr> parms_;
24779 public:
24780
priv()24781 priv()
24782 {}
24783 }; // end class template_decl::priv
24784
24785 /// Add a new template parameter to the current instance of @ref
24786 /// template_decl.
24787 ///
24788 /// @param p the new template parameter to add.
24789 void
add_template_parameter(const template_parameter_sptr p)24790 template_decl::add_template_parameter(const template_parameter_sptr p)
24791 {priv_->parms_.push_back(p);}
24792
24793 /// Get the list of template parameters of the current instance of
24794 /// @ref template_decl.
24795 ///
24796 /// @return the list of template parameters.
24797 const std::list<template_parameter_sptr>&
get_template_parameters() const24798 template_decl::get_template_parameters() const
24799 {return priv_->parms_;}
24800
24801 /// Constructor.
24802 ///
24803 /// @param env the environment we are operating from.
24804 ///
24805 /// @param name the name of the template decl.
24806 ///
24807 /// @param locus the source location where the template declaration is
24808 /// defined.
24809 ///
24810 /// @param vis the visibility of the template declaration.
template_decl(const environment & env,const string & name,const location & locus,visibility vis)24811 template_decl::template_decl(const environment& env,
24812 const string& name,
24813 const location& locus,
24814 visibility vis)
24815 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
24816 decl_base(env, name, locus, /*mangled_name=*/"", vis),
24817 priv_(new priv)
24818 {
24819 runtime_type_instance(this);
24820 }
24821
24822 /// Destructor.
~template_decl()24823 template_decl::~template_decl()
24824 {}
24825
24826 /// Equality operator.
24827 ///
24828 /// @param o the other instance to compare against.
24829 ///
24830 /// @return true iff @p equals the current instance.
24831 bool
operator ==(const template_decl & o) const24832 template_decl::operator==(const template_decl& o) const
24833 {
24834 try
24835 {
24836 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
24837 for (t0 = get_template_parameters().begin(),
24838 t1 = o.get_template_parameters().begin();
24839 (t0 != get_template_parameters().end()
24840 && t1 != o.get_template_parameters().end());
24841 ++t0, ++t1)
24842 {
24843 if (**t0 != **t1)
24844 return false;
24845 }
24846
24847 if (t0 != get_template_parameters().end()
24848 || t1 != o.get_template_parameters().end())
24849 return false;
24850
24851 return true;
24852 }
24853 catch(...)
24854 {return false;}
24855 }
24856
24857 // </template_decl stuff>
24858
24859 //<template_parameter>
24860
24861 /// The type of the private data of the @ref template_parameter type.
24862 class template_parameter::priv
24863 {
24864 friend class template_parameter;
24865
24866 unsigned index_;
24867 template_decl_wptr template_decl_;
24868 mutable bool hashing_started_;
24869 mutable bool comparison_started_;
24870
24871 priv();
24872
24873 public:
24874
priv(unsigned index,template_decl_sptr enclosing_template_decl)24875 priv(unsigned index, template_decl_sptr enclosing_template_decl)
24876 : index_(index),
24877 template_decl_(enclosing_template_decl),
24878 hashing_started_(),
24879 comparison_started_()
24880 {}
24881 }; // end class template_parameter::priv
24882
template_parameter(unsigned index,template_decl_sptr enclosing_template)24883 template_parameter::template_parameter(unsigned index,
24884 template_decl_sptr enclosing_template)
24885 : priv_(new priv(index, enclosing_template))
24886 {}
24887
24888 unsigned
get_index() const24889 template_parameter::get_index() const
24890 {return priv_->index_;}
24891
24892 const template_decl_sptr
get_enclosing_template_decl() const24893 template_parameter::get_enclosing_template_decl() const
24894 {return priv_->template_decl_.lock();}
24895
24896 bool
get_hashing_has_started() const24897 template_parameter::get_hashing_has_started() const
24898 {return priv_->hashing_started_;}
24899
24900 void
set_hashing_has_started(bool f) const24901 template_parameter::set_hashing_has_started(bool f) const
24902 {priv_->hashing_started_ = f;}
24903
24904 bool
operator ==(const template_parameter & o) const24905 template_parameter::operator==(const template_parameter& o) const
24906 {
24907 if (get_index() != o.get_index())
24908 return false;
24909
24910 if (priv_->comparison_started_)
24911 return true;
24912
24913 bool result = false;
24914
24915 // Avoid inifite loops due to the fact that comparison the enclosing
24916 // template decl might lead to comparing this very same template
24917 // parameter with another one ...
24918 priv_->comparison_started_ = true;
24919
24920 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
24921 ;
24922 else if (get_enclosing_template_decl()
24923 && (*get_enclosing_template_decl()
24924 != *o.get_enclosing_template_decl()))
24925 ;
24926 else
24927 result = true;
24928
24929 priv_->comparison_started_ = false;
24930
24931 return result;
24932 }
24933
24934 /// Inequality operator.
24935 ///
24936 /// @param other the other instance to compare against.
24937 ///
24938 /// @return true iff the other instance is different from the current
24939 /// one.
24940 bool
operator !=(const template_parameter & other) const24941 template_parameter::operator!=(const template_parameter& other) const
24942 {return !operator==(other);}
24943
24944 /// Destructor.
~template_parameter()24945 template_parameter::~template_parameter()
24946 {}
24947
24948 /// The type of the private data of the @ref type_tparameter type.
24949 class type_tparameter::priv
24950 {
24951 friend class type_tparameter;
24952 }; // end class type_tparameter::priv
24953
24954 /// Constructor of the @ref type_tparameter type.
24955 ///
24956 /// @param index the index the type template parameter.
24957 ///
24958 /// @param enclosing_tdecl the enclosing template declaration.
24959 ///
24960 /// @param name the name of the template parameter.
24961 ///
24962 /// @param locus the location of the declaration of this type template
24963 /// parameter.
type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)24964 type_tparameter::type_tparameter(unsigned index,
24965 template_decl_sptr enclosing_tdecl,
24966 const string& name,
24967 const location& locus)
24968 : type_or_decl_base(enclosing_tdecl->get_environment(),
24969 ABSTRACT_DECL_BASE
24970 | ABSTRACT_TYPE_BASE
24971 | BASIC_TYPE),
24972 decl_base(enclosing_tdecl->get_environment(), name, locus),
24973 type_base(enclosing_tdecl->get_environment(), 0, 0),
24974 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
24975 template_parameter(index, enclosing_tdecl),
24976 priv_(new priv)
24977 {
24978 runtime_type_instance(this);
24979 }
24980
24981 bool
operator ==(const type_base & other) const24982 type_tparameter::operator==(const type_base& other) const
24983 {
24984 if (!type_decl::operator==(other))
24985 return false;
24986
24987 try
24988 {
24989 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
24990 return template_parameter::operator==(o);
24991 }
24992 catch (...)
24993 {return false;}
24994 }
24995
24996 bool
operator ==(const template_parameter & other) const24997 type_tparameter::operator==(const template_parameter& other) const
24998 {
24999 try
25000 {
25001 const type_base& o = dynamic_cast<const type_base&>(other);
25002 return *this == o;
25003 }
25004 catch(...)
25005 {return false;}
25006 }
25007
25008 bool
operator ==(const type_tparameter & other) const25009 type_tparameter::operator==(const type_tparameter& other) const
25010 {return *this == static_cast<const type_base&>(other);}
25011
~type_tparameter()25012 type_tparameter::~type_tparameter()
25013 {}
25014
25015 /// The type of the private data of the @ref non_type_tparameter type.
25016 class non_type_tparameter::priv
25017 {
25018 friend class non_type_tparameter;
25019
25020 type_base_wptr type_;
25021
25022 priv();
25023
25024 public:
25025
priv(type_base_sptr type)25026 priv(type_base_sptr type)
25027 : type_(type)
25028 {}
25029 }; // end class non_type_tparameter::priv
25030
25031 /// The constructor for the @ref non_type_tparameter type.
25032 ///
25033 /// @param index the index of the template parameter.
25034 ///
25035 /// @param enclosing_tdecl the enclosing template declaration that
25036 /// holds this parameter parameter.
25037 ///
25038 /// @param name the name of the template parameter.
25039 ///
25040 /// @param type the type of the template parameter.
25041 ///
25042 /// @param locus the location of the declaration of this template
25043 /// parameter.
non_type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,type_base_sptr type,const location & locus)25044 non_type_tparameter::non_type_tparameter(unsigned index,
25045 template_decl_sptr enclosing_tdecl,
25046 const string& name,
25047 type_base_sptr type,
25048 const location& locus)
25049 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
25050 decl_base(type->get_environment(), name, locus, ""),
25051 template_parameter(index, enclosing_tdecl),
25052 priv_(new priv(type))
25053 {
25054 runtime_type_instance(this);
25055 }
25056
25057 /// Getter for the type of the template parameter.
25058 ///
25059 /// @return the type of the template parameter.
25060 const type_base_sptr
get_type() const25061 non_type_tparameter::get_type() const
25062 {return priv_->type_.lock();}
25063
25064 /// Get the hash value of the current instance.
25065 ///
25066 /// @return the hash value.
25067 size_t
get_hash() const25068 non_type_tparameter::get_hash() const
25069 {
25070 non_type_tparameter::hash hash_tparm;
25071 return hash_tparm(this);
25072 }
25073
25074 bool
operator ==(const decl_base & other) const25075 non_type_tparameter::operator==(const decl_base& other) const
25076 {
25077 if (!decl_base::operator==(other))
25078 return false;
25079
25080 try
25081 {
25082 const non_type_tparameter& o =
25083 dynamic_cast<const non_type_tparameter&>(other);
25084 return (template_parameter::operator==(o)
25085 && get_type() == o.get_type());
25086 }
25087 catch(...)
25088 {return false;}
25089 }
25090
25091 bool
operator ==(const template_parameter & other) const25092 non_type_tparameter::operator==(const template_parameter& other) const
25093 {
25094 try
25095 {
25096 const decl_base& o = dynamic_cast<const decl_base&>(other);
25097 return *this == o;
25098 }
25099 catch(...)
25100 {return false;}
25101 }
25102
~non_type_tparameter()25103 non_type_tparameter::~non_type_tparameter()
25104 {}
25105
25106 // <template_tparameter stuff>
25107
25108 /// Type of the private data of the @ref template_tparameter type.
25109 class template_tparameter::priv
25110 {
25111 }; //end class template_tparameter::priv
25112
25113 /// Constructor for the @ref template_tparameter.
25114 ///
25115 /// @param index the index of the template parameter.
25116 ///
25117 /// @param enclosing_tdecl the enclosing template declaration.
25118 ///
25119 /// @param name the name of the template parameter.
25120 ///
25121 /// @param locus the location of the declaration of the template
25122 /// parameter.
template_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)25123 template_tparameter::template_tparameter(unsigned index,
25124 template_decl_sptr enclosing_tdecl,
25125 const string& name,
25126 const location& locus)
25127 : type_or_decl_base(enclosing_tdecl->get_environment(),
25128 ABSTRACT_DECL_BASE
25129 | ABSTRACT_TYPE_BASE
25130 | BASIC_TYPE),
25131 decl_base(enclosing_tdecl->get_environment(), name, locus),
25132 type_base(enclosing_tdecl->get_environment(), 0, 0),
25133 type_decl(enclosing_tdecl->get_environment(), name,
25134 0, 0, locus, name, VISIBILITY_DEFAULT),
25135 type_tparameter(index, enclosing_tdecl, name, locus),
25136 template_decl(enclosing_tdecl->get_environment(), name, locus),
25137 priv_(new priv)
25138 {
25139 runtime_type_instance(this);
25140 }
25141
25142 bool
operator ==(const type_base & other) const25143 template_tparameter::operator==(const type_base& other) const
25144 {
25145 try
25146 {
25147 const template_tparameter& o =
25148 dynamic_cast<const template_tparameter&>(other);
25149 return (type_tparameter::operator==(o)
25150 && template_decl::operator==(o));
25151 }
25152 catch(...)
25153 {return false;}
25154 }
25155
25156 bool
operator ==(const template_parameter & o) const25157 template_tparameter::operator==(const template_parameter& o) const
25158 {
25159 try
25160 {
25161 const template_tparameter& other =
25162 dynamic_cast<const template_tparameter&>(o);
25163 return *this == static_cast<const type_base&>(other);
25164 }
25165 catch(...)
25166 {return false;}
25167 }
25168
25169 bool
operator ==(const template_decl & o) const25170 template_tparameter::operator==(const template_decl& o) const
25171 {
25172 try
25173 {
25174 const template_tparameter& other =
25175 dynamic_cast<const template_tparameter&>(o);
25176 return type_base::operator==(other);
25177 }
25178 catch(...)
25179 {return false;}
25180 }
25181
~template_tparameter()25182 template_tparameter::~template_tparameter()
25183 {}
25184
25185 // </template_tparameter stuff>
25186
25187 // <type_composition stuff>
25188
25189 /// The type of the private data of the @ref type_composition type.
25190 class type_composition::priv
25191 {
25192 friend class type_composition;
25193
25194 type_base_wptr type_;
25195
25196 // Forbid this.
25197 priv();
25198
25199 public:
25200
priv(type_base_wptr type)25201 priv(type_base_wptr type)
25202 : type_(type)
25203 {}
25204 }; //end class type_composition::priv
25205
25206 /// Constructor for the @ref type_composition type.
25207 ///
25208 /// @param index the index of the template type composition.
25209 ///
25210 /// @param tdecl the enclosing template parameter that owns the
25211 /// composition.
25212 ///
25213 /// @param t the resulting type.
type_composition(unsigned index,template_decl_sptr tdecl,type_base_sptr t)25214 type_composition::type_composition(unsigned index,
25215 template_decl_sptr tdecl,
25216 type_base_sptr t)
25217 : type_or_decl_base(tdecl->get_environment(),
25218 ABSTRACT_DECL_BASE),
25219 decl_base(tdecl->get_environment(), "", location()),
25220 template_parameter(index, tdecl),
25221 priv_(new priv(t))
25222 {
25223 runtime_type_instance(this);
25224 }
25225
25226 /// Getter for the resulting composed type.
25227 ///
25228 /// @return the composed type.
25229 const type_base_sptr
get_composed_type() const25230 type_composition::get_composed_type() const
25231 {return priv_->type_.lock();}
25232
25233 /// Setter for the resulting composed type.
25234 ///
25235 /// @param t the composed type.
25236 void
set_composed_type(type_base_sptr t)25237 type_composition::set_composed_type(type_base_sptr t)
25238 {priv_->type_ = t;}
25239
25240 /// Get the hash value for the current instance.
25241 ///
25242 /// @return the hash value.
25243 size_t
get_hash() const25244 type_composition::get_hash() const
25245 {
25246 type_composition::hash hash_type_composition;
25247 return hash_type_composition(this);
25248 }
25249
~type_composition()25250 type_composition::~type_composition()
25251 {}
25252
25253 // </type_composition stuff>
25254
25255 //</template_parameter stuff>
25256
25257 // <function_template>
25258
25259 class function_tdecl::priv
25260 {
25261 friend class function_tdecl;
25262
25263 function_decl_sptr pattern_;
25264 binding binding_;
25265
25266 priv();
25267
25268 public:
25269
priv(function_decl_sptr pattern,binding bind)25270 priv(function_decl_sptr pattern, binding bind)
25271 : pattern_(pattern), binding_(bind)
25272 {}
25273
priv(binding bind)25274 priv(binding bind)
25275 : binding_(bind)
25276 {}
25277 }; // end class function_tdecl::priv
25278
25279 /// Constructor for a function template declaration.
25280 ///
25281 /// @param env the environment we are operating from.
25282 ///
25283 /// @param locus the location of the declaration.
25284 ///
25285 /// @param vis the visibility of the declaration. This is the
25286 /// visibility the functions instantiated from this template are going
25287 /// to have.
25288 ///
25289 /// @param bind the binding of the declaration. This is the binding
25290 /// the functions instantiated from this template are going to have.
function_tdecl(const environment & env,const location & locus,visibility vis,binding bind)25291 function_tdecl::function_tdecl(const environment& env,
25292 const location& locus,
25293 visibility vis,
25294 binding bind)
25295 : type_or_decl_base(env,
25296 ABSTRACT_DECL_BASE
25297 | TEMPLATE_DECL
25298 | ABSTRACT_SCOPE_DECL),
25299 decl_base(env, "", locus, "", vis),
25300 template_decl(env, "", locus, vis),
25301 scope_decl(env, "", locus),
25302 priv_(new priv(bind))
25303 {
25304 runtime_type_instance(this);
25305 }
25306
25307 /// Constructor for a function template declaration.
25308 ///
25309 /// @param pattern the pattern of the template.
25310 ///
25311 /// @param locus the location of the declaration.
25312 ///
25313 /// @param vis the visibility of the declaration. This is the
25314 /// visibility the functions instantiated from this template are going
25315 /// to have.
25316 ///
25317 /// @param bind the binding of the declaration. This is the binding
25318 /// the functions instantiated from this template are going to have.
function_tdecl(function_decl_sptr pattern,const location & locus,visibility vis,binding bind)25319 function_tdecl::function_tdecl(function_decl_sptr pattern,
25320 const location& locus,
25321 visibility vis,
25322 binding bind)
25323 : type_or_decl_base(pattern->get_environment(),
25324 ABSTRACT_DECL_BASE
25325 | TEMPLATE_DECL
25326 | ABSTRACT_SCOPE_DECL),
25327 decl_base(pattern->get_environment(), pattern->get_name(), locus,
25328 pattern->get_name(), vis),
25329 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
25330 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
25331 priv_(new priv(pattern, bind))
25332 {
25333 runtime_type_instance(this);
25334 }
25335
25336 /// Set a new pattern to the function template.
25337 ///
25338 /// @param p the new pattern.
25339 void
set_pattern(function_decl_sptr p)25340 function_tdecl::set_pattern(function_decl_sptr p)
25341 {
25342 priv_->pattern_ = p;
25343 add_decl_to_scope(p, this);
25344 set_name(p->get_name());
25345 }
25346
25347 /// Get the pattern of the function template.
25348 ///
25349 /// @return the pattern.
25350 function_decl_sptr
get_pattern() const25351 function_tdecl::get_pattern() const
25352 {return priv_->pattern_;}
25353
25354 /// Get the binding of the function template.
25355 ///
25356 /// @return the binding
25357 decl_base::binding
get_binding() const25358 function_tdecl::get_binding() const
25359 {return priv_->binding_;}
25360
25361 /// Comparison operator for the @ref function_tdecl type.
25362 ///
25363 /// @param other the other instance of @ref function_tdecl to compare against.
25364 ///
25365 /// @return true iff the two instance are equal.
25366 bool
operator ==(const decl_base & other) const25367 function_tdecl::operator==(const decl_base& other) const
25368 {
25369 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
25370 if (o)
25371 return *this == *o;
25372 return false;
25373 }
25374
25375 /// Comparison operator for the @ref function_tdecl type.
25376 ///
25377 /// @param other the other instance of @ref function_tdecl to compare against.
25378 ///
25379 /// @return true iff the two instance are equal.
25380 bool
operator ==(const template_decl & other) const25381 function_tdecl::operator==(const template_decl& other) const
25382 {
25383 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
25384 if (o)
25385 return *this == *o;
25386 return false;
25387 }
25388
25389 /// Comparison operator for the @ref function_tdecl type.
25390 ///
25391 /// @param o the other instance of @ref function_tdecl to compare against.
25392 ///
25393 /// @return true iff the two instance are equal.
25394 bool
operator ==(const function_tdecl & o) const25395 function_tdecl::operator==(const function_tdecl& o) const
25396 {
25397 if (!(get_binding() == o.get_binding()
25398 && template_decl::operator==(o)
25399 && scope_decl::operator==(o)
25400 && !!get_pattern() == !!o.get_pattern()))
25401 return false;
25402
25403 if (get_pattern())
25404 return (*get_pattern() == *o.get_pattern());
25405
25406 return true;
25407 }
25408
25409 /// This implements the ir_traversable_base::traverse pure virtual
25410 /// function.
25411 ///
25412 /// @param v the visitor used on the current instance and on the
25413 /// function pattern of the template.
25414 ///
25415 /// @return true if the entire IR node tree got traversed, false
25416 /// otherwise.
25417 bool
traverse(ir_node_visitor & v)25418 function_tdecl::traverse(ir_node_visitor&v)
25419 {
25420 if (visiting())
25421 return true;
25422
25423 if (!v.visit_begin(this))
25424 {
25425 visiting(true);
25426 if (get_pattern())
25427 get_pattern()->traverse(v);
25428 visiting(false);
25429 }
25430 return v.visit_end(this);
25431 }
25432
~function_tdecl()25433 function_tdecl::~function_tdecl()
25434 {}
25435
25436 // </function_template>
25437
25438 // <class template>
25439
25440 /// Type of the private data of the the @ref class_tdecl type.
25441 class class_tdecl::priv
25442 {
25443 friend class class_tdecl;
25444 class_decl_sptr pattern_;
25445
25446 public:
25447
priv()25448 priv()
25449 {}
25450
priv(class_decl_sptr pattern)25451 priv(class_decl_sptr pattern)
25452 : pattern_(pattern)
25453 {}
25454 }; // end class class_tdecl::priv
25455
25456 /// Constructor for the @ref class_tdecl type.
25457 ///
25458 /// @param env the environment we are operating from.
25459 ///
25460 /// @param locus the location of the declaration of the class_tdecl
25461 /// type.
25462 ///
25463 /// @param vis the visibility of the instance of class instantiated
25464 /// from this template.
class_tdecl(const environment & env,const location & locus,visibility vis)25465 class_tdecl::class_tdecl(const environment& env,
25466 const location& locus,
25467 visibility vis)
25468 : type_or_decl_base(env,
25469 ABSTRACT_DECL_BASE
25470 | TEMPLATE_DECL
25471 | ABSTRACT_SCOPE_DECL),
25472 decl_base(env, "", locus, "", vis),
25473 template_decl(env, "", locus, vis),
25474 scope_decl(env, "", locus),
25475 priv_(new priv)
25476 {
25477 runtime_type_instance(this);
25478 }
25479
25480 /// Constructor for the @ref class_tdecl type.
25481 ///
25482 /// @param pattern The details of the class template. This must NOT be a
25483 /// null pointer. If you really this to be null, please use the
25484 /// constructor above instead.
25485 ///
25486 /// @param locus the source location of the declaration of the type.
25487 ///
25488 /// @param vis the visibility of the instances of class instantiated
25489 /// from this template.
class_tdecl(class_decl_sptr pattern,const location & locus,visibility vis)25490 class_tdecl::class_tdecl(class_decl_sptr pattern,
25491 const location& locus,
25492 visibility vis)
25493 : type_or_decl_base(pattern->get_environment(),
25494 ABSTRACT_DECL_BASE
25495 | TEMPLATE_DECL
25496 | ABSTRACT_SCOPE_DECL),
25497 decl_base(pattern->get_environment(), pattern->get_name(),
25498 locus, pattern->get_name(), vis),
25499 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
25500 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
25501 priv_(new priv(pattern))
25502 {
25503 runtime_type_instance(this);
25504 }
25505
25506 /// Setter of the pattern of the template.
25507 ///
25508 /// @param p the new template.
25509 void
set_pattern(class_decl_sptr p)25510 class_tdecl::set_pattern(class_decl_sptr p)
25511 {
25512 priv_->pattern_ = p;
25513 add_decl_to_scope(p, this);
25514 set_name(p->get_name());
25515 }
25516
25517 /// Getter of the pattern of the template.
25518 ///
25519 /// @return p the new template.
25520 class_decl_sptr
get_pattern() const25521 class_tdecl::get_pattern() const
25522 {return priv_->pattern_;}
25523
25524 bool
operator ==(const decl_base & other) const25525 class_tdecl::operator==(const decl_base& other) const
25526 {
25527 try
25528 {
25529 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
25530
25531 if (!(template_decl::operator==(o)
25532 && scope_decl::operator==(o)
25533 && !!get_pattern() == !!o.get_pattern()))
25534 return false;
25535
25536 if (!get_pattern() || !o.get_pattern())
25537 return true;
25538
25539 return get_pattern()->decl_base::operator==(*o.get_pattern());
25540 }
25541 catch(...) {}
25542 return false;
25543 }
25544
25545 bool
operator ==(const template_decl & other) const25546 class_tdecl::operator==(const template_decl& other) const
25547 {
25548 try
25549 {
25550 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
25551 return *this == static_cast<const decl_base&>(o);
25552 }
25553 catch(...)
25554 {return false;}
25555 }
25556
25557 bool
operator ==(const class_tdecl & o) const25558 class_tdecl::operator==(const class_tdecl& o) const
25559 {return *this == static_cast<const decl_base&>(o);}
25560
25561 /// This implements the ir_traversable_base::traverse pure virtual
25562 /// function.
25563 ///
25564 /// @param v the visitor used on the current instance and on the class
25565 /// pattern of the template.
25566 ///
25567 /// @return true if the entire IR node tree got traversed, false
25568 /// otherwise.
25569 bool
traverse(ir_node_visitor & v)25570 class_tdecl::traverse(ir_node_visitor&v)
25571 {
25572 if (visiting())
25573 return true;
25574
25575 if (v.visit_begin(this))
25576 {
25577 visiting(true);
25578 if (class_decl_sptr pattern = get_pattern())
25579 pattern->traverse(v);
25580 visiting(false);
25581 }
25582 return v.visit_end(this);
25583 }
25584
~class_tdecl()25585 class_tdecl::~class_tdecl()
25586 {}
25587
25588 /// This visitor checks if a given type as non-canonicalized sub
25589 /// types.
25590 class non_canonicalized_subtype_detector : public ir::ir_node_visitor
25591 {
25592 type_base* type_;
25593 type_base* has_non_canonical_type_;
25594
25595 private:
25596 non_canonicalized_subtype_detector();
25597
25598 public:
non_canonicalized_subtype_detector(type_base * type)25599 non_canonicalized_subtype_detector(type_base* type)
25600 : type_(type),
25601 has_non_canonical_type_()
25602 {}
25603
25604 /// Return true if the visitor detected that there is a
25605 /// non-canonicalized sub-type.
25606 ///
25607 /// @return true if the visitor detected that there is a
25608 /// non-canonicalized sub-type.
25609 type_base*
has_non_canonical_type() const25610 has_non_canonical_type() const
25611 {return has_non_canonical_type_;}
25612
25613 /// The intent of this visitor handler is to avoid looking into
25614 /// sub-types of member functions of the type we are traversing.
25615 bool
visit_begin(function_decl * f)25616 visit_begin(function_decl* f)
25617 {
25618 // Do not look at sub-types of non-virtual member functions.
25619 if (is_member_function(f)
25620 && get_member_function_is_virtual(*f))
25621 return false;
25622 return true;
25623 }
25624
25625 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
25626 /// the 'has_non_canonical_type' flag. And in any case, when
25627 /// visiting a sub-type, do not visit its children nodes. So this
25628 /// function only goes to the level below the level of the top-most
25629 /// type.
25630 ///
25631 /// @return true if we are at the same level as the top-most type,
25632 /// otherwise return false.
25633 bool
visit_begin(type_base * t)25634 visit_begin(type_base* t)
25635 {
25636 if (t != type_)
25637 {
25638 if (!t->get_canonical_type())
25639 // We are looking a sub-type of 'type_' which has no
25640 // canonical type. So tada! we found one! Get out right
25641 // now with the trophy.
25642 has_non_canonical_type_ = t;
25643
25644 return false;
25645 }
25646 return true;
25647 }
25648
25649 /// When we are done visiting a sub-type, if it's been flagged as
25650 /// been non-canonicalized, then stop the traversing.
25651 ///
25652 /// Otherwise, keep going.
25653 ///
25654 /// @return false iff the sub-type that has been visited is
25655 /// non-canonicalized.
25656 bool
visit_end(type_base *)25657 visit_end(type_base* )
25658 {
25659 if (has_non_canonical_type_)
25660 return false;
25661 return true;
25662 }
25663 }; //end class non_canonicalized_subtype_detector
25664
25665 /// Test if a type has sub-types that are non-canonicalized.
25666 ///
25667 /// @param t the type which sub-types to consider.
25668 ///
25669 /// @return true if a type has sub-types that are non-canonicalized.
25670 type_base*
type_has_non_canonicalized_subtype(type_base_sptr t)25671 type_has_non_canonicalized_subtype(type_base_sptr t)
25672 {
25673 if (!t)
25674 return 0;
25675
25676 non_canonicalized_subtype_detector v(t.get());
25677 t->traverse(v);
25678 return v.has_non_canonical_type();
25679 }
25680
25681 /// Tests if the change of a given type effectively comes from just
25682 /// its sub-types. That is, if the type has changed but its type name
25683 /// hasn't changed, then the change of the type mostly likely is a
25684 /// sub-type change.
25685 ///
25686 /// @param t_v1 the first version of the type.
25687 ///
25688 /// @param t_v2 the second version of the type.
25689 ///
25690 /// @return true iff the type changed and the change is about its
25691 /// sub-types.
25692 bool
type_has_sub_type_changes(const type_base_sptr t_v1,const type_base_sptr t_v2)25693 type_has_sub_type_changes(const type_base_sptr t_v1,
25694 const type_base_sptr t_v2)
25695 {
25696 type_base_sptr t1 = strip_typedef(t_v1);
25697 type_base_sptr t2 = strip_typedef(t_v2);
25698
25699 string repr1 = get_pretty_representation(t1, /*internal=*/false),
25700 repr2 = get_pretty_representation(t2, /*internal=*/false);
25701 return (t1 != t2 && repr1 == repr2);
25702 }
25703
25704 /// Make sure that the life time of a given (smart pointer to a) type
25705 /// is the same as the life time of the libabigail library.
25706 ///
25707 /// @param t the type to consider.
25708 void
keep_type_alive(type_base_sptr t)25709 keep_type_alive(type_base_sptr t)
25710 {
25711 const environment& env = t->get_environment();
25712 env.priv_->extra_live_types_.push_back(t);
25713 }
25714
25715 /// Hash an ABI artifact that is either a type or a decl.
25716 ///
25717 /// This function intends to provides the fastest possible hashing for
25718 /// types and decls, while being completely correct.
25719 ///
25720 /// Note that if the artifact is a type and if it has a canonical
25721 /// type, the hash value is going to be the pointer value of the
25722 /// canonical type. Otherwise, this function computes a hash value
25723 /// for the type by recursively walking the type members. This last
25724 /// code path is possibly *very* slow and should only be used when
25725 /// only handful of types are going to be hashed.
25726 ///
25727 /// If the artifact is a decl, then a combination of the hash of its
25728 /// type and the hash of the other properties of the decl is computed.
25729 ///
25730 /// @param tod the type or decl to hash.
25731 ///
25732 /// @return the resulting hash value.
25733 size_t
hash_type_or_decl(const type_or_decl_base * tod)25734 hash_type_or_decl(const type_or_decl_base *tod)
25735 {
25736 size_t result = 0;
25737
25738 if (tod == 0)
25739 ;
25740 else if (const type_base* t = is_type(tod))
25741 result = hash_type(t);
25742 else if (const decl_base* d = is_decl(tod))
25743 {
25744 if (var_decl* v = is_var_decl(d))
25745 {
25746 ABG_ASSERT(v->get_type());
25747 size_t h = hash_type_or_decl(v->get_type());
25748 string repr = v->get_pretty_representation(/*internal=*/true);
25749 std::hash<string> hash_string;
25750 h = hashing::combine_hashes(h, hash_string(repr));
25751 result = h;
25752 }
25753 else if (function_decl* f = is_function_decl(d))
25754 {
25755 ABG_ASSERT(f->get_type());
25756 size_t h = hash_type_or_decl(f->get_type());
25757 string repr = f->get_pretty_representation(/*internal=*/true);
25758 std::hash<string> hash_string;
25759 h = hashing::combine_hashes(h, hash_string(repr));
25760 result = h;
25761 }
25762 else if (function_decl::parameter* p = is_function_parameter(d))
25763 {
25764 type_base_sptr parm_type = p->get_type();
25765 ABG_ASSERT(parm_type);
25766 std::hash<bool> hash_bool;
25767 std::hash<unsigned> hash_unsigned;
25768 size_t h = hash_type_or_decl(parm_type);
25769 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
25770 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
25771 result = h;
25772 }
25773 else if (class_decl::base_spec *bs = is_class_base_spec(d))
25774 {
25775 member_base::hash hash_member;
25776 std::hash<size_t> hash_size;
25777 std::hash<bool> hash_bool;
25778 type_base_sptr type = bs->get_base_class();
25779 size_t h = hash_type_or_decl(type);
25780 h = hashing::combine_hashes(h, hash_member(*bs));
25781 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
25782 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
25783 result = h;
25784 }
25785 else
25786 // This is a *really* *SLOW* path. If it shows up in a
25787 // performance profile, I bet it'd be a good idea to try to
25788 // avoid it altogether.
25789 result = d->get_hash();
25790 }
25791 else
25792 // We should never get here.
25793 abort();
25794 return result;
25795 }
25796
25797 /// Hash an ABI artifact that is either a type.
25798 ///
25799 /// This function intends to provides the fastest possible hashing for
25800 /// types while being completely correct.
25801 ///
25802 /// Note that if the type artifact has a canonical type, the hash
25803 /// value is going to be the pointer value of the canonical type.
25804 /// Otherwise, this function computes a hash value for the type by
25805 /// recursively walking the type members. This last code path is
25806 /// possibly *very* slow and should only be used when only handful of
25807 /// types are going to be hashed.
25808 ///
25809 /// @param t the type or decl to hash.
25810 ///
25811 /// @return the resulting hash value.
25812 size_t
hash_type(const type_base * t)25813 hash_type(const type_base *t)
25814 {return hash_as_canonical_type_or_constant(t);}
25815
25816 /// Hash an ABI artifact that is either a type of a decl.
25817 ///
25818 /// @param tod the ABI artifact to hash.
25819 ///
25820 /// @return the hash value of the ABI artifact.
25821 size_t
hash_type_or_decl(const type_or_decl_base_sptr & tod)25822 hash_type_or_decl(const type_or_decl_base_sptr& tod)
25823 {return hash_type_or_decl(tod.get());}
25824
25825 /// Test if a given type is allowed to be non canonicalized
25826 ///
25827 /// This is a subroutine of hash_as_canonical_type_or_constant.
25828 ///
25829 /// For now, the only types allowed to be non canonicalized in the
25830 /// system are decl-only class/union, the void type and variadic
25831 /// parameter types.
25832 ///
25833 /// @return true iff @p t is a one of the only types allowed to be
25834 /// non-canonicalized in the system.
25835 bool
is_non_canonicalized_type(const type_base * t)25836 is_non_canonicalized_type(const type_base *t)
25837 {
25838 if (!t)
25839 return true;
25840
25841 const environment& env = t->get_environment();
25842 return (is_declaration_only_class_or_union_type(t)
25843 || env.is_void_type(t)
25844 || env.is_variadic_parameter_type(t));
25845 }
25846
25847 /// For a given type, return its exemplar type.
25848 ///
25849 /// For a given type, its exemplar type is either its canonical type
25850 /// or the canonical type of the definition type of a given
25851 /// declaration-only type. If the neither of those two types exist,
25852 /// then the exemplar type is the given type itself.
25853 ///
25854 /// @param type the input to consider.
25855 ///
25856 /// @return the exemplar type.
25857 type_base*
get_exemplar_type(const type_base * type)25858 get_exemplar_type(const type_base* type)
25859 {
25860 if (decl_base * decl = is_decl(type))
25861 {
25862 // Make sure we get the real definition of a decl-only type.
25863 decl = look_through_decl_only(decl);
25864 type = is_type(decl);
25865 ABG_ASSERT(type);
25866 }
25867 type_base *exemplar = type->get_naked_canonical_type();
25868 if (!exemplar)
25869 {
25870 // The type has no canonical type. Let's be sure that it's one
25871 // of those rare types that are allowed to be non canonicalized
25872 // in the system.
25873 exemplar = const_cast<type_base*>(type);
25874 ABG_ASSERT(is_non_canonicalized_type(exemplar));
25875 }
25876 return exemplar;
25877 }
25878
25879 /// Test if a given type is allowed to be non canonicalized
25880 ///
25881 /// This is a subroutine of hash_as_canonical_type_or_constant.
25882 ///
25883 /// For now, the only types allowed to be non canonicalized in the
25884 /// system are decl-only class/union and the void type.
25885 ///
25886 /// @return true iff @p t is a one of the only types allowed to be
25887 /// non-canonicalized in the system.
25888 bool
is_non_canonicalized_type(const type_base_sptr & t)25889 is_non_canonicalized_type(const type_base_sptr& t)
25890 {return is_non_canonicalized_type(t.get());}
25891
25892 /// Hash a type by either returning the pointer value of its canonical
25893 /// type or by returning a constant if the type doesn't have a
25894 /// canonical type.
25895 ///
25896 /// This is a subroutine of hash_type.
25897 ///
25898 /// @param t the type to consider.
25899 ///
25900 /// @return the hash value.
25901 static size_t
hash_as_canonical_type_or_constant(const type_base * t)25902 hash_as_canonical_type_or_constant(const type_base *t)
25903 {
25904 type_base *canonical_type = 0;
25905
25906 if (t)
25907 canonical_type = t->get_naked_canonical_type();
25908
25909 if (!canonical_type)
25910 {
25911 // If the type doesn't have a canonical type, maybe it's because
25912 // it's a declaration-only type? If that's the case, let's try
25913 // to get the canonical type of the definition of this
25914 // declaration.
25915 decl_base *decl = is_decl(t);
25916 if (decl
25917 && decl->get_is_declaration_only()
25918 && decl->get_naked_definition_of_declaration())
25919 {
25920 type_base *definition =
25921 is_type(decl->get_naked_definition_of_declaration());
25922 ABG_ASSERT(definition);
25923 canonical_type = definition->get_naked_canonical_type();
25924 }
25925 }
25926
25927 if (canonical_type)
25928 return reinterpret_cast<size_t>(canonical_type);
25929
25930 // If we reached this point, it means we are seeing a
25931 // non-canonicalized type. It must be a decl-only class or a void
25932 // type, otherwise it means that for some weird reason, the type
25933 // hasn't been canonicalized. It should be!
25934 ABG_ASSERT(is_non_canonicalized_type(t));
25935
25936 return 0xDEADBABE;
25937 }
25938
25939 /// Test if the pretty representation of a given @ref function_decl is
25940 /// lexicographically less then the pretty representation of another
25941 /// @ref function_decl.
25942 ///
25943 /// @param f the first @ref function_decl to consider for comparison.
25944 ///
25945 /// @param s the second @ref function_decl to consider for comparison.
25946 ///
25947 /// @return true iff the pretty representation of @p f is
25948 /// lexicographically less than the pretty representation of @p s.
25949 bool
function_decl_is_less_than(const function_decl & f,const function_decl & s)25950 function_decl_is_less_than(const function_decl &f, const function_decl &s)
25951 {
25952 string fr = f.get_pretty_representation_of_declarator(),
25953 sr = s.get_pretty_representation_of_declarator();
25954
25955 if (fr != sr)
25956 return fr < sr;
25957
25958 fr = f.get_pretty_representation(/*internal=*/true),
25959 sr = s.get_pretty_representation(/*internal=*/true);
25960
25961 if (fr != sr)
25962 return fr < sr;
25963
25964 if (f.get_symbol())
25965 fr = f.get_symbol()->get_id_string();
25966 else if (!f.get_linkage_name().empty())
25967 fr = f.get_linkage_name();
25968
25969 if (s.get_symbol())
25970 sr = s.get_symbol()->get_id_string();
25971 else if (!s.get_linkage_name().empty())
25972 sr = s.get_linkage_name();
25973
25974 return fr < sr;
25975 }
25976
25977 /// Test if two types have similar structures, even though they are
25978 /// (or can be) different.
25979 ///
25980 /// const and volatile qualifiers are completely ignored.
25981 ///
25982 /// typedef are resolved to their definitions; their names are ignored.
25983 ///
25984 /// Two indirect types (pointers or references) have similar structure
25985 /// if their underlying types are of the same kind and have the same
25986 /// name. In the indirect types case, the size of the underlying type
25987 /// does not matter.
25988 ///
25989 /// Two direct types (i.e, non indirect) have a similar structure if
25990 /// they have the same kind, name and size. Two class types have
25991 /// similar structure if they have the same name, size, and if the
25992 /// types of their data members have similar types.
25993 ///
25994 /// @param first the first type to consider.
25995 ///
25996 /// @param second the second type to consider.
25997 ///
25998 /// @param indirect_type whether to do an indirect comparison
25999 ///
26000 /// @return true iff @p first and @p second have similar structures.
26001 bool
types_have_similar_structure(const type_base_sptr & first,const type_base_sptr & second,bool indirect_type)26002 types_have_similar_structure(const type_base_sptr& first,
26003 const type_base_sptr& second,
26004 bool indirect_type)
26005 {return types_have_similar_structure(first.get(), second.get(), indirect_type);}
26006
26007 /// Test if two types have similar structures, even though they are
26008 /// (or can be) different.
26009 ///
26010 /// const and volatile qualifiers are completely ignored.
26011 ///
26012 /// typedef are resolved to their definitions; their names are ignored.
26013 ///
26014 /// Two indirect types (pointers, references or arrays) have similar
26015 /// structure if their underlying types are of the same kind and have
26016 /// the same name. In the indirect types case, the size of the
26017 /// underlying type does not matter.
26018 ///
26019 /// Two direct types (i.e, non indirect) have a similar structure if
26020 /// they have the same kind, name and size. Two class types have
26021 /// similar structure if they have the same name, size, and if the
26022 /// types of their data members have similar types.
26023 ///
26024 /// @param first the first type to consider.
26025 ///
26026 /// @param second the second type to consider.
26027 ///
26028 /// @param indirect_type if true, then consider @p first and @p
26029 /// second as being underlying types of indirect types. Meaning that
26030 /// their size does not matter.
26031 ///
26032 /// @return true iff @p first and @p second have similar structures.
26033 bool
types_have_similar_structure(const type_base * first,const type_base * second,bool indirect_type)26034 types_have_similar_structure(const type_base* first,
26035 const type_base* second,
26036 bool indirect_type)
26037 {
26038 if (!!first != !!second)
26039 return false;
26040
26041 if (!first)
26042 return false;
26043
26044 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
26045 first = peel_qualified_or_typedef_type(first);
26046 second = peel_qualified_or_typedef_type(second);
26047
26048 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
26049 // various ty2 below cannot be null.
26050 if (typeid(*first) != typeid(*second))
26051 return false;
26052
26053 // Peel off matching pointers.
26054 if (const pointer_type_def* ty1 = is_pointer_type(first))
26055 {
26056 const pointer_type_def* ty2 = is_pointer_type(second);
26057 return types_have_similar_structure(ty1->get_pointed_to_type(),
26058 ty2->get_pointed_to_type(),
26059 /*indirect_type=*/true);
26060 }
26061
26062 // Peel off matching references.
26063 if (const reference_type_def* ty1 = is_reference_type(first))
26064 {
26065 const reference_type_def* ty2 = is_reference_type(second);
26066 if (ty1->is_lvalue() != ty2->is_lvalue())
26067 return false;
26068 return types_have_similar_structure(ty1->get_pointed_to_type(),
26069 ty2->get_pointed_to_type(),
26070 /*indirect_type=*/true);
26071 }
26072
26073 if (const type_decl* ty1 = is_type_decl(first))
26074 {
26075 const type_decl* ty2 = is_type_decl(second);
26076 if (!indirect_type)
26077 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
26078 return false;
26079
26080 return ty1->get_name() == ty2->get_name();
26081 }
26082
26083 if (const enum_type_decl* ty1 = is_enum_type(first))
26084 {
26085 const enum_type_decl* ty2 = is_enum_type(second);
26086 if (!indirect_type)
26087 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
26088 return false;
26089
26090 return (get_name(ty1->get_underlying_type())
26091 == get_name(ty2->get_underlying_type()));
26092 }
26093
26094 if (const class_decl* ty1 = is_class_type(first))
26095 {
26096 const class_decl* ty2 = is_class_type(second);
26097 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
26098 && ty1->get_name() != ty2->get_name())
26099 return false;
26100
26101 if (!indirect_type)
26102 {
26103 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
26104 || (ty1->get_non_static_data_members().size()
26105 != ty2->get_non_static_data_members().size()))
26106 return false;
26107
26108 for (class_or_union::data_members::const_iterator
26109 i = ty1->get_non_static_data_members().begin(),
26110 j = ty2->get_non_static_data_members().begin();
26111 (i != ty1->get_non_static_data_members().end()
26112 && j != ty2->get_non_static_data_members().end());
26113 ++i, ++j)
26114 {
26115 var_decl_sptr dm1 = *i;
26116 var_decl_sptr dm2 = *j;
26117 if (!types_have_similar_structure(dm1->get_type().get(),
26118 dm2->get_type().get(),
26119 indirect_type))
26120 return false;
26121 }
26122 }
26123
26124 return true;
26125 }
26126
26127 if (const union_decl* ty1 = is_union_type(first))
26128 {
26129 const union_decl* ty2 = is_union_type(second);
26130 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
26131 && ty1->get_name() != ty2->get_name())
26132 return false;
26133
26134 if (!indirect_type)
26135 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
26136
26137 return true;
26138 }
26139
26140 if (const array_type_def* ty1 = is_array_type(first))
26141 {
26142 const array_type_def* ty2 = is_array_type(second);
26143 // TODO: Handle int[5][2] vs int[2][5] better.
26144 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
26145 || ty1->get_dimension_count() != ty2->get_dimension_count()
26146 || !types_have_similar_structure(ty1->get_element_type(),
26147 ty2->get_element_type(),
26148 /*indirect_type=*/true))
26149 return false;
26150
26151 return true;
26152 }
26153
26154 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
26155 {
26156 const array_type_def::subrange_type *ty2 = is_subrange_type(second);
26157 if (ty1->get_upper_bound() != ty2->get_upper_bound()
26158 || ty1->get_lower_bound() != ty2->get_lower_bound()
26159 || ty1->get_language() != ty2->get_language()
26160 || !types_have_similar_structure(ty1->get_underlying_type(),
26161 ty2->get_underlying_type(),
26162 indirect_type))
26163 return false;
26164
26165 return true;
26166 }
26167
26168 if (const function_type* ty1 = is_function_type(first))
26169 {
26170 const function_type* ty2 = is_function_type(second);
26171 if (!types_have_similar_structure(ty1->get_return_type(),
26172 ty2->get_return_type(),
26173 indirect_type))
26174 return false;
26175
26176 if (ty1->get_parameters().size() != ty2->get_parameters().size())
26177 return false;
26178
26179 for (function_type::parameters::const_iterator
26180 i = ty1->get_parameters().begin(),
26181 j = ty2->get_parameters().begin();
26182 (i != ty1->get_parameters().end()
26183 && j != ty2->get_parameters().end());
26184 ++i, ++j)
26185 if (!types_have_similar_structure((*i)->get_type(),
26186 (*j)->get_type(),
26187 indirect_type))
26188 return false;
26189
26190 return true;
26191 }
26192
26193 // All kinds of type should have been handled at this point.
26194 ABG_ASSERT_NOT_REACHED;
26195
26196 return false;
26197 }
26198
26199 /// Look for a data member of a given class, struct or union type and
26200 /// return it.
26201 ///
26202 /// The data member is designated by its name.
26203 ///
26204 /// @param type the class, struct or union type to consider.
26205 ///
26206 /// @param dm_name the name of the data member to lookup.
26207 ///
26208 /// @return the data member iff it was found in @type or NULL if no
26209 /// data member with that name was found.
26210 const var_decl*
lookup_data_member(const type_base * type,const char * dm_name)26211 lookup_data_member(const type_base* type,
26212 const char* dm_name)
26213
26214 {
26215 class_or_union *cou = is_class_or_union_type(type);
26216 if (!cou)
26217 return 0;
26218
26219 return cou->find_data_member(dm_name).get();
26220 }
26221
26222 /// Get the function parameter designated by its index.
26223 ///
26224 /// Note that the first function parameter has index 0.
26225 ///
26226 /// @param fun the function to consider.
26227 ///
26228 /// @param parm_index the index of the function parameter to get.
26229 ///
26230 /// @return the function parameter designated by its index, of NULL if
26231 /// no function parameter with that index was found.
26232 const function_decl::parameter*
get_function_parameter(const decl_base * fun,unsigned parm_index)26233 get_function_parameter(const decl_base* fun,
26234 unsigned parm_index)
26235 {
26236 function_decl* fn = is_function_decl(fun);
26237 if (!fn)
26238 return 0;
26239
26240 const function_decl::parameters &parms = fn->get_type()->get_parameters();
26241 if (parms.size() <= parm_index)
26242 return 0;
26243
26244 return parms[parm_index].get();
26245 }
26246
26247 /// Build the internal name of the underlying type of an enum.
26248 ///
26249 /// @param base_name the (unqualified) name of the enum the underlying
26250 /// type is destined to.
26251 ///
26252 /// @param is_anonymous true if the underlying type of the enum is to
26253 /// be anonymous.
26254 string
build_internal_underlying_enum_type_name(const string & base_name,bool is_anonymous,uint64_t size)26255 build_internal_underlying_enum_type_name(const string &base_name,
26256 bool is_anonymous,
26257 uint64_t size)
26258 {
26259 std::ostringstream o;
26260
26261 if (is_anonymous)
26262 o << "unnamed-enum";
26263 else
26264 o << "enum-" << base_name;
26265
26266 o << "-underlying-type-" << size;
26267
26268 return o.str();
26269 }
26270
26271 bool
traverse(ir_node_visitor &)26272 ir_traversable_base::traverse(ir_node_visitor&)
26273 {return true;}
26274
26275 // <ir_node_visitor stuff>
26276
26277 /// The private data structure of the ir_node_visitor type.
26278 struct ir_node_visitor::priv
26279 {
26280 pointer_set visited_ir_nodes;
26281 bool allow_visiting_already_visited_type_node;
26282
privabigail::ir::ir_node_visitor::priv26283 priv()
26284 : allow_visiting_already_visited_type_node(true)
26285 {}
26286 }; // end struct ir_node_visitory::priv
26287
26288 /// Default Constructor of the ir_node_visitor type.
ir_node_visitor()26289 ir_node_visitor::ir_node_visitor()
26290 : priv_(new priv)
26291 {}
26292
26293 ir_node_visitor::~ir_node_visitor() = default;
26294
26295 /// Set if the walker using this visitor is allowed to re-visit a type
26296 /// node that was previously visited or not.
26297 ///
26298 /// @param f if true, then the walker using this visitor is allowed to
26299 /// re-visit a type node that was previously visited.
26300 void
allow_visiting_already_visited_type_node(bool f)26301 ir_node_visitor::allow_visiting_already_visited_type_node(bool f)
26302 {priv_->allow_visiting_already_visited_type_node = f;}
26303
26304 /// Get if the walker using this visitor is allowed to re-visit a type
26305 /// node that was previously visited or not.
26306 ///
26307 /// @return true iff the walker using this visitor is allowed to
26308 /// re-visit a type node that was previously visited.
26309 bool
allow_visiting_already_visited_type_node() const26310 ir_node_visitor::allow_visiting_already_visited_type_node() const
26311 {return priv_->allow_visiting_already_visited_type_node;}
26312
26313 /// Mark a given type node as having been visited.
26314 ///
26315 /// Note that for this function to work, the type node must have been
26316 /// canonicalized. Otherwise the process is aborted.
26317 ///
26318 /// @param p the type to mark as having been visited.
26319 void
mark_type_node_as_visited(type_base * p)26320 ir_node_visitor::mark_type_node_as_visited(type_base *p)
26321 {
26322 if (allow_visiting_already_visited_type_node())
26323 return;
26324
26325 if (p == 0 || type_node_has_been_visited(p))
26326 return;
26327
26328 type_base* canonical_type = p->get_naked_canonical_type();
26329 ABG_ASSERT(canonical_type);
26330
26331 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
26332 priv_->visited_ir_nodes.insert(canonical_ptr_value);
26333 }
26334
26335 /// Un-mark all visited type nodes.
26336 ///
26337 /// That is, no type node is going to be considered as having been
26338 /// visited anymore.
26339 ///
26340 /// In other words, after invoking this funciton,
26341 /// ir_node_visitor::type_node_has_been_visited() is going to return
26342 /// false on all type nodes.
26343 void
forget_visited_type_nodes()26344 ir_node_visitor::forget_visited_type_nodes()
26345 {priv_->visited_ir_nodes.clear();}
26346
26347 /// Test if a given type node has been marked as visited.
26348 ///
26349 /// @param p the type node to consider.
26350 ///
26351 /// @return true iff the type node @p p has been marked as visited by
26352 /// the function ir_node_visitor::mark_type_node_as_visited.
26353 bool
type_node_has_been_visited(type_base * p) const26354 ir_node_visitor::type_node_has_been_visited(type_base* p) const
26355 {
26356 if (allow_visiting_already_visited_type_node())
26357 return false;
26358
26359 if (p == 0)
26360 return false;
26361
26362 type_base *canonical_type = p->get_naked_canonical_type();
26363 ABG_ASSERT(canonical_type);
26364
26365 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
26366 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
26367 if (it == priv_->visited_ir_nodes.end())
26368 return false;
26369
26370 return true;
26371 }
26372
26373 bool
visit_begin(decl_base *)26374 ir_node_visitor::visit_begin(decl_base*)
26375 {return true;}
26376
26377 bool
visit_end(decl_base *)26378 ir_node_visitor::visit_end(decl_base*)
26379 {return true;}
26380
26381 bool
visit_begin(scope_decl *)26382 ir_node_visitor::visit_begin(scope_decl*)
26383 {return true;}
26384
26385 bool
visit_end(scope_decl *)26386 ir_node_visitor::visit_end(scope_decl*)
26387 {return true;}
26388
26389 bool
visit_begin(type_base *)26390 ir_node_visitor::visit_begin(type_base*)
26391 {return true;}
26392
26393 bool
visit_end(type_base *)26394 ir_node_visitor::visit_end(type_base*)
26395 {return true;}
26396
26397 bool
visit_begin(scope_type_decl * t)26398 ir_node_visitor::visit_begin(scope_type_decl* t)
26399 {return visit_begin(static_cast<type_base*>(t));}
26400
26401 bool
visit_end(scope_type_decl * t)26402 ir_node_visitor::visit_end(scope_type_decl* t)
26403 {return visit_end(static_cast<type_base*>(t));}
26404
26405 bool
visit_begin(type_decl * t)26406 ir_node_visitor::visit_begin(type_decl* t)
26407 {return visit_begin(static_cast<type_base*>(t));}
26408
26409 bool
visit_end(type_decl * t)26410 ir_node_visitor::visit_end(type_decl* t)
26411 {return visit_end(static_cast<type_base*>(t));}
26412
26413 bool
visit_begin(namespace_decl * d)26414 ir_node_visitor::visit_begin(namespace_decl* d)
26415 {return visit_begin(static_cast<decl_base*>(d));}
26416
26417 bool
visit_end(namespace_decl * d)26418 ir_node_visitor::visit_end(namespace_decl* d)
26419 {return visit_end(static_cast<decl_base*>(d));}
26420
26421 bool
visit_begin(qualified_type_def * t)26422 ir_node_visitor::visit_begin(qualified_type_def* t)
26423 {return visit_begin(static_cast<type_base*>(t));}
26424
26425 bool
visit_end(qualified_type_def * t)26426 ir_node_visitor::visit_end(qualified_type_def* t)
26427 {return visit_end(static_cast<type_base*>(t));}
26428
26429 bool
visit_begin(pointer_type_def * t)26430 ir_node_visitor::visit_begin(pointer_type_def* t)
26431 {return visit_begin(static_cast<type_base*>(t));}
26432
26433 bool
visit_end(pointer_type_def * t)26434 ir_node_visitor::visit_end(pointer_type_def* t)
26435 {return visit_end(static_cast<type_base*>(t));}
26436
26437 bool
visit_begin(reference_type_def * t)26438 ir_node_visitor::visit_begin(reference_type_def* t)
26439 {return visit_begin(static_cast<type_base*>(t));}
26440
26441 bool
visit_end(reference_type_def * t)26442 ir_node_visitor::visit_end(reference_type_def* t)
26443 {return visit_end(static_cast<type_base*>(t));}
26444
26445 bool
visit_begin(array_type_def * t)26446 ir_node_visitor::visit_begin(array_type_def* t)
26447 {return visit_begin(static_cast<type_base*>(t));}
26448
26449 bool
visit_end(array_type_def * t)26450 ir_node_visitor::visit_end(array_type_def* t)
26451 {return visit_end(static_cast<type_base*>(t));}
26452
26453 bool
visit_begin(array_type_def::subrange_type * t)26454 ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
26455 {return visit_begin(static_cast<type_base*>(t));}
26456
26457 bool
visit_end(array_type_def::subrange_type * t)26458 ir_node_visitor::visit_end(array_type_def::subrange_type* t)
26459 {return visit_end(static_cast<type_base*>(t));}
26460
26461 bool
visit_begin(enum_type_decl * t)26462 ir_node_visitor::visit_begin(enum_type_decl* t)
26463 {return visit_begin(static_cast<type_base*>(t));}
26464
26465 bool
visit_end(enum_type_decl * t)26466 ir_node_visitor::visit_end(enum_type_decl* t)
26467 {return visit_end(static_cast<type_base*>(t));}
26468
26469 bool
visit_begin(typedef_decl * t)26470 ir_node_visitor::visit_begin(typedef_decl* t)
26471 {return visit_begin(static_cast<type_base*>(t));}
26472
26473 bool
visit_end(typedef_decl * t)26474 ir_node_visitor::visit_end(typedef_decl* t)
26475 {return visit_end(static_cast<type_base*>(t));}
26476
26477 bool
visit_begin(function_type * t)26478 ir_node_visitor::visit_begin(function_type* t)
26479 {return visit_begin(static_cast<type_base*>(t));}
26480
26481 bool
visit_end(function_type * t)26482 ir_node_visitor::visit_end(function_type* t)
26483 {return visit_end(static_cast<type_base*>(t));}
26484
26485 bool
visit_begin(var_decl * d)26486 ir_node_visitor::visit_begin(var_decl* d)
26487 {return visit_begin(static_cast<decl_base*>(d));}
26488
26489 bool
visit_end(var_decl * d)26490 ir_node_visitor::visit_end(var_decl* d)
26491 {return visit_end(static_cast<decl_base*>(d));}
26492
26493 bool
visit_begin(function_decl * d)26494 ir_node_visitor::visit_begin(function_decl* d)
26495 {return visit_begin(static_cast<decl_base*>(d));}
26496
26497 bool
visit_end(function_decl * d)26498 ir_node_visitor::visit_end(function_decl* d)
26499 {return visit_end(static_cast<decl_base*>(d));}
26500
26501 bool
visit_begin(function_decl::parameter * d)26502 ir_node_visitor::visit_begin(function_decl::parameter* d)
26503 {return visit_begin(static_cast<decl_base*>(d));}
26504
26505 bool
visit_end(function_decl::parameter * d)26506 ir_node_visitor::visit_end(function_decl::parameter* d)
26507 {return visit_end(static_cast<decl_base*>(d));}
26508
26509 bool
visit_begin(function_tdecl * d)26510 ir_node_visitor::visit_begin(function_tdecl* d)
26511 {return visit_begin(static_cast<decl_base*>(d));}
26512
26513 bool
visit_end(function_tdecl * d)26514 ir_node_visitor::visit_end(function_tdecl* d)
26515 {return visit_end(static_cast<decl_base*>(d));}
26516
26517 bool
visit_begin(class_tdecl * d)26518 ir_node_visitor::visit_begin(class_tdecl* d)
26519 {return visit_begin(static_cast<decl_base*>(d));}
26520
26521 bool
visit_end(class_tdecl * d)26522 ir_node_visitor::visit_end(class_tdecl* d)
26523 {return visit_end(static_cast<decl_base*>(d));}
26524
26525 bool
visit_begin(class_or_union * t)26526 ir_node_visitor::visit_begin(class_or_union* t)
26527 {return visit_begin(static_cast<type_base*>(t));}
26528
26529 bool
visit_end(class_or_union * t)26530 ir_node_visitor::visit_end(class_or_union* t)
26531 {return visit_end(static_cast<type_base*>(t));}
26532
26533 bool
visit_begin(class_decl * t)26534 ir_node_visitor::visit_begin(class_decl* t)
26535 {return visit_begin(static_cast<type_base*>(t));}
26536
26537 bool
visit_end(class_decl * t)26538 ir_node_visitor::visit_end(class_decl* t)
26539 {return visit_end(static_cast<type_base*>(t));}
26540
26541 bool
visit_begin(union_decl * t)26542 ir_node_visitor::visit_begin(union_decl* t)
26543 {return visit_begin(static_cast<type_base*>(t));}
26544
26545 bool
visit_end(union_decl * t)26546 ir_node_visitor::visit_end(union_decl* t)
26547 {return visit_end(static_cast<type_base*>(t));}
26548
26549 bool
visit_begin(class_decl::base_spec * d)26550 ir_node_visitor::visit_begin(class_decl::base_spec* d)
26551 {return visit_begin(static_cast<decl_base*>(d));}
26552
26553 bool
visit_end(class_decl::base_spec * d)26554 ir_node_visitor::visit_end(class_decl::base_spec* d)
26555 {return visit_end(static_cast<decl_base*>(d));}
26556
26557 bool
visit_begin(member_function_template * d)26558 ir_node_visitor::visit_begin(member_function_template* d)
26559 {return visit_begin(static_cast<decl_base*>(d));}
26560
26561 bool
visit_end(member_function_template * d)26562 ir_node_visitor::visit_end(member_function_template* d)
26563 {return visit_end(static_cast<decl_base*>(d));}
26564
26565 bool
visit_begin(member_class_template * d)26566 ir_node_visitor::visit_begin(member_class_template* d)
26567 {return visit_begin(static_cast<decl_base*>(d));}
26568
26569 bool
visit_end(member_class_template * d)26570 ir_node_visitor::visit_end(member_class_template* d)
26571 {return visit_end(static_cast<decl_base*>(d));}
26572
26573 // </ir_node_visitor stuff>
26574
26575 // <debugging facilities>
26576
26577 /// Generate a different string at each invocation.
26578 ///
26579 /// @return the resulting string.
26580 static string
get_next_string()26581 get_next_string()
26582 {
26583 static __thread size_t counter;
26584 ++counter;
26585 std::ostringstream o;
26586 o << counter;
26587 return o.str();
26588 }
26589
26590 /// Convenience typedef for a hash map of pointer to function_decl and
26591 /// string.
26592 typedef unordered_map<const function_decl*, string,
26593 function_decl::hash,
26594 function_decl::ptr_equal> fns_to_str_map_type;
26595
26596 /// Return a string associated to a given function. Two functions
26597 /// that compare equal would yield the same string, as far as this
26598 /// routine is concerned. And two functions that are different would
26599 /// yield different strings.
26600 ///
26601 /// This is used to debug core diffing issues on functions. The
26602 /// sequence of strings can be given to the 'testdiff2' program that
26603 /// is in the tests/ directory of the source tree, to reproduce core
26604 /// diffing issues on string and thus ease the debugging.
26605 ///
26606 /// @param fn the function to generate a string for.
26607 ///
26608 /// @param m the function_decl* <-> string map to be used by this
26609 /// function to generate strings associated to a function.
26610 ///
26611 /// @return the resulting string.
26612 static const string&
fn_to_str(const function_decl * fn,fns_to_str_map_type & m)26613 fn_to_str(const function_decl* fn,
26614 fns_to_str_map_type& m)
26615 {
26616 fns_to_str_map_type::const_iterator i = m.find(fn);
26617 if (i != m.end())
26618 return i->second;
26619 string s = get_next_string();
26620 return m[fn]= s;
26621 }
26622
26623 /// Generate a sequence of string that matches a given sequence of
26624 /// function. In the resulting sequence, each function is "uniquely
26625 /// representated" by a string. For instance, if the same function "foo"
26626 /// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
26627 /// we don't care about the actual string) would appear at index 1 and 3.
26628 ///
26629 /// @param begin the beginning of the sequence of functions to consider.
26630 ///
26631 /// @param end the end of the sequence of functions. This points to
26632 /// one-passed-the-end of the actual sequence.
26633 ///
26634 /// @param m the function_decl* <-> string map to be used by this
26635 /// function to generate strings associated to a function.
26636 ///
26637 /// @param o the output stream where to emit the generated list of
26638 /// strings to.
26639 static void
fns_to_str(vector<function_decl * >::const_iterator begin,vector<function_decl * >::const_iterator end,fns_to_str_map_type & m,std::ostream & o)26640 fns_to_str(vector<function_decl*>::const_iterator begin,
26641 vector<function_decl*>::const_iterator end,
26642 fns_to_str_map_type& m,
26643 std::ostream& o)
26644 {
26645 vector<function_decl*>::const_iterator i;
26646 for (i = begin; i != end; ++i)
26647 o << "'" << fn_to_str(*i, m) << "' ";
26648 }
26649
26650 /// For each sequence of functions given in argument, generate a
26651 /// sequence of string that matches a given sequence of function. In
26652 /// the resulting sequence, each function is "uniquely representated"
26653 /// by a string. For instance, if the same function "foo" appears at
26654 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
26655 /// care about the actual string) would appear at index 1 and 3.
26656 ///
26657 /// @param a_begin the beginning of the sequence of functions to consider.
26658 ///
26659 /// @param a_end the end of the sequence of functions. This points to
26660 /// one-passed-the-end of the actual sequence.
26661 ///
26662 /// @param b_begin the beginning of the second sequence of functions
26663 /// to consider.
26664 ///
26665 /// @param b_end the end of the second sequence of functions.
26666 ///
26667 /// @param m the function_decl* <-> string map to be used by this
26668 /// function to generate strings associated to a function.
26669 ///
26670 /// @param o the output stream where to emit the generated list of
26671 /// strings to.
26672 static void
fns_to_str(vector<function_decl * >::const_iterator a_begin,vector<function_decl * >::const_iterator a_end,vector<function_decl * >::const_iterator b_begin,vector<function_decl * >::const_iterator b_end,fns_to_str_map_type & m,std::ostream & o)26673 fns_to_str(vector<function_decl*>::const_iterator a_begin,
26674 vector<function_decl*>::const_iterator a_end,
26675 vector<function_decl*>::const_iterator b_begin,
26676 vector<function_decl*>::const_iterator b_end,
26677 fns_to_str_map_type& m,
26678 std::ostream& o)
26679 {
26680 fns_to_str(a_begin, a_end, m, o);
26681 o << "->|<- ";
26682 fns_to_str(b_begin, b_end, m, o);
26683 o << "\n";
26684 }
26685
26686 /// For each sequence of functions given in argument, generate a
26687 /// sequence of string that matches a given sequence of function. In
26688 /// the resulting sequence, each function is "uniquely representated"
26689 /// by a string. For instance, if the same function "foo" appears at
26690 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
26691 /// care about the actual string) would appear at index 1 and 3.
26692 ///
26693 /// @param a_begin the beginning of the sequence of functions to consider.
26694 ///
26695 /// @param a_end the end of the sequence of functions. This points to
26696 /// one-passed-the-end of the actual sequence.
26697 ///
26698 /// @param b_begin the beginning of the second sequence of functions
26699 /// to consider.
26700 ///
26701 /// @param b_end the end of the second sequence of functions.
26702 ///
26703 /// @param o the output stream where to emit the generated list of
26704 /// strings to.
26705 void
fns_to_str(vector<function_decl * >::const_iterator a_begin,vector<function_decl * >::const_iterator a_end,vector<function_decl * >::const_iterator b_begin,vector<function_decl * >::const_iterator b_end,std::ostream & o)26706 fns_to_str(vector<function_decl*>::const_iterator a_begin,
26707 vector<function_decl*>::const_iterator a_end,
26708 vector<function_decl*>::const_iterator b_begin,
26709 vector<function_decl*>::const_iterator b_end,
26710 std::ostream& o)
26711 {
26712 fns_to_str_map_type m;
26713 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
26714 }
26715
26716 // </debugging facilities>
26717
26718 // </class template>
26719
26720 }// end namespace ir
26721 }//end namespace abigail
26722
26723 namespace
26724 {
26725
26726 /// Update the qualified parent name, qualified name and scoped name
26727 /// of a tree decl node.
26728 ///
26729 /// @return true if the tree walking should continue, false otherwise.
26730 ///
26731 /// @param d the tree node to take in account.
26732 bool
do_update(abigail::ir::decl_base * d)26733 qualified_name_setter::do_update(abigail::ir::decl_base* d)
26734 {
26735 std::string parent_qualified_name;
26736 abigail::ir::scope_decl* parent = d->get_scope();
26737 if (parent)
26738 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
26739 else
26740 d->priv_->qualified_parent_name_ = abigail::interned_string();
26741
26742 const abigail::ir::environment& env = d->get_environment();
26743
26744 if (!d->priv_->qualified_parent_name_.empty())
26745 {
26746 if (d->get_name().empty())
26747 d->priv_->qualified_name_ = abigail::interned_string();
26748 else
26749 d->priv_->qualified_name_ =
26750 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
26751 }
26752
26753 if (d->priv_->scoped_name_.empty())
26754 {
26755 if (parent
26756 && !parent->get_is_anonymous()
26757 && !parent->get_name().empty())
26758 d->priv_->scoped_name_ =
26759 env.intern(parent->get_name() + "::" + d->get_name());
26760 else
26761 d->priv_->scoped_name_ =
26762 env.intern(d->get_name());
26763 }
26764
26765 if (!is_scope_decl(d))
26766 return false;
26767
26768 return true;
26769 }
26770
26771 /// This is called when we start visiting a decl node, during the
26772 /// udpate of the qualified name of a given sub-tree.
26773 ///
26774 /// @param d the decl node we are visiting.
26775 ///
26776 /// @return true iff the traversal should keep going.
26777 bool
visit_begin(abigail::ir::decl_base * d)26778 qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
26779 {return do_update(d);}
26780
26781 /// This is called when we start visiting a type node, during the
26782 /// udpate of the qualified name of a given sub-tree.
26783 ///
26784 /// @param d the decl node we are visiting.
26785 ///
26786 /// @return true iff the traversal should keep going.
26787 bool
visit_begin(abigail::ir::type_base * t)26788 qualified_name_setter::visit_begin(abigail::ir::type_base* t)
26789 {
26790 if (abigail::ir::decl_base* d = get_type_declaration(t))
26791 return do_update(d);
26792 return false;
26793 }
26794 }// end anonymous namespace.
26795