1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -*- mode:
2 // C++ -*-
3 //
4 // Copyright (C) 2013-2023 Red Hat, Inc.
5 //
6 //Author: Dodji Seketeli
7
8 /// @file
9 ///
10 /// Definitions for the Internal Representation artifacts of libabigail.
11
12 #include <cxxabi.h>
13 #include <algorithm>
14 #include <cstdint>
15 #include <functional>
16 #include <iterator>
17 #include <memory>
18 #include <sstream>
19 #include <typeinfo>
20 #include <unordered_map>
21 #include <utility>
22 #include <vector>
23
24 #include "abg-internal.h"
25 // <headers defining libabigail's API go under here>
26 ABG_BEGIN_EXPORT_DECLARATIONS
27
28 #include "abg-interned-str.h"
29 #include "abg-ir.h"
30 #include "abg-corpus.h"
31 #include "abg-regex.h"
32
33 ABG_END_EXPORT_DECLARATIONS
34 // </headers defining libabigail's API>
35
36 #include "abg-corpus-priv.h"
37 #include "abg-tools-utils.h"
38 #include "abg-comp-filter.h"
39 #include "abg-ir-priv.h"
40
41 namespace
42 {
43 /// This internal type is a tree walking that is used to set the
44 /// qualified name of a tree of decls and types. It used by the
45 /// function update_qualified_name().
46 class qualified_name_setter : public abigail::ir::ir_node_visitor
47 {
48
49 public:
50 bool
51 do_update(abigail::ir::decl_base* d);
52
53 bool
54 visit_begin(abigail::ir::decl_base* d);
55
56 bool
57 visit_begin(abigail::ir::type_base* d);
58 }; // end class qualified_name_setter
59
60 }// end anon namespace
61
62 namespace abigail
63 {
64
65 // Inject.
66 using std::string;
67 using std::list;
68 using std::vector;
69 using std::unordered_map;
70 using std::dynamic_pointer_cast;
71 using std::static_pointer_cast;
72
73 /// Convenience typedef for a map of string -> string*.
74 typedef unordered_map<string, string*> pool_map_type;
75
76 /// The type of the private data structure of type @ref
77 /// intered_string_pool.
78 struct interned_string_pool::priv
79 {
80 pool_map_type map;
81 }; //end struc struct interned_string_pool::priv
82
83 /// Default constructor.
interned_string_pool()84 interned_string_pool::interned_string_pool()
85 : priv_(new priv)
86 {
87 priv_->map[""] = 0;
88 }
89
90 /// Test if the interned string pool already contains a string with a
91 /// given value.
92 ///
93 /// @param s the string to test for.
94 ///
95 /// @return true if the pool contains a string with the value @p s.
96 bool
has_string(const char * s) const97 interned_string_pool::has_string(const char* s) const
98 {return priv_->map.find(s) != priv_->map.end();}
99
100 /// Get a pointer to the interned string which has a given value.
101 ///
102 /// @param s the value of the interned string to look for.
103 ///
104 /// @return a pointer to the raw string of characters which has the
105 /// value of @p s. Or null if no string with value @p s was interned.
106 const char*
get_string(const char * s) const107 interned_string_pool::get_string(const char* s) const
108 {
109 unordered_map<string, string*>::const_iterator i =
110 priv_->map.find(s);
111 if (i == priv_->map.end())
112 return 0;
113 if (i->second)
114 return i->second->c_str();
115 return "";
116 }
117
118 /// Create an interned string with a given value.
119 ///
120 /// @param str_value the value of the interned string to create.
121 ///
122 /// @return the new created instance of @ref interned_string created.
123 interned_string
create_string(const std::string & str_value)124 interned_string_pool::create_string(const std::string& str_value)
125 {
126 string*& result = priv_->map[str_value];
127 if (!result && !str_value.empty())
128 result = new string(str_value);
129 return interned_string(result);
130 }
131
132 /// Destructor.
~interned_string_pool()133 interned_string_pool::~interned_string_pool()
134 {
135 for (pool_map_type::iterator i = priv_->map.begin();
136 i != priv_->map.end();
137 ++i)
138 if (i->second)
139 delete i->second;
140 }
141
142 /// Equality operator.
143 ///
144 /// @param l the instance of std::string on the left-hand-side of the
145 /// equality operator.
146 ///
147 /// @param r the instance of @ref interned_string on the
148 /// right-hand-side of the equality operator.
149 ///
150 /// @return true iff the two string are equal.
151 bool
operator ==(const std::string & l,const interned_string & r)152 operator==(const std::string& l, const interned_string& r)
153 {return r.operator==(l);}
154
155 bool
operator !=(const std::string & l,const interned_string & r)156 operator!=(const std::string& l, const interned_string& r)
157 {return !(l == r);}
158
159 /// Streaming operator.
160 ///
161 /// Streams an instance of @ref interned_string to an output stream.
162 ///
163 /// @param o the destination output stream.
164 ///
165 /// @param s the instance of @ref interned_string to stream out.
166 ///
167 /// @return the output stream this function just streamed to.
168 std::ostream&
operator <<(std::ostream & o,const interned_string & s)169 operator<<(std::ostream& o, const interned_string& s)
170 {
171 o << static_cast<std::string>(s);
172 return o;
173 }
174
175 /// Concatenation operator.
176 ///
177 /// Concatenate two instances of @ref interned_string, builds an
178 /// instance of std::string with the resulting string and return it.
179 ///
180 /// @param s1 the first string to consider.
181 ///
182 /// @param s2 the second string to consider.
183 ///
184 /// @return the resuting concatenated string.
185 std::string
operator +(const interned_string & s1,const std::string & s2)186 operator+(const interned_string& s1,const std::string& s2)
187 {return static_cast<std::string>(s1) + s2;}
188
189 /// Concatenation operator.
190 ///
191 /// Concatenate two instances of @ref interned_string, builds an
192 /// instance of std::string with the resulting string and return it.
193 ///
194 /// @param s1 the first string to consider.
195 ///
196 /// @param s2 the second string to consider.
197 ///
198 /// @return the resuting concatenated string.
199 std::string
operator +(const std::string & s1,const interned_string & s2)200 operator+(const std::string& s1, const interned_string& s2)
201 {return s1 + static_cast<std::string>(s2);}
202
203 namespace ir
204 {
205
206 static size_t
207 hash_as_canonical_type_or_constant(const type_base *t);
208
209 static bool
210 has_generic_anonymous_internal_type_name(const decl_base *d);
211
212 static interned_string
213 get_generic_anonymous_internal_type_name(const decl_base *d);
214
215 static string
216 get_internal_integral_type_name(const type_base*);
217
218 static void
219 update_qualified_name(decl_base * d);
220
221 static void
222 update_qualified_name(decl_base_sptr d);
223
224 void
225 push_composite_type_comparison_operands(const type_base& left,
226 const type_base& right);
227
228 void
229 pop_composite_type_comparison_operands(const type_base& left,
230 const type_base& right);
231
232 bool
233 mark_dependant_types_compared_until(const type_base &r);
234
235 /// Push a pair of operands on the stack of operands of the current
236 /// type comparison, during type canonicalization.
237 ///
238 /// For more information on this, please look at the description of
239 /// the environment::priv::right_type_comp_operands_ data member.
240 ///
241 /// @param left the left-hand-side comparison operand to push.
242 ///
243 /// @param right the right-hand-side comparison operand to push.
244 void
push_composite_type_comparison_operands(const type_base & left,const type_base & right)245 push_composite_type_comparison_operands(const type_base& left,
246 const type_base& right)
247 {
248 const environment& env = left.get_environment();
249 env.priv_->push_composite_type_comparison_operands(&left, &right);
250 }
251
252 /// Pop a pair of operands from the stack of operands to the current
253 /// type comparison.
254 ///
255 /// For more information on this, please look at the description of
256 /// the environment::privright_type_comp_operands_ data member.
257 ///
258 /// @param left the left-hand-side comparison operand we expect to
259 /// pop from the top of the stack. If this doesn't match the
260 /// operand found on the top of the stack, the function aborts.
261 ///
262 /// @param right the right-hand-side comparison operand we expect to
263 /// pop from the bottom of the stack. If this doesn't match the
264 /// operand found on the top of the stack, the function aborts.
265 void
pop_composite_type_comparison_operands(const type_base & left,const type_base & right)266 pop_composite_type_comparison_operands(const type_base& left,
267 const type_base& right)
268 {
269 const environment& env = left.get_environment();
270 env.priv_->pop_composite_type_comparison_operands(&left, &right);
271 }
272
273 /// In the stack of the current types being compared (as part of type
274 /// canonicalization), mark all the types that comes after a certain
275 /// one as NOT being eligible to the canonical type propagation
276 /// optimization.
277 ///
278 /// For a starter, please read about the @ref
279 /// OnTheFlyCanonicalization, aka, "canonical type propagation
280 /// optimization".
281 ///
282 /// To implement that optimization, we need, among other things to
283 /// maintain stack of the types (and their sub-types) being
284 /// currently compared as part of type canonicalization.
285 ///
286 /// Note that we only consider the type that is the right-hand-side
287 /// operand of the comparison because it's that one that is being
288 /// canonicalized and thus, that is not yet canonicalized.
289 ///
290 /// The reason why a type is deemed NON-eligible to the canonical
291 /// type propagation optimization is that it "depends" on
292 /// recursively present type. Let me explain.
293 ///
294 /// Suppose we have a type T that has sub-types named ST0 and ST1.
295 /// Suppose ST1 itself has a sub-type that is T itself. In this
296 /// case, we say that T is a recursive type, because it has T
297 /// (itself) as one of its sub-types:
298 ///
299 /// T
300 /// +-- ST0
301 /// |
302 /// +-- ST1
303 /// +
304 /// |
305 /// +-- T
306 ///
307 /// ST1 is said to "depend" on T because it has T as a sub-type.
308 /// But because T is recursive, then ST1 is said to depend on a
309 /// recursive type. Notice however that ST0 does not depend on any
310 /// recursive type.
311 ///
312 /// When we are at the point of comparing the sub-type T of ST1
313 /// against its counterpart, the stack of the right-hand-side
314 /// operands of the type canonicalization is going to look like
315 /// this:
316 ///
317 /// | T | ST1 |
318 ///
319 /// We don't add the type T to the stack as we detect that T was
320 /// already in there (recursive cycle).
321 ///
322 /// So, this function will basically mark ST1 as being NON-eligible
323 /// to being the target of canonical type propagation, by marking ST1
324 /// as being dependant on T.
325 ///
326 /// @param right the right-hand-side operand of the type comparison.
327 ///
328 /// @return true iff the operation was successful.
329 bool
mark_dependant_types_compared_until(const type_base & r)330 mark_dependant_types_compared_until(const type_base &r)
331 {
332 const environment& env = r.get_environment();
333 if (env.do_on_the_fly_canonicalization())
334 return env.priv_->mark_dependant_types_compared_until(&r);
335 return false;
336 }
337
338 /// @brief the location of a token represented in its simplest form.
339 /// Instances of this type are to be stored in a sorted vector, so the
340 /// type must have proper relational operators.
341 class expanded_location
342 {
343 string path_;
344 unsigned line_;
345 unsigned column_;
346
347 expanded_location();
348
349 public:
350
351 friend class location_manager;
352
expanded_location(const string & path,unsigned line,unsigned column)353 expanded_location(const string& path, unsigned line, unsigned column)
354 : path_(path), line_(line), column_(column)
355 {}
356
357 bool
operator ==(const expanded_location & l) const358 operator==(const expanded_location& l) const
359 {
360 return (path_ == l.path_
361 && line_ == l.line_
362 && column_ && l.column_);
363 }
364
365 bool
operator <(const expanded_location & l) const366 operator<(const expanded_location& l) const
367 {
368 if (path_ < l.path_)
369 return true;
370 else if (path_ > l.path_)
371 return false;
372
373 if (line_ < l.line_)
374 return true;
375 else if (line_ > l.line_)
376 return false;
377
378 return column_ < l.column_;
379 }
380 };
381
382 /// Expand the location into a tripplet path, line and column number.
383 ///
384 /// @param path the output parameter where this function sets the
385 /// expanded path.
386 ///
387 /// @param line the output parameter where this function sets the
388 /// expanded line.
389 ///
390 /// @param column the ouptut parameter where this function sets the
391 /// expanded column.
392 void
expand(std::string & path,unsigned & line,unsigned & column) const393 location::expand(std::string& path, unsigned& line, unsigned& column) const
394 {
395 if (!get_location_manager())
396 {
397 // We don't have a location manager maybe because this location
398 // was just freshly instanciated. We still want to be able to
399 // expand to default values.
400 path = "";
401 line = 0;
402 column = 0;
403 return;
404 }
405 get_location_manager()->expand_location(*this, path, line, column);
406 }
407
408
409 /// Expand the location into a string.
410 ///
411 /// @return the string representing the location.
412 string
expand(void) const413 location::expand(void) const
414 {
415 string path, result;
416 unsigned line = 0, column = 0;
417 expand(path, line, column);
418
419 std::ostringstream o;
420 o << path << ":" << line << ":" << column;
421 return o.str();
422 }
423
424 struct location_manager::priv
425 {
426 /// This sorted vector contains the expanded locations of the tokens
427 /// coming from a given ABI Corpus. The index of a given expanded
428 /// location in the table gives us an integer that is used to build
429 /// instance of location types.
430 std::vector<expanded_location> locs;
431 };
432
location_manager()433 location_manager::location_manager()
434 : priv_(new location_manager::priv)
435 {}
436
437 location_manager::~location_manager() = default;
438
439 /// Insert the triplet representing a source locus into our internal
440 /// vector of location triplet. Return an instance of location type,
441 /// built from an integral type that represents the index of the
442 /// source locus triplet into our source locus table.
443 ///
444 /// @param file_path the file path of the source locus
445 /// @param line the line number of the source location
446 /// @param col the column number of the source location
447 location
create_new_location(const std::string & file_path,size_t line,size_t col)448 location_manager::create_new_location(const std::string& file_path,
449 size_t line,
450 size_t col)
451 {
452 expanded_location l(file_path, line, col);
453
454 // Just append the new expanded location to the end of the vector
455 // and return its index. Note that indexes start at 1.
456 priv_->locs.push_back(l);
457 return location(priv_->locs.size(), this);
458 }
459
460 /// Given an instance of location type, return the triplet
461 /// {path,line,column} that represents the source locus. Note that
462 /// the location must have been previously created from the function
463 /// location_manager::create_new_location, otherwise this function yields
464 /// unexpected results, including possibly a crash.
465 ///
466 /// @param location the instance of location type to expand
467 /// @param path the resulting path of the source locus
468 /// @param line the resulting line of the source locus
469 /// @param column the resulting colum of the source locus
470 void
expand_location(const location & location,std::string & path,unsigned & line,unsigned & column) const471 location_manager::expand_location(const location& location,
472 std::string& path,
473 unsigned& line,
474 unsigned& column) const
475 {
476 if (location.value_ == 0)
477 return;
478 expanded_location &l = priv_->locs[location.value_ - 1];
479 path = l.path_;
480 line = l.line_;
481 column = l.column_;
482 }
483
484 typedef unordered_map<function_type_sptr,
485 bool,
486 function_type::hash,
487 type_shared_ptr_equal> fn_type_ptr_map;
488
489 // <type_maps stuff>
490
491 struct type_maps::priv
492 {
493 mutable istring_type_base_wptrs_map_type basic_types_;
494 mutable istring_type_base_wptrs_map_type class_types_;
495 mutable istring_type_base_wptrs_map_type union_types_;
496 mutable istring_type_base_wptrs_map_type enum_types_;
497 mutable istring_type_base_wptrs_map_type typedef_types_;
498 mutable istring_type_base_wptrs_map_type qualified_types_;
499 mutable istring_type_base_wptrs_map_type pointer_types_;
500 mutable istring_type_base_wptrs_map_type reference_types_;
501 mutable istring_type_base_wptrs_map_type array_types_;
502 mutable istring_type_base_wptrs_map_type subrange_types_;
503 mutable istring_type_base_wptrs_map_type function_types_;
504 mutable vector<type_base_wptr> sorted_types_;
505 }; // end struct type_maps::priv
506
type_maps()507 type_maps::type_maps()
508 : priv_(new priv)
509 {}
510
511 type_maps::~type_maps() = default;
512
513 /// Test if the type_maps is empty.
514 ///
515 /// @return true iff the type_maps is empty.
516 bool
empty() const517 type_maps::empty() const
518 {
519 return (basic_types().empty()
520 && class_types().empty()
521 && union_types().empty()
522 && enum_types().empty()
523 && typedef_types().empty()
524 && qualified_types().empty()
525 && pointer_types().empty()
526 && reference_types().empty()
527 && array_types().empty()
528 && subrange_types().empty()
529 && function_types().empty());
530 }
531
532 /// Getter for the map that associates the name of a basic type to the
533 /// vector instances of type_decl_sptr that represents that type.
534 const istring_type_base_wptrs_map_type&
basic_types() const535 type_maps::basic_types() const
536 {return priv_->basic_types_;}
537
538 /// Getter for the map that associates the name of a basic type to the
539 /// vector of instances of @ref type_decl_sptr that represents that
540 /// type.
541 istring_type_base_wptrs_map_type&
basic_types()542 type_maps::basic_types()
543 {return priv_->basic_types_;}
544
545 /// Getter for the map that associates the name of a class type to the
546 /// vector of instances of @ref class_decl_sptr that represents that
547 /// type.
548 const istring_type_base_wptrs_map_type&
class_types() const549 type_maps::class_types() const
550 {return priv_->class_types_;}
551
552 /// Getter for the map that associates the name of a class type to the
553 /// vector of instances of @ref class_decl_sptr that represents that
554 /// type.
555 istring_type_base_wptrs_map_type&
class_types()556 type_maps::class_types()
557 {return priv_->class_types_;}
558
559 /// Getter for the map that associates the name of a union type to the
560 /// vector of instances of @ref union_decl_sptr that represents that
561 /// type.
562 istring_type_base_wptrs_map_type&
union_types()563 type_maps::union_types()
564 {return priv_->union_types_;}
565
566 /// Getter for the map that associates the name of a union type to the
567 /// vector of instances of @ref union_decl_sptr that represents that
568 /// type.
569 const istring_type_base_wptrs_map_type&
union_types() const570 type_maps::union_types() const
571 {return priv_->union_types_;}
572
573 /// Getter for the map that associates the name of an enum type to the
574 /// vector of instances of @ref enum_type_decl_sptr that represents
575 /// that type.
576 istring_type_base_wptrs_map_type&
enum_types()577 type_maps::enum_types()
578 {return priv_->enum_types_;}
579
580 /// Getter for the map that associates the name of an enum type to the
581 /// vector of instances of @ref enum_type_decl_sptr that represents
582 /// that type.
583 const istring_type_base_wptrs_map_type&
enum_types() const584 type_maps::enum_types() const
585 {return priv_->enum_types_;}
586
587 /// Getter for the map that associates the name of a typedef to the
588 /// vector of instances of @ref typedef_decl_sptr that represents tha
589 /// type.
590 istring_type_base_wptrs_map_type&
typedef_types()591 type_maps::typedef_types()
592 {return priv_->typedef_types_;}
593
594 /// Getter for the map that associates the name of a typedef to the
595 /// vector of instances of @ref typedef_decl_sptr that represents tha
596 /// type.
597 const istring_type_base_wptrs_map_type&
typedef_types() const598 type_maps::typedef_types() const
599 {return priv_->typedef_types_;}
600
601 /// Getter for the map that associates the name of a qualified type to
602 /// the vector of instances of @ref qualified_type_def_sptr.
603 istring_type_base_wptrs_map_type&
qualified_types()604 type_maps::qualified_types()
605 {return priv_->qualified_types_;}
606
607 /// Getter for the map that associates the name of a qualified type to
608 /// the vector of instances of @ref qualified_type_def_sptr.
609 const istring_type_base_wptrs_map_type&
qualified_types() const610 type_maps::qualified_types() const
611 {return priv_->qualified_types_;}
612
613 /// Getter for the map that associates the name of a pointer type to
614 /// the vector of instances of @ref pointer_type_def_sptr that
615 /// represents that type.
616 istring_type_base_wptrs_map_type&
pointer_types()617 type_maps::pointer_types()
618 {return priv_->pointer_types_;}
619
620 /// Getter for the map that associates the name of a pointer type to
621 /// the vector of instances of @ref pointer_type_def_sptr that
622 /// represents that type.
623 const istring_type_base_wptrs_map_type&
pointer_types() const624 type_maps::pointer_types() const
625 {return priv_->pointer_types_;}
626
627 /// Getter for the map that associates the name of a reference type to
628 /// the vector of instances of @ref reference_type_def_sptr that
629 /// represents that type.
630 istring_type_base_wptrs_map_type&
reference_types()631 type_maps::reference_types()
632 {return priv_->reference_types_;}
633
634 /// Getter for the map that associates the name of a reference type to
635 /// the vector of instances of @ref reference_type_def_sptr that
636 /// represents that type.
637 const istring_type_base_wptrs_map_type&
reference_types() const638 type_maps::reference_types() const
639 {return priv_->reference_types_;}
640
641 /// Getter for the map that associates the name of an array type to
642 /// the vector of instances of @ref array_type_def_sptr that
643 /// represents that type.
644 istring_type_base_wptrs_map_type&
array_types()645 type_maps::array_types()
646 {return priv_->array_types_;}
647
648 /// Getter for the map that associates the name of an array type to
649 /// the vector of instances of @ref array_type_def_sptr that
650 /// represents that type.
651 const istring_type_base_wptrs_map_type&
array_types() const652 type_maps::array_types() const
653 {return priv_->array_types_;}
654
655 /// Getter for the map that associates the name of a subrange type to
656 /// the vector of instances of @ref array_type_def::subrange_sptr that
657 /// represents that type.
658 istring_type_base_wptrs_map_type&
subrange_types()659 type_maps::subrange_types()
660 {return priv_->subrange_types_;}
661
662 /// Getter for the map that associates the name of a subrange type to
663 /// the vector of instances of @ref array_type_def::subrange_sptr that
664 /// represents that type.
665 const istring_type_base_wptrs_map_type&
subrange_types() const666 type_maps::subrange_types() const
667 {return priv_->subrange_types_;}
668
669 /// Getter for the map that associates the name of a function type to
670 /// the vector of instances of @ref function_type_sptr that represents
671 /// that type.
672 const istring_type_base_wptrs_map_type&
function_types() const673 type_maps::function_types() const
674 {return priv_->function_types_;}
675
676 /// Getter for the map that associates the name of a function type to
677 /// the vector of instances of @ref function_type_sptr that represents
678 /// that type.
679 istring_type_base_wptrs_map_type&
function_types()680 type_maps::function_types()
681 {return priv_->function_types_;}
682
683 /// A comparison functor to compare/sort types based on their pretty
684 /// representations.
685 struct type_name_comp
686 {
687 /// Comparison operator for two instances of @ref type_base.
688 ///
689 /// This compares the two types by lexicographically comparing their
690 /// pretty representation.
691 ///
692 /// @param l the left-most type to compare.
693 ///
694 /// @param r the right-most type to compare.
695 ///
696 /// @return true iff @p l < @p r.
697 bool
operator ()abigail::ir::type_name_comp698 operator()(type_base *l, type_base *r) const
699 {
700 if (l == 0 && r == 0)
701 return false;
702
703 string l_repr = get_pretty_representation(l);
704 string r_repr = get_pretty_representation(r);
705 return l_repr < r_repr;
706 }
707
708 /// Comparison operator for two instances of @ref type_base.
709 ///
710 /// This compares the two types by lexicographically comparing their
711 /// pretty representation.
712 ///
713 /// @param l the left-most type to compare.
714 ///
715 /// @param r the right-most type to compare.
716 ///
717 /// @return true iff @p l < @p r.
718 bool
operator ()abigail::ir::type_name_comp719 operator()(const type_base_sptr &l, const type_base_sptr &r) const
720 {return operator()(l.get(), r.get());}
721
722 /// Comparison operator for two instances of @ref type_base.
723 ///
724 /// This compares the two types by lexicographically comparing their
725 /// pretty representation.
726 ///
727 /// @param l the left-most type to compare.
728 ///
729 /// @param r the right-most type to compare.
730 ///
731 /// @return true iff @p l < @p r.
732 bool
operator ()abigail::ir::type_name_comp733 operator()(const type_base_wptr &l, const type_base_wptr &r) const
734 {return operator()(type_base_sptr(l), type_base_sptr(r));}
735 }; // end struct type_name_comp
736
737 #ifdef WITH_DEBUG_SELF_COMPARISON
738
739 /// This is a function called when the ABG_RETURN* macros defined
740 /// below return false.
741 ///
742 /// The purpose of this function is to ease debugging. To know where
743 /// the equality functions first compare non-equal, we can just set a
744 /// breakpoint on this notify_equality_failed function and run the
745 /// equality functions. Because all the equality functions use the
746 /// ABG_RETURN* macros to return their values, this function is always
747 /// called when any of those equality function return false.
748 ///
749 /// @param l the first operand of the equality.
750 ///
751 /// @param r the second operand of the equality.
752 static void
notify_equality_failed(const type_or_decl_base & l,const type_or_decl_base & r)753 notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
754 const type_or_decl_base &r __attribute__((unused)))
755 {}
756
757 /// This is a function called when the ABG_RETURN* macros defined
758 /// below return false.
759 ///
760 /// The purpose of this function is to ease debugging. To know where
761 /// the equality functions first compare non-equal, we can just set a
762 /// breakpoint on this notify_equality_failed function and run the
763 /// equality functions. Because all the equality functions use the
764 /// ABG_RETURN* macros to return their values, this function is always
765 /// called when any of those equality function return false.
766 ///
767 /// @param l the first operand of the equality.
768 ///
769 /// @param r the second operand of the equality.
770 static void
notify_equality_failed(const type_or_decl_base * l,const type_or_decl_base * r)771 notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
772 const type_or_decl_base *r __attribute__((unused)))
773 {}
774
775 #define ABG_RETURN_EQUAL(l, r) \
776 do \
777 { \
778 if (l != r) \
779 notify_equality_failed(l, r); \
780 return (l == r); \
781 } \
782 while(false)
783
784
785 #define ABG_RETURN_FALSE \
786 do \
787 { \
788 notify_equality_failed(l, r); \
789 return false; \
790 } while(false)
791
792 #define ABG_RETURN(value) \
793 do \
794 { \
795 if (value == false) \
796 notify_equality_failed(l, r); \
797 return value; \
798 } while (false)
799
800 #else // WITH_DEBUG_SELF_COMPARISON
801
802 #define ABG_RETURN_FALSE return false
803 #define ABG_RETURN(value) return (value)
804 #define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
805 #endif
806
807 /// Compare two types by comparing their canonical types if present.
808 ///
809 /// If the canonical types are not present (because the types have not
810 /// yet been canonicalized, for instance) then the types are compared
811 /// structurally.
812 ///
813 /// @param l the first type to take into account in the comparison.
814 ///
815 /// @param r the second type to take into account in the comparison.
816 template<typename T>
817 bool
try_canonical_compare(const T * l,const T * r)818 try_canonical_compare(const T *l, const T *r)
819 {
820 #if WITH_DEBUG_TYPE_CANONICALIZATION
821 // We are debugging the canonicalization of a type down the stack.
822 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
823 // type being canonicalized. We are at a point where we can compare
824 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
825 // have canonical types) or structural comparison.
826 //
827 // Because we are debugging the process of type canonicalization, we
828 // want to compare 'l' and 'r' canonically *AND* structurally. Both
829 // kinds of comparison should yield the same result, otherwise type
830 // canonicalization just failed for the subtype 'r' of the type
831 // being canonicalized.
832 //
833 // In concrete terms, this function is going to be called twice with
834 // the same pair {'l', 'r'} to compare: The first time with
835 // environment::priv_->use_canonical_type_comparison_ set to true,
836 // instructing us to compare them canonically, and the second time
837 // with that boolean set to false, instructing us to compare them
838 // structurally.
839 const environment&env = l->get_environment();
840 if (env.priv_->use_canonical_type_comparison_)
841 {
842 if (const type_base *lc = l->get_naked_canonical_type())
843 if (const type_base *rc = r->get_naked_canonical_type())
844 ABG_RETURN_EQUAL(lc, rc);
845 }
846 return equals(*l, *r, 0);
847 #else
848 if (const type_base *lc = l->get_naked_canonical_type())
849 if (const type_base *rc = r->get_naked_canonical_type())
850 ABG_RETURN_EQUAL(lc, rc);
851 return equals(*l, *r, 0);
852 #endif
853
854
855 }
856
857 /// Detect if a recursive comparison cycle is detected while
858 /// structurally comparing two types (a.k.a member-wise comparison).
859 ///
860 /// @param l the left-hand-side operand of the current comparison.
861 ///
862 /// @param r the right-hand-side operand of the current comparison.
863 ///
864 /// @return true iff a comparison cycle is detected.
865 template<typename T>
866 bool
is_comparison_cycle_detected(T & l,T & r)867 is_comparison_cycle_detected(T& l, T& r)
868 {
869 bool result = l.priv_->comparison_started(l, r);
870 return result ;
871 }
872
873 /// Detect if a recursive comparison cycle is detected while
874 /// structurally comparing two @ref class_decl types.
875 ///
876 /// @param l the left-hand-side operand of the current comparison.
877 ///
878 /// @param r the right-hand-side operand of the current comparison.
879 ///
880 /// @return true iff a comparison cycle is detected.
881 template<>
882 bool
is_comparison_cycle_detected(const class_decl & l,const class_decl & r)883 is_comparison_cycle_detected(const class_decl& l, const class_decl& r)
884 {
885 return is_comparison_cycle_detected(static_cast<const class_or_union&>(l),
886 static_cast<const class_or_union&>(r));
887 }
888
889 /// This macro is to be used while comparing composite types that
890 /// might recursively refer to themselves. Comparing two such types
891 /// might get us into a cyle.
892 ///
893 /// Practically, if we detect that we are already into comparing 'l'
894 /// and 'r'; then, this is a cycle.
895 //
896 /// To break the cycle, we assume the result of the comparison is true
897 /// for now. Comparing the other sub-types of l & r will tell us later
898 /// if l & r are actually different or not.
899 ///
900 /// In the mean time, returning true from this macro should not be
901 /// used to propagate the canonical type of 'l' onto 'r' as we don't
902 /// know yet if l equals r. All the types that depend on l and r
903 /// can't (and that are in the comparison stack currently) can't have
904 /// their canonical type propagated either. So this macro disallows
905 /// canonical type propagation for those types that depend on a
906 /// recursively defined sub-type for now.
907 ///
908 /// @param l the left-hand-side operand of the comparison.
909 #define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
910 do \
911 { \
912 if (is_comparison_cycle_detected(l, r)) \
913 { \
914 mark_dependant_types_compared_until(r); \
915 return true; \
916 } \
917 } \
918 while(false)
919
920
921 /// Mark a pair of types as being compared.
922 ///
923 /// This is helpful to later detect recursive cycles in the comparison
924 /// stack.
925 ///
926 /// @param l the left-hand-side operand of the comparison.
927 ///
928 /// @parm r the right-hand-side operand of the comparison.
929 template<typename T>
930 void
mark_types_as_being_compared(T & l,T & r)931 mark_types_as_being_compared(T& l, T&r)
932 {
933 l.priv_->mark_as_being_compared(l, r);
934 push_composite_type_comparison_operands(l, r);
935 }
936
937 /// Mark a pair of @ref class_decl types as being compared.
938 ///
939 /// This is helpful to later detect recursive cycles in the comparison
940 /// stack.
941 ///
942 /// @param l the left-hand-side operand of the comparison.
943 ///
944 /// @parm r the right-hand-side operand of the comparison.
945 template<>
946 void
mark_types_as_being_compared(const class_decl & l,const class_decl & r)947 mark_types_as_being_compared(const class_decl& l, const class_decl &r)
948 {
949 return mark_types_as_being_compared(static_cast<const class_or_union&>(l),
950 static_cast<const class_or_union&>(r));
951 }
952
953 /// Mark a pair of types as being not compared anymore.
954 ///
955 /// This is helpful to later detect recursive cycles in the comparison
956 /// stack.
957 ///
958 /// Note that the types must have been passed to
959 /// mark_types_as_being_compared prior to calling this function.
960 ///
961 /// @param l the left-hand-side operand of the comparison.
962 ///
963 /// @parm r the right-hand-side operand of the comparison.
964 template<typename T>
965 void
unmark_types_as_being_compared(T & l,T & r)966 unmark_types_as_being_compared(T& l, T&r)
967 {
968 l.priv_->unmark_as_being_compared(l, r);
969 pop_composite_type_comparison_operands(l, r);
970 }
971
972 /// Mark a pair of @ref class_decl types as being not compared
973 /// anymore.
974 ///
975 /// This is helpful to later detect recursive cycles in the comparison
976 /// stack.
977 ///
978 /// Note that the types must have been passed to
979 /// mark_types_as_being_compared prior to calling this function.
980 ///
981 /// @param l the left-hand-side operand of the comparison.
982 ///
983 /// @parm r the right-hand-side operand of the comparison.
984 template<>
985 void
unmark_types_as_being_compared(const class_decl & l,const class_decl & r)986 unmark_types_as_being_compared(const class_decl& l, const class_decl &r)
987 {
988 return unmark_types_as_being_compared(static_cast<const class_or_union&>(l),
989 static_cast<const class_or_union&>(r));
990 }
991
992 /// Return the result of the comparison of two (sub) types.
993 ///
994 /// The function does the necessary book keeping before returning the
995 /// result of the comparison of two (sub) types.
996 ///
997 /// The book-keeping done is in the following
998 /// areas:
999 ///
1000 /// * Management of the Canonical Type Propagation optimization
1001 /// * type comparison cycle detection
1002 ///
1003 /// @param l the left-hand-side operand of the type comparison
1004 ///
1005 /// @param r the right-hand-side operand of the type comparison
1006 ///
1007 /// @param propagate_canonical_type if true, it means the function
1008 /// performs the @ref OnTheFlyCanonicalization, aka, "canonical type
1009 /// propagation optimization".
1010 ///
1011 /// @param value the result of the comparison of @p l and @p r.
1012 ///
1013 /// @return the value @p value.
1014 template<typename T>
1015 bool
return_comparison_result(T & l,T & r,bool value,bool propagate_canonical_type=true)1016 return_comparison_result(T& l, T& r, bool value,
1017 bool propagate_canonical_type = true)
1018 {
1019 if (propagate_canonical_type && (value == true))
1020 maybe_propagate_canonical_type(l, r);
1021
1022 unmark_types_as_being_compared(l, r);
1023
1024 const environment& env = l.get_environment();
1025 if (env.do_on_the_fly_canonicalization())
1026 // We are instructed to perform the "canonical type propagation"
1027 // optimization, making 'r' to possibly get the canonical type of
1028 // 'l' if it has one. This mostly means that we are currently
1029 // canonicalizing the type that contain the subtype provided in
1030 // the 'r' argument.
1031 {
1032 if (value == true
1033 && (is_type(&r)->priv_->depends_on_recursive_type()
1034 || env.priv_->is_recursive_type(&r))
1035 && is_type(&r)->priv_->canonical_type_propagated()
1036 && !is_type(&r)->priv_->propagated_canonical_type_confirmed()
1037 && !env.priv_->right_type_comp_operands_.empty())
1038 {
1039 // Track the object 'r' for which the propagated canonical
1040 // type might be re-initialized if the current comparison
1041 // eventually fails.
1042 env.priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
1043 }
1044 else if (value == true
1045 && env.priv_->right_type_comp_operands_.empty()
1046 && is_type(&r)->priv_->canonical_type_propagated()
1047 && !is_type(&r)->priv_->propagated_canonical_type_confirmed())
1048 {
1049 // The type provided in the 'r' argument is the type that is
1050 // being canonicalized; 'r' is not a mere subtype being
1051 // compared, it's the whole type being canonicalized. And
1052 // its canonicalization has just succeeded.
1053 //
1054 // Let's confirm the canonical type resulting from the
1055 // "canonical type propagation" optimization.
1056 env.priv_->confirm_ct_propagation(&r);
1057 }
1058 else if (value == true
1059 && is_type(&r)->priv_->canonical_type_propagated()
1060 && !is_type(&r)->priv_->propagated_canonical_type_confirmed())
1061 // In any other case, we are not sure if propagated types
1062 // should be confirmed yet. So let's mark them as such.
1063 env.priv_->add_to_types_with_non_confirmed_propagated_ct(is_type(&r));
1064 else if (value == false)
1065 {
1066 // The comparison of the current sub-type failed. So all
1067 // the with non-confirmed propagated types (those in
1068 // env.prix_->types_with_non_confirmed_propagated_ct_)
1069 // should see their tentatively propagated canonical type
1070 // cancelled.
1071 env.priv_->cancel_all_non_confirmed_propagated_canonical_types();
1072 }
1073 }
1074
1075 // If we reached this point with value == true and the stack of
1076 // types being compared is empty, then it means that the type pair
1077 // that was at the bottom of the stack is now fully compared.
1078 //
1079 // It follows that all types that were target of canonical type
1080 // propagation can now see their tentative canonical type be
1081 // confirmed for real.
1082 if (value == true
1083 && env.priv_->right_type_comp_operands_.empty()
1084 && !env.priv_->types_with_non_confirmed_propagated_ct_.empty())
1085 // So the comparison is completely done and there are some
1086 // types for which their propagated canonical type is sitll
1087 // considered not confirmed. As the comparison did yield true, we
1088 // shall now confirm the propagation for all those types.
1089 env.priv_->confirm_ct_propagation();
1090
1091 #ifdef WITH_DEBUG_SELF_COMPARISON
1092 if (value == false && env.priv_->right_type_comp_operands_.empty())
1093 {
1094 for (const auto i : env.priv_->types_with_non_confirmed_propagated_ct_)
1095 {
1096 type_base *t = reinterpret_cast<type_base*>(i);
1097 env.priv_->check_abixml_canonical_type_propagation_during_self_comp(t);
1098 }
1099 }
1100 #endif
1101
1102 ABG_RETURN(value);
1103 }
1104
1105 #define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1106 do \
1107 { \
1108 bool res = return_comparison_result(l, r, value); \
1109 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1110 return res; \
1111 } while (false)
1112
1113 /// Cache the result of a comparison between too artifacts (l & r) and
1114 /// return immediately.
1115 ///
1116 /// @param value the value to cache.
1117 #define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1118 do \
1119 { \
1120 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1121 return value; \
1122 } while (false)
1123
1124 /// Getter of all types types sorted by their pretty representation.
1125 ///
1126 /// @return a sorted vector of all types sorted by their pretty
1127 /// representation.
1128 const vector<type_base_wptr>&
get_types_sorted_by_name() const1129 type_maps::get_types_sorted_by_name() const
1130 {
1131 if (priv_->sorted_types_.empty())
1132 {
1133 istring_type_base_wptrs_map_type::const_iterator i;
1134 vector<type_base_wptr>::const_iterator j;
1135
1136 for (i = basic_types().begin(); i != basic_types().end(); ++i)
1137 for (j = i->second.begin(); j != i->second.end(); ++j)
1138 priv_->sorted_types_.push_back(*j);
1139
1140 for (i = class_types().begin(); i != class_types().end(); ++i)
1141 for (j = i->second.begin(); j != i->second.end(); ++j)
1142 priv_->sorted_types_.push_back(*j);
1143
1144 for (i = union_types().begin(); i != union_types().end(); ++i)
1145 for (j = i->second.begin(); j != i->second.end(); ++j)
1146 priv_->sorted_types_.push_back(*j);
1147
1148 for (i = enum_types().begin(); i != enum_types().end(); ++i)
1149 for (j = i->second.begin(); j != i->second.end(); ++j)
1150 priv_->sorted_types_.push_back(*j);
1151
1152 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1153 for (j = i->second.begin(); j != i->second.end(); ++j)
1154 priv_->sorted_types_.push_back(*j);
1155
1156 type_name_comp comp;
1157 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1158 }
1159
1160 return priv_->sorted_types_;
1161 }
1162
1163 // </type_maps stuff>
1164
1165 // <translation_unit stuff>
1166
1167 /// Constructor of translation_unit.
1168 ///
1169 /// @param env the environment of this translation unit. Please note
1170 /// that the life time of the environment must be greater than the
1171 /// life time of the translation unit because the translation uses
1172 /// resources that are allocated in the environment.
1173 ///
1174 /// @param path the location of the translation unit.
1175 ///
1176 /// @param address_size the size of addresses in the translation unit,
1177 /// in bits.
translation_unit(const environment & env,const std::string & path,char address_size)1178 translation_unit::translation_unit(const environment& env,
1179 const std::string& path,
1180 char address_size)
1181 : priv_(new priv(env))
1182 {
1183 priv_->path_ = path;
1184 priv_->address_size_ = address_size;
1185 }
1186
1187 /// Getter of the the global scope of the translation unit.
1188 ///
1189 /// @return the global scope of the current translation unit. If
1190 /// there is not global scope allocated yet, this function creates one
1191 /// and returns it.
1192 const scope_decl_sptr&
get_global_scope() const1193 translation_unit::get_global_scope() const
1194 {
1195 return const_cast<translation_unit*>(this)->get_global_scope();
1196 }
1197
1198 /// Getter of the the global scope of the translation unit.
1199 ///
1200 /// @return the global scope of the current translation unit. If
1201 /// there is not global scope allocated yet, this function creates one
1202 /// and returns it.
1203 scope_decl_sptr&
get_global_scope()1204 translation_unit::get_global_scope()
1205 {
1206 if (!priv_->global_scope_)
1207 {
1208 priv_->global_scope_.reset
1209 (new global_scope(const_cast<translation_unit*>(this)));
1210 priv_->global_scope_->set_translation_unit
1211 (const_cast<translation_unit*>(this));
1212 }
1213 return priv_->global_scope_;
1214 }
1215
1216 /// Getter of the types of the current @ref translation_unit.
1217 ///
1218 /// @return the maps of the types of the translation unit.
1219 const type_maps&
get_types() const1220 translation_unit::get_types() const
1221 {return priv_->types_;}
1222
1223 /// Getter of the types of the current @ref translation_unit.
1224 ///
1225 /// @return the maps of the types of the translation unit.
1226 type_maps&
get_types()1227 translation_unit::get_types()
1228 {return priv_->types_;}
1229
1230 /// Get the vector of function types that are used in the current
1231 /// translation unit.
1232 ///
1233 /// @return the vector of function types that are used in the current
1234 /// translation unit.
1235 const vector<function_type_sptr>&
get_live_fn_types() const1236 translation_unit::get_live_fn_types() const
1237 {return priv_->live_fn_types_;}
1238
1239 /// Getter of the environment of the current @ref translation_unit.
1240 ///
1241 /// @return the translation unit of the current translation unit.
1242 const environment&
get_environment() const1243 translation_unit::get_environment() const
1244 {return priv_->env_;}
1245
1246 /// Getter of the language of the source code of the translation unit.
1247 ///
1248 /// @return the language of the source code.
1249 translation_unit::language
get_language() const1250 translation_unit::get_language() const
1251 {return priv_->language_;}
1252
1253 /// Setter of the language of the source code of the translation unit.
1254 ///
1255 /// @param l the new language.
1256 void
set_language(language l)1257 translation_unit::set_language(language l)
1258 {priv_->language_ = l;}
1259
1260
1261 /// Get the path of the current translation unit.
1262 ///
1263 /// This path is relative to the build directory of the translation
1264 /// unit as returned by translation_unit::get_compilation_dir_path.
1265 ///
1266 /// @return the relative path of the compilation unit associated to
1267 /// the current instance of translation_unit.
1268 //
1269 const std::string&
get_path() const1270 translation_unit::get_path() const
1271 {return priv_->path_;}
1272
1273 /// Set the path associated to the current instance of
1274 /// translation_unit.
1275 ///
1276 /// This path is relative to the build directory of the translation
1277 /// unit as returned by translation_unit::get_compilation_dir_path.
1278 ///
1279 /// @param a_path the new relative path to set.
1280 void
set_path(const string & a_path)1281 translation_unit::set_path(const string& a_path)
1282 {priv_->path_ = a_path;}
1283
1284
1285 /// Get the path of the directory that was 'current' when the
1286 /// translation unit was compiled.
1287 ///
1288 /// Note that the path returned by translation_unit::get_path is
1289 /// relative to the path returned by this function.
1290 ///
1291 /// @return the compilation directory for the current translation
1292 /// unit.
1293 const std::string&
get_compilation_dir_path() const1294 translation_unit::get_compilation_dir_path() const
1295 {return priv_->comp_dir_path_;}
1296
1297 /// Set the path of the directory that was 'current' when the
1298 /// translation unit was compiled.
1299 ///
1300 /// Note that the path returned by translation_unit::get_path is
1301 /// relative to the path returned by this function.
1302 ///
1303 /// @param the compilation directory for the current translation unit.
1304 void
set_compilation_dir_path(const std::string & d)1305 translation_unit::set_compilation_dir_path(const std::string& d)
1306 {priv_->comp_dir_path_ = d;}
1307
1308 /// Get the concatenation of the build directory and the relative path
1309 /// of the translation unit.
1310 ///
1311 /// @return the absolute path of the translation unit.
1312 const std::string&
get_absolute_path() const1313 translation_unit::get_absolute_path() const
1314 {
1315 if (priv_->abs_path_.empty())
1316 {
1317 string path;
1318 if (!priv_->path_.empty())
1319 {
1320 if (!priv_->comp_dir_path_.empty())
1321 {
1322 path = priv_->comp_dir_path_;
1323 path += "/";
1324 }
1325 path += priv_->path_;
1326 }
1327 priv_->abs_path_ = path;
1328 }
1329
1330 return priv_->abs_path_;
1331 }
1332
1333 /// Set the corpus this translation unit is a member of.
1334 ///
1335 /// Note that adding a translation unit to a @ref corpus automatically
1336 /// triggers a call to this member function.
1337 ///
1338 /// @param corpus the corpus.
1339 void
set_corpus(corpus * c)1340 translation_unit::set_corpus(corpus* c)
1341 {priv_->corp = c;}
1342
1343 /// Get the corpus this translation unit is a member of.
1344 ///
1345 /// @return the parent corpus, or nil if this doesn't belong to any
1346 /// corpus yet.
1347 corpus*
get_corpus()1348 translation_unit::get_corpus()
1349 {return priv_->corp;}
1350
1351 /// Get the corpus this translation unit is a member of.
1352 ///
1353 /// @return the parent corpus, or nil if this doesn't belong to any
1354 /// corpus yet.
1355 const corpus*
get_corpus() const1356 translation_unit::get_corpus() const
1357 {return const_cast<translation_unit*>(this)->get_corpus();}
1358
1359 /// Getter of the location manager for the current translation unit.
1360 ///
1361 /// @return a reference to the location manager for the current
1362 /// translation unit.
1363 location_manager&
get_loc_mgr()1364 translation_unit::get_loc_mgr()
1365 {return priv_->loc_mgr_;}
1366
1367 /// const Getter of the location manager.
1368 ///
1369 /// @return a const reference to the location manager for the current
1370 /// translation unit.
1371 const location_manager&
get_loc_mgr() const1372 translation_unit::get_loc_mgr() const
1373 {return priv_->loc_mgr_;}
1374
1375 /// Tests whether if the current translation unit contains ABI
1376 /// artifacts or not.
1377 ///
1378 /// @return true iff the current translation unit is empty.
1379 bool
is_empty() const1380 translation_unit::is_empty() const
1381 {
1382 if (!priv_->global_scope_)
1383 return true;
1384 return get_global_scope()->is_empty();
1385 }
1386
1387 /// Getter of the address size in this translation unit.
1388 ///
1389 /// @return the address size, in bits.
1390 char
get_address_size() const1391 translation_unit::get_address_size() const
1392 {return priv_->address_size_;}
1393
1394 /// Setter of the address size in this translation unit.
1395 ///
1396 /// @param a the new address size in bits.
1397 void
set_address_size(char a)1398 translation_unit::set_address_size(char a)
1399 {priv_->address_size_= a;}
1400
1401 /// Getter of the 'is_constructed" flag. It says if the translation
1402 /// unit is fully constructed or not.
1403 ///
1404 /// This flag is important for cases when comparison might depend on
1405 /// if the translation unit is fully built or not. For instance, when
1406 /// reading types from DWARF, the virtual methods of a class are not
1407 /// necessarily fully constructed until we have reached the end of the
1408 /// translation unit. In that case, before we've reached the end of
1409 /// the translation unit, we might not take virtual functions into
1410 /// account when comparing classes.
1411 ///
1412 /// @return true if the translation unit is constructed.
1413 bool
is_constructed() const1414 translation_unit::is_constructed() const
1415 {return priv_->is_constructed_;}
1416
1417 /// Setter of the 'is_constructed" flag. It says if the translation
1418 /// unit is fully constructed or not.
1419 ///
1420 /// This flag is important for cases when comparison might depend on
1421 /// if the translation unit is fully built or not. For instance, when
1422 /// reading types from DWARF, the virtual methods of a class are not
1423 /// necessarily fully constructed until we have reached the end of the
1424 /// translation unit. In that case, before we've reached the end of
1425 /// the translation unit, we might not take virtual functions into
1426 /// account when comparing classes.
1427 ///
1428 /// @param f true if the translation unit is constructed.
1429 void
set_is_constructed(bool f)1430 translation_unit::set_is_constructed(bool f)
1431 {priv_->is_constructed_ = f;}
1432
1433 /// Compare the current translation unit against another one.
1434 ///
1435 /// @param other the other tu to compare against.
1436 ///
1437 /// @return true if the two translation units are equal, false
1438 /// otherwise.
1439 bool
operator ==(const translation_unit & other) const1440 translation_unit::operator==(const translation_unit& other)const
1441 {
1442 if (get_address_size() != other.get_address_size())
1443 return false;
1444
1445 return *get_global_scope() == *other.get_global_scope();
1446 }
1447
1448 /// Inequality operator.
1449 ///
1450 /// @param o the instance of @ref translation_unit to compare the
1451 /// current instance against.
1452 ///
1453 /// @return true iff the current instance is different from @p o.
1454 bool
operator !=(const translation_unit & o) const1455 translation_unit::operator!=(const translation_unit& o) const
1456 {return ! operator==(o);}
1457
1458 /// Ensure that the life time of a function type is bound to the life
1459 /// time of the current translation unit.
1460 ///
1461 /// @param ftype the function time which life time to bind to the life
1462 /// time of the current instance of @ref translation_unit. That is,
1463 /// it's onlyh when the translation unit is destroyed that the
1464 /// function type can be destroyed to.
1465 void
bind_function_type_life_time(function_type_sptr ftype) const1466 translation_unit::bind_function_type_life_time(function_type_sptr ftype) const
1467 {
1468 const environment& env = get_environment();
1469
1470 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1471
1472 interned_string repr = get_type_name(ftype);
1473 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1474 push_back(ftype);
1475
1476 // The function type must be out of the same environment as its
1477 // translation unit.
1478 {
1479 const environment& e = ftype->get_environment();
1480 ABG_ASSERT(&env == &e);
1481 }
1482
1483 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1484 ABG_ASSERT(existing_tu == this);
1485 else
1486 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1487
1488 maybe_update_types_lookup_map(ftype);
1489 }
1490
1491 /// This implements the ir_traversable_base::traverse virtual
1492 /// function.
1493 ///
1494 /// @param v the visitor used on the member nodes of the translation
1495 /// unit during the traversal.
1496 ///
1497 /// @return true if the entire type IR tree got traversed, false
1498 /// otherwise.
1499 bool
traverse(ir_node_visitor & v)1500 translation_unit::traverse(ir_node_visitor& v)
1501 {return get_global_scope()->traverse(v);}
1502
~translation_unit()1503 translation_unit::~translation_unit()
1504 {}
1505
1506 /// Converts a translation_unit::language enumerator into a string.
1507 ///
1508 /// @param l the language enumerator to translate.
1509 ///
1510 /// @return the resulting string.
1511 string
translation_unit_language_to_string(translation_unit::language l)1512 translation_unit_language_to_string(translation_unit::language l)
1513 {
1514 switch (l)
1515 {
1516 case translation_unit::LANG_UNKNOWN:
1517 return "LANG_UNKNOWN";
1518 case translation_unit::LANG_Cobol74:
1519 return "LANG_Cobol74";
1520 case translation_unit::LANG_Cobol85:
1521 return "LANG_Cobol85";
1522 case translation_unit::LANG_C89:
1523 return "LANG_C89";
1524 case translation_unit::LANG_C99:
1525 return "LANG_C99";
1526 case translation_unit::LANG_C11:
1527 return "LANG_C11";
1528 case translation_unit::LANG_C:
1529 return "LANG_C";
1530 case translation_unit::LANG_C_plus_plus_11:
1531 return "LANG_C_plus_plus_11";
1532 case translation_unit::LANG_C_plus_plus_14:
1533 return "LANG_C_plus_plus_14";
1534 case translation_unit::LANG_C_plus_plus:
1535 return "LANG_C_plus_plus";
1536 case translation_unit::LANG_ObjC:
1537 return "LANG_ObjC";
1538 case translation_unit::LANG_ObjC_plus_plus:
1539 return "LANG_ObjC_plus_plus";
1540 case translation_unit::LANG_Fortran77:
1541 return "LANG_Fortran77";
1542 case translation_unit::LANG_Fortran90:
1543 return "LANG_Fortran90";
1544 case translation_unit::LANG_Fortran95:
1545 return "LANG_Fortran95";
1546 case translation_unit::LANG_Ada83:
1547 return "LANG_Ada83";
1548 case translation_unit::LANG_Ada95:
1549 return "LANG_Ada95";
1550 case translation_unit::LANG_Pascal83:
1551 return "LANG_Pascal83";
1552 case translation_unit::LANG_Modula2:
1553 return "LANG_Modula2";
1554 case translation_unit::LANG_Java:
1555 return "LANG_Java";
1556 case translation_unit::LANG_PLI:
1557 return "LANG_PLI";
1558 case translation_unit::LANG_UPC:
1559 return "LANG_UPC";
1560 case translation_unit::LANG_D:
1561 return "LANG_D";
1562 case translation_unit::LANG_Python:
1563 return "LANG_Python";
1564 case translation_unit::LANG_Go:
1565 return "LANG_Go";
1566 case translation_unit::LANG_Mips_Assembler:
1567 return "LANG_Mips_Assembler";
1568 default:
1569 return "LANG_UNKNOWN";
1570 }
1571
1572 return "LANG_UNKNOWN";
1573 }
1574
1575 /// Parse a string representing a language into a
1576 /// translation_unit::language enumerator into a string.
1577 ///
1578 /// @param l the string representing the language.
1579 ///
1580 /// @return the resulting translation_unit::language enumerator.
1581 translation_unit::language
string_to_translation_unit_language(const string & l)1582 string_to_translation_unit_language(const string& l)
1583 {
1584 if (l == "LANG_Cobol74")
1585 return translation_unit::LANG_Cobol74;
1586 else if (l == "LANG_Cobol85")
1587 return translation_unit::LANG_Cobol85;
1588 else if (l == "LANG_C89")
1589 return translation_unit::LANG_C89;
1590 else if (l == "LANG_C99")
1591 return translation_unit::LANG_C99;
1592 else if (l == "LANG_C11")
1593 return translation_unit::LANG_C11;
1594 else if (l == "LANG_C")
1595 return translation_unit::LANG_C;
1596 else if (l == "LANG_C_plus_plus_11")
1597 return translation_unit::LANG_C_plus_plus_11;
1598 else if (l == "LANG_C_plus_plus_14")
1599 return translation_unit::LANG_C_plus_plus_14;
1600 else if (l == "LANG_C_plus_plus")
1601 return translation_unit::LANG_C_plus_plus;
1602 else if (l == "LANG_ObjC")
1603 return translation_unit::LANG_ObjC;
1604 else if (l == "LANG_ObjC_plus_plus")
1605 return translation_unit::LANG_ObjC_plus_plus;
1606 else if (l == "LANG_Fortran77")
1607 return translation_unit::LANG_Fortran77;
1608 else if (l == "LANG_Fortran90")
1609 return translation_unit::LANG_Fortran90;
1610 else if (l == "LANG_Fortran95")
1611 return translation_unit::LANG_Fortran95;
1612 else if (l == "LANG_Ada83")
1613 return translation_unit::LANG_Ada83;
1614 else if (l == "LANG_Ada95")
1615 return translation_unit::LANG_Ada95;
1616 else if (l == "LANG_Pascal83")
1617 return translation_unit::LANG_Pascal83;
1618 else if (l == "LANG_Modula2")
1619 return translation_unit::LANG_Modula2;
1620 else if (l == "LANG_Java")
1621 return translation_unit::LANG_Java;
1622 else if (l == "LANG_PLI")
1623 return translation_unit::LANG_PLI;
1624 else if (l == "LANG_UPC")
1625 return translation_unit::LANG_UPC;
1626 else if (l == "LANG_D")
1627 return translation_unit::LANG_D;
1628 else if (l == "LANG_Python")
1629 return translation_unit::LANG_Python;
1630 else if (l == "LANG_Go")
1631 return translation_unit::LANG_Go;
1632 else if (l == "LANG_Mips_Assembler")
1633 return translation_unit::LANG_Mips_Assembler;
1634
1635 return translation_unit::LANG_UNKNOWN;
1636 }
1637
1638 /// Test if a language enumerator designates the C language.
1639 ///
1640 /// @param l the language enumerator to consider.
1641 ///
1642 /// @return true iff @p l designates the C language.
1643 bool
is_c_language(translation_unit::language l)1644 is_c_language(translation_unit::language l)
1645 {
1646 return (l == translation_unit::LANG_C89
1647 || l == translation_unit::LANG_C99
1648 || l == translation_unit::LANG_C11
1649 || l == translation_unit::LANG_C);
1650 }
1651
1652 /// Test if a language enumerator designates the C++ language.
1653 ///
1654 /// @param l the language enumerator to consider.
1655 ///
1656 /// @return true iff @p l designates the C++ language.
1657 bool
is_cplus_plus_language(translation_unit::language l)1658 is_cplus_plus_language(translation_unit::language l)
1659 {
1660 return (l == translation_unit::LANG_C_plus_plus_03
1661 || l == translation_unit::LANG_C_plus_plus_11
1662 || l == translation_unit::LANG_C_plus_plus_14
1663 || l == translation_unit::LANG_C_plus_plus);
1664 }
1665
1666 /// Test if a language enumerator designates the Java language.
1667 ///
1668 /// @param l the language enumerator to consider.
1669 ///
1670 /// @return true iff @p l designates the Java language.
1671 bool
is_java_language(translation_unit::language l)1672 is_java_language(translation_unit::language l)
1673 {return l == translation_unit::LANG_Java;}
1674
1675 /// Test if a language enumerator designates the Ada language.
1676 ///
1677 /// @param l the language enumerator to consider.
1678 ///
1679 /// @return true iff @p l designates the Ada language.
1680 bool
is_ada_language(translation_unit::language l)1681 is_ada_language(translation_unit::language l)
1682 {
1683 return (l == translation_unit::LANG_Ada83
1684 || l == translation_unit::LANG_Ada95);
1685 }
1686
1687 /// A deep comparison operator for pointers to translation units.
1688 ///
1689 /// @param l the first translation unit to consider for the comparison.
1690 ///
1691 /// @param r the second translation unit to consider for the comparison.
1692 ///
1693 /// @return true if the two translation units are equal, false otherwise.
1694 bool
operator ==(const translation_unit_sptr & l,const translation_unit_sptr & r)1695 operator==(const translation_unit_sptr& l, const translation_unit_sptr& r)
1696 {
1697 if (l.get() == r.get())
1698 return true;
1699
1700 if (!!l != !!r)
1701 return false;
1702
1703 return *l == *r;
1704 }
1705
1706 /// A deep inequality operator for pointers to translation units.
1707 ///
1708 /// @param l the first translation unit to consider for the comparison.
1709 ///
1710 /// @param r the second translation unit to consider for the comparison.
1711 ///
1712 /// @return true iff the two translation units are different.
1713 bool
operator !=(const translation_unit_sptr & l,const translation_unit_sptr & r)1714 operator!=(const translation_unit_sptr& l, const translation_unit_sptr& r)
1715 {return !operator==(l, r);}
1716
1717 // </translation_unit stuff>
1718
1719 // <elf_symbol stuff>
1720 struct elf_symbol::priv
1721 {
1722 const environment& env_;
1723 size_t index_;
1724 size_t size_;
1725 string name_;
1726 elf_symbol::type type_;
1727 elf_symbol::binding binding_;
1728 elf_symbol::version version_;
1729 elf_symbol::visibility visibility_;
1730 bool is_defined_;
1731 // This flag below says if the symbol is a common elf symbol. In
1732 // relocatable files, a common symbol is a symbol defined in a
1733 // section of kind SHN_COMMON.
1734 //
1735 // Note that a symbol of kind STT_COMMON is also considered a common
1736 // symbol. Here is what the gABI says about STT_COMMON and
1737 // SHN_COMMON:
1738 //
1739 // Symbols with type STT_COMMON label uninitialized common
1740 // blocks. In relocatable objects, these symbols are not
1741 // allocated and must have the special section index SHN_COMMON
1742 // (see below). In shared objects and executables these symbols
1743 // must be allocated to some section in the defining object.
1744 //
1745 // In relocatable objects, symbols with type STT_COMMON are
1746 // treated just as other symbols with index SHN_COMMON. If the
1747 // link-editor allocates space for the SHN_COMMON symbol in an
1748 // output section of the object it is producing, it must
1749 // preserve the type of the output symbol as STT_COMMON.
1750 //
1751 // When the dynamic linker encounters a reference to a symbol
1752 // that resolves to a definition of type STT_COMMON, it may (but
1753 // is not required to) change its symbol resolution rules as
1754 // follows: instead of binding the reference to the first symbol
1755 // found with the given name, the dynamic linker searches for
1756 // the first symbol with that name with type other than
1757 // STT_COMMON. If no such symbol is found, it looks for the
1758 // STT_COMMON definition of that name that has the largest size.
1759 bool is_common_;
1760 bool is_in_ksymtab_;
1761 abg_compat::optional<uint32_t> crc_;
1762 abg_compat::optional<std::string> namespace_;
1763 bool is_suppressed_;
1764 elf_symbol_wptr main_symbol_;
1765 elf_symbol_wptr next_alias_;
1766 elf_symbol_wptr next_common_instance_;
1767 string id_string_;
1768
privabigail::ir::elf_symbol::priv1769 priv(const environment& e)
1770 : env_(e),
1771 index_(),
1772 size_(),
1773 type_(elf_symbol::NOTYPE_TYPE),
1774 binding_(elf_symbol::GLOBAL_BINDING),
1775 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1776 is_defined_(false),
1777 is_common_(false),
1778 is_in_ksymtab_(false),
1779 crc_(),
1780 namespace_(),
1781 is_suppressed_(false)
1782 {}
1783
privabigail::ir::elf_symbol::priv1784 priv(const environment& e,
1785 size_t i,
1786 size_t s,
1787 const string& n,
1788 elf_symbol::type t,
1789 elf_symbol::binding b,
1790 bool d,
1791 bool c,
1792 const elf_symbol::version& ve,
1793 elf_symbol::visibility vi,
1794 bool is_in_ksymtab,
1795 const abg_compat::optional<uint32_t>& crc,
1796 const abg_compat::optional<std::string>& ns,
1797 bool is_suppressed)
1798 : env_(e),
1799 index_(i),
1800 size_(s),
1801 name_(n),
1802 type_(t),
1803 binding_(b),
1804 version_(ve),
1805 visibility_(vi),
1806 is_defined_(d),
1807 is_common_(c),
1808 is_in_ksymtab_(is_in_ksymtab),
1809 crc_(crc),
1810 namespace_(ns),
1811 is_suppressed_(is_suppressed)
1812 {
1813 if (!is_common_)
1814 is_common_ = type_ == COMMON_TYPE;
1815 }
1816 }; // end struct elf_symbol::priv
1817
1818 /// Constructor of the @ref elf_symbol type.
1819 ///
1820 /// Note that this constructor is private, so client code cannot use
1821 /// it to create instances of @ref elf_symbol. Rather, client code
1822 /// should use the @ref elf_symbol::create() function to create
1823 /// instances of @ref elf_symbol instead.
1824 ///
1825 /// @param e the environment we are operating from.
1826 ///
1827 /// @param i the index of the symbol in the (ELF) symbol table.
1828 ///
1829 /// @param s the size of the symbol.
1830 ///
1831 /// @param n the name of the symbol.
1832 ///
1833 /// @param t the type of the symbol.
1834 ///
1835 /// @param b the binding of the symbol.
1836 ///
1837 /// @param d true if the symbol is defined, false otherwise.
1838 ///
1839 /// @param c true if the symbol is a common symbol, false otherwise.
1840 ///
1841 /// @param ve the version of the symbol.
1842 ///
1843 /// @param vi the visibility of the symbol.
1844 ///
1845 /// @param crc the CRC (modversions) value of Linux Kernel symbols
1846 ///
1847 /// @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)1848 elf_symbol::elf_symbol(const environment& e,
1849 size_t i,
1850 size_t s,
1851 const string& n,
1852 type t,
1853 binding b,
1854 bool d,
1855 bool c,
1856 const version& ve,
1857 visibility vi,
1858 bool is_in_ksymtab,
1859 const abg_compat::optional<uint32_t>& crc,
1860 const abg_compat::optional<std::string>& ns,
1861 bool is_suppressed)
1862 : priv_(new priv(e,
1863 i,
1864 s,
1865 n,
1866 t,
1867 b,
1868 d,
1869 c,
1870 ve,
1871 vi,
1872 is_in_ksymtab,
1873 crc,
1874 ns,
1875 is_suppressed))
1876 {}
1877
1878 /// Factory of instances of @ref elf_symbol.
1879 ///
1880 /// This is the function to use to create instances of @ref elf_symbol.
1881 ///
1882 /// @param e the environment we are operating from.
1883 ///
1884 /// @param i the index of the symbol in the (ELF) symbol table.
1885 ///
1886 /// @param s the size of the symbol.
1887 ///
1888 /// @param n the name of the symbol.
1889 ///
1890 /// @param t the type of the symbol.
1891 ///
1892 /// @param b the binding of the symbol.
1893 ///
1894 /// @param d true if the symbol is defined, false otherwise.
1895 ///
1896 /// @param c true if the symbol is a common symbol.
1897 ///
1898 /// @param ve the version of the symbol.
1899 ///
1900 /// @param vi the visibility of the symbol.
1901 ///
1902 /// @param crc the CRC (modversions) value of Linux Kernel symbols
1903 ///
1904 /// @param ns the namespace of Linux Kernel symbols, if any
1905 ///
1906 /// @return a (smart) pointer to a newly created instance of @ref
1907 /// elf_symbol.
1908 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)1909 elf_symbol::create(const environment& e,
1910 size_t i,
1911 size_t s,
1912 const string& n,
1913 type t,
1914 binding b,
1915 bool d,
1916 bool c,
1917 const version& ve,
1918 visibility vi,
1919 bool is_in_ksymtab,
1920 const abg_compat::optional<uint32_t>& crc,
1921 const abg_compat::optional<std::string>& ns,
1922 bool is_suppressed)
1923 {
1924 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
1925 is_in_ksymtab, crc, ns, is_suppressed));
1926 sym->priv_->main_symbol_ = sym;
1927 return sym;
1928 }
1929
1930 /// Test textual equality between two symbols.
1931 ///
1932 /// Textual equality means that the aliases of the compared symbols
1933 /// are not taken into account. Only the name, type, and version of
1934 /// the symbols are compared.
1935 ///
1936 /// @return true iff the two symbols are textually equal.
1937 static bool
textually_equals(const elf_symbol & l,const elf_symbol & r)1938 textually_equals(const elf_symbol&l,
1939 const elf_symbol&r)
1940 {
1941 bool equals = (l.get_name() == r.get_name()
1942 && l.get_type() == r.get_type()
1943 && l.is_public() == r.is_public()
1944 && l.is_defined() == r.is_defined()
1945 && l.is_common_symbol() == r.is_common_symbol()
1946 && l.get_version() == r.get_version()
1947 && l.get_crc() == r.get_crc()
1948 && l.get_namespace() == r.get_namespace());
1949
1950 if (equals && l.is_variable())
1951 // These are variable symbols. Let's compare their symbol size.
1952 // The symbol size in this case is the size taken by the storage
1953 // of the variable. If that size changes, then it's an ABI
1954 // change.
1955 equals = l.get_size() == r.get_size();
1956
1957 return equals;
1958 }
1959
1960 /// Getter of the environment used by the current instance of @ref
1961 /// elf_symbol.
1962 ///
1963 /// @return the enviroment used by the current instance of @ref elf_symbol.
1964 const environment&
get_environment() const1965 elf_symbol::get_environment() const
1966 {return priv_->env_;}
1967
1968 /// Getter for the index
1969 ///
1970 /// @return the index of the symbol.
1971 size_t
get_index() const1972 elf_symbol::get_index() const
1973 {return priv_->index_;}
1974
1975 /// Setter for the index.
1976 ///
1977 /// @param s the new index.
1978 void
set_index(size_t s)1979 elf_symbol::set_index(size_t s)
1980 {priv_->index_ = s;}
1981
1982 /// Getter for the name of the @ref elf_symbol.
1983 ///
1984 /// @return a reference to the name of the @ref symbol.
1985 const string&
get_name() const1986 elf_symbol::get_name() const
1987 {return priv_->name_;}
1988
1989 /// Setter for the name of the current intance of @ref elf_symbol.
1990 ///
1991 /// @param n the new name.
1992 void
set_name(const string & n)1993 elf_symbol::set_name(const string& n)
1994 {
1995 priv_->name_ = n;
1996 priv_->id_string_.clear();
1997 }
1998
1999 /// Getter for the type of the current instance of @ref elf_symbol.
2000 ///
2001 /// @return the type of the elf symbol.
2002 elf_symbol::type
get_type() const2003 elf_symbol::get_type() const
2004 {return priv_->type_;}
2005
2006 /// Setter for the type of the current instance of @ref elf_symbol.
2007 ///
2008 /// @param t the new symbol type.
2009 void
set_type(type t)2010 elf_symbol::set_type(type t)
2011 {priv_->type_ = t;}
2012
2013 /// Getter of the size of the symbol.
2014 ///
2015 /// @return the size of the symbol, in bytes.
2016 size_t
get_size() const2017 elf_symbol::get_size() const
2018 {return priv_->size_;}
2019
2020 /// Setter of the size of the symbol.
2021 ///
2022 /// @param size the new size of the symbol, in bytes.
2023 void
set_size(size_t size)2024 elf_symbol::set_size(size_t size)
2025 {priv_->size_ = size;}
2026
2027 /// Getter for the binding of the current instance of @ref elf_symbol.
2028 ///
2029 /// @return the binding of the symbol.
2030 elf_symbol::binding
get_binding() const2031 elf_symbol::get_binding() const
2032 {return priv_->binding_;}
2033
2034 /// Setter for the binding of the current instance of @ref elf_symbol.
2035 ///
2036 /// @param b the new binding.
2037 void
set_binding(binding b)2038 elf_symbol::set_binding(binding b)
2039 {priv_->binding_ = b;}
2040
2041 /// Getter for the version of the current instanc of @ref elf_symbol.
2042 ///
2043 /// @return the version of the elf symbol.
2044 elf_symbol::version&
get_version() const2045 elf_symbol::get_version() const
2046 {return priv_->version_;}
2047
2048 /// Setter for the version of the current instance of @ref elf_symbol.
2049 ///
2050 /// @param v the new version of the elf symbol.
2051 void
set_version(const version & v)2052 elf_symbol::set_version(const version& v)
2053 {
2054 priv_->version_ = v;
2055 priv_->id_string_.clear();
2056 }
2057
2058 /// Setter of the visibility of the current instance of @ref
2059 /// elf_symbol.
2060 ///
2061 /// @param v the new visibility of the elf symbol.
2062 void
set_visibility(visibility v)2063 elf_symbol::set_visibility(visibility v)
2064 {priv_->visibility_ = v;}
2065
2066 /// Getter of the visibility of the current instance of @ref
2067 /// elf_symbol.
2068 ///
2069 /// @return the visibility of the elf symbol.
2070 elf_symbol::visibility
get_visibility() const2071 elf_symbol::get_visibility() const
2072 {return priv_->visibility_;}
2073
2074 /// Test if the current instance of @ref elf_symbol is defined or not.
2075 ///
2076 /// @return true if the current instance of @ref elf_symbol is
2077 /// defined, false otherwise.
2078 bool
is_defined() const2079 elf_symbol::is_defined() const
2080 {return priv_->is_defined_;}
2081
2082 /// Sets a flag saying if the current instance of @ref elf_symbol is
2083 /// defined
2084 ///
2085 /// @param b the new value of the flag.
2086 void
is_defined(bool d)2087 elf_symbol::is_defined(bool d)
2088 {priv_->is_defined_ = d;}
2089
2090 /// Test if the current instance of @ref elf_symbol is public or not.
2091 ///
2092 /// This tests if the symbol is defined, has default or protected
2093 ///visibility, and either:
2094 /// - has global binding
2095 /// - has weak binding
2096 /// - or has a GNU_UNIQUE binding.
2097 ///
2098 /// return true if the current instance of @ref elf_symbol is public,
2099 /// false otherwise.
2100 bool
is_public() const2101 elf_symbol::is_public() const
2102 {
2103 return (is_defined()
2104 && (get_binding() == GLOBAL_BINDING
2105 || get_binding() == WEAK_BINDING
2106 || get_binding() == GNU_UNIQUE_BINDING)
2107 && (get_visibility() == DEFAULT_VISIBILITY
2108 || get_visibility() == PROTECTED_VISIBILITY));
2109 }
2110
2111 /// Test if the current instance of @ref elf_symbol is a function
2112 /// symbol or not.
2113 ///
2114 /// @return true if the current instance of @ref elf_symbol is a
2115 /// function symbol, false otherwise.
2116 bool
is_function() const2117 elf_symbol::is_function() const
2118 {return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2119
2120 /// Test if the current instance of @ref elf_symbol is a variable
2121 /// symbol or not.
2122 ///
2123 /// @return true if the current instance of @ref elf_symbol is a
2124 /// variable symbol, false otherwise.
2125 bool
is_variable() const2126 elf_symbol::is_variable() const
2127 {return get_type() == OBJECT_TYPE || get_type() == TLS_TYPE;}
2128
2129 /// Getter of the 'is-in-ksymtab' property.
2130 ///
2131 /// @return true iff the current symbol is in the Linux Kernel
2132 /// specific 'ksymtab' symbol table.
2133 bool
is_in_ksymtab() const2134 elf_symbol::is_in_ksymtab() const
2135 {return priv_->is_in_ksymtab_;}
2136
2137 /// Setter of the 'is-in-ksymtab' property.
2138 ///
2139 /// @param is_in_ksymtab this is true iff the current symbol is in the
2140 /// Linux Kernel specific 'ksymtab' symbol table.
2141 void
set_is_in_ksymtab(bool is_in_ksymtab)2142 elf_symbol::set_is_in_ksymtab(bool is_in_ksymtab)
2143 {priv_->is_in_ksymtab_ = is_in_ksymtab;}
2144
2145 /// Getter of the 'crc' property.
2146 ///
2147 /// @return the CRC (modversions) value for Linux Kernel symbols, if any
2148 const abg_compat::optional<uint32_t>&
get_crc() const2149 elf_symbol::get_crc() const
2150 {return priv_->crc_;}
2151
2152 /// Setter of the 'crc' property.
2153 ///
2154 /// @param crc the new CRC (modversions) value for Linux Kernel symbols
2155 void
set_crc(const abg_compat::optional<uint32_t> & crc)2156 elf_symbol::set_crc(const abg_compat::optional<uint32_t>& crc)
2157 {priv_->crc_ = crc;}
2158
2159 /// Getter of the 'namespace' property.
2160 ///
2161 /// @return the namespace for Linux Kernel symbols, if any
2162 const abg_compat::optional<std::string>&
get_namespace() const2163 elf_symbol::get_namespace() const
2164 {return priv_->namespace_;}
2165
2166 /// Setter of the 'namespace' property.
2167 ///
2168 /// @param ns the new namespace for Linux Kernel symbols, if any
2169 void
set_namespace(const abg_compat::optional<std::string> & ns)2170 elf_symbol::set_namespace(const abg_compat::optional<std::string>& ns)
2171 {priv_->namespace_ = ns;}
2172
2173 /// Getter for the 'is-suppressed' property.
2174 ///
2175 /// @return true iff the current symbol has been suppressed by a
2176 /// suppression specification that was provided in the context that
2177 /// led to the creation of the corpus this ELF symbol belongs to.
2178 bool
is_suppressed() const2179 elf_symbol::is_suppressed() const
2180 {return priv_->is_suppressed_;}
2181
2182 /// Setter for the 'is-suppressed' property.
2183 ///
2184 /// @param true iff the current symbol has been suppressed by a
2185 /// suppression specification that was provided in the context that
2186 /// led to the creation of the corpus this ELF symbol belongs to.
2187 void
set_is_suppressed(bool is_suppressed)2188 elf_symbol::set_is_suppressed(bool is_suppressed)
2189 {priv_->is_suppressed_ = is_suppressed;}
2190
2191 /// @name Elf symbol aliases
2192 ///
2193 /// An alias A for an elf symbol S is a symbol that is defined at the
2194 /// same address as S. S is chained to A through the
2195 /// elf_symbol::get_next_alias() method.
2196 ///
2197 /// When there are several aliases to a symbol, the main symbol is the
2198 /// the first symbol found in the symbol table for a given address.
2199 ///
2200 /// The alias chain is circular. That means if S is the main symbol
2201 /// and A is the alias, S is chained to A and A
2202 /// is chained back to the main symbol S. The last alias in an alias
2203 ///chain is always chained to the main symbol.
2204 ///
2205 /// Thus, when looping over the aliases of an elf_symbol A, detecting
2206 /// an alias that is equal to the main symbol should logically be a
2207 /// loop exit condition.
2208 ///
2209 /// Accessing and adding aliases for instances of elf_symbol is done
2210 /// through the member functions below.
2211
2212 /// @{
2213
2214 /// Get the main symbol of an alias chain.
2215 ///
2216 ///@return the main symbol.
2217 const elf_symbol_sptr
get_main_symbol() const2218 elf_symbol::get_main_symbol() const
2219 {return priv_->main_symbol_.lock();}
2220
2221 /// Get the main symbol of an alias chain.
2222 ///
2223 ///@return the main symbol.
2224 elf_symbol_sptr
get_main_symbol()2225 elf_symbol::get_main_symbol()
2226 {return priv_->main_symbol_.lock();}
2227
2228 /// Tests whether this symbol is the main symbol.
2229 ///
2230 /// @return true iff this symbol is the main symbol.
2231 bool
is_main_symbol() const2232 elf_symbol::is_main_symbol() const
2233 {return get_main_symbol().get() == this;}
2234
2235 /// Get the next alias of the current symbol.
2236 ///
2237 ///@return the alias, or NULL if there is no alias.
2238 elf_symbol_sptr
get_next_alias() const2239 elf_symbol::get_next_alias() const
2240 {return priv_->next_alias_.lock();}
2241
2242
2243 /// Check if the current elf_symbol has an alias.
2244 ///
2245 ///@return true iff the current elf_symbol has an alias.
2246 bool
has_aliases() const2247 elf_symbol::has_aliases() const
2248 {return bool(get_next_alias());}
2249
2250 /// Get the number of aliases to this elf symbol
2251 ///
2252 /// @return the number of aliases to this elf symbol.
2253 int
get_number_of_aliases() const2254 elf_symbol::get_number_of_aliases() const
2255 {
2256 int result = 0;
2257
2258 for (elf_symbol_sptr a = get_next_alias();
2259 a && a.get() != get_main_symbol().get();
2260 a = a->get_next_alias())
2261 ++result;
2262
2263 return result;
2264 }
2265
2266 /// Add an alias to the current elf symbol.
2267 ///
2268 /// @param alias the new alias. Note that this elf_symbol should *NOT*
2269 /// have aliases prior to the invocation of this function.
2270 void
add_alias(const elf_symbol_sptr & alias)2271 elf_symbol::add_alias(const elf_symbol_sptr& alias)
2272 {
2273 if (!alias)
2274 return;
2275
2276 ABG_ASSERT(!alias->has_aliases());
2277 ABG_ASSERT(is_main_symbol());
2278
2279 if (has_aliases())
2280 {
2281 elf_symbol_sptr last_alias;
2282 for (elf_symbol_sptr a = get_next_alias();
2283 a && !a->is_main_symbol();
2284 a = a->get_next_alias())
2285 {
2286 if (a->get_next_alias()->is_main_symbol())
2287 {
2288 ABG_ASSERT(last_alias == 0);
2289 last_alias = a;
2290 }
2291 }
2292 ABG_ASSERT(last_alias);
2293
2294 last_alias->priv_->next_alias_ = alias;
2295 }
2296 else
2297 priv_->next_alias_ = alias;
2298
2299 alias->priv_->next_alias_ = get_main_symbol();
2300 alias->priv_->main_symbol_ = get_main_symbol();
2301 }
2302
2303 /// Update the main symbol for a group of aliased symbols
2304 ///
2305 /// If after the construction of the symbols (in order of discovery), the
2306 /// actual main symbol can be identified (e.g. as the symbol that actually is
2307 /// defined in the code), this method offers a way of updating the main symbol
2308 /// through one of the aliased symbols.
2309 ///
2310 /// For that, locate the new main symbol by name and update all references to
2311 /// the main symbol among the group of aliased symbols.
2312 ///
2313 /// @param name the name of the main symbol
2314 ///
2315 /// @return the new main elf_symbol
2316 elf_symbol_sptr
update_main_symbol(const std::string & name)2317 elf_symbol::update_main_symbol(const std::string& name)
2318 {
2319 ABG_ASSERT(is_main_symbol());
2320 if (!has_aliases() || get_name() == name)
2321 return get_main_symbol();
2322
2323 // find the new main symbol
2324 elf_symbol_sptr new_main;
2325 // we've already checked this; check the rest of the aliases
2326 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2327 a = a->get_next_alias())
2328 if (a->get_name() == name)
2329 {
2330 new_main = a;
2331 break;
2332 }
2333
2334 if (!new_main)
2335 return get_main_symbol();
2336
2337 // now update all main symbol references
2338 priv_->main_symbol_ = new_main;
2339 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2340 a = a->get_next_alias())
2341 a->priv_->main_symbol_ = new_main;
2342
2343 return new_main;
2344 }
2345
2346 /// Return true if the symbol is a common one.
2347 ///
2348 /// @return true iff the symbol is common.
2349 bool
is_common_symbol() const2350 elf_symbol::is_common_symbol() const
2351 {return priv_->is_common_;}
2352
2353 /// Return true if this common common symbol has other common instances.
2354 ///
2355 /// A common instance of a given common symbol is another common
2356 /// symbol with the same name. Those exist in relocatable files. The
2357 /// linker normally allocates all the instances into a common block in
2358 /// the final output file.
2359 ///
2360 /// Note that the current object must be a common symbol, otherwise,
2361 /// this function aborts.
2362 ///
2363 /// @return true iff the current common symbol has other common
2364 /// instances.
2365 bool
has_other_common_instances() const2366 elf_symbol::has_other_common_instances() const
2367 {
2368 ABG_ASSERT(is_common_symbol());
2369 return bool(get_next_common_instance());
2370 }
2371
2372 /// Get the next common instance of the current common symbol.
2373 ///
2374 /// A common instance of a given common symbol is another common
2375 /// symbol with the same name. Those exist in relocatable files. The
2376 /// linker normally allocates all the instances into a common block in
2377 /// the final output file.
2378 ///
2379 /// @return the next common instance, or nil if there is not any.
2380 elf_symbol_sptr
get_next_common_instance() const2381 elf_symbol::get_next_common_instance() const
2382 {return priv_->next_common_instance_.lock();}
2383
2384 /// Add a common instance to the current common elf symbol.
2385 ///
2386 /// Note that this symbol must be the main symbol. Being the main
2387 /// symbol means being the first common symbol to appear in the symbol
2388 /// table.
2389 ///
2390 /// @param common the other common instance to add.
2391 void
add_common_instance(const elf_symbol_sptr & common)2392 elf_symbol::add_common_instance(const elf_symbol_sptr& common)
2393 {
2394 if (!common)
2395 return;
2396
2397 ABG_ASSERT(!common->has_other_common_instances());
2398 ABG_ASSERT(is_common_symbol());
2399 ABG_ASSERT(is_main_symbol());
2400
2401 if (has_other_common_instances())
2402 {
2403 elf_symbol_sptr last_common_instance;
2404 for (elf_symbol_sptr c = get_next_common_instance();
2405 c && (c.get() != get_main_symbol().get());
2406 c = c->get_next_common_instance())
2407 {
2408 if (c->get_next_common_instance().get() == get_main_symbol().get())
2409 {
2410 ABG_ASSERT(last_common_instance == 0);
2411 last_common_instance = c;
2412 }
2413 }
2414 ABG_ASSERT(last_common_instance);
2415
2416 last_common_instance->priv_->next_common_instance_ = common;
2417 }
2418 else
2419 priv_->next_common_instance_ = common;
2420
2421 common->priv_->next_common_instance_ = get_main_symbol();
2422 common->priv_->main_symbol_ = get_main_symbol();
2423 }
2424
2425 /// Get a string that is representative of a given elf_symbol.
2426 ///
2427 /// If the symbol has a version, then the ID string is the
2428 /// concatenation of the name of the symbol, the '@' character, and
2429 /// the version of the symbol. If the version is the default version
2430 /// of the symbol then the '@' character is replaced by a "@@" string.
2431 ///
2432 /// Otherwise, if the symbol does not have any version, this function
2433 /// returns the name of the symbol.
2434 ///
2435 /// @return a the ID string.
2436 const string&
get_id_string() const2437 elf_symbol::get_id_string() const
2438 {
2439 if (priv_->id_string_.empty())
2440 {
2441 string s = get_name ();
2442
2443 if (!get_version().is_empty())
2444 {
2445 if (get_version().is_default())
2446 s += "@@";
2447 else
2448 s += "@";
2449 s += get_version().str();
2450 }
2451 priv_->id_string_ = s;
2452 }
2453
2454 return priv_->id_string_;
2455 }
2456
2457 /// From the aliases of the current symbol, lookup one with a given name.
2458 ///
2459 /// @param name the name of symbol alias we are looking for.
2460 ///
2461 /// @return the symbol alias that has the name @p name, or nil if none
2462 /// has been found.
2463 elf_symbol_sptr
get_alias_from_name(const string & name) const2464 elf_symbol::get_alias_from_name(const string& name) const
2465 {
2466 if (name == get_name())
2467 return elf_symbol_sptr(priv_->main_symbol_);
2468
2469 for (elf_symbol_sptr a = get_next_alias();
2470 a && a.get() != get_main_symbol().get();
2471 a = a->get_next_alias())
2472 if (a->get_name() == name)
2473 return a;
2474
2475 return elf_symbol_sptr();
2476 }
2477
2478 /// In the list of aliases of a given elf symbol, get the alias that
2479 /// equals this current symbol.
2480 ///
2481 /// @param other the elf symbol to get the potential aliases from.
2482 ///
2483 /// @return the alias of @p other that texually equals the current
2484 /// symbol, or nil if no alias textually equals the current symbol.
2485 elf_symbol_sptr
get_alias_which_equals(const elf_symbol & other) const2486 elf_symbol::get_alias_which_equals(const elf_symbol& other) const
2487 {
2488 for (elf_symbol_sptr a = other.get_next_alias();
2489 a && a.get() != a->get_main_symbol().get();
2490 a = a->get_next_alias())
2491 if (textually_equals(*this, *a))
2492 return a;
2493 return elf_symbol_sptr();
2494 }
2495
2496 /// Return a comma separated list of the id of the current symbol as
2497 /// well as the id string of its aliases.
2498 ///
2499 /// @param syms a map of all the symbols of the corpus the current
2500 /// symbol belongs to.
2501 ///
2502 /// @param include_symbol_itself if set to true, then the name of the
2503 /// current symbol is included in the list of alias names that is emitted.
2504 ///
2505 /// @return the string.
2506 string
get_aliases_id_string(const string_elf_symbols_map_type & syms,bool include_symbol_itself) const2507 elf_symbol::get_aliases_id_string(const string_elf_symbols_map_type& syms,
2508 bool include_symbol_itself) const
2509 {
2510 string result;
2511
2512 if (include_symbol_itself)
2513 result = get_id_string();
2514
2515 vector<elf_symbol_sptr> aliases;
2516 compute_aliases_for_elf_symbol(*this, syms, aliases);
2517 if (!aliases.empty() && include_symbol_itself)
2518 result += ", ";
2519
2520 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2521 i != aliases.end();
2522 ++i)
2523 {
2524 if (i != aliases.begin())
2525 result += ", ";
2526 result += (*i)->get_id_string();
2527 }
2528 return result;
2529 }
2530
2531 /// Return a comma separated list of the id of the current symbol as
2532 /// well as the id string of its aliases.
2533 ///
2534 /// @param include_symbol_itself if set to true, then the name of the
2535 /// current symbol is included in the list of alias names that is emitted.
2536 ///
2537 /// @return the string.
2538 string
get_aliases_id_string(bool include_symbol_itself) const2539 elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2540 {
2541 vector<elf_symbol_sptr> aliases;
2542 if (include_symbol_itself)
2543 aliases.push_back(get_main_symbol());
2544
2545 for (elf_symbol_sptr a = get_next_alias();
2546 a && a.get() != get_main_symbol().get();
2547 a = a->get_next_alias())
2548 aliases.push_back(a);
2549
2550 string result;
2551 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2552 i != aliases.end();
2553 ++i)
2554 {
2555 if (i != aliases.begin())
2556 result += ", ";
2557 result += (*i)->get_id_string();
2558 }
2559
2560 return result;
2561 }
2562
2563 /// Given the ID of a symbol, get the name and the version of said
2564 /// symbol.
2565 ///
2566 /// @param id the symbol ID to consider.
2567 ///
2568 /// @param name the symbol name extracted from the ID. This is set
2569 /// only if the function returned true.
2570 ///
2571 /// @param ver the symbol version extracted from the ID.
2572 bool
get_name_and_version_from_id(const string & id,string & name,string & ver)2573 elf_symbol::get_name_and_version_from_id(const string& id,
2574 string& name,
2575 string& ver)
2576 {
2577 name.clear(), ver.clear();
2578
2579 string::size_type i = id.find('@');
2580 if (i == string::npos)
2581 {
2582 name = id;
2583 return true;
2584 }
2585
2586 name = id.substr(0, i);
2587 ++i;
2588
2589 if (i >= id.size())
2590 return true;
2591
2592 string::size_type j = id.find('@', i);
2593 if (j == string::npos)
2594 j = i;
2595 else
2596 ++j;
2597
2598 if (j >= id.size())
2599 {
2600 ver = "";
2601 return true;
2602 }
2603
2604 ver = id.substr(j);
2605 return true;
2606 }
2607
2608 ///@}
2609
2610 /// Test if two main symbols are textually equal, or, if they have
2611 /// aliases that are textually equal.
2612 ///
2613 /// @param other the symbol to compare against.
2614 ///
2615 /// @return true iff the current instance of elf symbol equals the @p
2616 /// other.
2617 bool
operator ==(const elf_symbol & other) const2618 elf_symbol::operator==(const elf_symbol& other) const
2619 {
2620 bool are_equal = textually_equals(*this, other);
2621 if (!are_equal)
2622 are_equal = bool(get_alias_which_equals(other));
2623 return are_equal;
2624 }
2625
2626 /// Test if the current symbol aliases another one.
2627 ///
2628 /// @param o the other symbol to test against.
2629 ///
2630 /// @return true iff the current symbol aliases @p o.
2631 bool
does_alias(const elf_symbol & o) const2632 elf_symbol::does_alias(const elf_symbol& o) const
2633 {
2634 if (*this == o)
2635 return true;
2636
2637 if (get_main_symbol() == o.get_main_symbol())
2638 return true;
2639
2640 for (elf_symbol_sptr a = get_next_alias();
2641 a && !a->is_main_symbol();
2642 a = a->get_next_alias())
2643 {
2644 if (o == *a)
2645 return true;
2646 }
2647 return false;
2648 }
2649
2650 /// Equality operator for smart pointers to elf_symbol.
2651 ///
2652 /// @param lhs the first elf symbol to consider.
2653 ///
2654 /// @param rhs the second elf symbol to consider.
2655 ///
2656 /// @return true iff @p lhs equals @p rhs.
2657 bool
operator ==(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2658 operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2659 {
2660 if (!!lhs != !!rhs)
2661 return false;
2662
2663 if (!lhs)
2664 return true;
2665
2666 return *lhs == *rhs;
2667 }
2668
2669 /// Inequality operator for smart pointers to elf_symbol.
2670 ///
2671 /// @param lhs the first elf symbol to consider.
2672 ///
2673 /// @param rhs the second elf symbol to consider.
2674 ///
2675 /// @return true iff @p lhs is different from @p rhs.
2676 bool
operator !=(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2677 operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2678 {return !operator==(lhs, rhs);}
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 {return s1.does_alias(s2) || s2.does_alias(s1);}
2690
2691 void
compute_aliases_for_elf_symbol(const elf_symbol & sym,const string_elf_symbols_map_type & symtab,vector<elf_symbol_sptr> & aliases)2692 compute_aliases_for_elf_symbol(const elf_symbol& sym,
2693 const string_elf_symbols_map_type& symtab,
2694 vector<elf_symbol_sptr>& aliases)
2695 {
2696
2697 if (elf_symbol_sptr a = sym.get_next_alias())
2698 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2699 aliases.push_back(a);
2700 else
2701 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2702 i != symtab.end();
2703 ++i)
2704 for (elf_symbols::const_iterator j = i->second.begin();
2705 j != i->second.end();
2706 ++j)
2707 {
2708 if (**j == sym)
2709 for (elf_symbol_sptr s = (*j)->get_next_alias();
2710 s && !s->is_main_symbol();
2711 s = s->get_next_alias())
2712 aliases.push_back(s);
2713 else
2714 for (elf_symbol_sptr s = (*j)->get_next_alias();
2715 s && !s->is_main_symbol();
2716 s = s->get_next_alias())
2717 if (*s == sym)
2718 aliases.push_back(*j);
2719 }
2720 }
2721
2722 /// Test if two symbols alias.
2723 ///
2724 /// @param s1 the first symbol to consider.
2725 ///
2726 /// @param s2 the second symbol to consider.
2727 ///
2728 /// @return true if @p s1 aliases @p s2.
2729 bool
elf_symbols_alias(const elf_symbol * s1,const elf_symbol * s2)2730 elf_symbols_alias(const elf_symbol* s1, const elf_symbol* s2)
2731 {
2732 if (!!s1 != !!s2)
2733 return false;
2734 if (s1 == s2)
2735 return true;
2736 return elf_symbols_alias(*s1, *s2);
2737 }
2738
2739 /// Test if two symbols alias.
2740 ///
2741 /// @param s1 the first symbol to consider.
2742 ///
2743 /// @param s2 the second symbol to consider.
2744 ///
2745 /// @return true if @p s1 aliases @p s2.
2746 bool
elf_symbols_alias(const elf_symbol_sptr s1,const elf_symbol_sptr s2)2747 elf_symbols_alias(const elf_symbol_sptr s1, const elf_symbol_sptr s2)
2748 {return elf_symbols_alias(s1.get(), s2.get());}
2749
2750 /// Serialize an instance of @ref symbol_type and stream it to a given
2751 /// output stream.
2752 ///
2753 /// @param o the output stream to serialize the symbole type to.
2754 ///
2755 /// @param t the symbol type to serialize.
2756 std::ostream&
operator <<(std::ostream & o,elf_symbol::type t)2757 operator<<(std::ostream& o, elf_symbol::type t)
2758 {
2759 string repr;
2760
2761 switch (t)
2762 {
2763 case elf_symbol::NOTYPE_TYPE:
2764 repr = "unspecified symbol type";
2765 break;
2766 case elf_symbol::OBJECT_TYPE:
2767 repr = "variable symbol type";
2768 break;
2769 case elf_symbol::FUNC_TYPE:
2770 repr = "function symbol type";
2771 break;
2772 case elf_symbol::SECTION_TYPE:
2773 repr = "section symbol type";
2774 break;
2775 case elf_symbol::FILE_TYPE:
2776 repr = "file symbol type";
2777 break;
2778 case elf_symbol::COMMON_TYPE:
2779 repr = "common data object symbol type";
2780 break;
2781 case elf_symbol::TLS_TYPE:
2782 repr = "thread local data object symbol type";
2783 break;
2784 case elf_symbol::GNU_IFUNC_TYPE:
2785 repr = "indirect function symbol type";
2786 break;
2787 default:
2788 {
2789 std::ostringstream s;
2790 s << "unknown symbol type (" << (char)t << ')';
2791 repr = s.str();
2792 }
2793 break;
2794 }
2795
2796 o << repr;
2797 return o;
2798 }
2799
2800 /// Serialize an instance of @ref symbol_binding and stream it to a
2801 /// given output stream.
2802 ///
2803 /// @param o the output stream to serialize the symbole type to.
2804 ///
2805 /// @param b the symbol binding to serialize.
2806 std::ostream&
operator <<(std::ostream & o,elf_symbol::binding b)2807 operator<<(std::ostream& o, elf_symbol::binding b)
2808 {
2809 string repr;
2810
2811 switch (b)
2812 {
2813 case elf_symbol::LOCAL_BINDING:
2814 repr = "local binding";
2815 break;
2816 case elf_symbol::GLOBAL_BINDING:
2817 repr = "global binding";
2818 break;
2819 case elf_symbol::WEAK_BINDING:
2820 repr = "weak binding";
2821 break;
2822 case elf_symbol::GNU_UNIQUE_BINDING:
2823 repr = "GNU unique binding";
2824 break;
2825 default:
2826 {
2827 std::ostringstream s;
2828 s << "unknown binding (" << (unsigned char) b << ")";
2829 repr = s.str();
2830 }
2831 break;
2832 }
2833
2834 o << repr;
2835 return o;
2836 }
2837
2838 /// Serialize an instance of @ref elf_symbol::visibility and stream it
2839 /// to a given output stream.
2840 ///
2841 /// @param o the output stream to serialize the symbole type to.
2842 ///
2843 /// @param v the symbol visibility to serialize.
2844 std::ostream&
operator <<(std::ostream & o,elf_symbol::visibility v)2845 operator<<(std::ostream& o, elf_symbol::visibility v)
2846 {
2847 string repr;
2848
2849 switch (v)
2850 {
2851 case elf_symbol::DEFAULT_VISIBILITY:
2852 repr = "default visibility";
2853 break;
2854 case elf_symbol::PROTECTED_VISIBILITY:
2855 repr = "protected visibility";
2856 break;
2857 case elf_symbol::HIDDEN_VISIBILITY:
2858 repr = "hidden visibility";
2859 break;
2860 case elf_symbol::INTERNAL_VISIBILITY:
2861 repr = "internal visibility";
2862 break;
2863 default:
2864 {
2865 std::ostringstream s;
2866 s << "unknown visibility (" << (unsigned char) v << ")";
2867 repr = s.str();
2868 }
2869 break;
2870 }
2871
2872 o << repr;
2873 return o;
2874 }
2875
2876 /// Convert a string representing a symbol type into an
2877 /// elf_symbol::type.
2878 ///
2879 ///@param s the string to convert.
2880 ///
2881 ///@param t the resulting elf_symbol::type.
2882 ///
2883 /// @return true iff the conversion completed successfully.
2884 bool
string_to_elf_symbol_type(const string & s,elf_symbol::type & t)2885 string_to_elf_symbol_type(const string& s, elf_symbol::type& t)
2886 {
2887 if (s == "no-type")
2888 t = elf_symbol::NOTYPE_TYPE;
2889 else if (s == "object-type")
2890 t = elf_symbol::OBJECT_TYPE;
2891 else if (s == "func-type")
2892 t = elf_symbol::FUNC_TYPE;
2893 else if (s == "section-type")
2894 t = elf_symbol::SECTION_TYPE;
2895 else if (s == "file-type")
2896 t = elf_symbol::FILE_TYPE;
2897 else if (s == "common-type")
2898 t = elf_symbol::COMMON_TYPE;
2899 else if (s == "tls-type")
2900 t = elf_symbol::TLS_TYPE;
2901 else if (s == "gnu-ifunc-type")
2902 t = elf_symbol::GNU_IFUNC_TYPE;
2903 else
2904 return false;
2905
2906 return true;
2907 }
2908
2909 /// Convert a string representing a an elf symbol binding into an
2910 /// elf_symbol::binding.
2911 ///
2912 /// @param s the string to convert.
2913 ///
2914 /// @param b the resulting elf_symbol::binding.
2915 ///
2916 /// @return true iff the conversion completed successfully.
2917 bool
string_to_elf_symbol_binding(const string & s,elf_symbol::binding & b)2918 string_to_elf_symbol_binding(const string& s, elf_symbol::binding& b)
2919 {
2920 if (s == "local-binding")
2921 b = elf_symbol::LOCAL_BINDING;
2922 else if (s == "global-binding")
2923 b = elf_symbol::GLOBAL_BINDING;
2924 else if (s == "weak-binding")
2925 b = elf_symbol::WEAK_BINDING;
2926 else if (s == "gnu-unique-binding")
2927 b = elf_symbol::GNU_UNIQUE_BINDING;
2928 else
2929 return false;
2930
2931 return true;
2932 }
2933
2934 /// Convert a string representing a an elf symbol visibility into an
2935 /// elf_symbol::visibility.
2936 ///
2937 /// @param s the string to convert.
2938 ///
2939 /// @param b the resulting elf_symbol::visibility.
2940 ///
2941 /// @return true iff the conversion completed successfully.
2942 bool
string_to_elf_symbol_visibility(const string & s,elf_symbol::visibility & v)2943 string_to_elf_symbol_visibility(const string& s, elf_symbol::visibility& v)
2944 {
2945 if (s == "default-visibility")
2946 v = elf_symbol::DEFAULT_VISIBILITY;
2947 else if (s == "protected-visibility")
2948 v = elf_symbol::PROTECTED_VISIBILITY;
2949 else if (s == "hidden-visibility")
2950 v = elf_symbol::HIDDEN_VISIBILITY;
2951 else if (s == "internal-visibility")
2952 v = elf_symbol::INTERNAL_VISIBILITY;
2953 else
2954 return false;
2955
2956 return true;
2957 }
2958
2959 /// Test if the type of an ELF symbol denotes a function symbol.
2960 ///
2961 /// @param t the type of the ELF symbol.
2962 ///
2963 /// @return true iff elf symbol type @p t denotes a function symbol
2964 /// type.
2965 bool
elf_symbol_is_function(elf_symbol::type t)2966 elf_symbol_is_function(elf_symbol::type t)
2967 {return t == elf_symbol::FUNC_TYPE;}
2968
2969 /// Test if the type of an ELF symbol denotes a function symbol.
2970 ///
2971 /// @param t the type of the ELF symbol.
2972 ///
2973 /// @return true iff elf symbol type @p t denotes a function symbol
2974 /// type.
2975 bool
elf_symbol_is_variable(elf_symbol::type t)2976 elf_symbol_is_variable(elf_symbol::type t)
2977 {return t == elf_symbol::OBJECT_TYPE;}
2978
2979 // <elf_symbol::version stuff>
2980
2981 struct elf_symbol::version::priv
2982 {
2983 string version_;
2984 bool is_default_;
2985
privabigail::ir::elf_symbol::version::priv2986 priv()
2987 : is_default_(false)
2988 {}
2989
privabigail::ir::elf_symbol::version::priv2990 priv(const string& v,
2991 bool d)
2992 : version_(v),
2993 is_default_(d)
2994 {}
2995 }; // end struct elf_symbol::version::priv
2996
version()2997 elf_symbol::version::version()
2998 : priv_(new priv)
2999 {}
3000
3001 /// @param v the name of the version.
3002 ///
3003 /// @param is_default true if this is a default version.
version(const string & v,bool is_default)3004 elf_symbol::version::version(const string& v,
3005 bool is_default)
3006 : priv_(new priv(v, is_default))
3007 {}
3008
version(const elf_symbol::version & v)3009 elf_symbol::version::version(const elf_symbol::version& v)
3010 : priv_(new priv(v.str(), v.is_default()))
3011 {
3012 }
3013
3014 elf_symbol::version::~version() = default;
3015
3016 /// Cast the version_type into a string that is its name.
3017 ///
3018 /// @return the name of the version.
operator const string&() const3019 elf_symbol::version::operator const string&() const
3020 {return priv_->version_;}
3021
3022 /// Getter for the version name.
3023 ///
3024 /// @return the version name.
3025 const string&
str() const3026 elf_symbol::version::str() const
3027 {return priv_->version_;}
3028
3029 /// Setter for the version name.
3030 ///
3031 /// @param s the version name.
3032 void
str(const string & s)3033 elf_symbol::version::str(const string& s)
3034 {priv_->version_ = s;}
3035
3036 /// Getter for the 'is_default' property of the version.
3037 ///
3038 /// @return true iff this is a default version.
3039 bool
is_default() const3040 elf_symbol::version::is_default() const
3041 {return priv_->is_default_;}
3042
3043 /// Setter for the 'is_default' property of the version.
3044 ///
3045 /// @param f true if this is the default version.
3046 void
is_default(bool f)3047 elf_symbol::version::is_default(bool f)
3048 {priv_->is_default_ = f;}
3049
3050 bool
is_empty() const3051 elf_symbol::version::is_empty() const
3052 {return str().empty();}
3053
3054 /// Compares the current version against another one.
3055 ///
3056 /// @param o the other version to compare the current one to.
3057 ///
3058 /// @return true iff the current version equals @p o.
3059 bool
operator ==(const elf_symbol::version & o) const3060 elf_symbol::version::operator==(const elf_symbol::version& o) const
3061 {return str() == o.str();}
3062
3063 /// Inequality operator.
3064 ///
3065 /// @param o the version to compare against the current one.
3066 ///
3067 /// @return true iff both versions are different.
3068 bool
operator !=(const version & o) const3069 elf_symbol::version::operator!=(const version& o) const
3070 {return !operator==(o);}
3071
3072 /// Assign a version to the current one.
3073 ///
3074 /// @param o the other version to assign to this one.
3075 ///
3076 /// @return a reference to the assigned version.
3077 elf_symbol::version&
operator =(const elf_symbol::version & o)3078 elf_symbol::version::operator=(const elf_symbol::version& o)
3079 {
3080 str(o.str());
3081 is_default(o.is_default());
3082 return *this;
3083 }
3084
3085 // </elf_symbol::version stuff>
3086
3087 // </elf_symbol stuff>
3088
3089 // <class dm_context_rel stuff>
3090 struct dm_context_rel::priv
3091 {
3092 bool is_laid_out_;
3093 size_t offset_in_bits_;
3094 var_decl* anonymous_data_member_;
3095
privabigail::ir::dm_context_rel::priv3096 priv(bool is_static = false)
3097 : is_laid_out_(!is_static),
3098 offset_in_bits_(0),
3099 anonymous_data_member_()
3100 {}
3101
privabigail::ir::dm_context_rel::priv3102 priv(bool is_laid_out, size_t offset_in_bits)
3103 : is_laid_out_(is_laid_out),
3104 offset_in_bits_(offset_in_bits),
3105 anonymous_data_member_()
3106 {}
3107 }; //end struct dm_context_rel::priv
3108
dm_context_rel()3109 dm_context_rel::dm_context_rel()
3110 : context_rel(),
3111 priv_(new priv)
3112 {}
3113
dm_context_rel(scope_decl * s,bool is_laid_out,size_t offset_in_bits,access_specifier a,bool is_static)3114 dm_context_rel::dm_context_rel(scope_decl* s,
3115 bool is_laid_out,
3116 size_t offset_in_bits,
3117 access_specifier a,
3118 bool is_static)
3119 : context_rel(s, a, is_static),
3120 priv_(new priv(is_laid_out, offset_in_bits))
3121 {}
3122
dm_context_rel(scope_decl * s)3123 dm_context_rel::dm_context_rel(scope_decl* s)
3124 : context_rel(s),
3125 priv_(new priv())
3126 {}
3127
3128 bool
get_is_laid_out() const3129 dm_context_rel::get_is_laid_out() const
3130 {return priv_->is_laid_out_;}
3131
3132 void
set_is_laid_out(bool f)3133 dm_context_rel::set_is_laid_out(bool f)
3134 {priv_->is_laid_out_ = f;}
3135
3136 size_t
get_offset_in_bits() const3137 dm_context_rel::get_offset_in_bits() const
3138 {return priv_->offset_in_bits_;}
3139
3140 void
set_offset_in_bits(size_t o)3141 dm_context_rel::set_offset_in_bits(size_t o)
3142 {priv_->offset_in_bits_ = o;}
3143
3144 bool
operator ==(const dm_context_rel & o) const3145 dm_context_rel::operator==(const dm_context_rel& o) const
3146 {
3147 if (!context_rel::operator==(o))
3148 return false;
3149
3150 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3151 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3152 }
3153
3154 bool
operator !=(const dm_context_rel & o) const3155 dm_context_rel::operator!=(const dm_context_rel& o) const
3156 {return !operator==(o);}
3157
3158 /// Return a non-nil value if this data member context relationship
3159 /// has an anonymous data member. That means, if the data member this
3160 /// relation belongs to is part of an anonymous data member.
3161 ///
3162 /// @return the containing anonymous data member of this data member
3163 /// relationship. Nil if there is none.
3164 const var_decl*
get_anonymous_data_member() const3165 dm_context_rel::get_anonymous_data_member() const
3166 {return priv_->anonymous_data_member_;}
3167
3168 /// Set the containing anonymous data member of this data member
3169 /// context relationship. That means that the data member this
3170 /// relation belongs to is part of an anonymous data member.
3171 ///
3172 /// @param anon_dm the containing anonymous data member of this data
3173 /// member relationship. Nil if there is none.
3174 void
set_anonymous_data_member(var_decl * anon_dm)3175 dm_context_rel::set_anonymous_data_member(var_decl* anon_dm)
3176 {priv_->anonymous_data_member_ = anon_dm;}
3177
~dm_context_rel()3178 dm_context_rel::~dm_context_rel()
3179 {}
3180 // </class dm_context_rel stuff>
3181
3182 // <environment stuff>
3183
3184 /// Convenience typedef for a map of interned_string -> bool.
3185 typedef unordered_map<interned_string,
3186 bool, hash_interned_string> interned_string_bool_map_type;
3187
3188
3189 /// Default constructor of the @ref environment type.
environment()3190 environment::environment()
3191 :priv_(new priv)
3192 {}
3193
3194 /// Destructor for the @ref environment type.
~environment()3195 environment::~environment()
3196 {}
3197
3198 /// Getter the map of canonical types.
3199 ///
3200 /// @return the map of canonical types. The key of the map is the
3201 /// hash of the canonical type and its value if the canonical type.
3202 environment::canonical_types_map_type&
get_canonical_types_map()3203 environment::get_canonical_types_map()
3204 {return priv_->canonical_types_;}
3205
3206 /// Getter the map of canonical types.
3207 ///
3208 /// @return the map of canonical types. The key of the map is the
3209 /// hash of the canonical type and its value if the canonical type.
3210 const environment::canonical_types_map_type&
get_canonical_types_map() const3211 environment::get_canonical_types_map() const
3212 {return const_cast<environment*>(this)->get_canonical_types_map();}
3213
3214 /// Helper to detect if a type is either a reference, a pointer, or a
3215 /// qualified type.
3216 static bool
is_ptr_ref_or_qual_type(const type_base * t)3217 is_ptr_ref_or_qual_type(const type_base *t)
3218 {
3219 if (is_pointer_type(t)
3220 || is_reference_type(t)
3221 || is_qualified_type(t))
3222 return true;
3223 return false;
3224 }
3225
3226 /// Compare decls using their locations.
3227 ///
3228 /// @param f the first decl to compare.
3229 ///
3230 /// @param s the second decl to compare.
3231 ///
3232 /// @return true if @p f compares less than @p s.
3233 static bool
compare_using_locations(const decl_base * f,const decl_base * s)3234 compare_using_locations(const decl_base *f,
3235 const decl_base *s)
3236 {
3237 // If a decl has artificial location, then use that one over the
3238 // natural one.
3239 location fl = get_artificial_or_natural_location(f);
3240 location sl = get_artificial_or_natural_location(s);
3241
3242 ABG_ASSERT(fl.get_value() && sl.get_value());
3243 if (fl.get_is_artificial() == sl.get_is_artificial())
3244 {
3245 // The locations of the two artfifacts have the same
3246 // artificial-ness so they can be compared.
3247 string p1, p2;
3248 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3249 fl.expand(p1, l1, c1);
3250 sl.expand(p2, l2, c2);
3251 if (p1 != p2)
3252 return p1 < p2;
3253 if (l1 != l2)
3254 return l1 < l2;
3255 if (c1 != c2)
3256 return c1 < c2;
3257 }
3258
3259 return (get_pretty_representation(f, /*internal=*/false)
3260 < get_pretty_representation(s, /*internal=*/false));
3261 }
3262
3263 /// A functor to sort decls somewhat topologically. That is, types
3264 /// are sorted in a way that makes the ones that are defined "first"
3265 /// to come first.
3266 ///
3267 /// The topological criteria is a lexicographic sort of the definition
3268 /// location of the type. For types that have no location (or the
3269 /// same location), it's their qualified name that is used for the
3270 /// lexicographic sort.
3271 struct decl_topo_comp
3272 {
3273
3274 /// The "Less Than" comparison operator of this functor.
3275 ///
3276 /// @param f the first decl to be considered for the comparison.
3277 ///
3278 /// @param s the second decl to be considered for the comparison.
3279 ///
3280 /// @return true iff @p f is less than @p s.
3281 bool
operator ()abigail::ir::decl_topo_comp3282 operator()(const decl_base *f,
3283 const decl_base *s)
3284 {
3285 if (!!f != !!s)
3286 return f && !s;
3287
3288 if (!f)
3289 return false;
3290
3291 // Unique types that are artificially created in the environment
3292 // don't have locations. They ought to be compared on the basis
3293 // of their pretty representation before we start looking at IR
3294 // nodes' locations down the road.
3295 if (is_unique_type(is_type(f)) || is_unique_type(is_type(s)))
3296 return (get_pretty_representation(f, /*internal=*/false)
3297 < get_pretty_representation(s, /*internal=*/false));
3298
3299 // If both decls come from an abixml file, keep the order they
3300 // have from that abixml file.
3301 if ((!f->get_corpus() && !s->get_corpus())
3302 || (f->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
3303 && s->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN))
3304 return compare_using_locations(f, s);
3305
3306 // If a decl has artificial location, then use that one over the
3307 // natural one.
3308 location fl = get_artificial_or_natural_location(f);
3309 location sl = get_artificial_or_natural_location(s);
3310
3311 if (fl.get_value() && sl.get_value())
3312 return compare_using_locations(f, s);
3313 else if (!!fl != !!sl)
3314 // So one of the decls doesn't have location data.
3315 // The first decl is less than the second if it's the one not
3316 // having location data.
3317 return !fl && sl;
3318
3319 // We reach this point if location data is useless.
3320 if (f->get_is_anonymous()
3321 && s->get_is_anonymous()
3322 && (get_pretty_representation(f, /*internal=*/false)
3323 == get_pretty_representation(s, /*internal=*/false)))
3324 return f->get_name() < s->get_name();
3325
3326 return (get_pretty_representation(f, /*internal=*/false)
3327 < get_pretty_representation(s, /*internal=*/false));
3328 }
3329
3330 /// The "Less Than" comparison operator of this functor.
3331 ///
3332 /// @param f the first decl to be considered for the comparison.
3333 ///
3334 /// @param s the second decl to be considered for the comparison.
3335 ///
3336 /// @return true iff @p f is less than @p s.
3337 bool
operator ()abigail::ir::decl_topo_comp3338 operator()(const decl_base_sptr &f,
3339 const decl_base_sptr &s)
3340 {return operator()(f.get(), s.get());}
3341
3342 }; // end struct decl_topo_comp
3343
3344 /// A functor to sort types somewhat topologically. That is, types
3345 /// are sorted in a way that makes the ones that are defined "first"
3346 /// to come first.
3347 ///
3348 /// The topological criteria is a lexicographic sort of the definition
3349 /// location of the type. For types that have no location, it's their
3350 /// qualified name that is used for the lexicographic sort.
3351 struct type_topo_comp
3352 {
3353 /// Test if a decl has an artificial or natural location.
3354 ///
3355 /// @param d the decl to consider
3356 ///
3357 /// @return true iff @p d has a location.
3358 bool
has_artificial_or_natural_locationabigail::ir::type_topo_comp3359 has_artificial_or_natural_location(const decl_base* d)
3360 {return get_artificial_or_natural_location(d);}
3361
3362 /// Test if a type has an artificial or natural location.
3363 ///
3364 /// @param t the type to consider
3365 ///
3366 /// @return true iff @p t has a location.
3367 bool
has_artificial_or_natural_locationabigail::ir::type_topo_comp3368 has_artificial_or_natural_location(const type_base* t)
3369 {
3370 if (decl_base *d = is_decl(t))
3371 return has_artificial_or_natural_location(d);
3372 return false;
3373 }
3374
3375 /// The "Less Than" comparison operator of this functor.
3376 ///
3377 /// @param f the first type to be considered for the comparison.
3378 ///
3379 /// @param s the second type to be considered for the comparison.
3380 ///
3381 /// @return true iff @p f is less than @p s.
3382 bool
operator ()abigail::ir::type_topo_comp3383 operator()(const type_base_sptr &f,
3384 const type_base_sptr &s)
3385 {return operator()(f.get(), s.get());}
3386
3387 /// The "Less Than" comparison operator of this functor.
3388 ///
3389 /// @param f the first type to be considered for the comparison.
3390 ///
3391 /// @param s the second type to be considered for the comparison.
3392 ///
3393 /// @return true iff @p f is less than @p s.
3394 bool
operator ()abigail::ir::type_topo_comp3395 operator()(const type_base *f,
3396 const type_base *s)
3397 {
3398 // If both decls come from an abixml file, keep the order they
3399 // have from that abixml file.
3400 if ((!f->get_corpus() && !s->get_corpus())
3401 || (f->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
3402 && s->get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN))
3403 return compare_using_locations(is_decl(f), is_decl(s));
3404
3405 bool f_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(f);
3406 bool s_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(s);
3407
3408 if (f_is_ptr_ref_or_qual != s_is_ptr_ref_or_qual)
3409 return !f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual;
3410
3411 if (f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual
3412 && !has_artificial_or_natural_location(f)
3413 && !has_artificial_or_natural_location(s))
3414 {
3415 string s1 = get_pretty_representation(f, /*internal=*/false);
3416 string s2 = get_pretty_representation(s, /*internal=*/false);
3417 if (s1 == s2)
3418 {
3419 if (qualified_type_def * q = is_qualified_type(f))
3420 {
3421 if (q->get_cv_quals() == qualified_type_def::CV_NONE)
3422 if (!is_qualified_type(s))
3423 // We are looking at two types that are the result of
3424 // an optimization that happens during the IR
3425 // construction. Namely, type f is a cv-qualified
3426 // type with no qualifier (no const, no volatile, no
3427 // nothing, we call it an empty-qualified type).
3428 // These are the result of an optimization which
3429 // removes "redundant qualifiers" from some types.
3430 // For instance, consider a "const reference". The
3431 // const there is redundant because a reference is
3432 // always const. So as a result of the optimizaton
3433 // that type is going to be transformed into an
3434 // empty-qualified reference. If we don't make that
3435 // optimization, then we risk having spurious change
3436 // reports down the road. But then, as a consequence
3437 // of that optimization, we need to sort the
3438 // empty-qualified type and its non-qualified variant
3439 // e.g, to ensure stability in the abixml output; both
3440 // types are logically equal, but here, we decide that
3441 // the empty-qualified one is topologically "less
3442 // than" the non-qualified counterpart.
3443 //
3444 // So here, type f is an empty-qualified type and type
3445 // s is its non-qualified variant. We decide that f
3446 // is topologically less than s.
3447 return true;
3448 }
3449 // Now let's peel off the pointer (or reference types) and
3450 // see if the ultimate underlying types have the same
3451 // textual representation; if not, use that as sorting
3452 // criterion.
3453 type_base *peeled_f =
3454 peel_pointer_or_reference_type(f, true);
3455 type_base *peeled_s =
3456 peel_pointer_or_reference_type(s, true);
3457
3458 s1 = get_pretty_representation(peeled_f, /*internal=*/false);
3459 s2 = get_pretty_representation(peeled_s, /*internal=*/false);
3460 if (s1 != s2)
3461 return s1 < s2;
3462
3463 // The underlying type of pointer/reference have the same
3464 // textual representation; let's try to peel of typedefs
3465 // as well and we'll consider sorting the result as decls.
3466 peeled_f = peel_typedef_pointer_or_reference_type(peeled_f, true);
3467 peeled_s = peel_typedef_pointer_or_reference_type(peeled_s, true);
3468
3469 s1 = get_pretty_representation(peeled_f, false);
3470 s2 = get_pretty_representation(peeled_s, false);
3471 if (s1 != s2)
3472 return s1 < s2;
3473 }
3474 }
3475
3476 string s1 = get_pretty_representation(f, false);
3477 string s2 = get_pretty_representation(s, false);
3478
3479 if (s1 != s2)
3480 return s1 < s2;
3481
3482 if (is_typedef(f) && is_typedef(s))
3483 {
3484 s1 = get_pretty_representation(is_typedef(f)->get_underlying_type(),
3485 false);
3486 s2 = get_pretty_representation(is_typedef(s)->get_underlying_type(),
3487 false);
3488 if (s1 != s2)
3489 return s1 < s2;
3490 }
3491
3492 type_base *peeled_f = peel_typedef_pointer_or_reference_type(f, true);
3493 type_base *peeled_s = peel_typedef_pointer_or_reference_type(s, true);
3494
3495 s1 = get_pretty_representation(peeled_f, false);
3496 s2 = get_pretty_representation(peeled_s, false);
3497
3498 if (s1 != s2)
3499 return s1 < s2;
3500
3501 decl_base *fd = is_decl(f);
3502 decl_base *sd = is_decl(s);
3503
3504 if (!!fd != !!sd)
3505 return fd && !sd;
3506
3507 // If the two types have no decls, how come we could not sort them
3508 // until now? Let's investigate.
3509 ABG_ASSERT(fd);
3510
3511 // From this point, fd and sd should be non-nil
3512 decl_topo_comp decl_comp;
3513 return decl_comp(fd, sd);
3514 }
3515 }; //end struct type_topo_comp
3516
3517 /// Sort types in a hopefully stable manner.
3518 ///
3519 /// @param types a set of types with canonical types to sort.
3520 ///
3521 /// @param result the resulting sorted vector.
3522 void
sort_types(const canonical_type_sptr_set_type & types,vector<type_base_sptr> & result)3523 sort_types(const canonical_type_sptr_set_type& types,
3524 vector<type_base_sptr>& result)
3525 {
3526 for (auto t: types)
3527 result.push_back(t);
3528
3529 type_topo_comp comp;
3530 std::stable_sort(result.begin(), result.end(), comp);
3531 }
3532
3533 /// Get the unique @ref type_decl that represents a "void" type for
3534 /// the current environment. This node must be the only one
3535 /// representing a void type in the system.
3536 ///
3537 /// Note that upon first use of this IR node (by the relevant
3538 /// front-end, for instance) it must be added to a scope using e.g,
3539 /// the @ref add_decl_to_scope() function.
3540 ///
3541 /// @return the @ref type_decl that represents a "void" type.
3542 const type_base_sptr&
get_void_type() const3543 environment::get_void_type() const
3544 {
3545 if (!priv_->void_type_)
3546 priv_->void_type_.reset(new type_decl(*this,
3547 intern("void"),
3548 0, 0, location()));
3549 return priv_->void_type_;
3550 }
3551
3552 /// Getter of the "pointer-to-void" IR node that is shared across the
3553 /// ABI corpus. This node must be the only one representing a void
3554 /// pointer type in the system.
3555 ///
3556 /// Note that upon first use of this IR node (by the relevant
3557 /// front-end, for instance) it must be added to a scope using e.g,
3558 /// the @ref add_decl_to_scope() function.
3559 ///
3560 /// @return the "pointer-to-void" IR node.
3561 const type_base_sptr&
get_void_pointer_type() const3562 environment::get_void_pointer_type() const
3563 {
3564 if (!priv_->void_pointer_type_)
3565 priv_->void_pointer_type_.reset(new pointer_type_def(get_void_type(),
3566 0, 0, location()));
3567 return priv_->void_pointer_type_;
3568 }
3569
3570 /// Get a @ref type_decl instance that represents a the type of a
3571 /// variadic function parameter. This node must be the only one
3572 /// representing a variadic parameter type in the system.
3573 ///
3574 /// Note that upon first use of this IR node (by the relevant
3575 /// front-end, for instance) it must be added to a scope using e.g,
3576 /// the @ref add_decl_to_scope() function.
3577 ///
3578 /// @return the Get a @ref type_decl instance that represents a the
3579 /// type of a variadic function parameter.
3580 const type_base_sptr&
get_variadic_parameter_type() const3581 environment::get_variadic_parameter_type() const
3582 {
3583 if (!priv_->variadic_marker_type_)
3584 priv_->variadic_marker_type_.
3585 reset(new type_decl(*this, intern(get_variadic_parameter_type_name()),
3586 0, 0, location()));
3587 return priv_->variadic_marker_type_;
3588 }
3589
3590 /// Getter of the name of the variadic parameter type.
3591 ///
3592 /// @return the name of the variadic parameter type.
3593 string&
get_variadic_parameter_type_name()3594 environment::get_variadic_parameter_type_name()
3595 {
3596 static string variadic_parameter_type_name = "variadic parameter type";
3597 return variadic_parameter_type_name;
3598 }
3599
3600 /// Test if the canonicalization of types created out of the current
3601 /// environment is done.
3602 ///
3603 /// @return true iff the canonicalization of types created out of the current
3604 /// environment is done.
3605 bool
canonicalization_is_done() const3606 environment::canonicalization_is_done() const
3607 {return priv_->canonicalization_is_done_;}
3608
3609 /// Set a flag saying if the canonicalization of types created out of
3610 /// the current environment is done or not.
3611 ///
3612 /// Note that this function must only be called by internal code of
3613 /// the library that creates ABI artifacts (e.g, read an abi corpus
3614 /// from elf or from our own xml format and creates representations of
3615 /// types out of it) and thus needs to canonicalize types to speed-up
3616 /// further type comparison.
3617 ///
3618 /// @param f the new value of the flag.
3619 void
canonicalization_is_done(bool f)3620 environment::canonicalization_is_done(bool f)
3621 {priv_->canonicalization_is_done_ = f;}
3622
3623 /// Getter for the "on-the-fly-canonicalization" flag.
3624 ///
3625 /// @return true iff @ref OnTheFlyCanonicalization
3626 /// "on-the-fly-canonicalization" is to be performed during
3627 /// comparison.
3628 bool
do_on_the_fly_canonicalization() const3629 environment::do_on_the_fly_canonicalization() const
3630 {return priv_->do_on_the_fly_canonicalization_;}
3631
3632 /// Setter for the "on-the-fly-canonicalization" flag.
3633 ///
3634 /// @param f If this is true then @ref OnTheFlyCanonicalization
3635 /// "on-the-fly-canonicalization" is to be performed during
3636 /// comparison.
3637 void
do_on_the_fly_canonicalization(bool f)3638 environment::do_on_the_fly_canonicalization(bool f)
3639 {priv_->do_on_the_fly_canonicalization_ = f;}
3640
3641 /// Getter of the "decl-only-class-equals-definition" flag.
3642 ///
3643 /// Usually, a declaration-only class named 'struct foo' compares
3644 /// equal to any class definition named "struct foo'. This is at
3645 /// least true for C++.
3646 ///
3647 /// In C, though, because there can be multiple definitions of 'struct
3648 /// foo' in the binary, a declaration-only "struct foo" might be
3649 /// considered to *NOT* resolve to any of the struct foo defined. In
3650 /// that case, the declaration-only "struct foo" is considered
3651 /// different from the definitions.
3652 ///
3653 /// This flag controls the behaviour of the comparison of an
3654 /// unresolved decl-only class against a definition of the same name.
3655 ///
3656 /// If set to false, the the declaration equals the definition. If
3657 /// set to false, then the decalration is considered different from
3658 /// the declaration.
3659 ///
3660 /// @return the value of the "decl-only-class-equals-definition" flag.
3661 bool
decl_only_class_equals_definition() const3662 environment::decl_only_class_equals_definition() const
3663 {return priv_->decl_only_class_equals_definition_;}
3664
3665 /// Setter of the "decl-only-class-equals-definition" flag.
3666 ///
3667 /// Usually, a declaration-only class named 'struct foo' compares
3668 /// equal to any class definition named "struct foo'. This is at
3669 /// least true for C++.
3670 ///
3671 /// In C, though, because there can be multiple definitions of 'struct
3672 /// foo' in the binary, a declaration-only "struct foo" might be
3673 /// considered to *NOT* resolve to any of the struct foo defined. In
3674 /// that case, the declaration-only "struct foo" is considered
3675 /// different from the definitions.
3676 ///
3677 /// This flag controls the behaviour of the comparison of an
3678 /// unresolved decl-only class against a definition of the same name.
3679 ///
3680 /// If set to false, the the declaration equals the definition. If
3681 /// set to false, then the decalration is considered different from
3682 /// the declaration.
3683 ///
3684 /// @param the new value of the "decl-only-class-equals-definition"
3685 /// flag.
3686 void
decl_only_class_equals_definition(bool f) const3687 environment::decl_only_class_equals_definition(bool f) const
3688 {priv_->decl_only_class_equals_definition_ = f;}
3689
3690 /// Test if a given type is a void type as defined in the current
3691 /// environment.
3692 ///
3693 /// @param t the type to consider.
3694 ///
3695 /// @return true iff @p t is a void type as defined in the current
3696 /// environment.
3697 bool
is_void_type(const type_base_sptr & t) const3698 environment::is_void_type(const type_base_sptr& t) const
3699 {
3700 if (!t)
3701 return false;
3702 return is_void_type(t.get());
3703 }
3704
3705 /// Test if a given type is a void type as defined in the current
3706 /// environment.
3707 ///
3708 /// @param t the type to consider.
3709 ///
3710 /// @return true iff @p t is a void type as defined in the current
3711 /// environment.
3712 bool
is_void_type(const type_base * t) const3713 environment::is_void_type(const type_base* t) const
3714 {
3715 if (!t)
3716 return false;
3717 return (t == get_void_type().get()
3718 || (is_type_decl(t) && is_type_decl(t)->get_name() == "void"));
3719 }
3720
3721 /// Test if a given type is the same as the void pointer type of the
3722 /// environment.
3723 ///
3724 /// @param t the IR type to test.
3725 ///
3726 /// @return true iff @p t is the void pointer returned by
3727 /// environment::get_void_pointer_type().
3728 bool
is_void_pointer_type(const type_base_sptr & t) const3729 environment::is_void_pointer_type(const type_base_sptr& t) const
3730 {
3731 if (!t)
3732 return false;
3733
3734 return t.get() == get_void_pointer_type().get();
3735 }
3736
3737 /// Test if a given type is the same as the void pointer type of the
3738 /// environment.
3739 ///
3740 /// @param t the IR type to test.
3741 ///
3742 /// @return true iff @p t is the void pointer returned by
3743 /// environment::get_void_pointer_type().
3744 bool
is_void_pointer_type(const type_base * t) const3745 environment::is_void_pointer_type(const type_base* t) const
3746 {
3747 if (!t)
3748 return false;
3749
3750 return t == get_void_pointer_type().get();
3751 }
3752
3753 /// Test if a type is a variadic parameter type as defined in the
3754 /// current environment.
3755 ///
3756 /// @param t the type to consider.
3757 ///
3758 /// @return true iff @p t is a variadic parameter type as defined in
3759 /// the current environment.
3760 bool
is_variadic_parameter_type(const type_base * t) const3761 environment::is_variadic_parameter_type(const type_base* t) const
3762 {
3763 if (!t)
3764 return false;
3765 return t == get_variadic_parameter_type().get();
3766 }
3767
3768 /// Test if a type is a variadic parameter type as defined in the
3769 /// current environment.
3770 ///
3771 /// @param t the type to consider.
3772 ///
3773 /// @return true iff @p t is a variadic parameter type as defined in
3774 /// the current environment.
3775 bool
is_variadic_parameter_type(const type_base_sptr & t) const3776 environment::is_variadic_parameter_type(const type_base_sptr& t) const
3777 {return is_variadic_parameter_type(t.get());}
3778
3779 /// Do intern a string.
3780 ///
3781 /// If a value of this string already exists in the interned string
3782 /// pool of the current environment, then this function returns a new
3783 /// interned_string pointing to that already existing string.
3784 /// Otherwise, a new string is created, stored in the interned string
3785 /// pool and a new interned_string instance is created to point to
3786 /// that new intrerned string, and it's return.
3787 ///
3788 /// @param s the value of the string to intern.
3789 ///
3790 /// @return the interned string.
3791 interned_string
intern(const string & s) const3792 environment::intern(const string& s) const
3793 {return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3794
3795 /// Getter of the general configuration object.
3796 ///
3797 /// @return the configuration object.
3798 const config&
get_config() const3799 environment::get_config() const
3800 {return priv_->config_;}
3801
3802 /// Getter for a property that says if the user actually did set the
3803 /// analyze_exported_interfaces_only() property. If not, it means
3804 /// the default behaviour prevails.
3805 ///
3806 /// @return tru iff the user did set the
3807 /// analyze_exported_interfaces_only() property.
3808 bool
user_set_analyze_exported_interfaces_only() const3809 environment::user_set_analyze_exported_interfaces_only() const
3810 {return priv_->analyze_exported_interfaces_only_.has_value();}
3811
3812 /// Setter for the property that controls if we are to restrict the
3813 /// analysis to the types that are only reachable from the exported
3814 /// interfaces only, or if the set of types should be more broad than
3815 /// that. Typically, we'd restrict the analysis to types reachable
3816 /// from exported interfaces only (stricto sensu, that would really be
3817 /// only the types that are part of the ABI of well designed
3818 /// libraries) for performance reasons.
3819 ///
3820 /// @param f the value of the flag.
3821 void
analyze_exported_interfaces_only(bool f)3822 environment::analyze_exported_interfaces_only(bool f)
3823 {priv_->analyze_exported_interfaces_only_ = f;}
3824
3825 /// Getter for the property that controls if we are to restrict the
3826 /// analysis to the types that are only reachable from the exported
3827 /// interfaces only, or if the set of types should be more broad than
3828 /// that. Typically, we'd restrict the analysis to types reachable
3829 /// from exported interfaces only (stricto sensu, that would really be
3830 /// only the types that are part of the ABI of well designed
3831 /// libraries) for performance reasons.
3832 ///
3833 /// @param f the value of the flag.
3834 bool
analyze_exported_interfaces_only() const3835 environment::analyze_exported_interfaces_only() const
3836 {return priv_->analyze_exported_interfaces_only_.value_or(false);}
3837
3838 #ifdef WITH_DEBUG_SELF_COMPARISON
3839 /// Setter of the corpus of the input corpus of the self comparison
3840 /// that takes place when doing "abidw --debug-abidiff <binary>".
3841 ///
3842 /// The first invocation of this function sets the first corpus of the
3843 /// self comparison. The second invocation of this very same function
3844 /// sets the second corpus of the self comparison. That second corpus
3845 /// is supposed to come from the abixml serialization of the first
3846 /// corpus.
3847 ///
3848 /// @param c the corpus of the input binary or the corpus of the
3849 /// abixml serialization of the initial binary input.
3850 void
set_self_comparison_debug_input(const corpus_sptr & c)3851 environment::set_self_comparison_debug_input(const corpus_sptr& c)
3852 {
3853 self_comparison_debug_is_on(true);
3854 if (priv_->first_self_comparison_corpus_.expired())
3855 priv_->first_self_comparison_corpus_ = c;
3856 else if (priv_->second_self_comparison_corpus_.expired()
3857 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3858 priv_->second_self_comparison_corpus_ = c;
3859 }
3860
3861 /// Getter for the corpora of the input binary and the intermediate
3862 /// abixml of the self comparison that takes place when doing
3863 /// 'abidw --debug-abidiff <binary>'.
3864 ///
3865 /// @param first_corpus output parameter that is set to the corpus of
3866 /// the input corpus.
3867 ///
3868 /// @param second_corpus output parameter that is set to the corpus of
3869 /// the second corpus.
3870 void
get_self_comparison_debug_inputs(corpus_sptr & first_corpus,corpus_sptr & second_corpus)3871 environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3872 corpus_sptr& second_corpus)
3873 {
3874 first_corpus = priv_->first_self_comparison_corpus_.lock();
3875 second_corpus = priv_->second_self_comparison_corpus_.lock();
3876 }
3877
3878 /// Turn on/off the self comparison debug mode.
3879 ///
3880 /// @param f true iff the self comparison debug mode is turned on.
3881 void
self_comparison_debug_is_on(bool f)3882 environment::self_comparison_debug_is_on(bool f)
3883 {priv_->self_comparison_debug_on_ = f;}
3884
3885 /// Test if we are in the process of the 'self-comparison
3886 /// debugging' as triggered by 'abidw --debug-abidiff' command.
3887 ///
3888 /// @return true if self comparison debug is on.
3889 bool
self_comparison_debug_is_on() const3890 environment::self_comparison_debug_is_on() const
3891 {return priv_->self_comparison_debug_on_;}
3892 #endif
3893
3894 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3895 /// Set the "type canonicalization debugging" mode, triggered by using
3896 /// the command: "abidw --debug-tc".
3897 ///
3898 /// @param flag if true then the type canonicalization debugging mode
3899 /// is enabled.
3900 void
debug_type_canonicalization_is_on(bool flag)3901 environment::debug_type_canonicalization_is_on(bool flag)
3902 {priv_->debug_type_canonicalization_ = flag;}
3903
3904 /// Getter of the "type canonicalization debugging" mode, triggered by
3905 /// using the command: "abidw --debug-tc".
3906 ///
3907 /// @return true iff the type canonicalization debugging mode is
3908 /// enabled.
3909 bool
debug_type_canonicalization_is_on() const3910 environment::debug_type_canonicalization_is_on() const
3911 {return priv_->debug_type_canonicalization_;}
3912
3913 /// Setter of the "DIE canonicalization debugging" mode, triggered by
3914 /// using the command: "abidw --debug-dc".
3915 ///
3916 /// @param flag true iff the DIE canonicalization debugging mode is
3917 /// enabled.
3918 void
debug_die_canonicalization_is_on(bool flag)3919 environment::debug_die_canonicalization_is_on(bool flag)
3920 {priv_->debug_die_canonicalization_ = flag;}
3921
3922 /// Getter of the "DIE canonicalization debugging" mode, triggered by
3923 /// using the command: "abidw --debug-dc".
3924 ///
3925 /// @return true iff the DIE canonicalization debugging mode is
3926 /// enabled.
3927 bool
debug_die_canonicalization_is_on() const3928 environment::debug_die_canonicalization_is_on() const
3929 {return priv_->debug_die_canonicalization_;}
3930 #endif // WITH_DEBUG_TYPE_CANONICALIZATION
3931
3932 /// Get the vector of canonical types which have a given "string
3933 /// representation".
3934 ///
3935 /// @param 'name', the textual representation of the type as returned
3936 /// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3937 /// /*qualified=*/true)
3938 ///
3939 /// This is useful to for debugging purposes as it's handy to use from
3940 /// inside a debugger like GDB.
3941 ///
3942 /// @return a pointer to the vector of canonical types having the
3943 /// representation @p name, or nullptr if no type with that
3944 /// representation exists.
3945 vector<type_base_sptr>*
get_canonical_types(const char * name)3946 environment::get_canonical_types(const char* name)
3947 {
3948 auto ti = get_canonical_types_map().find(name);
3949 if (ti == get_canonical_types_map().end())
3950 return nullptr;
3951 return &ti->second;
3952 }
3953
3954 /// Get a given canonical type which has a given "string
3955 /// representation".
3956 ///
3957 /// @param 'name', the textual representation of the type as returned
3958 /// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3959 /// /*qualified=*/true).
3960 ///
3961 /// @param index, the index of the type in the vector of types that
3962 /// all have the same textual representation @p 'name'. That vector
3963 /// is returned by the function environment::get_canonical_types().
3964 ///
3965 /// @return the canonical type which has the representation @p name,
3966 /// and which is at index @p index in the vector of canonical types
3967 /// having that same textual representation.
3968 type_base*
get_canonical_type(const char * name,unsigned index)3969 environment::get_canonical_type(const char* name, unsigned index)
3970 {
3971 vector<type_base_sptr> *types = get_canonical_types(name);
3972 if (!types ||index >= types->size())
3973 return nullptr;
3974 return (*types)[index].get();
3975 }
3976
3977 #ifdef WITH_DEBUG_SELF_COMPARISON
3978 /// Get the set of abixml type-id and the pointer value of the
3979 /// (canonical) type it's associated to.
3980 ///
3981 /// This is useful for debugging purposes, especially in the context
3982 /// of the use of the command:
3983 /// 'abidw --debug-abidiff <binary>'.
3984 ///
3985 /// @return the set of abixml type-id and the pointer value of the
3986 /// (canonical) type it's associated to.
3987 const unordered_map<string, uintptr_t>&
get_type_id_canonical_type_map() const3988 environment::get_type_id_canonical_type_map() const
3989 {return priv_->get_type_id_canonical_type_map();}
3990
3991 /// Get the set of abixml type-id and the pointer value of the
3992 /// (canonical) type it's associated to.
3993 ///
3994 /// This is useful for debugging purposes, especially in the context
3995 /// of the use of the command:
3996 /// 'abidw --debug-abidiff <binary>'.
3997 ///
3998 /// @return the set of abixml type-id and the pointer value of the
3999 /// (canonical) type it's associated to.
4000 unordered_map<string, uintptr_t>&
get_type_id_canonical_type_map()4001 environment::get_type_id_canonical_type_map()
4002 {return priv_->get_type_id_canonical_type_map();}
4003
4004 /// Getter of the map that associates the values of type pointers to
4005 /// their type-id strings.
4006 ///
4007 /// Note that this map is populated at abixml reading time, (by
4008 /// build_type()) when a given XML element representing a type is
4009 /// read into a corresponding abigail::ir::type_base.
4010 ///
4011 /// This is used only for the purpose of debugging the
4012 /// self-comparison process. That is, when invoking "abidw
4013 /// --debug-abidiff".
4014 ///
4015 /// @return the map that associates the values of type pointers to
4016 /// their type-id strings.
4017 const unordered_map<uintptr_t, string>&
get_pointer_type_id_map() const4018 environment::get_pointer_type_id_map() const
4019 {return priv_->get_pointer_type_id_map();}
4020
4021 /// Getter of the map that associates the values of type pointers to
4022 /// their type-id strings.
4023 ///
4024 /// Note that this map is populated at abixml reading time, (by
4025 /// build_type()) when a given XML element representing a type is
4026 /// read into a corresponding abigail::ir::type_base.
4027 ///
4028 /// This is used only for the purpose of debugging the
4029 /// self-comparison process. That is, when invoking "abidw
4030 /// --debug-abidiff".
4031 ///
4032 /// @return the map that associates the values of type pointers to
4033 /// their type-id strings.
4034 unordered_map<uintptr_t, string>&
get_pointer_type_id_map()4035 environment::get_pointer_type_id_map()
4036 {return priv_->get_pointer_type_id_map();}
4037
4038 /// Getter of the type-id that corresponds to the value of a pointer
4039 /// to abigail::ir::type_base that was created from the abixml reader.
4040 ///
4041 /// That value is retrieved from the map returned from
4042 /// environment::get_pointer_type_id_map().
4043 ///
4044 /// That map is populated at abixml reading time, (by build_type())
4045 /// when a given XML element representing a type is read into a
4046 /// corresponding abigail::ir::type_base.
4047 ///
4048 /// This is used only for the purpose of debugging the
4049 /// self-comparison process. That is, when invoking "abidw
4050 /// --debug-abidiff".
4051 ///
4052 /// @return the type-id strings that corresponds
4053 string
get_type_id_from_pointer(uintptr_t ptr) const4054 environment::get_type_id_from_pointer(uintptr_t ptr) const
4055 {return priv_->get_type_id_from_pointer(ptr);}
4056
4057 /// Getter of the type-id that corresponds to the value of an
4058 /// abigail::ir::type_base that was created from the abixml reader.
4059 ///
4060 /// That value is retrieved from the map returned from
4061 /// environment::get_pointer_type_id_map().
4062 ///
4063 /// That map is populated at abixml reading time, (by build_type())
4064 /// when a given XML element representing a type is read into a
4065 /// corresponding abigail::ir::type_base.
4066 ///
4067 /// This is used only for the purpose of debugging the
4068 /// self-comparison process. That is, when invoking "abidw
4069 /// --debug-abidiff".
4070 ///
4071 /// @return the type-id strings that corresponds
4072 string
get_type_id_from_type(const type_base * t) const4073 environment::get_type_id_from_type(const type_base *t) const
4074 {return priv_->get_type_id_from_type(t);}
4075
4076 /// Getter of the canonical type of the artifact designated by a
4077 /// type-id.
4078 ///
4079 /// That type-id was generated by the abixml writer at the emitting
4080 /// time of the abixml file. The corresponding canonical type was
4081 /// stored in the map returned by
4082 /// environment::get_type_id_canonical_type_map().
4083 ///
4084 /// This is useful for debugging purposes, especially in the context
4085 /// of the use of the command:
4086 /// 'abidw --debug-abidiff <binary>'.
4087 ///
4088 /// @return the set of abixml type-id and the pointer value of the
4089 /// (canonical) type it's associated to.
4090 uintptr_t
get_canonical_type_from_type_id(const char * type_id) const4091 environment::get_canonical_type_from_type_id(const char* type_id) const
4092 {return priv_->get_canonical_type_from_type_id(type_id);}
4093 #endif
4094
4095 // </environment stuff>
4096
4097 // <type_or_decl_base stuff>
4098
4099 /// The private data of @ref type_or_decl_base.
4100 struct type_or_decl_base::priv
4101 {
4102 // This holds the kind of dynamic type of particular instance.
4103 // Yes, this is part of the implementation of a "poor man" runtime
4104 // type identification. We are doing this because profiling shows
4105 // that using dynamic_cast in some places is really to slow and is
4106 // constituting a hotspot. This poor man's implementation made
4107 // things be much faster.
4108 enum type_or_decl_kind kind_;
4109 // This holds the runtime type instance pointer of particular
4110 // instance. In other words, this is the "this pointer" of the
4111 // dynamic type of a particular instance.
4112 void* rtti_;
4113 // This holds a pointer to either the type_base sub-object (if the
4114 // current instance is a type) or the decl_base sub-object (if the
4115 // current instance is a decl). This is used by the is_decl() and
4116 // is_type() functions, which also show up during profiling as
4117 // hotspots, due to their use of dynamic_cast.
4118 void* type_or_decl_ptr_;
4119 bool hashing_started_;
4120 const environment& env_;
4121 translation_unit* translation_unit_;
4122 // The location of an artifact as seen from its input by the
4123 // artifact reader. This might be different from the source
4124 // location advertised by the original emitter of the artifact
4125 // emitter.
4126 location artificial_location_;
4127 // Flags if the current ABI artifact is artificial (i.e, *NOT*
4128 // generated from the initial source code, but rather either
4129 // artificially by the compiler or by libabigail itself).
4130 bool is_artificial_;
4131
4132 /// Constructor of the type_or_decl_base::priv private type.
4133 ///
4134 /// @param e the environment in which the ABI artifact was created.
4135 ///
4136 /// @param k the identifier of the runtime type of the current
4137 /// instance of ABI artifact.
privabigail::ir::type_or_decl_base::priv4138 priv(const environment& e,
4139 enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
4140 : kind_(k),
4141 rtti_(),
4142 type_or_decl_ptr_(),
4143 hashing_started_(),
4144 env_(e),
4145 translation_unit_(),
4146 is_artificial_()
4147 {}
4148
4149 enum type_or_decl_kind
kindabigail::ir::type_or_decl_base::priv4150 kind() const
4151 {return kind_;}
4152
4153 void
kindabigail::ir::type_or_decl_base::priv4154 kind (enum type_or_decl_kind k)
4155 {kind_ |= k;}
4156 }; // end struct type_or_decl_base::priv
4157
4158 /// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
4159 /// bitmap type.
4160 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)4161 operator|(type_or_decl_base::type_or_decl_kind l,
4162 type_or_decl_base::type_or_decl_kind r)
4163 {
4164 return static_cast<type_or_decl_base::type_or_decl_kind>
4165 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
4166 }
4167
4168 /// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
4169 /// bitmap type.
4170 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)4171 operator|=(type_or_decl_base::type_or_decl_kind& l,
4172 type_or_decl_base::type_or_decl_kind r)
4173 {
4174 l = l | r;
4175 return l;
4176 }
4177
4178 /// bitwise "AND" operator for the
4179 /// type_or_decl_base::type_or_decl_kind bitmap type.
4180 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)4181 operator&(type_or_decl_base::type_or_decl_kind l,
4182 type_or_decl_base::type_or_decl_kind r)
4183 {
4184 return static_cast<type_or_decl_base::type_or_decl_kind>
4185 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
4186 }
4187
4188 /// bitwise "A&=" operator for the
4189 /// type_or_decl_base::type_or_decl_kind bitmap type.
4190 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)4191 operator&=(type_or_decl_base::type_or_decl_kind& l,
4192 type_or_decl_base::type_or_decl_kind r)
4193 {
4194 l = l & r;
4195 return l;
4196 }
4197
4198 /// Constructor of @ref type_or_decl_base.
4199 ///
4200 /// @param the environment the current ABI artifact is constructed
4201 /// from.
4202 ///
4203 /// @param k the runtime identifier bitmap of the type being built.
type_or_decl_base(const environment & e,enum type_or_decl_kind k)4204 type_or_decl_base::type_or_decl_base(const environment& e,
4205 enum type_or_decl_kind k)
4206 :priv_(new priv(e, k))
4207 {}
4208
4209 /// The destructor of the @ref type_or_decl_base type.
~type_or_decl_base()4210 type_or_decl_base::~type_or_decl_base()
4211 {}
4212
4213 /// Getter of the flag that says if the artefact is artificial.
4214 ///
4215 /// Being artificial means it was not explicitely mentionned in the
4216 /// source code, but was rather artificially created by the compiler
4217 /// or libabigail.
4218 ///
4219 /// @return true iff the declaration is artificial.
4220 bool
get_is_artificial() const4221 type_or_decl_base::get_is_artificial() const
4222 {return priv_->is_artificial_;}
4223
4224 /// Setter of the flag that says if the artefact is artificial.
4225 ///
4226 /// Being artificial means the artefact was not explicitely
4227 /// mentionned in the source code, but was rather artificially created
4228 /// by the compiler or by libabigail.
4229 ///
4230 /// @param f the new value of the flag that says if the artefact is
4231 /// artificial.
4232 void
set_is_artificial(bool f)4233 type_or_decl_base::set_is_artificial(bool f)
4234 {priv_->is_artificial_ = f;}
4235
4236 /// Getter for the "kind" property of @ref type_or_decl_base type.
4237 ///
4238 /// This property holds the identifier bitmap of the runtime type of
4239 /// an ABI artifact.
4240 ///
4241 /// @return the runtime type identifier bitmap of the current ABI
4242 /// artifact.
4243 enum type_or_decl_base::type_or_decl_kind
kind() const4244 type_or_decl_base::kind() const
4245 {return priv_->kind();}
4246
4247 /// Setter for the "kind" property of @ref type_or_decl_base type.
4248 ///
4249 /// This property holds the identifier bitmap of the runtime type of
4250 /// an ABI artifact.
4251 ///
4252 /// @param the runtime type identifier bitmap of the current ABI
4253 /// artifact.
4254 void
kind(enum type_or_decl_kind k)4255 type_or_decl_base::kind(enum type_or_decl_kind k)
4256 {priv_->kind(k);}
4257
4258 /// Getter of the pointer to the runtime type sub-object of the
4259 /// current instance.
4260 ///
4261 /// @return the pointer to the runtime type sub-object of the current
4262 /// instance.
4263 const void*
runtime_type_instance() const4264 type_or_decl_base::runtime_type_instance() const
4265 {return priv_->rtti_;}
4266
4267 /// Getter of the pointer to the runtime type sub-object of the
4268 /// current instance.
4269 ///
4270 /// @return the pointer to the runtime type sub-object of the current
4271 /// instance.
4272 void*
runtime_type_instance()4273 type_or_decl_base::runtime_type_instance()
4274 {return priv_->rtti_;}
4275
4276 /// Setter of the pointer to the runtime type sub-object of the
4277 /// current instance.
4278 ///
4279 /// @param i the new pointer to the runtime type sub-object of the
4280 /// current instance.
4281 void
runtime_type_instance(void * i)4282 type_or_decl_base::runtime_type_instance(void* i)
4283 {
4284 priv_->rtti_ = i;
4285 if (type_base* t = dynamic_cast<type_base*>(this))
4286 priv_->type_or_decl_ptr_ = t;
4287 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4288 priv_->type_or_decl_ptr_ = d;
4289 }
4290
4291 /// Getter of the pointer to either the type_base sub-object of the
4292 /// current instance if it's a type, or to the decl_base sub-object of
4293 /// the current instance if it's a decl.
4294 ///
4295 /// @return the pointer to either the type_base sub-object of the
4296 /// current instance if it's a type, or to the decl_base sub-object of
4297 /// the current instance if it's a decl.
4298 const void*
type_or_decl_base_pointer() const4299 type_or_decl_base::type_or_decl_base_pointer() const
4300 {return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
4301
4302 /// Getter of the pointer to either the type_base sub-object of the
4303 /// current instance if it's a type, or to the decl_base sub-object of
4304 /// the current instance if it's a decl.
4305 ///
4306 /// @return the pointer to either the type_base sub-object of the
4307 /// current instance if it's a type, or to the decl_base sub-object of
4308 /// the current instance if it's a decl.
4309 void*
type_or_decl_base_pointer()4310 type_or_decl_base::type_or_decl_base_pointer()
4311 {return priv_->type_or_decl_ptr_;}
4312
4313 /// Getter for the 'hashing_started' property.
4314 ///
4315 /// @return the 'hashing_started' property.
4316 bool
hashing_started() const4317 type_or_decl_base::hashing_started() const
4318 {return priv_->hashing_started_;}
4319
4320 /// Setter for the 'hashing_started' property.
4321 ///
4322 /// @param b the value to set the 'hashing_property' to.
4323 void
hashing_started(bool b) const4324 type_or_decl_base::hashing_started(bool b) const
4325 {priv_->hashing_started_ = b;}
4326
4327 /// Getter of the environment of the current ABI artifact.
4328 ///
4329 /// @return the environment of the artifact.
4330 const environment&
get_environment() const4331 type_or_decl_base::get_environment() const
4332 {return priv_->env_;}
4333
4334 /// Setter of the artificial location of the artificat.
4335 ///
4336 /// The artificial location is a location that was artificially
4337 /// generated by libabigail, not generated by the original emitter of
4338 /// the ABI meta-data. For instance, when reading an XML element from
4339 /// an abixml file, the artificial location is the source location of
4340 /// the XML element within the file, not the value of the
4341 /// 'location'property that might be carried by the element.
4342 ///
4343 /// Artificial locations might be useful to ensure that abixml emitted
4344 /// by the abixml writer are sorted the same way as the input abixml
4345 /// read by the reader.
4346 ///
4347 /// @param l the new artificial location.
4348 void
set_artificial_location(const location & l)4349 type_or_decl_base::set_artificial_location(const location &l)
4350 {priv_->artificial_location_ = l;}
4351
4352 /// Getter of the artificial location of the artifact.
4353 ///
4354 /// The artificial location is a location that was artificially
4355 /// generated by libabigail, not generated by the original emitter of
4356 /// the ABI meta-data. For instance, when reading an XML element from
4357 /// an abixml file, the artificial location is the source location of
4358 /// the XML element within the file, not the value of the
4359 /// 'location'property that might be carried by the element.
4360 ///
4361 /// Artificial locations might be useful to ensure that the abixml
4362 /// emitted by the abixml writer is sorted the same way as the input
4363 /// abixml read by the reader.
4364 ///
4365 /// @return the new artificial location.
4366 location&
get_artificial_location() const4367 type_or_decl_base::get_artificial_location() const
4368 {return priv_->artificial_location_;}
4369
4370 /// Test if the current ABI artifact carries an artificial location.
4371 ///
4372 /// @return true iff the current ABI artifact carries an artificial location.
4373 bool
has_artificial_location() const4374 type_or_decl_base::has_artificial_location() const
4375 {
4376 return (priv_->artificial_location_
4377 && priv_->artificial_location_.get_is_artificial());
4378 }
4379
4380 /// Get the @ref corpus this ABI artifact belongs to.
4381 ///
4382 /// @return the corpus this ABI artifact belongs to, or nil if it
4383 /// belongs to none for now.
4384 corpus*
get_corpus()4385 type_or_decl_base::get_corpus()
4386 {
4387 translation_unit* tu = get_translation_unit();
4388 if (!tu)
4389 return 0;
4390 return tu->get_corpus();
4391 }
4392
4393
4394 /// Get the @ref corpus this ABI artifact belongs to.
4395 ///
4396 /// @return the corpus this ABI artifact belongs to, or nil if it
4397 /// belongs to none for now.
4398 const corpus*
get_corpus() const4399 type_or_decl_base::get_corpus() const
4400 {return const_cast<type_or_decl_base*>(this)->get_corpus();}
4401
4402 /// Set the @ref translation_unit this ABI artifact belongs to.
4403 ///
4404 /// Note that adding an ABI artifact to a containining on should
4405 /// invoke this member function.
4406 void
set_translation_unit(translation_unit * tu)4407 type_or_decl_base::set_translation_unit(translation_unit* tu)
4408 {priv_->translation_unit_ = tu;}
4409
4410
4411 /// Get the @ref translation_unit this ABI artifact belongs to.
4412 ///
4413 /// @return the translation unit this ABI artifact belongs to, or nil
4414 /// if belongs to none for now.
4415 translation_unit*
get_translation_unit()4416 type_or_decl_base::get_translation_unit()
4417 {return priv_->translation_unit_;}
4418
4419 /// Get the @ref translation_unit this ABI artifact belongs to.
4420 ///
4421 /// @return the translation unit this ABI artifact belongs to, or nil
4422 /// if belongs to none for now.
4423 const translation_unit*
get_translation_unit() const4424 type_or_decl_base::get_translation_unit() const
4425 {return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4426
4427 /// Traverse the the ABI artifact.
4428 ///
4429 /// @param v the visitor used to traverse the sub-tree nodes of the
4430 /// artifact.
4431 bool
traverse(ir_node_visitor &)4432 type_or_decl_base::traverse(ir_node_visitor&)
4433 {return true;}
4434
4435 /// Non-member equality operator for the @type_or_decl_base type.
4436 ///
4437 /// @param lr the left-hand operand of the equality.
4438 ///
4439 /// @param rr the right-hand operatnr of the equality.
4440 ///
4441 /// @return true iff @p lr equals @p rr.
4442 bool
operator ==(const type_or_decl_base & lr,const type_or_decl_base & rr)4443 operator==(const type_or_decl_base& lr, const type_or_decl_base& rr)
4444 {
4445 const type_or_decl_base* l = &lr;
4446 const type_or_decl_base* r = &rr;
4447
4448 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4449 *dr = dynamic_cast<const decl_base*>(r);
4450
4451 if (!!dl != !!dr)
4452 return false;
4453
4454 if (dl && dr)
4455 return *dl == *dr;
4456
4457 const type_base* tl = dynamic_cast<const type_base*>(l),
4458 *tr = dynamic_cast<const type_base*>(r);
4459
4460 if (!!tl != !!tr)
4461 return false;
4462
4463 if (tl && tr)
4464 return *tl == *tr;
4465
4466 return false;
4467 }
4468
4469 /// Non-member equality operator for the @type_or_decl_base type.
4470 ///
4471 /// @param l the left-hand operand of the equality.
4472 ///
4473 /// @param r the right-hand operatnr of the equality.
4474 ///
4475 /// @return true iff @p l equals @p r.
4476 bool
operator ==(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)4477 operator==(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
4478 {
4479 if (!! l != !!r)
4480 return false;
4481
4482 if (!l)
4483 return true;
4484
4485 return *r == *l;
4486 }
4487
4488 /// Non-member inequality operator for the @type_or_decl_base type.
4489 ///
4490 /// @param l the left-hand operand of the equality.
4491 ///
4492 /// @param r the right-hand operator of the equality.
4493 ///
4494 /// @return true iff @p l is different from @p r.
4495 bool
operator !=(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)4496 operator!=(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
4497 {return !operator==(l, r);}
4498
4499 // </type_or_decl_base stuff>
4500
4501 // <Decl definition>
4502
4503 struct decl_base::priv
4504 {
4505 bool in_pub_sym_tab_;
4506 bool is_anonymous_;
4507 location location_;
4508 context_rel *context_;
4509 interned_string name_;
4510 interned_string qualified_parent_name_;
4511 // This temporary qualified name is the cache used for the qualified
4512 // name before the type associated to this decl (if applicable) is
4513 // canonicalized. Once the type is canonicalized, the cached use is
4514 // the data member qualified_parent_name_ above.
4515 interned_string temporary_qualified_name_;
4516 // This is the fully qualified name of the decl. It contains the
4517 // name of the decl and the qualified name of its scope. So if in
4518 // the parent scopes of the decl, there is one anonymous struct,
4519 // somewhere in the name, there is going to by an
4520 // __anonymous_struct__ string, even if the anonymous struct is not
4521 // the direct containing scope of this decl.
4522 interned_string qualified_name_;
4523 interned_string temporary_internal_qualified_name_;
4524 interned_string internal_qualified_name_;
4525 // Unline qualified_name_, scoped_name_ contains the name of the
4526 // decl and the name of its scope; not the qualified name of the
4527 // scope.
4528 interned_string scoped_name_;
4529 interned_string linkage_name_;
4530 visibility visibility_;
4531 decl_base_sptr declaration_;
4532 decl_base_wptr definition_of_declaration_;
4533 decl_base* naked_definition_of_declaration_;
4534 bool is_declaration_only_;
4535 typedef_decl_sptr naming_typedef_;
4536
privabigail::ir::decl_base::priv4537 priv()
4538 : in_pub_sym_tab_(false),
4539 is_anonymous_(true),
4540 context_(),
4541 visibility_(VISIBILITY_DEFAULT),
4542 naked_definition_of_declaration_(),
4543 is_declaration_only_(false)
4544 {}
4545
privabigail::ir::decl_base::priv4546 priv(interned_string name, interned_string linkage_name, visibility vis)
4547 : in_pub_sym_tab_(false),
4548 context_(),
4549 name_(name),
4550 qualified_name_(name),
4551 linkage_name_(linkage_name),
4552 visibility_(vis),
4553 naked_definition_of_declaration_(),
4554 is_declaration_only_(false)
4555 {
4556 is_anonymous_ = name_.empty();
4557 }
4558
~privabigail::ir::decl_base::priv4559 ~priv()
4560 {
4561 delete context_;
4562 }
4563 };// end struct decl_base::priv
4564
4565 /// Constructor for the @ref decl_base type.
4566 ///
4567 /// @param e the environment the current @ref decl_base is being
4568 /// created in.
4569 ///
4570 /// @param name the name of the declaration.
4571 ///
4572 /// @param locus the location where to find the declaration in the
4573 /// source code.
4574 ///
4575 /// @param linkage_name the linkage name of the declaration.
4576 ///
4577 /// @param vis the visibility of the declaration.
decl_base(const environment & e,const string & name,const location & locus,const string & linkage_name,visibility vis)4578 decl_base::decl_base(const environment& e,
4579 const string& name,
4580 const location& locus,
4581 const string& linkage_name,
4582 visibility vis)
4583 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4584 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4585 {
4586 set_location(locus);
4587 }
4588
4589 /// Constructor.
4590 ///
4591 /// @param e the environment this instance of @ref decl_base is
4592 /// created in.
4593 ///
4594 /// @param name the name of the declaration being constructed.
4595 ///
4596 /// @param locus the source location of the declaration being constructed.
4597 ///
4598 /// @param linkage_name the linkage name of the declaration being
4599 /// constructed.
4600 ///
4601 /// @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)4602 decl_base::decl_base(const environment& e,
4603 const interned_string& name,
4604 const location& locus,
4605 const interned_string& linkage_name,
4606 visibility vis)
4607 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4608 priv_(new priv(name, linkage_name, vis))
4609 {
4610 set_location(locus);
4611 }
4612
4613 /// Constructor for the @ref decl_base type.
4614 ///
4615 ///@param environment the environment this instance of @ref decl_base
4616 /// is being constructed in.
4617 ///
4618 /// @param l the location where to find the declaration in the source
4619 /// code.
decl_base(const environment & e,const location & l)4620 decl_base::decl_base(const environment& e, const location& l)
4621 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4622 priv_(new priv())
4623 {
4624 set_location(l);
4625 }
4626
4627 /// Getter for the qualified name.
4628 ///
4629 /// Unlike decl_base::get_qualified_name() this doesn't try to update
4630 /// the qualified name.
4631 ///
4632 /// @return the qualified name.
4633 const interned_string&
peek_qualified_name() const4634 decl_base::peek_qualified_name() const
4635 {return priv_->qualified_name_;}
4636
4637 /// Clear the qualified name of this decl.
4638 ///
4639 /// This is useful to ensure that the cache for the qualified name of
4640 /// the decl is refreshed right after type canonicalization, for
4641 /// instance.
4642 void
clear_qualified_name()4643 decl_base::clear_qualified_name()
4644 {priv_->qualified_name_.clear();}
4645
4646 /// Setter for the qualified name.
4647 ///
4648 /// @param n the new qualified name.
4649 void
set_qualified_name(const interned_string & n) const4650 decl_base::set_qualified_name(const interned_string& n) const
4651 {priv_->qualified_name_ = n;}
4652
4653 /// Getter of the temporary qualified name of the current declaration.
4654 ///
4655 /// This temporary qualified name is used as a qualified name cache by
4656 /// the type for which this is the declaration (when applicable)
4657 /// before the type is canonicalized. Once the type is canonicalized,
4658 /// it's the result of decl_base::peek_qualified_name() that becomes
4659 /// the qualified name cached.
4660 ///
4661 /// @return the temporary qualified name.
4662 const interned_string&
peek_temporary_qualified_name() const4663 decl_base::peek_temporary_qualified_name() const
4664 {return priv_->temporary_qualified_name_;}
4665
4666 /// Setter for the temporary qualified name of the current
4667 /// declaration.
4668 ///
4669 ///@param n the new temporary qualified name.
4670 ///
4671 /// This temporary qualified name is used as a qualified name cache by
4672 /// the type for which this is the declaration (when applicable)
4673 /// before the type is canonicalized. Once the type is canonicalized,
4674 /// it's the result of decl_base::peek_qualified_name() that becomes
4675 /// the qualified name cached.
4676 void
set_temporary_qualified_name(const interned_string & n) const4677 decl_base::set_temporary_qualified_name(const interned_string& n) const
4678 {priv_->temporary_qualified_name_ = n;}
4679
4680 ///Getter for the context relationship.
4681 ///
4682 ///@return the context relationship for the current decl_base.
4683 const context_rel*
get_context_rel() const4684 decl_base::get_context_rel() const
4685 {return priv_->context_;}
4686
4687 ///Getter for the context relationship.
4688 ///
4689 ///@return the context relationship for the current decl_base.
4690 context_rel*
get_context_rel()4691 decl_base::get_context_rel()
4692 {return priv_->context_;}
4693
4694 void
set_context_rel(context_rel * c)4695 decl_base::set_context_rel(context_rel *c)
4696 {priv_->context_ = c;}
4697
4698 /// Get the hash of a decl. If the hash hasn't been computed yet,
4699 /// compute it ans store its value; otherwise, just return the hash.
4700 ///
4701 /// @return the hash of the decl.
4702 size_t
get_hash() const4703 decl_base::get_hash() const
4704 {
4705 size_t result = 0;
4706
4707 if (const type_base* t = dynamic_cast<const type_base*>(this))
4708 {
4709 type_base::dynamic_hash hash;
4710 result = hash(t);
4711 }
4712 else
4713 // If we reach this point, it mean we are missing a virtual
4714 // overload for decl_base::get_hash. Add it!
4715 abort();
4716
4717 return result;
4718 }
4719
4720 /// Test if the decl is defined in a ELF symbol table as a public
4721 /// symbol.
4722 ///
4723 /// @return true iff the decl is defined in a ELF symbol table as a
4724 /// public symbol.
4725 bool
get_is_in_public_symbol_table() const4726 decl_base::get_is_in_public_symbol_table() const
4727 {return priv_->in_pub_sym_tab_;}
4728
4729 /// Set the flag saying if this decl is from a symbol that is in
4730 /// a public symbols table, defined as public (global or weak).
4731 ///
4732 /// @param f the new flag value.
4733 void
set_is_in_public_symbol_table(bool f)4734 decl_base::set_is_in_public_symbol_table(bool f)
4735 {priv_->in_pub_sym_tab_ = f;}
4736
4737 /// Get the location of a given declaration.
4738 ///
4739 /// The location is an abstraction for the tripplet {file path,
4740 /// line, column} that defines where the declaration appeared in the
4741 /// source code.
4742 ///
4743 /// To get the value of the tripplet {file path, line, column} from
4744 /// the @ref location, you need to use the
4745 /// location_manager::expand_location() method.
4746 ///
4747 /// The instance of @ref location_manager that you want is
4748 /// accessible from the instance of @ref translation_unit that the
4749 /// current instance of @ref decl_base belongs to, via a call to
4750 /// translation_unit::get_loc_mgr().
4751 ///
4752 /// @return the location of the current instance of @ref decl_base.
4753 const location&
get_location() const4754 decl_base::get_location() const
4755 {return priv_->location_;}
4756
4757 /// Set the location for a given declaration.
4758 ///
4759 /// The location is an abstraction for the tripplet {file path,
4760 /// line, column} that defines where the declaration appeared in the
4761 /// source code.
4762 ///
4763 /// To create a location from a tripplet {file path, line, column},
4764 /// you need to use the method @ref
4765 /// location_manager::create_new_location().
4766 ///
4767 /// Note that there can be two kinds of location. An artificial
4768 /// location and a non-artificial one. The non-artificial location is
4769 /// the one emitted by the original emitter of the ABI artifact, for
4770 /// instance, if the ABI artifact comes from debug info, then the
4771 /// source location that is present in the debug info represent a
4772 /// non-artificial location. When looking at an abixml file on the
4773 /// other hand, the value of the 'location' attribute of an XML
4774 /// element describing an artifact is the non-artificial location.
4775 /// The artificial location is the location (line number from the
4776 /// beginning of the file) of the XML element within the abixml file.
4777 ///
4778 /// So, if the location that is being set is artificial, note that the
4779 /// type_or_decl_base::has_artificial_location() method of this decl will
4780 /// subsequently return true and that artificial location will have to
4781 /// be retrieved using type_or_decl_base::get_artificial_location().
4782 /// If the location is non-artificial however,
4783 /// type_or_decl_base::has_artificial_location() will subsequently
4784 /// return false and the non-artificial location will have to be
4785 /// retrieved using decl_base::get_location().
4786 ///
4787 /// The instance of @ref location_manager that you want is
4788 /// accessible from the instance of @ref translation_unit that the
4789 /// current instance of @ref decl_base belongs to, via a call to
4790 /// translation_unit::get_loc_mgr().
4791 void
set_location(const location & l)4792 decl_base::set_location(const location& l)
4793 {
4794 if (l.get_is_artificial())
4795 set_artificial_location(l);
4796 else
4797 priv_->location_ = l;
4798 }
4799
4800 /// Setter for the name of the decl.
4801 ///
4802 /// @param n the new name to set.
4803 void
set_name(const string & n)4804 decl_base::set_name(const string& n)
4805 {
4806 priv_->name_ = get_environment().intern(n);
4807 priv_->is_anonymous_ = n.empty();
4808 }
4809
4810 /// Test if the current declaration is anonymous.
4811 ///
4812 /// Being anonymous means that the declaration was created without a
4813 /// name. This can usually happen for enum or struct types.
4814 ///
4815 /// @return true iff the type is anonymous.
4816 bool
get_is_anonymous() const4817 decl_base::get_is_anonymous() const
4818 {return priv_->is_anonymous_;}
4819
4820 /// Set the "is_anonymous" flag of the current declaration.
4821 ///
4822 /// Being anonymous means that the declaration was created without a
4823 /// name. This can usually happen for enum or struct types.
4824 ///
4825 /// @param f the new value of the flag.
4826 void
set_is_anonymous(bool f)4827 decl_base::set_is_anonymous(bool f)
4828 {priv_->is_anonymous_ = f;}
4829
4830
4831 /// Get the "has_anonymous_parent" flag of the current declaration.
4832 ///
4833 /// Having an anoymous parent means having a anonymous parent scope
4834 /// (containing type or namespace) which is either direct or indirect.
4835 ///
4836 /// @return true iff the current decl has a direct or indirect scope
4837 /// which is anonymous.
4838 bool
get_has_anonymous_parent() const4839 decl_base::get_has_anonymous_parent() const
4840 {
4841 scope_decl *scope = get_scope();
4842 if (!scope)
4843 return false;
4844 return scope->get_is_anonymous();
4845 }
4846
4847 /// @return the logical "OR" of decl_base::get_is_anonymous() and
4848 /// decl_base::get_has_anonymous_parent().
4849 bool
get_is_anonymous_or_has_anonymous_parent() const4850 decl_base::get_is_anonymous_or_has_anonymous_parent() const
4851 {return get_is_anonymous() || get_has_anonymous_parent();}
4852
4853 /// Getter for the naming typedef of the current decl.
4854 ///
4855 /// Consider the C idiom:
4856 ///
4857 /// typedef struct {int member;} foo_type;
4858 ///
4859 /// In that idiom, foo_type is the naming typedef of the anonymous
4860 /// struct that is declared.
4861 ///
4862 /// @return the naming typedef, if any. Otherwise, returns nil.
4863 typedef_decl_sptr
get_naming_typedef() const4864 decl_base::get_naming_typedef() const
4865 {return priv_->naming_typedef_;}
4866
4867 /// Set the naming typedef of the current instance of @ref decl_base.
4868 ///
4869 /// Consider the C idiom:
4870 ///
4871 /// typedef struct {int member;} foo_type;
4872 ///
4873 /// In that idiom, foo_type is the naming typedef of the anonymous
4874 /// struct that is declared.
4875 ///
4876 /// After completion of this function, the decl will not be considered
4877 /// anonymous anymore. It's name is going to be the name of the
4878 /// naming typedef.
4879 ///
4880 /// @param typedef_type the new naming typedef.
4881 void
set_naming_typedef(const typedef_decl_sptr & t)4882 decl_base::set_naming_typedef(const typedef_decl_sptr& t)
4883 {
4884 // A naming typedef is usually for an anonymous type.
4885 ABG_ASSERT(get_is_anonymous()
4886 // Whe the typedef-named decl is saved into abixml, it's
4887 // not anonymous anymore. Its name is the typedef name.
4888 // So when we read it back, we must still be able to
4889 // apply the naming typedef to the decl.
4890 || t->get_name() == get_name());
4891 // Only non canonicalized types can be edited this way.
4892 ABG_ASSERT(is_type(this)
4893 && is_type(this)->get_naked_canonical_type() == nullptr);
4894
4895 priv_->naming_typedef_ = t;
4896 set_name(t->get_name());
4897 string qualified_name = build_qualified_name(get_scope(), t->get_name());
4898 set_qualified_name(get_environment().intern(qualified_name));
4899 set_is_anonymous(false);
4900 // Now that the qualified type of the decl has changed, let's update
4901 // the qualified names of the member types of this decls.
4902 update_qualified_name(this);
4903 }
4904
4905 /// Getter for the mangled name.
4906 ///
4907 /// @return the new mangled name.
4908 const interned_string&
get_linkage_name() const4909 decl_base::get_linkage_name() const
4910 {return priv_->linkage_name_;}
4911
4912 /// Setter for the linkage name.
4913 ///
4914 /// @param m the new linkage name.
4915 void
set_linkage_name(const string & m)4916 decl_base::set_linkage_name(const string& m)
4917 {
4918 const environment& env = get_environment();
4919 priv_->linkage_name_ = env.intern(m);
4920 }
4921
4922 /// Getter for the visibility of the decl.
4923 ///
4924 /// @return the new visibility.
4925 decl_base::visibility
get_visibility() const4926 decl_base::get_visibility() const
4927 {return priv_->visibility_;}
4928
4929 /// Setter for the visibility of the decl.
4930 ///
4931 /// @param v the new visibility.
4932 void
set_visibility(visibility v)4933 decl_base::set_visibility(visibility v)
4934 {priv_->visibility_ = v;}
4935
4936 /// Return the type containing the current decl, if any.
4937 ///
4938 /// @return the type that contains the current decl, or NULL if there
4939 /// is none.
4940 scope_decl*
get_scope() const4941 decl_base::get_scope() const
4942 {
4943 if (priv_->context_)
4944 return priv_->context_->get_scope();
4945 return 0;
4946 }
4947
4948 /// Return a copy of the qualified name of the parent of the current
4949 /// decl.
4950 ///
4951 /// @return the newly-built qualified name of the of the current decl.
4952 const interned_string&
get_qualified_parent_name() const4953 decl_base::get_qualified_parent_name() const
4954 {return priv_->qualified_parent_name_;}
4955
4956 /// Getter for the name of the current decl.
4957 ///
4958 /// @return the name of the current decl.
4959 const interned_string&
get_name() const4960 decl_base::get_name() const
4961 {return priv_->name_;}
4962
4963 /// Compute the qualified name of the decl.
4964 ///
4965 /// @param qn the resulting qualified name.
4966 ///
4967 /// @param internal set to true if the call is intended for an
4968 /// internal use (for technical use inside the library itself), false
4969 /// otherwise. If you don't know what this is for, then set it to
4970 /// false.
4971 void
get_qualified_name(interned_string & qn,bool internal) const4972 decl_base::get_qualified_name(interned_string& qn, bool internal) const
4973 {qn = get_qualified_name(internal);}
4974
4975 /// Get the pretty representatin of the current declaration.
4976 ///
4977 ///
4978 /// @param internal set to true if the call is intended to get a
4979 /// representation of the decl (or type) for the purpose of canonical
4980 /// type comparison. This is mainly used in the function
4981 /// type_base::get_canonical_type_for().
4982 ///
4983 /// In other words if the argument for this parameter is true then the
4984 /// call is meant for internal use (for technical use inside the
4985 /// library itself), false otherwise. If you don't know what this is
4986 /// for, then set it to false.
4987 ///
4988 /// @param qualified_name if true, names emitted in the pretty
4989 /// representation are fully qualified.
4990 ///
4991 /// @return the default pretty representation for a decl. This is
4992 /// basically the fully qualified name of the decl optionally prefixed
4993 /// with a meaningful string to add context for the user.
4994 string
get_pretty_representation(bool internal,bool qualified_name) const4995 decl_base::get_pretty_representation(bool internal,
4996 bool qualified_name) const
4997 {
4998 if (internal
4999 && get_is_anonymous()
5000 && has_generic_anonymous_internal_type_name(this))
5001 {
5002 // We are looking at an anonymous enum, union or class and we
5003 // want an *internal* pretty representation for it. All
5004 // anonymous types of this kind in the same namespace must have
5005 // the same internal representation for type canonicalization to
5006 // work properly.
5007 //
5008 // OK, in practise, we are certainly looking at an enum because
5009 // classes and unions should have their own overloaded virtual
5010 // member function for this.
5011 string name = get_generic_anonymous_internal_type_name(this);
5012 if (qualified_name && !get_qualified_parent_name().empty())
5013 name = get_qualified_parent_name() + "::" + name;
5014 return name;
5015 }
5016
5017 if (qualified_name)
5018 return get_qualified_name(internal);
5019 return get_name();
5020 }
5021
5022 /// Return the qualified name of the decl.
5023 ///
5024 /// This is the fully qualified name of the decl. It's made of the
5025 /// concatenation of the name of the decl with the qualified name of
5026 /// its scope.
5027 ///
5028 /// Note that the value returned by this function is computed by @ref
5029 /// update_qualified_name when the decl is added to its scope.
5030 ///
5031 /// @param internal set to true if the call is intended for an
5032 /// internal use (for technical use inside the library itself), false
5033 /// otherwise. If you don't know what this is for, then set it to
5034 /// false.
5035 ///
5036 /// @return the resulting qualified name.
5037 const interned_string&
get_qualified_name(bool) const5038 decl_base::get_qualified_name(bool /*internal*/) const
5039 {return priv_->qualified_name_;}
5040
5041 /// Return the scoped name of the decl.
5042 ///
5043 /// This is made of the concatenation of the name of the decl with the
5044 /// name of its scope. It doesn't contain the qualified name of its
5045 /// scope, unlike what is returned by decl_base::get_qualified_name.
5046 ///
5047 /// Note that the value returned by this function is computed by @ref
5048 /// update_qualified_name when the decl is added to its scope.
5049 ///
5050 /// @return the scoped name of the decl.
5051 const interned_string&
get_scoped_name() const5052 decl_base::get_scoped_name() const
5053 {return priv_->scoped_name_;}
5054
5055 /// If this @ref decl_base is a definition, get its earlier
5056 /// declaration.
5057 ///
5058 /// @return the earlier declaration of the class, if any.
5059 const decl_base_sptr
get_earlier_declaration() const5060 decl_base::get_earlier_declaration() const
5061 {return priv_->declaration_;}
5062
5063 /// set the earlier declaration of this @ref decl_base definition.
5064 ///
5065 /// @param d the earlier declaration to set. Note that it's set only
5066 /// if it's a pure declaration.
5067 void
set_earlier_declaration(const decl_base_sptr & d)5068 decl_base::set_earlier_declaration(const decl_base_sptr& d)
5069 {
5070 if (d && d->get_is_declaration_only())
5071 priv_->declaration_ = d;
5072 }
5073
5074
5075 /// If this @ref decl_base is declaration-only, get its definition, if
5076 /// any.
5077 ///
5078 /// @return the definition of this decl-only @ref decl_base.
5079 const decl_base_sptr
get_definition_of_declaration() const5080 decl_base::get_definition_of_declaration() const
5081 {return priv_->definition_of_declaration_.lock();}
5082
5083 /// If this @ref decl_base is declaration-only, get its definition,
5084 /// if any.
5085 ///
5086 /// Note that this function doesn't return a smart pointer, but rather
5087 /// the underlying pointer managed by the smart pointer. So it's as
5088 /// fast as possible. This getter is to be used in code paths that
5089 /// are proven to be performance hot spots; especially, when comparing
5090 /// sensitive types like enums, classes or unions. Those are compared
5091 /// extremely frequently and thus, their access to the definition of
5092 /// declaration must be fast.
5093 ///
5094 /// @return the definition of the declaration.
5095 const decl_base*
get_naked_definition_of_declaration() const5096 decl_base::get_naked_definition_of_declaration() const
5097 {return priv_->naked_definition_of_declaration_;}
5098
5099 /// Test if a @ref decl_base is a declaration-only decl.
5100 ///
5101 /// @return true iff the current @ref decl_base is declaration-only.
5102 bool
get_is_declaration_only() const5103 decl_base::get_is_declaration_only() const
5104 {return priv_->is_declaration_only_;}
5105
5106 /// Set a flag saying if the @ref enum_type_decl is a declaration-only
5107 /// @ref enum_type_decl.
5108 ///
5109 /// @param f true if the @ref enum_type_decl is a declaration-only
5110 /// @ref enum_type_decl.
5111 void
set_is_declaration_only(bool f)5112 decl_base::set_is_declaration_only(bool f)
5113 {
5114 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
5115
5116 priv_->is_declaration_only_ = f;
5117
5118 if (update_types_lookup_map)
5119 if (scope_decl* s = get_scope())
5120 {
5121 scope_decl::declarations::iterator i;
5122 if (s->find_iterator_for_member(this, i))
5123 maybe_update_types_lookup_map(*i);
5124 else
5125 ABG_ASSERT_NOT_REACHED;
5126 }
5127 }
5128
5129 change_kind
operator |(change_kind l,change_kind r)5130 operator|(change_kind l, change_kind r)
5131 {
5132 return static_cast<change_kind>(static_cast<unsigned>(l)
5133 | static_cast<unsigned>(r));
5134 }
5135
5136 change_kind
operator &(change_kind l,change_kind r)5137 operator&(change_kind l, change_kind r)
5138 {
5139 return static_cast<change_kind>(static_cast<unsigned>(l)
5140 & static_cast<unsigned>(r));
5141 }
5142
5143 change_kind&
operator |=(change_kind & l,change_kind r)5144 operator|=(change_kind& l, change_kind r)
5145 {
5146 l = l | r;
5147 return l;
5148 }
5149
5150 change_kind&
operator &=(change_kind & l,change_kind r)5151 operator&=(change_kind& l, change_kind r)
5152 {
5153 l = l & r;
5154 return l;
5155 }
5156
5157 /// Compare the properties that belong to the "is-a-member-relation"
5158 /// of a decl.
5159 ///
5160 /// For instance, access specifiers are part of the
5161 /// "is-a-member-relation" of a decl.
5162 ///
5163 /// This comparison however doesn't take decl names into account. So
5164 /// typedefs for instance are decls that we want to compare with this
5165 /// function.
5166 ///
5167 /// This function is a sub-routine of the more general 'equals'
5168 /// overload for instances of decl_base.
5169 ///
5170 /// @param l the left-hand side operand of the comparison.
5171 ///
5172 /// @param r the right-hand side operand of the comparison.
5173 ///
5174 /// @return true iff @p l compare equals, as a member decl, to @p r.
5175 bool
maybe_compare_as_member_decls(const decl_base & l,const decl_base & r,change_kind * k)5176 maybe_compare_as_member_decls(const decl_base& l,
5177 const decl_base& r,
5178 change_kind* k)
5179 {
5180 bool result = true;
5181 if (is_member_decl(l) && is_member_decl(r))
5182 {
5183 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
5184 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
5185
5186 access_specifier la = no_access, ra = no_access;
5187 bool member_types_or_functions =
5188 ((is_type(l) && is_type(r))
5189 || (is_function_decl(l) && is_function_decl(r)));
5190
5191 if (member_types_or_functions)
5192 {
5193 // Access specifiers on member types in DWARF is not
5194 // reliable; in the same DSO, the same struct can be either
5195 // a class or a struct, and the access specifiers of its
5196 // member types are not necessarily given, so they
5197 // effectively can be considered differently, again, in the
5198 // same DSO. So, here, let's avoid considering those!
5199 // during comparison.
5200 la = r1->get_access_specifier();
5201 ra = r2->get_access_specifier();
5202 r1->set_access_specifier(no_access);
5203 r2->set_access_specifier(no_access);
5204 }
5205
5206 bool rels_are_different = *r1 != *r2;
5207
5208 if (member_types_or_functions)
5209 {
5210 // restore the access specifiers.
5211 r1->set_access_specifier(la);
5212 r2->set_access_specifier(ra);
5213 }
5214
5215 if (rels_are_different)
5216 {
5217 result = false;
5218 if (k)
5219 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
5220 }
5221 }
5222 ABG_RETURN(result);
5223 }
5224
5225 /// Get the name of a decl for the purpose of comparing two decl
5226 /// names.
5227 ///
5228 /// This is a sub-routine of the 'equal' overload for decl_base.
5229 ///
5230 /// This function takes into account the fact that all anonymous names
5231 /// shall have the same name for the purpose of comparison.
5232 ///
5233 /// For decls that are part of an anonymous scope, only the
5234 /// non-qualified name should be taken into account.
5235 static interned_string
get_decl_name_for_comparison(const decl_base & d)5236 get_decl_name_for_comparison(const decl_base &d)
5237 {
5238 if (has_generic_anonymous_internal_type_name(&d)
5239 && d.get_is_anonymous())
5240 {
5241 // The decl is anonymous. It should have the same name ass the
5242 // other anymous types of the same kind.
5243 string r;
5244 r += get_generic_anonymous_internal_type_name(&d);
5245 return d.get_environment().intern(r);
5246 }
5247
5248 interned_string n = (is_anonymous_or_typedef_named(d)
5249 || d.get_has_anonymous_parent()
5250 || is_typedef(&d))
5251 ? d.get_name()
5252 : d.get_qualified_name(/*internal=*/true);
5253 return n;
5254 }
5255
5256 /// Compares two instances of @ref decl_base.
5257 ///
5258 /// If the two intances are different, set a bitfield to give some
5259 /// insight about the kind of differences there are.
5260 ///
5261 /// @param l the first artifact of the comparison.
5262 ///
5263 /// @param r the second artifact of the comparison.
5264 ///
5265 /// @param k a pointer to a bitfield that gives information about the
5266 /// kind of changes there are between @p l and @p r. This one is set
5267 /// iff it's non-null and if the function returns false.
5268 ///
5269 /// Please note that setting k to a non-null value does have a
5270 /// negative performance impact because even if @p l and @p r are not
5271 /// equal, the function keeps up the comparison in order to determine
5272 /// the different kinds of ways in which they are different.
5273 ///
5274 /// @return true if @p l equals @p r, false otherwise.
5275 bool
equals(const decl_base & l,const decl_base & r,change_kind * k)5276 equals(const decl_base& l, const decl_base& r, change_kind* k)
5277 {
5278 bool result = true;
5279 const interned_string &l_linkage_name = l.get_linkage_name();
5280 const interned_string &r_linkage_name = r.get_linkage_name();
5281 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5282 {
5283 if (l_linkage_name != r_linkage_name)
5284 {
5285 // Linkage names are different. That usually means the two
5286 // decls are different, unless we are looking at two
5287 // function declarations which have two different symbols
5288 // that are aliases of each other.
5289 const function_decl *f1 = is_function_decl(&l),
5290 *f2 = is_function_decl(&r);
5291 if (f1 && f2 && function_decls_alias(*f1, *f2))
5292 ;// The two functions are aliases, so they are not
5293 // different.
5294 else
5295 {
5296 result = false;
5297 if (k)
5298 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
5299 else
5300 ABG_RETURN_FALSE;
5301 }
5302 }
5303 }
5304
5305 // This is the qualified name of the decls that we want to compare.
5306 // We want to use the "internal" version of the qualified name as
5307 // that one is stable even for anonymous decls.
5308 interned_string ln = get_decl_name_for_comparison(l);
5309 interned_string rn = get_decl_name_for_comparison(r);
5310
5311 /// If both of the current decls have an anonymous scope then let's
5312 /// compare their name component by component by properly handling
5313 /// anonymous scopes. That's the slow path.
5314 ///
5315 /// Otherwise, let's just compare their name, the obvious way.
5316 /// That's the fast path because in that case the names are
5317 /// interned_string and comparing them is much faster.
5318 bool decls_are_same = (ln == rn);
5319 if (!decls_are_same
5320 && l.get_is_anonymous()
5321 && !l.get_has_anonymous_parent()
5322 && r.get_is_anonymous()
5323 && !r.get_has_anonymous_parent())
5324 // Both decls are anonymous and their scope are *NOT* anonymous.
5325 // So we consider the decls to have equivalent names (both
5326 // anonymous, remember). We are still in the fast path here.
5327 decls_are_same = true;
5328
5329 if (!decls_are_same
5330 && l.get_has_anonymous_parent()
5331 && r.get_has_anonymous_parent())
5332 // This is the slow path as we are comparing the decl qualified
5333 // names component by component, properly handling anonymous
5334 // scopes.
5335 decls_are_same = tools_utils::decl_names_equal(ln, rn);
5336
5337 if (!decls_are_same)
5338 {
5339 result = false;
5340 if (k)
5341 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
5342 else
5343 ABG_RETURN_FALSE;
5344 }
5345
5346 result &= maybe_compare_as_member_decls(l, r, k);
5347
5348 ABG_RETURN(result);
5349 }
5350
5351 /// Return true iff the two decls have the same name.
5352 ///
5353 /// This function doesn't test if the scopes of the the two decls are
5354 /// equal.
5355 ///
5356 /// Note that this virtual function is to be implemented by classes
5357 /// that extend the \p decl_base class.
5358 bool
operator ==(const decl_base & other) const5359 decl_base::operator==(const decl_base& other) const
5360 {return equals(*this, other, 0);}
5361
5362 /// Inequality operator.
5363 ///
5364 /// @param other to other instance of @ref decl_base to compare the
5365 /// current instance to.
5366 ///
5367 /// @return true iff the current instance of @ref decl_base is
5368 /// different from @p other.
5369 bool
operator !=(const decl_base & other) const5370 decl_base::operator!=(const decl_base& other) const
5371 {return !operator==(other);}
5372
5373 /// Destructor of the @ref decl_base type.
~decl_base()5374 decl_base::~decl_base()
5375 {delete priv_;}
5376
5377 /// This implements the ir_traversable_base::traverse pure virtual
5378 /// function.
5379 ///
5380 /// @param v the visitor used on the member nodes of the translation
5381 /// unit during the traversal.
5382 ///
5383 /// @return true if the entire IR node tree got traversed, false
5384 /// otherwise.
5385 bool
traverse(ir_node_visitor &)5386 decl_base::traverse(ir_node_visitor&)
5387 {
5388 // Do nothing in the base class.
5389 return true;
5390 }
5391
5392 /// Setter of the scope of the current decl.
5393 ///
5394 /// Note that the decl won't hold a reference on the scope. It's
5395 /// rather the scope that holds a reference on its members.
5396 void
set_scope(scope_decl * scope)5397 decl_base::set_scope(scope_decl* scope)
5398 {
5399 if (!priv_->context_)
5400 priv_->context_ = new context_rel(scope);
5401 else
5402 priv_->context_->set_scope(scope);
5403 }
5404
5405 // </decl_base definition>
5406
5407 /// Streaming operator for the decl_base::visibility.
5408 ///
5409 /// @param o the output stream to serialize the visibility to.
5410 ///
5411 /// @param v the visibility to serialize.
5412 ///
5413 /// @return the output stream.
5414 std::ostream&
operator <<(std::ostream & o,decl_base::visibility v)5415 operator<<(std::ostream& o, decl_base::visibility v)
5416 {
5417 string r;
5418 switch (v)
5419 {
5420 case decl_base::VISIBILITY_NONE:
5421 r = "none";
5422 break;
5423 case decl_base::VISIBILITY_DEFAULT:
5424 r = "default";
5425 break;
5426 case decl_base::VISIBILITY_PROTECTED:
5427 r = "protected";
5428 break;
5429 case decl_base::VISIBILITY_HIDDEN:
5430 r = "hidden";
5431 break;
5432 case decl_base::VISIBILITY_INTERNAL:
5433 r = "internal";
5434 break;
5435 }
5436 return o;
5437 }
5438
5439 /// Streaming operator for decl_base::binding.
5440 ///
5441 /// @param o the output stream to serialize the visibility to.
5442 ///
5443 /// @param b the binding to serialize.
5444 ///
5445 /// @return the output stream.
5446 std::ostream&
operator <<(std::ostream & o,decl_base::binding b)5447 operator<<(std::ostream& o, decl_base::binding b)
5448 {
5449 string r;
5450 switch (b)
5451 {
5452 case decl_base::BINDING_NONE:
5453 r = "none";
5454 break;
5455 case decl_base::BINDING_LOCAL:
5456 r = "local";
5457 break;
5458 case decl_base::BINDING_GLOBAL:
5459 r = "global";
5460 break;
5461 case decl_base::BINDING_WEAK:
5462 r = "weak";
5463 break;
5464 }
5465 o << r;
5466 return o;
5467 }
5468
5469 /// Turn equality of shared_ptr of decl_base into a deep equality;
5470 /// that is, make it compare the pointed to objects, not just the
5471 /// pointers.
5472 ///
5473 /// @param l the shared_ptr of decl_base on left-hand-side of the
5474 /// equality.
5475 ///
5476 /// @param r the shared_ptr of decl_base on right-hand-side of the
5477 /// equality.
5478 ///
5479 /// @return true if the decl_base pointed to by the shared_ptrs are
5480 /// equal, false otherwise.
5481 bool
operator ==(const decl_base_sptr & l,const decl_base_sptr & r)5482 operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5483 {
5484 if (l.get() == r.get())
5485 return true;
5486 if (!!l != !!r)
5487 return false;
5488
5489 return *l == *r;
5490 }
5491
5492 /// Inequality operator of shared_ptr of @ref decl_base.
5493 ///
5494 /// This is a deep equality operator, that is, it compares the
5495 /// pointed-to objects, rather than just the pointers.
5496 ///
5497 /// @param l the left-hand-side operand.
5498 ///
5499 /// @param r the right-hand-side operand.
5500 ///
5501 /// @return true iff @p l is different from @p r.
5502 bool
operator !=(const decl_base_sptr & l,const decl_base_sptr & r)5503 operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5504 {return !operator==(l, r);}
5505
5506 /// Turn equality of shared_ptr of type_base into a deep equality;
5507 /// that is, make it compare the pointed to objects too.
5508 ///
5509 /// @param l the shared_ptr of type_base on left-hand-side of the
5510 /// equality.
5511 ///
5512 /// @param r the shared_ptr of type_base on right-hand-side of the
5513 /// equality.
5514 ///
5515 /// @return true if the type_base pointed to by the shared_ptrs are
5516 /// equal, false otherwise.
5517 bool
operator ==(const type_base_sptr & l,const type_base_sptr & r)5518 operator==(const type_base_sptr& l, const type_base_sptr& r)
5519 {
5520 if (l.get() == r.get())
5521 return true;
5522 if (!!l != !!r)
5523 return false;
5524
5525 return *l == *r;
5526 }
5527
5528 /// Turn inequality of shared_ptr of type_base into a deep equality;
5529 /// that is, make it compare the pointed to objects..
5530 ///
5531 /// @param l the shared_ptr of type_base on left-hand-side of the
5532 /// equality.
5533 ///
5534 /// @param r the shared_ptr of type_base on right-hand-side of the
5535 /// equality.
5536 ///
5537 /// @return true iff the type_base pointed to by the shared_ptrs are
5538 /// different.
5539 bool
operator !=(const type_base_sptr & l,const type_base_sptr & r)5540 operator!=(const type_base_sptr& l, const type_base_sptr& r)
5541 {return !operator==(l, r);}
5542
5543 /// Tests if a declaration has got a scope.
5544 ///
5545 /// @param d the declaration to consider.
5546 ///
5547 /// @return true if the declaration has got a scope, false otherwise.
5548 bool
has_scope(const decl_base & d)5549 has_scope(const decl_base& d)
5550 {return (d.get_scope());}
5551
5552 /// Tests if a declaration has got a scope.
5553 ///
5554 /// @param d the declaration to consider.
5555 ///
5556 /// @return true if the declaration has got a scope, false otherwise.
5557 bool
has_scope(const decl_base_sptr d)5558 has_scope(const decl_base_sptr d)
5559 {return has_scope(*d.get());}
5560
5561 /// Tests if a declaration is a class member.
5562 ///
5563 /// @param d the declaration to consider.
5564 ///
5565 /// @return true if @p d is a class member, false otherwise.
5566 bool
is_member_decl(const decl_base_sptr d)5567 is_member_decl(const decl_base_sptr d)
5568 {return is_at_class_scope(d) || is_method_decl(d);}
5569
5570 /// Tests if a declaration is a class member.
5571 ///
5572 /// @param d the declaration to consider.
5573 ///
5574 /// @return true if @p d is a class member, false otherwise.
5575 bool
is_member_decl(const decl_base * d)5576 is_member_decl(const decl_base* d)
5577 {return is_at_class_scope(d) || is_method_decl(d);}
5578
5579 /// Tests if a declaration is a class member.
5580 ///
5581 /// @param d the declaration to consider.
5582 ///
5583 /// @return true if @p d is a class member, false otherwise.
5584 bool
is_member_decl(const decl_base & d)5585 is_member_decl(const decl_base& d)
5586 {return is_at_class_scope(d) || is_method_decl(d);}
5587
5588 /// Test if a declaration is a @ref scope_decl.
5589 ///
5590 /// @param d the declaration to take in account.
5591 ///
5592 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
5593 /// if d is a @ref scope_decl.
5594 scope_decl*
is_scope_decl(decl_base * d)5595 is_scope_decl(decl_base* d)
5596 {return dynamic_cast<scope_decl*>(d);}
5597
5598 /// Test if a declaration is a @ref scope_decl.
5599 ///
5600 /// @param d the declaration to take in account.
5601 ///
5602 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
5603 /// if d is a @ref scope_decl.
5604 scope_decl_sptr
is_scope_decl(const decl_base_sptr & d)5605 is_scope_decl(const decl_base_sptr& d)
5606 {return dynamic_pointer_cast<scope_decl>(d);}
5607
5608 /// Tests if a type is a class member.
5609 ///
5610 /// @param t the type to consider.
5611 ///
5612 /// @return true if @p t is a class member type, false otherwise.
5613 bool
is_member_type(const type_base_sptr & t)5614 is_member_type(const type_base_sptr& t)
5615 {
5616 decl_base_sptr d = get_type_declaration(t);
5617 return is_member_decl(d);
5618 }
5619
5620 /// Test if a type is user-defined.
5621 ///
5622 /// A type is considered user-defined if it's a
5623 /// struct/class/union/enum that is *NOT* artificial.
5624 ///
5625 /// @param t the type to consider.
5626 ///
5627 /// @return true iff the type @p t is user-defined.
5628 bool
is_user_defined_type(const type_base * t)5629 is_user_defined_type(const type_base* t)
5630 {
5631 if (t == 0)
5632 return false;
5633
5634 t = peel_qualified_or_typedef_type(t);
5635 decl_base *d = is_decl(t);
5636
5637 if ((is_class_or_union_type(t) || is_enum_type(t))
5638 && d && !d->get_is_artificial())
5639 return true;
5640
5641 return false;
5642 }
5643
5644 /// Test if a type is user-defined.
5645 ///
5646 /// A type is considered user-defined if it's a
5647 /// struct/class/union/enum.
5648 ///
5649 ///
5650 /// @param t the type to consider.
5651 ///
5652 /// @return true iff the type @p t is user-defined.
5653 bool
is_user_defined_type(const type_base_sptr & t)5654 is_user_defined_type(const type_base_sptr& t)
5655 {return is_user_defined_type(t.get());}
5656
5657 /// Gets the access specifier for a class member.
5658 ///
5659 /// @param d the declaration of the class member to consider. Note
5660 /// that this must be a class member otherwise the function aborts the
5661 /// current process.
5662 ///
5663 /// @return the access specifier for the class member @p d.
5664 access_specifier
get_member_access_specifier(const decl_base & d)5665 get_member_access_specifier(const decl_base& d)
5666 {
5667 ABG_ASSERT(is_member_decl(d));
5668
5669 const context_rel* c = d.get_context_rel();
5670 ABG_ASSERT(c);
5671
5672 return c->get_access_specifier();
5673 }
5674
5675 /// Gets the access specifier for a class member.
5676 ///
5677 /// @param d the declaration of the class member to consider. Note
5678 /// that this must be a class member otherwise the function aborts the
5679 /// current process.
5680 ///
5681 /// @return the access specifier for the class member @p d.
5682 access_specifier
get_member_access_specifier(const decl_base_sptr & d)5683 get_member_access_specifier(const decl_base_sptr& d)
5684 {return get_member_access_specifier(*d);}
5685
5686 /// Sets the access specifier for a class member.
5687 ///
5688 /// @param d the class member to set the access specifier for. Note
5689 /// that this must be a class member otherwise the function aborts the
5690 /// current process.
5691 ///
5692 /// @param a the new access specifier to set the class member to.
5693 void
set_member_access_specifier(decl_base & d,access_specifier a)5694 set_member_access_specifier(decl_base& d,
5695 access_specifier a)
5696 {
5697 ABG_ASSERT(is_member_decl(d));
5698
5699 context_rel* c = d.get_context_rel();
5700 ABG_ASSERT(c);
5701
5702 c->set_access_specifier(a);
5703 }
5704
5705 /// Sets the access specifier for a class member.
5706 ///
5707 /// @param d the class member to set the access specifier for. Note
5708 /// that this must be a class member otherwise the function aborts the
5709 /// current process.
5710 ///
5711 /// @param a the new access specifier to set the class member to.
5712 void
set_member_access_specifier(const decl_base_sptr & d,access_specifier a)5713 set_member_access_specifier(const decl_base_sptr& d,
5714 access_specifier a)
5715 {set_member_access_specifier(*d, a);}
5716
5717 /// Gets a flag saying if a class member is static or not.
5718 ///
5719 /// @param d the declaration for the class member to consider. Note
5720 /// that this must be a class member otherwise the function aborts the
5721 /// current process.
5722 ///
5723 /// @return true if the class member @p d is static, false otherwise.
5724 bool
get_member_is_static(const decl_base & d)5725 get_member_is_static(const decl_base&d)
5726 {
5727 ABG_ASSERT(is_member_decl(d));
5728
5729 const context_rel* c = d.get_context_rel();
5730 ABG_ASSERT(c);
5731
5732 return c->get_is_static();
5733 }
5734
5735 /// Gets a flag saying if a class member is static or not.
5736 ///
5737 /// @param d the declaration for the class member to consider. Note
5738 /// that this must be a class member otherwise the function aborts the
5739 /// current process.
5740 ///
5741 /// @return true if the class member @p d is static, false otherwise.
5742 bool
get_member_is_static(const decl_base * d)5743 get_member_is_static(const decl_base* d)
5744 {return get_member_is_static(*d);}
5745
5746 /// Gets a flag saying if a class member is static or not.
5747 ///
5748 /// @param d the declaration for the class member to consider. Note
5749 /// that this must be a class member otherwise the function aborts the
5750 /// current process.
5751 ///
5752 /// @return true if the class member @p d is static, false otherwise.
5753 bool
get_member_is_static(const decl_base_sptr & d)5754 get_member_is_static(const decl_base_sptr& d)
5755 {return get_member_is_static(*d);}
5756
5757 /// Test if a var_decl is a data member.
5758 ///
5759 /// @param v the var_decl to consider.
5760 ///
5761 /// @return true if @p v is data member, false otherwise.
5762 bool
is_data_member(const var_decl & v)5763 is_data_member(const var_decl& v)
5764 {return is_at_class_scope(v);}
5765
5766 /// Test if a var_decl is a data member.
5767 ///
5768 /// @param v the var_decl to consider.
5769 ///
5770 /// @return true if @p v is data member, false otherwise.
5771 bool
is_data_member(const var_decl * v)5772 is_data_member(const var_decl* v)
5773 {return is_data_member(*v);}
5774
5775 /// Test if a var_decl is a data member.
5776 ///
5777 /// @param v the var_decl to consider.
5778 ///
5779 /// @return true if @p v is data member, false otherwise.
5780 bool
is_data_member(const var_decl_sptr d)5781 is_data_member(const var_decl_sptr d)
5782 {return is_at_class_scope(d);}
5783
5784 /// Test if a decl is a data member.
5785 ///
5786 /// @param d the decl to consider.
5787 ///
5788 /// @return a pointer to the data member iff @p d is a data member, or
5789 /// a null pointer.
5790 var_decl_sptr
is_data_member(const decl_base_sptr & d)5791 is_data_member(const decl_base_sptr& d)
5792 {
5793 if (var_decl_sptr v = is_var_decl(d))
5794 {
5795 if (is_data_member(v))
5796 return v;
5797 }
5798 return var_decl_sptr();
5799 }
5800
5801 /// Test if a decl is a data member.
5802 ///
5803 /// @param d the decl to consider.
5804 ///
5805 /// @return a pointer to the data member iff @p d is a data member, or
5806 /// a null pointer.
5807 var_decl_sptr
is_data_member(const type_or_decl_base_sptr & d)5808 is_data_member(const type_or_decl_base_sptr& d)
5809 {
5810 if (var_decl_sptr v = is_var_decl(d))
5811 {
5812 if (is_data_member(v))
5813 return v;
5814 }
5815 return var_decl_sptr();
5816 }
5817
5818 /// Test if a decl is a data member.
5819 ///
5820 /// @param d the decl to consider.
5821 ///
5822 /// @return a pointer to the data member iff @p d is a data member, or
5823 /// a null pointer.
5824 var_decl*
is_data_member(const type_or_decl_base * d)5825 is_data_member(const type_or_decl_base* d)
5826 {
5827 if (var_decl *v = is_var_decl(d))
5828 if (is_data_member(v))
5829 return v;
5830 return 0;
5831 }
5832
5833 /// Test if a decl is a data member.
5834 ///
5835 /// @param d the decl to consider.
5836 ///
5837 /// @return a pointer to the data member iff @p d is a data member, or
5838 /// a null pointer.
5839 var_decl*
is_data_member(const decl_base * d)5840 is_data_member(const decl_base *d)
5841 {
5842 if (var_decl *v = is_var_decl(d))
5843 if (is_data_member(v))
5844 return v;
5845 return 0;
5846 }
5847
5848 /// Get the first non-anonymous data member of a given anonymous data
5849 /// member.
5850 ///
5851 /// E.g:
5852 ///
5853 /// struct S
5854 /// {
5855 /// union // <-- for this anonymous data member, the function
5856 /// // returns a.
5857 /// {
5858 /// int a;
5859 /// charb;
5860 /// };
5861 /// };
5862 ///
5863 /// @return anon_dm the anonymous data member to consider.
5864 ///
5865 /// @return the first non-anonymous data member of @p anon_dm. If no
5866 /// data member was found then this function returns @p anon_dm.
5867 const var_decl_sptr
get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)5868 get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
5869 {
5870 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5871 return anon_dm;
5872
5873 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5874 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5875
5876 if (is_anonymous_data_member(first))
5877 return get_first_non_anonymous_data_member(first);
5878
5879 return first;
5880 }
5881
5882 /// In the context of a given class or union, this function returns
5883 /// the data member that is located after a given data member.
5884 ///
5885 /// @param klass the class or union to consider.
5886 ///
5887 /// @param the data member to consider.
5888 ///
5889 /// @return the data member that is located right after @p
5890 /// data_member.
5891 const var_decl_sptr
get_next_data_member(const class_or_union * klass,const var_decl_sptr & data_member)5892 get_next_data_member(const class_or_union *klass,
5893 const var_decl_sptr &data_member)
5894 {
5895 if (!klass ||!data_member)
5896 return var_decl_sptr();
5897
5898 for (class_or_union::data_members::const_iterator it =
5899 klass->get_non_static_data_members().begin();
5900 it != klass->get_non_static_data_members().end();
5901 ++it)
5902 if (**it == *data_member)
5903 {
5904 ++it;
5905 if (it != klass->get_non_static_data_members().end())
5906 return get_first_non_anonymous_data_member(*it);
5907 break;
5908 }
5909
5910 return var_decl_sptr();
5911 }
5912
5913 /// In the context of a given class or union, this function returns
5914 /// the data member that is located after a given data member.
5915 ///
5916 /// @param klass the class or union to consider.
5917 ///
5918 /// @param the data member to consider.
5919 ///
5920 /// @return the data member that is located right after @p
5921 /// data_member.
5922 const var_decl_sptr
get_next_data_member(const class_or_union_sptr & klass,const var_decl_sptr & data_member)5923 get_next_data_member(const class_or_union_sptr& klass,
5924 const var_decl_sptr &data_member)
5925 {return get_next_data_member(klass.get(), data_member);}
5926
5927 /// Get the last data member of a class type.
5928 ///
5929 /// @param klass the class type to consider.
5930 var_decl_sptr
get_last_data_member(const class_or_union & klass)5931 get_last_data_member(const class_or_union& klass)
5932 {return klass.get_non_static_data_members().back();}
5933
5934 /// Get the last data member of a class type.
5935 ///
5936 /// @param klass the class type to consider.
5937 var_decl_sptr
get_last_data_member(const class_or_union * klass)5938 get_last_data_member(const class_or_union* klass)
5939 {return get_last_data_member(*klass);}
5940
5941 /// Get the last data member of a class type.
5942 ///
5943 /// @param klass the class type to consider.
5944 var_decl_sptr
get_last_data_member(const class_or_union_sptr & klass)5945 get_last_data_member(const class_or_union_sptr &klass)
5946 {return get_last_data_member(klass.get());}
5947
5948 /// Test if a decl is an anonymous data member.
5949 ///
5950 /// @param d the decl to consider.
5951 ///
5952 /// @return true iff @p d is an anonymous data member.
5953 bool
is_anonymous_data_member(const decl_base & d)5954 is_anonymous_data_member(const decl_base& d)
5955 {return is_anonymous_data_member(&d);}
5956
5957 /// Test if a decl is an anonymous data member.
5958 ///
5959 /// @param d the decl to consider.
5960 ///
5961 /// @return the var_decl representing the data member iff @p d is an
5962 /// anonymous data member.
5963 const var_decl*
is_anonymous_data_member(const type_or_decl_base * d)5964 is_anonymous_data_member(const type_or_decl_base* d)
5965 {
5966 if (const var_decl* v = is_data_member(d))
5967 {
5968 if (is_anonymous_data_member(v))
5969 return v;
5970 }
5971 return 0;
5972 }
5973
5974 /// Test if a decl is an anonymous data member.
5975 ///
5976 /// @param d the decl to consider.
5977 ///
5978 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5979 /// it's an anonymous data member. Otherwise returns a nil pointer.
5980 const var_decl*
is_anonymous_data_member(const decl_base * d)5981 is_anonymous_data_member(const decl_base* d)
5982 {
5983 if (const var_decl* v = is_data_member(d))
5984 {
5985 if (is_anonymous_data_member(v))
5986 return v;
5987 }
5988 return 0;
5989 }
5990
5991 /// Test if a decl is an anonymous data member.
5992 ///
5993 /// @param d the decl to consider.
5994 ///
5995 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5996 /// it's an anonymous data member. Otherwise returns a nil pointer.
5997 var_decl_sptr
is_anonymous_data_member(const type_or_decl_base_sptr & d)5998 is_anonymous_data_member(const type_or_decl_base_sptr& d)
5999 {
6000 if (var_decl_sptr v = is_data_member(d))
6001 {
6002 if (is_anonymous_data_member(v))
6003 return v;
6004 }
6005 return var_decl_sptr();
6006 }
6007
6008 /// Test if a decl is an anonymous data member.
6009 ///
6010 /// @param d the decl to consider.
6011 ///
6012 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6013 /// it's an anonymous data member. Otherwise returns a nil pointer.
6014 var_decl_sptr
is_anonymous_data_member(const decl_base_sptr & d)6015 is_anonymous_data_member(const decl_base_sptr& d)
6016 {
6017 if (var_decl_sptr v = is_data_member(d))
6018 return is_anonymous_data_member(v);
6019 return var_decl_sptr();
6020 }
6021
6022 /// Test if a @ref var_decl is an anonymous data member.
6023 ///
6024 /// @param d the @ref var_decl to consider.
6025 ///
6026 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6027 /// it's an anonymous data member. Otherwise returns a nil pointer.
6028 var_decl_sptr
is_anonymous_data_member(const var_decl_sptr & d)6029 is_anonymous_data_member(const var_decl_sptr& d)
6030 {
6031 if (is_anonymous_data_member(d.get()))
6032 return d;
6033 return var_decl_sptr();
6034 }
6035
6036 /// Test if a @ref var_decl is an anonymous data member.
6037 ///
6038 /// @param d the @ref var_decl to consider.
6039 ///
6040 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
6041 /// it's an anonymous data member. Otherwise returns a nil pointer.
6042 const var_decl*
is_anonymous_data_member(const var_decl * d)6043 is_anonymous_data_member(const var_decl* d)
6044 {
6045 if (d && is_anonymous_data_member(*d))
6046 return d;
6047 return 0;
6048 }
6049
6050 /// Test if a @ref var_decl is an anonymous data member.
6051 ///
6052 /// @param d the @ref var_decl to consider.
6053 ///
6054 /// @return true iff @p d is an anonymous data member.
6055 bool
is_anonymous_data_member(const var_decl & d)6056 is_anonymous_data_member(const var_decl& d)
6057 {
6058 return (is_data_member(d)
6059 && d.get_is_anonymous()
6060 && d.get_name().empty()
6061 && is_class_or_union_type(d.get_type()));
6062 }
6063
6064 /// Test if a @ref var_decl is a data member belonging to an anonymous
6065 /// type.
6066 ///
6067 /// @param d the @ref var_decl to consider.
6068 ///
6069 /// @return true iff @p d is a data member belonging to an anonymous
6070 /// type.
6071 bool
is_data_member_of_anonymous_class_or_union(const var_decl & d)6072 is_data_member_of_anonymous_class_or_union(const var_decl& d)
6073 {
6074 if (is_data_member(d))
6075 {
6076 scope_decl* scope = d.get_scope();
6077 if (scope && scope->get_is_anonymous())
6078 return true;
6079 }
6080 return false;
6081 }
6082
6083 /// Test if a @ref var_decl is a data member belonging to an anonymous
6084 /// type.
6085 ///
6086 /// @param d the @ref var_decl to consider.
6087 ///
6088 /// @return true iff @p d is a data member belonging to an anonymous
6089 /// type.
6090 bool
is_data_member_of_anonymous_class_or_union(const var_decl * d)6091 is_data_member_of_anonymous_class_or_union(const var_decl* d)
6092 {return is_data_member_of_anonymous_class_or_union(*d);}
6093
6094 /// Test if a @ref var_decl is a data member belonging to an anonymous
6095 /// type.
6096 ///
6097 /// @param d the @ref var_decl to consider.
6098 ///
6099 /// @return true iff @p d is a data member belonging to an anonymous
6100 /// type.
6101 bool
is_data_member_of_anonymous_class_or_union(const var_decl_sptr & d)6102 is_data_member_of_anonymous_class_or_union(const var_decl_sptr& d)
6103 {return is_data_member_of_anonymous_class_or_union(d.get());}
6104
6105 /// Get the @ref class_or_union type of a given anonymous data member.
6106 ///
6107 /// @param d the anonymous data member to consider.
6108 ///
6109 /// @return the @ref class_or_union type of the anonymous data member
6110 /// @p d.
6111 class_or_union*
anonymous_data_member_to_class_or_union(const var_decl * d)6112 anonymous_data_member_to_class_or_union(const var_decl* d)
6113 {
6114 if ((d = is_anonymous_data_member(d)))
6115 return is_class_or_union_type(d->get_type().get());
6116 return 0;
6117 }
6118
6119 /// Get the @ref class_or_union type of a given anonymous data member.
6120 ///
6121 /// @param d the anonymous data member to consider.
6122 ///
6123 /// @return the @ref class_or_union type of the anonymous data member
6124 /// @p d.
6125 class_or_union_sptr
anonymous_data_member_to_class_or_union(const var_decl & d)6126 anonymous_data_member_to_class_or_union(const var_decl& d)
6127 {
6128 if (is_anonymous_data_member(d))
6129 return is_class_or_union_type(d.get_type());
6130 return class_or_union_sptr();
6131 }
6132
6133 /// Test if a data member has annonymous type or not.
6134 ///
6135 /// @param d the data member to consider.
6136 ///
6137 /// @return the anonymous class or union type iff @p turns out to have
6138 /// an anonymous type. Otherwise, returns nil.
6139 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl & d)6140 data_member_has_anonymous_type(const var_decl& d)
6141 {
6142 if (is_data_member(d))
6143 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
6144 if (cou->get_is_anonymous())
6145 return cou;
6146
6147 return class_or_union_sptr();
6148 }
6149
6150 /// Test if a data member has annonymous type or not.
6151 ///
6152 /// @param d the data member to consider.
6153 ///
6154 /// @return the anonymous class or union type iff @p turns out to have
6155 /// an anonymous type. Otherwise, returns nil.
6156 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl * d)6157 data_member_has_anonymous_type(const var_decl* d)
6158 {
6159 if (d)
6160 return data_member_has_anonymous_type(*d);
6161 return class_or_union_sptr();
6162 }
6163
6164 /// Test if a data member has annonymous type or not.
6165 ///
6166 /// @param d the data member to consider.
6167 ///
6168 /// @return the anonymous class or union type iff @p turns out to have
6169 /// an anonymous type. Otherwise, returns nil.
6170 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl_sptr & d)6171 data_member_has_anonymous_type(const var_decl_sptr& d)
6172 {return data_member_has_anonymous_type(d.get());}
6173
6174 /// Get the @ref class_or_union type of a given anonymous data member.
6175 ///
6176 /// @param d the anonymous data member to consider.
6177 ///
6178 /// @return the @ref class_or_union type of the anonymous data member
6179 /// @p d.
6180 class_or_union_sptr
anonymous_data_member_to_class_or_union(const var_decl_sptr & d)6181 anonymous_data_member_to_class_or_union(const var_decl_sptr &d)
6182 {
6183 if (var_decl_sptr v = is_anonymous_data_member(d))
6184 return is_class_or_union_type(v->get_type());
6185 return class_or_union_sptr();
6186 }
6187
6188 /// Test if a given anonymous data member exists in a class or union.
6189 ///
6190 /// @param anon_dm the anonymous data member to consider.
6191 ///
6192 /// @param clazz the class to consider.
6193 ///
6194 /// @return true iff @p anon_dm exists in the @clazz.
6195 bool
anonymous_data_member_exists_in_class(const var_decl & anon_dm,const class_or_union & clazz)6196 anonymous_data_member_exists_in_class(const var_decl& anon_dm,
6197 const class_or_union& clazz)
6198 {
6199 if (!anon_dm.get_is_anonymous()
6200 || !is_class_or_union_type(anon_dm.get_type()))
6201 return false;
6202
6203 class_or_union_sptr cl = is_class_or_union_type(anon_dm.get_type());
6204 ABG_ASSERT(cl);
6205
6206 // Look for the presence of each data member of anon_dm in clazz.
6207 //
6208 // If one data member of anon_dm is not present in clazz, then the
6209 // data member anon_dm is considered to not exist in clazz.
6210 for (auto anon_dm_m : cl->get_non_static_data_members())
6211 {
6212 // If the data member anon_dm_m is not an anonymous data member,
6213 // it's easy to look for it.
6214 if (!is_anonymous_data_member(anon_dm_m))
6215 {
6216 if (!clazz.find_data_member(anon_dm_m->get_name()))
6217 return false;
6218 }
6219 // If anon_dm_m is itself an anonymous data member then recurse
6220 else
6221 {
6222 if (!anonymous_data_member_exists_in_class(*anon_dm_m, clazz))
6223 return false;
6224 }
6225 }
6226
6227 return true;
6228 }
6229
6230 /// Test if a given decl is anonymous or has a naming typedef.
6231 ///
6232 /// @param d the decl to consider.
6233 ///
6234 /// @return true iff @p d is anonymous or has a naming typedef.
6235 bool
is_anonymous_or_typedef_named(const decl_base & d)6236 is_anonymous_or_typedef_named(const decl_base& d)
6237 {
6238 if (d.get_is_anonymous() || d.get_naming_typedef())
6239 return true;
6240 return false;
6241 }
6242
6243 /// Set the offset of a data member into its containing class.
6244 ///
6245 /// @param m the data member to consider.
6246 ///
6247 /// @param o the offset, in bits.
6248 void
set_data_member_offset(var_decl_sptr m,uint64_t o)6249 set_data_member_offset(var_decl_sptr m, uint64_t o)
6250 {
6251 ABG_ASSERT(is_data_member(m));
6252
6253 dm_context_rel* ctxt_rel =
6254 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6255 ABG_ASSERT(ctxt_rel);
6256
6257 ctxt_rel->set_offset_in_bits(o);
6258 }
6259
6260 /// Get the offset of a data member.
6261 ///
6262 /// @param m the data member to consider.
6263 ///
6264 /// @return the offset (in bits) of @p m in its containing class.
6265 uint64_t
get_data_member_offset(const var_decl & m)6266 get_data_member_offset(const var_decl& m)
6267 {
6268 ABG_ASSERT(is_data_member(m));
6269 const dm_context_rel* ctxt_rel =
6270 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6271 ABG_ASSERT(ctxt_rel);
6272 return ctxt_rel->get_offset_in_bits();
6273 }
6274
6275 /// Get the offset of a data member.
6276 ///
6277 /// @param m the data member to consider.
6278 ///
6279 /// @return the offset (in bits) of @p m in its containing class.
6280 uint64_t
get_data_member_offset(const var_decl_sptr m)6281 get_data_member_offset(const var_decl_sptr m)
6282 {return get_data_member_offset(*m);}
6283
6284 /// Get the offset of a data member.
6285 ///
6286 /// @param m the data member to consider.
6287 ///
6288 /// @return the offset (in bits) of @p m in its containing class.
6289 uint64_t
get_data_member_offset(const decl_base_sptr d)6290 get_data_member_offset(const decl_base_sptr d)
6291 {return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
6292
6293 /// Get the offset of the non-static data member that comes after a
6294 /// given one.
6295 ///
6296 /// If there is no data member after after the one given to this
6297 /// function (maybe because the given one is the last data member of
6298 /// the class type) then the function return false.
6299 ///
6300 /// @param klass the class to consider.
6301 ///
6302 /// @param dm the data member before the one we want to retrieve.
6303 ///
6304 /// @param offset out parameter. This parameter is set by the
6305 /// function to the offset of the data member that comes right after
6306 /// the data member @p dm, iff the function returns true.
6307 ///
6308 /// @return true iff the data member coming right after @p dm was
6309 /// found.
6310 bool
get_next_data_member_offset(const class_or_union * klass,const var_decl_sptr & dm,uint64_t & offset)6311 get_next_data_member_offset(const class_or_union* klass,
6312 const var_decl_sptr& dm,
6313 uint64_t& offset)
6314 {
6315 var_decl_sptr next_dm = get_next_data_member(klass, dm);
6316 if (!next_dm)
6317 return false;
6318 offset = get_data_member_offset(next_dm);
6319 return true;
6320 }
6321
6322 /// Get the offset of the non-static data member that comes after a
6323 /// given one.
6324 ///
6325 /// If there is no data member after after the one given to this
6326 /// function (maybe because the given one is the last data member of
6327 /// the class type) then the function return false.
6328 ///
6329 /// @param klass the class to consider.
6330 ///
6331 /// @param dm the data member before the one we want to retrieve.
6332 ///
6333 /// @param offset out parameter. This parameter is set by the
6334 /// function to the offset of the data member that comes right after
6335 /// the data member @p dm, iff the function returns true.
6336 ///
6337 /// @return true iff the data member coming right after @p dm was
6338 /// found.
6339 bool
get_next_data_member_offset(const class_or_union_sptr & klass,const var_decl_sptr & dm,uint64_t & offset)6340 get_next_data_member_offset(const class_or_union_sptr& klass,
6341 const var_decl_sptr& dm,
6342 uint64_t& offset)
6343 {return get_next_data_member_offset(klass.get(), dm, offset);}
6344
6345 /// Get the absolute offset of a data member.
6346 ///
6347 /// If the data member is part of an anonymous data member then this
6348 /// returns the absolute offset -- relative to the beginning of the
6349 /// containing class of the anonymous data member.
6350 ///
6351 /// @param m the data member to consider.
6352 ///
6353 /// @return the aboslute offset of the data member @p m.
6354 uint64_t
get_absolute_data_member_offset(const var_decl & m)6355 get_absolute_data_member_offset(const var_decl& m)
6356 {
6357 ABG_ASSERT(is_data_member(m));
6358 const dm_context_rel* ctxt_rel =
6359 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6360 ABG_ASSERT(ctxt_rel);
6361
6362 const var_decl *containing_anonymous_data_member =
6363 ctxt_rel->get_anonymous_data_member();
6364
6365 uint64_t containing_anonymous_data_member_offset = 0;
6366 if (containing_anonymous_data_member)
6367 containing_anonymous_data_member_offset =
6368 get_absolute_data_member_offset(*containing_anonymous_data_member);
6369
6370 return (ctxt_rel->get_offset_in_bits()
6371 +
6372 containing_anonymous_data_member_offset);
6373 }
6374
6375 /// Get the absolute offset of a data member.
6376 ///
6377 /// If the data member is part of an anonymous data member then this
6378 /// returns the absolute offset -- relative to the beginning of the
6379 /// containing class of the anonymous data member.
6380 ///
6381 /// @param m the data member to consider.
6382 ///
6383 /// @return the aboslute offset of the data member @p m.
6384 uint64_t
get_absolute_data_member_offset(const var_decl_sptr & m)6385 get_absolute_data_member_offset(const var_decl_sptr& m)
6386 {
6387 if (!m)
6388 return 0;
6389 return get_absolute_data_member_offset(*m);
6390 }
6391
6392 /// Get the size of a given variable.
6393 ///
6394 /// @param v the variable to consider.
6395 ///
6396 /// @return the size of variable @p v.
6397 uint64_t
get_var_size_in_bits(const var_decl_sptr & v)6398 get_var_size_in_bits(const var_decl_sptr& v)
6399 {
6400 type_base_sptr t = v->get_type();
6401 ABG_ASSERT(t);
6402
6403 return t->get_size_in_bits();
6404 }
6405
6406 /// Set a flag saying if a data member is laid out.
6407 ///
6408 /// @param m the data member to consider.
6409 ///
6410 /// @param l true if @p m is to be considered as laid out.
6411 void
set_data_member_is_laid_out(var_decl_sptr m,bool l)6412 set_data_member_is_laid_out(var_decl_sptr m, bool l)
6413 {
6414 ABG_ASSERT(is_data_member(m));
6415 dm_context_rel* ctxt_rel =
6416 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6417 ctxt_rel->set_is_laid_out(l);
6418 }
6419
6420 /// Test whether a data member is laid out.
6421 ///
6422 /// @param m the data member to consider.
6423 ///
6424 /// @return true if @p m is laid out, false otherwise.
6425 bool
get_data_member_is_laid_out(const var_decl & m)6426 get_data_member_is_laid_out(const var_decl& m)
6427 {
6428 ABG_ASSERT(is_data_member(m));
6429 const dm_context_rel* ctxt_rel =
6430 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6431
6432 return ctxt_rel->get_is_laid_out();
6433 }
6434
6435 /// Test whether a data member is laid out.
6436 ///
6437 /// @param m the data member to consider.
6438 ///
6439 /// @return true if @p m is laid out, false otherwise.
6440 bool
get_data_member_is_laid_out(const var_decl_sptr m)6441 get_data_member_is_laid_out(const var_decl_sptr m)
6442 {return get_data_member_is_laid_out(*m);}
6443
6444 /// Test whether a function_decl is a member function.
6445 ///
6446 /// @param f the function_decl to test.
6447 ///
6448 /// @return true if @p f is a member function, false otherwise.
6449 bool
is_member_function(const function_decl & f)6450 is_member_function(const function_decl& f)
6451 {return is_member_decl(f);}
6452
6453 /// Test whether a function_decl is a member function.
6454 ///
6455 /// @param f the function_decl to test.
6456 ///
6457 /// @return true if @p f is a member function, false otherwise.
6458 bool
is_member_function(const function_decl * f)6459 is_member_function(const function_decl* f)
6460 {return is_member_decl(*f);}
6461
6462 /// Test whether a function_decl is a member function.
6463 ///
6464 /// @param f the function_decl to test.
6465 ///
6466 /// @return true if @p f is a member function, false otherwise.
6467 bool
is_member_function(const function_decl_sptr & f)6468 is_member_function(const function_decl_sptr& f)
6469 {return is_member_decl(*f);}
6470
6471 /// Test whether a member function is a constructor.
6472 ///
6473 /// @param f the member function to test.
6474 ///
6475 /// @return true if @p f is a constructor, false otherwise.
6476 bool
get_member_function_is_ctor(const function_decl & f)6477 get_member_function_is_ctor(const function_decl& f)
6478 {
6479 ABG_ASSERT(is_member_function(f));
6480
6481 const method_decl* m = is_method_decl(&f);
6482 ABG_ASSERT(m);
6483
6484 const mem_fn_context_rel* ctxt =
6485 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6486
6487 return ctxt->is_constructor();
6488 }
6489
6490 /// Test whether a member function is a constructor.
6491 ///
6492 /// @param f the member function to test.
6493 ///
6494 /// @return true if @p f is a constructor, false otherwise.
6495 bool
get_member_function_is_ctor(const function_decl_sptr & f)6496 get_member_function_is_ctor(const function_decl_sptr& f)
6497 {return get_member_function_is_ctor(*f);}
6498
6499
6500 /// Setter for the is_ctor property of the member function.
6501 ///
6502 /// @param f the member function to set.
6503 ///
6504 /// @param f the new boolean value of the is_ctor property. Is true
6505 /// if @p f is a constructor, false otherwise.
6506 void
set_member_function_is_ctor(function_decl & f,bool c)6507 set_member_function_is_ctor(function_decl& f, bool c)
6508 {
6509 ABG_ASSERT(is_member_function(f));
6510
6511 method_decl* m = is_method_decl(&f);
6512 ABG_ASSERT(m);
6513
6514 mem_fn_context_rel* ctxt =
6515 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6516
6517 ctxt->is_constructor(c);
6518 }
6519
6520 /// Setter for the is_ctor property of the member function.
6521 ///
6522 /// @param f the member function to set.
6523 ///
6524 /// @param f the new boolean value of the is_ctor property. Is true
6525 /// if @p f is a constructor, false otherwise.
6526 void
set_member_function_is_ctor(const function_decl_sptr & f,bool c)6527 set_member_function_is_ctor(const function_decl_sptr& f, bool c)
6528 {set_member_function_is_ctor(*f, c);}
6529
6530 /// Test whether a member function is a destructor.
6531 ///
6532 /// @param f the function to test.
6533 ///
6534 /// @return true if @p f is a destructor, false otherwise.
6535 bool
get_member_function_is_dtor(const function_decl & f)6536 get_member_function_is_dtor(const function_decl& f)
6537 {
6538 ABG_ASSERT(is_member_function(f));
6539
6540 const method_decl* m = is_method_decl(&f);
6541 ABG_ASSERT(m);
6542
6543 const mem_fn_context_rel* ctxt =
6544 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6545
6546 return ctxt->is_destructor();
6547 }
6548
6549 /// Test whether a member function is a destructor.
6550 ///
6551 /// @param f the function to test.
6552 ///
6553 /// @return true if @p f is a destructor, false otherwise.
6554 bool
get_member_function_is_dtor(const function_decl_sptr & f)6555 get_member_function_is_dtor(const function_decl_sptr& f)
6556 {return get_member_function_is_dtor(*f);}
6557
6558 /// Set the destructor-ness property of a member function.
6559 ///
6560 /// @param f the function to set.
6561 ///
6562 /// @param d true if @p f is a destructor, false otherwise.
6563 void
set_member_function_is_dtor(function_decl & f,bool d)6564 set_member_function_is_dtor(function_decl& f, bool d)
6565 {
6566 ABG_ASSERT(is_member_function(f));
6567
6568 method_decl* m = is_method_decl(&f);
6569 ABG_ASSERT(m);
6570
6571 mem_fn_context_rel* ctxt =
6572 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6573
6574 ctxt->is_destructor(d);
6575 }
6576
6577 /// Set the destructor-ness property of a member function.
6578 ///
6579 /// @param f the function to set.
6580 ///
6581 /// @param d true if @p f is a destructor, false otherwise.
6582 void
set_member_function_is_dtor(const function_decl_sptr & f,bool d)6583 set_member_function_is_dtor(const function_decl_sptr& f, bool d)
6584 {set_member_function_is_dtor(*f, d);}
6585
6586 /// Test whether a member function is const.
6587 ///
6588 /// @param f the function to test.
6589 ///
6590 /// @return true if @p f is const, false otherwise.
6591 bool
get_member_function_is_const(const function_decl & f)6592 get_member_function_is_const(const function_decl& f)
6593 {
6594 ABG_ASSERT(is_member_function(f));
6595
6596 const method_decl* m = is_method_decl(&f);
6597 ABG_ASSERT(m);
6598
6599 const mem_fn_context_rel* ctxt =
6600 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6601
6602 return ctxt->is_const();
6603 }
6604
6605 /// Test whether a member function is const.
6606 ///
6607 /// @param f the function to test.
6608 ///
6609 /// @return true if @p f is const, false otherwise.
6610 bool
get_member_function_is_const(const function_decl_sptr & f)6611 get_member_function_is_const(const function_decl_sptr& f)
6612 {return get_member_function_is_const(*f);}
6613
6614 /// set the const-ness property of a member function.
6615 ///
6616 /// @param f the function to set.
6617 ///
6618 /// @param is_const the new value of the const-ness property of @p f
6619 void
set_member_function_is_const(function_decl & f,bool is_const)6620 set_member_function_is_const(function_decl& f, bool is_const)
6621 {
6622 ABG_ASSERT(is_member_function(f));
6623
6624 method_decl* m = is_method_decl(&f);
6625 ABG_ASSERT(m);
6626
6627 mem_fn_context_rel* ctxt =
6628 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6629
6630 ctxt->is_const(is_const);
6631 }
6632
6633 /// set the const-ness property of a member function.
6634 ///
6635 /// @param f the function to set.
6636 ///
6637 /// @param is_const the new value of the const-ness property of @p f
6638 void
set_member_function_is_const(const function_decl_sptr & f,bool is_const)6639 set_member_function_is_const(const function_decl_sptr& f, bool is_const)
6640 {set_member_function_is_const(*f, is_const);}
6641
6642 /// Test if a virtual member function has a vtable offset set.
6643 ///
6644 /// @param f the virtual member function to consider.
6645 ///
6646 /// @return true iff the virtual member function has its vtable offset
6647 /// set, i.e, if the vtable offset of @p is different from -1.
6648 bool
member_function_has_vtable_offset(const function_decl & f)6649 member_function_has_vtable_offset(const function_decl& f)
6650 {return get_member_function_vtable_offset(f) != -1;}
6651
6652 /// Get the vtable offset of a member function.
6653 ///
6654 /// @param f the member function to consider.
6655 ///
6656 /// @return the vtable offset of @p f. Note that a vtable offset of
6657 /// value -1 means that the member function does *NOT* yet have a
6658 /// vtable offset associated to it.
6659 ssize_t
get_member_function_vtable_offset(const function_decl & f)6660 get_member_function_vtable_offset(const function_decl& f)
6661 {
6662 ABG_ASSERT(is_member_function(f));
6663
6664 const method_decl* m =
6665 dynamic_cast<const method_decl*>(&f);
6666 ABG_ASSERT(m);
6667
6668 const mem_fn_context_rel* ctxt =
6669 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6670
6671 return ctxt->vtable_offset();
6672 }
6673
6674 /// Get the vtable offset of a member function.
6675 ///
6676 /// @param f the member function to consider.
6677 ///
6678 /// @return the vtable offset of @p f. Note that a vtable offset of
6679 /// value -1 means that the member function does *NOT* yet have a
6680 /// vtable offset associated to it.
6681 ssize_t
get_member_function_vtable_offset(const function_decl_sptr & f)6682 get_member_function_vtable_offset(const function_decl_sptr& f)
6683 {return get_member_function_vtable_offset(*f);}
6684
6685 /// Set the vtable offset of a member function.
6686 ///
6687 /// @param f the member function to consider.
6688 ///
6689 /// @param s the new vtable offset. Please note that a vtable offset
6690 /// of value -1 means that the virtual member function does not (yet)
6691 /// have any vtable offset associated to it.
6692 void
set_member_function_vtable_offset(function_decl & f,ssize_t s)6693 set_member_function_vtable_offset(function_decl& f, ssize_t s)
6694 {
6695 ABG_ASSERT(is_member_function(f));
6696
6697 method_decl* m = is_method_decl(&f);
6698 ABG_ASSERT(m);
6699
6700 mem_fn_context_rel* ctxt =
6701 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6702
6703 ctxt->vtable_offset(s);
6704 }
6705
6706 /// Get the vtable offset of a member function.
6707 ///
6708 /// @param f the member function to consider.
6709 ///
6710 /// @param s the new vtable offset. Please note that a vtable offset
6711 /// of value -1 means that the virtual member function does not (yet)
6712 /// have any vtable offset associated to it.
6713 void
set_member_function_vtable_offset(const function_decl_sptr & f,ssize_t s)6714 set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6715 {return set_member_function_vtable_offset(*f, s);}
6716
6717 /// Test if a given member function is virtual.
6718 ///
6719 /// @param mem_fn the member function to consider.
6720 ///
6721 /// @return true iff a @p mem_fn is virtual.
6722 bool
get_member_function_is_virtual(const function_decl & f)6723 get_member_function_is_virtual(const function_decl& f)
6724 {
6725 ABG_ASSERT(is_member_function(f));
6726
6727 const method_decl* m =
6728 dynamic_cast<const method_decl*>(&f);
6729 ABG_ASSERT(m);
6730
6731 const mem_fn_context_rel* ctxt =
6732 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6733
6734 return ctxt->is_virtual();
6735 }
6736
6737 /// Test if a given member function is virtual.
6738 ///
6739 /// @param mem_fn the member function to consider.
6740 ///
6741 /// @return true iff a @p mem_fn is virtual.
6742 bool
get_member_function_is_virtual(const function_decl_sptr & mem_fn)6743 get_member_function_is_virtual(const function_decl_sptr& mem_fn)
6744 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6745
6746 /// Test if a given member function is virtual.
6747 ///
6748 /// @param mem_fn the member function to consider.
6749 ///
6750 /// @return true iff a @p mem_fn is virtual.
6751 bool
get_member_function_is_virtual(const function_decl * mem_fn)6752 get_member_function_is_virtual(const function_decl* mem_fn)
6753 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6754
6755 /// Set the virtual-ness of a member function.
6756 ///
6757 /// @param f the member function to consider.
6758 ///
6759 /// @param is_virtual set to true if the function is virtual.
6760 void
set_member_function_is_virtual(function_decl & f,bool is_virtual)6761 set_member_function_is_virtual(function_decl& f, bool is_virtual)
6762 {
6763 ABG_ASSERT(is_member_function(f));
6764
6765 method_decl* m = is_method_decl(&f);
6766 ABG_ASSERT(m);
6767
6768 mem_fn_context_rel* ctxt =
6769 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6770
6771 ctxt->is_virtual(is_virtual);
6772 }
6773
6774 /// Set the virtual-ness of a member function.
6775 ///
6776 /// @param f the member function to consider.
6777 ///
6778 /// @param is_virtual set to true if the function is virtual.
6779 void
set_member_function_is_virtual(const function_decl_sptr & fn,bool is_virtual)6780 set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6781 {
6782 if (fn)
6783 {
6784 set_member_function_is_virtual(*fn, is_virtual);
6785 fixup_virtual_member_function
6786 (dynamic_pointer_cast<method_decl>(fn));
6787 }
6788 }
6789
6790 /// Recursively returns the the underlying type of a typedef. The
6791 /// return type should not be a typedef of anything anymore.
6792 ///
6793 ///
6794 /// Also recursively strip typedefs from the sub-types of the type
6795 /// given in arguments.
6796 ///
6797 /// Note that this function builds types in which typedefs are
6798 /// stripped off. Usually, types are held by their scope, so their
6799 /// life time is bound to the life time of their scope. But as this
6800 /// function cannot really insert the built type into it's scope, it
6801 /// must ensure that the newly built type stays live long enough.
6802 ///
6803 /// So, if the newly built type has a canonical type, this function
6804 /// returns the canonical type. Otherwise, this function ensure that
6805 /// the newly built type has a life time that is the same as the life
6806 /// time of the entire libabigail library.
6807 ///
6808 /// @param type the type to strip the typedefs from.
6809 ///
6810 /// @return the resulting type stripped from its typedefs, or just
6811 /// return @p type if it has no typedef in any of its sub-types.
6812 type_base_sptr
strip_typedef(const type_base_sptr type)6813 strip_typedef(const type_base_sptr type)
6814 {
6815 if (!type)
6816 return type;
6817
6818 // If type is a class type then do not try to strip typedefs from it.
6819 // And if it has no canonical type (which can mean that it's a
6820 // declaration-only class), then, make sure its live for ever and
6821 // return it.
6822 if (class_decl_sptr cl = is_class_type(type))
6823 {
6824 if (!cl->get_canonical_type())
6825 keep_type_alive(type);
6826 return type;
6827 }
6828
6829 const environment& env = type->get_environment();
6830 type_base_sptr t = type;
6831
6832 if (const typedef_decl_sptr ty = is_typedef(t))
6833 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6834 else if (const reference_type_def_sptr ty = is_reference_type(t))
6835 {
6836 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6837 env));
6838 ABG_ASSERT(p);
6839 t.reset(new reference_type_def(p,
6840 ty->is_lvalue(),
6841 ty->get_size_in_bits(),
6842 ty->get_alignment_in_bits(),
6843 ty->get_location()));
6844 }
6845 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6846 {
6847 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6848 env));
6849 ABG_ASSERT(p);
6850 t.reset(new pointer_type_def(p,
6851 ty->get_size_in_bits(),
6852 ty->get_alignment_in_bits(),
6853 ty->get_location()));
6854 }
6855 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6856 {
6857 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6858 env));
6859 ABG_ASSERT(p);
6860 t.reset(new qualified_type_def(p,
6861 ty->get_cv_quals(),
6862 ty->get_location()));
6863 }
6864 else if (const array_type_def_sptr ty = is_array_type(t))
6865 {
6866 type_base_sptr p = strip_typedef(ty->get_element_type());
6867 ABG_ASSERT(p);
6868 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6869 }
6870 else if (const method_type_sptr ty = is_method_type(t))
6871 {
6872 function_decl::parameters parm;
6873 for (function_decl::parameters::const_iterator i =
6874 ty->get_parameters().begin();
6875 i != ty->get_parameters().end();
6876 ++i)
6877 {
6878 function_decl::parameter_sptr p = *i;
6879 type_base_sptr typ = strip_typedef(p->get_type());
6880 ABG_ASSERT(typ);
6881 function_decl::parameter_sptr stripped
6882 (new function_decl::parameter(typ,
6883 p->get_index(),
6884 p->get_name(),
6885 p->get_location(),
6886 p->get_variadic_marker(),
6887 p->get_is_artificial()));
6888 parm.push_back(stripped);
6889 }
6890 type_base_sptr p = strip_typedef(ty->get_return_type());
6891 ABG_ASSERT(!!p == !!ty->get_return_type());
6892 t.reset(new method_type(p, ty->get_class_type(),
6893 parm, ty->get_is_const(),
6894 ty->get_size_in_bits(),
6895 ty->get_alignment_in_bits()));
6896 }
6897 else if (const function_type_sptr ty = is_function_type(t))
6898 {
6899 function_decl::parameters parm;
6900 for (function_decl::parameters::const_iterator i =
6901 ty->get_parameters().begin();
6902 i != ty->get_parameters().end();
6903 ++i)
6904 {
6905 function_decl::parameter_sptr p = *i;
6906 type_base_sptr typ = strip_typedef(p->get_type());
6907 ABG_ASSERT(typ);
6908 function_decl::parameter_sptr stripped
6909 (new function_decl::parameter(typ,
6910 p->get_index(),
6911 p->get_name(),
6912 p->get_location(),
6913 p->get_variadic_marker(),
6914 p->get_is_artificial()));
6915 parm.push_back(stripped);
6916 }
6917 type_base_sptr p = strip_typedef(ty->get_return_type());
6918 ABG_ASSERT(!!p == !!ty->get_return_type());
6919 t.reset(new function_type(p, parm,
6920 ty->get_size_in_bits(),
6921 ty->get_alignment_in_bits()));
6922 }
6923
6924 if (!t->get_translation_unit())
6925 t->set_translation_unit(type->get_translation_unit());
6926
6927 if (!(type->get_canonical_type() && canonicalize(t)))
6928 keep_type_alive(t);
6929
6930 return t->get_canonical_type() ? t->get_canonical_type() : t;
6931 }
6932
6933 /// Strip qualification from a qualified type, when it makes sense.
6934 ///
6935 /// DWARF constructs "const reference". This is redundant because a
6936 /// reference is always const. It also constructs the useless "const
6937 /// void" type. The issue is these redundant types then leak into the
6938 /// IR and make for bad diagnostics.
6939 ///
6940 /// This function thus strips the const qualifier from the type in
6941 /// that case. It might contain code to strip other cases like this
6942 /// in the future.
6943 ///
6944 /// @param t the type to strip const qualification from.
6945 ///
6946 /// @return the stripped type or just return @p t.
6947 decl_base_sptr
strip_useless_const_qualification(const qualified_type_def_sptr t)6948 strip_useless_const_qualification(const qualified_type_def_sptr t)
6949 {
6950 if (!t)
6951 return t;
6952
6953 decl_base_sptr result = t;
6954 type_base_sptr u = t->get_underlying_type();
6955 const environment& env = t->get_environment();
6956
6957 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6958 && (is_reference_type(u)))
6959 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6960 && env.is_void_type(u))
6961 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6962 // Let's strip the const qualifier because a reference is always
6963 // 'const' and a const void doesn't make sense. They will just
6964 // lead to spurious changes later down the pipeline, that we'll
6965 // have to deal with by doing painful and error-prone editing of
6966 // the diff IR. Dropping that useless and inconsistent artefact
6967 // right here seems to be a good way to go.
6968 result = is_decl(u);
6969
6970 return result;
6971 }
6972
6973 /// Merge redundant qualifiers from a tree of qualified types.
6974 ///
6975 /// Suppose a tree of qualified types leads to:
6976 ///
6977 /// const virtual const restrict const int;
6978 ///
6979 /// Suppose the IR tree of qualified types ressembles (with C meaning
6980 /// const, V meaning virtual and R meaning restrict):
6981 ///
6982 /// [C|V]-->[C|R] -->[C] --> [int].
6983 ///
6984 /// This function walks the IR and remove the redundant CV qualifiers
6985 /// so the IR becomes:
6986 ///
6987 /// [C|V] --> [R] --> [] -->[int].
6988 ///
6989 /// Note that the empty qualified type (noted []) represents a
6990 /// qualified type with no qualifier. It's rare, but it can exist.
6991 /// I've put it here just for the sake of example.
6992 ///
6993 /// The resulting IR thus represents the (merged) type:
6994 ///
6995 /// const virtual restrict int.
6996 ///
6997 /// This function is a sub-routine of the overload @ref
6998 /// strip_useless_const_qualification which doesn't return any value.
6999 ///
7000 /// @param t the qualified type to consider.
7001 ///
7002 /// @param redundant_quals the (redundant) qualifiers to be removed
7003 /// from the qualifiers of the underlying types of @p t.
7004 ///
7005 /// @return the underlying type of @p t which might have had its
7006 /// redundant qualifiers removed.
7007 static qualified_type_def_sptr
strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr & t,qualified_type_def::CV redundant_quals)7008 strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t,
7009 qualified_type_def::CV redundant_quals)
7010 {
7011 if (!t)
7012 return t;
7013
7014 // We must NOT edit canonicalized types.
7015 ABG_ASSERT(!t->get_canonical_type());
7016
7017 qualified_type_def_sptr underlying_qualified_type =
7018 is_qualified_type(t->get_underlying_type());
7019
7020 // Let's build 'currated qualifiers' that are the qualifiers of the
7021 // current type from which redundant qualifiers are removed.
7022 qualified_type_def::CV currated_quals = t->get_cv_quals();
7023
7024 // Remove the redundant qualifiers from these currated qualifiers
7025 currated_quals &= ~redundant_quals;
7026 t->set_cv_quals(currated_quals);
7027
7028 // The redundant qualifiers, moving forward, is now the union of the
7029 // previous set of redundant qualifiers and the currated qualifiers.
7030 redundant_quals |= currated_quals;
7031
7032 qualified_type_def_sptr result = t;
7033 if (underlying_qualified_type)
7034 // Now remove the redundant qualifiers from the qualified types
7035 // potentially carried by the underlying type.
7036 result =
7037 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
7038 redundant_quals);
7039
7040 return result;
7041 }
7042
7043 /// Merge redundant qualifiers from a tree of qualified types.
7044 ///
7045 /// Suppose a tree of qualified types leads to:
7046 ///
7047 /// const virtual const restrict const int;
7048 ///
7049 /// Suppose the IR tree of qualified types ressembles (with C meaning
7050 /// const, V meaning virtual and R meaning restrict):
7051 ///
7052 /// [C|V]-->[C|R] -->[C] --> [int].
7053 ///
7054 /// This function walks the IR and remove the redundant CV qualifiers
7055 /// so the IR becomes:
7056 ///
7057 /// [C|V] --> [R] --> [] -->[int].
7058 ///
7059 /// Note that the empty qualified type (noted []) represents a
7060 /// qualified type with no qualifier. It's rare, but it can exist.
7061 /// I've put it here just for the sake of example.
7062 ///
7063 /// The resulting IR thus represents the (merged) type:
7064 ///
7065 /// const virtual restrict int.
7066 ///
7067 /// @param t the qualified type to consider. The IR below the
7068 /// argument to this parameter will be edited to remove redundant
7069 /// qualifiers where applicable.
7070 void
strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr & t)7071 strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr& t)
7072 {
7073 if (!t)
7074 return;
7075
7076 qualified_type_def::CV redundant_quals = qualified_type_def::CV_NONE;
7077 strip_redundant_quals_from_underyling_types(t, redundant_quals);
7078 }
7079
7080 /// Return the leaf underlying type node of a @ref typedef_decl node.
7081 ///
7082 /// If the underlying type of a @ref typedef_decl node is itself a
7083 /// @ref typedef_decl node, then recursively look at the underlying
7084 /// type nodes to get the first one that is not a a @ref typedef_decl
7085 /// node. This is what a leaf underlying type node means.
7086 ///
7087 /// Otherwise, if the underlying type node of @ref typedef_decl is
7088 /// *NOT* a @ref typedef_decl node, then just return the underlying
7089 /// type node.
7090 ///
7091 /// And if the type node considered is not a @ref typedef_decl node,
7092 /// then just return it.
7093 ///
7094 /// @return the leaf underlying type node of a @p type.
7095 type_base_sptr
peel_typedef_type(const type_base_sptr & type)7096 peel_typedef_type(const type_base_sptr& type)
7097 {
7098 typedef_decl_sptr t = is_typedef(type);
7099 if (!t)
7100 return type;
7101
7102 if (is_typedef(t->get_underlying_type()))
7103 return peel_typedef_type(t->get_underlying_type());
7104 return t->get_underlying_type();
7105 }
7106
7107 /// Return the leaf underlying type node of a @ref typedef_decl node.
7108 ///
7109 /// If the underlying type of a @ref typedef_decl node is itself a
7110 /// @ref typedef_decl node, then recursively look at the underlying
7111 /// type nodes to get the first one that is not a a @ref typedef_decl
7112 /// node. This is what a leaf underlying type node means.
7113 ///
7114 /// Otherwise, if the underlying type node of @ref typedef_decl is
7115 /// *NOT* a @ref typedef_decl node, then just return the underlying
7116 /// type node.
7117 ///
7118 /// And if the type node considered is not a @ref typedef_decl node,
7119 /// then just return it.
7120 ///
7121 /// @return the leaf underlying type node of a @p type.
7122 const type_base*
peel_typedef_type(const type_base * type)7123 peel_typedef_type(const type_base* type)
7124 {
7125 const typedef_decl* t = is_typedef(type);
7126 if (!t)
7127 return type;
7128
7129 return peel_typedef_type(t->get_underlying_type()).get();
7130 }
7131
7132 /// Return the leaf pointed-to type node of a @ref pointer_type_def
7133 /// node.
7134 ///
7135 /// If the pointed-to type of a @ref pointer_type_def node is itself a
7136 /// @ref pointer_type_def node, then recursively look at the
7137 /// pointed-to type nodes to get the first one that is not a a @ref
7138 /// pointer_type_def node. This is what a leaf pointed-to type node
7139 /// means.
7140 ///
7141 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7142 /// *NOT* a @ref pointer_type_def node, then just return the
7143 /// pointed-to type node.
7144 ///
7145 /// And if the type node considered is not a @ref pointer_type_def
7146 /// node, then just return it.
7147 ///
7148 /// @return the leaf pointed-to type node of a @p type.
7149 type_base_sptr
peel_pointer_type(const type_base_sptr & type)7150 peel_pointer_type(const type_base_sptr& type)
7151 {
7152 pointer_type_def_sptr t = is_pointer_type(type);
7153 if (!t)
7154 return type;
7155
7156 if (is_pointer_type(t->get_pointed_to_type()))
7157 return peel_pointer_type(t->get_pointed_to_type());
7158 return t->get_pointed_to_type();
7159 }
7160
7161 /// Return the leaf pointed-to type node of a @ref pointer_type_def
7162 /// node.
7163 ///
7164 /// If the pointed-to type of a @ref pointer_type_def node is itself a
7165 /// @ref pointer_type_def node, then recursively look at the
7166 /// pointed-to type nodes to get the first one that is not a a @ref
7167 /// pointer_type_def node. This is what a leaf pointed-to type node
7168 /// means.
7169 ///
7170 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
7171 /// *NOT* a @ref pointer_type_def node, then just return the
7172 /// pointed-to type node.
7173 ///
7174 /// And if the type node considered is not a @ref pointer_type_def
7175 /// node, then just return it.
7176 ///
7177 /// @return the leaf pointed-to type node of a @p type.
7178 const type_base*
peel_pointer_type(const type_base * type)7179 peel_pointer_type(const type_base* type)
7180 {
7181 const pointer_type_def* t = is_pointer_type(type);
7182 if (!t)
7183 return type;
7184
7185 return peel_pointer_type(t->get_pointed_to_type()).get();
7186 }
7187
7188 /// Return the leaf pointed-to type node of a @ref reference_type_def
7189 /// node.
7190 ///
7191 /// If the pointed-to type of a @ref reference_type_def node is itself
7192 /// a @ref reference_type_def node, then recursively look at the
7193 /// pointed-to type nodes to get the first one that is not a a @ref
7194 /// reference_type_def node. This is what a leaf pointed-to type node
7195 /// means.
7196 ///
7197 /// Otherwise, if the pointed-to type node of @ref reference_type_def
7198 /// is *NOT* a @ref reference_type_def node, then just return the
7199 /// pointed-to type node.
7200 ///
7201 /// And if the type node considered is not a @ref reference_type_def
7202 /// node, then just return it.
7203 ///
7204 /// @return the leaf pointed-to type node of a @p type.
7205 type_base_sptr
peel_reference_type(const type_base_sptr & type)7206 peel_reference_type(const type_base_sptr& type)
7207 {
7208 reference_type_def_sptr t = is_reference_type(type);
7209 if (!t)
7210 return type;
7211
7212 if (is_reference_type(t->get_pointed_to_type()))
7213 return peel_reference_type(t->get_pointed_to_type());
7214 return t->get_pointed_to_type();
7215 }
7216
7217 /// Return the leaf pointed-to type node of a @ref reference_type_def
7218 /// node.
7219 ///
7220 /// If the pointed-to type of a @ref reference_type_def node is itself
7221 /// a @ref reference_type_def node, then recursively look at the
7222 /// pointed-to type nodes to get the first one that is not a a @ref
7223 /// reference_type_def node. This is what a leaf pointed-to type node
7224 /// means.
7225 ///
7226 /// Otherwise, if the pointed-to type node of @ref reference_type_def
7227 /// is *NOT* a @ref reference_type_def node, then just return the
7228 /// pointed-to type node.
7229 ///
7230 /// And if the type node considered is not a @ref reference_type_def
7231 /// node, then just return it.
7232 ///
7233 /// @return the leaf pointed-to type node of a @p type.
7234 const type_base*
peel_reference_type(const type_base * type)7235 peel_reference_type(const type_base* type)
7236 {
7237 const reference_type_def* t = is_reference_type(type);
7238 if (!t)
7239 return type;
7240
7241 return peel_reference_type(t->get_pointed_to_type()).get();
7242 }
7243
7244 /// Return the leaf element type of an array.
7245 ///
7246 /// If the element type is itself an array, then recursively return
7247 /// the element type of that array itself.
7248 ///
7249 /// @param type the array type to consider. If this is not an array
7250 /// type, this type is returned by the function.
7251 ///
7252 /// @return the leaf element type of the array @p type, or, if it's
7253 /// not an array type, then just return @p.
7254 const type_base_sptr
peel_array_type(const type_base_sptr & type)7255 peel_array_type(const type_base_sptr& type)
7256 {
7257 const array_type_def_sptr t = is_array_type(type);
7258 if (!t)
7259 return type;
7260
7261 return peel_array_type(t->get_element_type());
7262 }
7263
7264 /// Return the leaf element type of an array.
7265 ///
7266 /// If the element type is itself an array, then recursively return
7267 /// the element type of that array itself.
7268 ///
7269 /// @param type the array type to consider. If this is not an array
7270 /// type, this type is returned by the function.
7271 ///
7272 /// @return the leaf element type of the array @p type, or, if it's
7273 /// not an array type, then just return @p.
7274 const type_base*
peel_array_type(const type_base * type)7275 peel_array_type(const type_base* type)
7276 {
7277 const array_type_def* t = is_array_type(type);
7278 if (!t)
7279 return type;
7280
7281 return peel_array_type(t->get_element_type()).get();
7282 }
7283
7284 /// Return the leaf underlying type of a qualified type.
7285 ///
7286 /// If the underlying type is itself a qualified type, then
7287 /// recursively return the first underlying type of that qualified
7288 /// type to return the first underlying type that is not a qualified type.
7289 ///
7290 /// If the underlying type is NOT a qualified type, then just return
7291 /// that underlying type.
7292 ///
7293 /// @param type the qualified type to consider.
7294 ///
7295 /// @return the leaf underlying type.
7296 const type_base*
peel_qualified_type(const type_base * type)7297 peel_qualified_type(const type_base* type)
7298 {
7299 const qualified_type_def* t = is_qualified_type(type);
7300 if (!t)
7301 return type;
7302
7303 return peel_qualified_type(t->get_underlying_type().get());
7304 }
7305
7306 /// Return the leaf underlying type of a qualified type.
7307 ///
7308 /// If the underlying type is itself a qualified type, then
7309 /// recursively return the first underlying type of that qualified
7310 /// type to return the first underlying type that is not a qualified type.
7311 ///
7312 /// If the underlying type is NOT a qualified type, then just return
7313 /// that underlying type.
7314 ///
7315 /// @param type the qualified type to consider.
7316 ///
7317 /// @return the leaf underlying type.
7318 const type_base_sptr
peel_qualified_type(const type_base_sptr & type)7319 peel_qualified_type(const type_base_sptr& type)
7320 {
7321 const qualified_type_def_sptr t = is_qualified_type(type);
7322 if (!t)
7323 return type;
7324
7325 return peel_qualified_type(t->get_underlying_type());
7326 }
7327
7328 /// Return the leaf underlying type of a qualified or typedef type.
7329 ///
7330 /// If the underlying type is itself a qualified or typedef type, then
7331 /// recursively return the first underlying type of that qualified or
7332 /// typedef type to return the first underlying type that is not a
7333 /// qualified or typedef type.
7334 ///
7335 /// If the underlying type is NOT a qualified nor a typedef type, then
7336 /// just return that underlying type.
7337 ///
7338 /// @param type the qualified or typedef type to consider.
7339 ///
7340 /// @return the leaf underlying type.
7341 type_base*
peel_qualified_or_typedef_type(const type_base * type)7342 peel_qualified_or_typedef_type(const type_base* type)
7343 {
7344 while (is_typedef(type) || is_qualified_type(type))
7345 {
7346 if (const typedef_decl* t = is_typedef(type))
7347 type = peel_typedef_type(t);
7348
7349 if (const qualified_type_def* t = is_qualified_type(type))
7350 type = peel_qualified_type(t);
7351 }
7352
7353 return const_cast<type_base*>(type);
7354 }
7355
7356 /// Return the leaf underlying type of a qualified or typedef type.
7357 ///
7358 /// If the underlying type is itself a qualified or typedef type, then
7359 /// recursively return the first underlying type of that qualified or
7360 /// typedef type to return the first underlying type that is not a
7361 /// qualified or typedef type.
7362 ///
7363 /// If the underlying type is NOT a qualified nor a typedef type, then
7364 /// just return that underlying type.
7365 ///
7366 /// @param type the qualified or typedef type to consider.
7367 ///
7368 /// @return the leaf underlying type.
7369 type_base_sptr
peel_qualified_or_typedef_type(const type_base_sptr & t)7370 peel_qualified_or_typedef_type(const type_base_sptr &t)
7371 {
7372 type_base_sptr type = t;
7373 while (is_typedef(type) || is_qualified_type(type))
7374 {
7375 if (typedef_decl_sptr t = is_typedef(type))
7376 type = peel_typedef_type(t);
7377
7378 if (qualified_type_def_sptr t = is_qualified_type(type))
7379 type = peel_qualified_type(t);
7380 }
7381
7382 return type;
7383 }
7384
7385 /// Return the leaf underlying or pointed-to type node of a @ref
7386 /// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
7387 /// or @ref array_type_def node.
7388 ///
7389 /// @param type the type to peel.
7390 ///
7391 /// @return the leaf underlying or pointed-to type node of @p type.
7392 type_base_sptr
peel_typedef_pointer_or_reference_type(const type_base_sptr type)7393 peel_typedef_pointer_or_reference_type(const type_base_sptr type)
7394 {
7395 type_base_sptr typ = type;
7396 while (is_typedef(typ)
7397 || is_pointer_type(typ)
7398 || is_reference_type(typ)
7399 || is_array_type(typ))
7400 {
7401 if (typedef_decl_sptr t = is_typedef(typ))
7402 typ = peel_typedef_type(t);
7403
7404 if (pointer_type_def_sptr t = is_pointer_type(typ))
7405 typ = peel_pointer_type(t);
7406
7407 if (reference_type_def_sptr t = is_reference_type(typ))
7408 typ = peel_reference_type(t);
7409
7410 if (const array_type_def_sptr t = is_array_type(typ))
7411 typ = peel_array_type(t);
7412 }
7413
7414 return typ;
7415 }
7416
7417 /// Return the leaf underlying or pointed-to type node of a @ref
7418 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7419 /// node.
7420 ///
7421 /// @param type the type to peel.
7422 ///
7423 /// @return the leaf underlying or pointed-to type node of @p type.
7424 type_base*
peel_typedef_pointer_or_reference_type(const type_base * type)7425 peel_typedef_pointer_or_reference_type(const type_base* type)
7426 {
7427 while (is_typedef(type)
7428 || is_pointer_type(type)
7429 || is_reference_type(type)
7430 || is_array_type(type))
7431 {
7432 if (const typedef_decl* t = is_typedef(type))
7433 type = peel_typedef_type(t);
7434
7435 if (const pointer_type_def* t = is_pointer_type(type))
7436 type = peel_pointer_type(t);
7437
7438 if (const reference_type_def* t = is_reference_type(type))
7439 type = peel_reference_type(t);
7440
7441 if (const array_type_def* t = is_array_type(type))
7442 type = peel_array_type(t);
7443 }
7444
7445 return const_cast<type_base*>(type);
7446 }
7447
7448 /// Return the leaf underlying or pointed-to type node of a @ref
7449 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
7450 /// node.
7451 ///
7452 /// @param type the type to peel.
7453 ///
7454 /// @return the leaf underlying or pointed-to type node of @p type.
7455 type_base*
peel_typedef_pointer_or_reference_type(const type_base * type,bool peel_qual_type)7456 peel_typedef_pointer_or_reference_type(const type_base* type,
7457 bool peel_qual_type)
7458 {
7459 while (is_typedef(type)
7460 || is_pointer_type(type)
7461 || is_reference_type(type)
7462 || is_array_type(type)
7463 || (peel_qual_type && is_qualified_type(type)))
7464 {
7465 if (const typedef_decl* t = is_typedef(type))
7466 type = peel_typedef_type(t);
7467
7468 if (const pointer_type_def* t = is_pointer_type(type))
7469 type = peel_pointer_type(t);
7470
7471 if (const reference_type_def* t = is_reference_type(type))
7472 type = peel_reference_type(t);
7473
7474 if (const array_type_def* t = is_array_type(type))
7475 type = peel_array_type(t);
7476
7477 if (peel_qual_type)
7478 if (const qualified_type_def* t = is_qualified_type(type))
7479 type = peel_qualified_type(t);
7480 }
7481
7482 return const_cast<type_base*>(type);
7483 }
7484
7485 /// Return the leaf underlying or pointed-to type node of a, @ref
7486 /// pointer_type_def, @ref reference_type_def or @ref
7487 /// qualified_type_def type node.
7488 ///
7489 /// @param type the type to peel.
7490 ///
7491 /// @param peel_qualified_type if true, also peel qualified types.
7492 ///
7493 /// @return the leaf underlying or pointed-to type node of @p type.
7494 type_base*
peel_pointer_or_reference_type(const type_base * type,bool peel_qual_type)7495 peel_pointer_or_reference_type(const type_base *type,
7496 bool peel_qual_type)
7497 {
7498 while (is_pointer_type(type)
7499 || is_reference_type(type)
7500 || is_array_type(type)
7501 || (peel_qual_type && is_qualified_type(type)))
7502 {
7503 if (const pointer_type_def* t = is_pointer_type(type))
7504 type = peel_pointer_type(t);
7505
7506 if (const reference_type_def* t = is_reference_type(type))
7507 type = peel_reference_type(t);
7508
7509 if (const array_type_def* t = is_array_type(type))
7510 type = peel_array_type(t);
7511
7512 if (peel_qual_type)
7513 if (const qualified_type_def* t = is_qualified_type(type))
7514 type = peel_qualified_type(t);
7515 }
7516
7517 return const_cast<type_base*>(type);
7518 }
7519
7520 /// Clone an array type.
7521 ///
7522 /// Note that the element type of the new array is shared witht the
7523 /// old one.
7524 ///
7525 /// @param array the array type to clone.
7526 ///
7527 /// @return a newly built array type. Note that it needs to be added
7528 /// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7529 /// bound to the one of that scope. Otherwise, its lifetime is bound
7530 /// to the lifetime of its containing shared pointer.
7531 array_type_def_sptr
clone_array(const array_type_def_sptr & array)7532 clone_array(const array_type_def_sptr& array)
7533 {
7534 vector<array_type_def::subrange_sptr> subranges;
7535
7536 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7537 array->get_subranges().begin();
7538 i != array->get_subranges().end();
7539 ++i)
7540 {
7541 array_type_def::subrange_sptr subrange
7542 (new array_type_def::subrange_type(array->get_environment(),
7543 (*i)->get_name(),
7544 (*i)->get_lower_bound(),
7545 (*i)->get_upper_bound(),
7546 (*i)->get_underlying_type(),
7547 (*i)->get_location(),
7548 (*i)->get_language()));
7549 subrange->is_infinite((*i)->is_infinite());
7550 if (scope_decl *scope = (*i)->get_scope())
7551 add_decl_to_scope(subrange, scope);
7552 subranges.push_back(subrange);
7553 }
7554
7555 array_type_def_sptr result
7556 (new array_type_def(array->get_element_type(),
7557 subranges, array->get_location()));
7558
7559 return result;
7560 }
7561
7562 /// Clone a typedef type.
7563 ///
7564 /// Note that the underlying type of the newly constructed typedef is
7565 /// shared with the old one.
7566 ///
7567 /// @param t the typedef to clone.
7568 ///
7569 /// @return the newly constructed typedef. Note that it needs to be
7570 /// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7571 /// to be bound to the one of that scope. Otherwise, its lifetime is
7572 /// bound to the lifetime of its containing shared pointer.
7573 typedef_decl_sptr
clone_typedef(const typedef_decl_sptr & t)7574 clone_typedef(const typedef_decl_sptr& t)
7575 {
7576 if (!t)
7577 return t;
7578
7579 typedef_decl_sptr result
7580 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7581 t->get_location(), t->get_linkage_name(),
7582 t->get_visibility()));
7583 return result;
7584 }
7585
7586 /// Clone a qualifiend type.
7587 ///
7588 /// Note that underlying type of the newly constructed qualified type
7589 /// is shared with the old one.
7590 ///
7591 /// @param t the qualified type to clone.
7592 ///
7593 /// @return the newly constructed qualified type. Note that it needs
7594 /// to be added to a scope (e.g, using add_decl_to_scope) for its
7595 /// lifetime to be bound to the one of that scope. Otherwise, its
7596 /// lifetime is bound to the lifetime of its containing shared
7597 /// pointer.
7598 qualified_type_def_sptr
clone_qualified_type(const qualified_type_def_sptr & t)7599 clone_qualified_type(const qualified_type_def_sptr& t)
7600 {
7601 if (!t)
7602 return t;
7603
7604 qualified_type_def_sptr result
7605 (new qualified_type_def(t->get_underlying_type(),
7606 t->get_cv_quals(), t->get_location()));
7607
7608 return result;
7609 }
7610
7611 /// Clone a typedef, an array or a qualified tree.
7612 ///
7613 /// @param type the typedef, array or qualified tree to clone. any
7614 /// order.
7615 ///
7616 /// @return the cloned type, or NULL if @type was neither a typedef,
7617 /// array nor a qualified type.
7618 static type_base_sptr
clone_typedef_array_qualified_type(type_base_sptr type)7619 clone_typedef_array_qualified_type(type_base_sptr type)
7620 {
7621 if (!type)
7622 return type;
7623
7624 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7625 type_base_sptr result;
7626
7627 if (typedef_decl_sptr t = is_typedef(type))
7628 result = clone_typedef(is_typedef(t));
7629 else if (qualified_type_def_sptr t = is_qualified_type(type))
7630 result = clone_qualified_type(t);
7631 else if (array_type_def_sptr t = is_array_type(type))
7632 result = clone_array(t);
7633 else
7634 return type_base_sptr();
7635
7636 if (scope)
7637 add_decl_to_scope(is_decl(result), scope);
7638
7639 return result;
7640 }
7641
7642 /// Clone a type tree made of an array or a typedef of array.
7643 ///
7644 /// Note that this can be a tree which root node is a typedef an which
7645 /// sub-tree can be any arbitrary combination of typedef, qualified
7646 /// type and arrays.
7647 ///
7648 /// @param t the array or typedef of qualified array to consider.
7649 ///
7650 /// @return a clone of @p t.
7651 type_base_sptr
clone_array_tree(const type_base_sptr t)7652 clone_array_tree(const type_base_sptr t)
7653 {
7654 ABG_ASSERT(is_typedef_of_array(t) || is_array_type(t));
7655
7656 scope_decl* scope = is_decl(t)->get_scope();
7657 type_base_sptr result = clone_typedef_array_qualified_type(t);
7658 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7659
7660 type_base_sptr subtree;
7661 if (typedef_decl_sptr type = is_typedef(result))
7662 {
7663 type_base_sptr s =
7664 clone_typedef_array_qualified_type(type->get_underlying_type());
7665 if (s)
7666 {
7667 subtree = s;
7668 type->set_underlying_type(subtree);
7669 }
7670 }
7671 else if (array_type_def_sptr type = is_array_type(result))
7672 {
7673 type_base_sptr s =
7674 clone_typedef_array_qualified_type(type->get_element_type());
7675 if (s)
7676 {
7677 subtree = s;
7678 type->set_element_type(subtree);
7679 }
7680 }
7681 add_decl_to_scope(is_decl(subtree), scope);
7682
7683 for (;;)
7684 {
7685 if (typedef_decl_sptr t = is_typedef(subtree))
7686 {
7687 type_base_sptr s =
7688 clone_typedef_array_qualified_type(t->get_underlying_type());
7689 if (s)
7690 {
7691 scope_decl* scope =
7692 is_decl(t->get_underlying_type())->get_scope();
7693 ABG_ASSERT(scope);
7694 add_decl_to_scope(is_decl(s), scope);
7695 t->set_underlying_type (s);
7696 subtree = s;
7697 }
7698 else
7699 break;
7700 }
7701 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7702 {
7703 type_base_sptr s =
7704 clone_typedef_array_qualified_type(t->get_underlying_type());
7705 if (s)
7706 {
7707 scope_decl* scope =
7708 is_decl(t->get_underlying_type())->get_scope();
7709 ABG_ASSERT(scope);
7710 add_decl_to_scope(is_decl(s), scope);
7711 t->set_underlying_type(s);
7712 subtree = s;
7713 }
7714 else
7715 break;
7716 }
7717 else if (array_type_def_sptr t = is_array_type(subtree))
7718 {
7719 type_base_sptr e = t->get_element_type();
7720 if (is_typedef(e) || is_qualified_type(e))
7721 {
7722 type_base_sptr s =
7723 clone_typedef_array_qualified_type(e);
7724 if (s)
7725 {
7726 scope_decl* scope = is_decl(e)->get_scope();
7727 ABG_ASSERT(scope);
7728 add_decl_to_scope(is_decl(s), scope);
7729 t->set_element_type(s);
7730 }
7731 else
7732 break;
7733 }
7734 break;
7735 }
7736 else
7737 break;
7738 }
7739 return result;
7740 }
7741
7742 /// Update the qualified name of a given sub-tree.
7743 ///
7744 /// @param d the sub-tree for which to update the qualified name.
7745 static void
update_qualified_name(decl_base * d)7746 update_qualified_name(decl_base * d)
7747 {
7748 ::qualified_name_setter setter;
7749 d->traverse(setter);
7750 }
7751
7752 /// Update the qualified name of a given sub-tree.
7753 ///
7754 /// @param d the sub-tree for which to update the qualified name.
7755 static void
update_qualified_name(decl_base_sptr d)7756 update_qualified_name(decl_base_sptr d)
7757 {return update_qualified_name(d.get());}
7758
7759 // <scope_decl stuff>
7760
7761 /// Hash a type by returning the pointer value of its canonical type.
7762 ///
7763 /// @param l the type to hash.
7764 ///
7765 /// @return the the pointer value of the canonical type of @p l.
7766 size_t
operator ()(const type_base_sptr & l) const7767 canonical_type_hash::operator()(const type_base_sptr& l) const
7768 {return operator()(l.get());}
7769
7770 /// Hash a (canonical) type by returning its pointer value
7771 ///
7772 /// @param l the canonical type to hash.
7773 ///
7774 /// @return the pointer value of the canonical type of @p l.
7775 size_t
operator ()(const type_base * l) const7776 canonical_type_hash::operator()(const type_base *l) const
7777 {return reinterpret_cast<size_t>(l);}
7778
7779 struct scope_decl::priv
7780 {
7781 declarations members_;
7782 declarations sorted_members_;
7783 type_base_sptrs_type member_types_;
7784 type_base_sptrs_type sorted_member_types_;
7785 scopes member_scopes_;
7786 canonical_type_sptr_set_type canonical_types_;
7787 type_base_sptrs_type sorted_canonical_types_;
7788 }; // end struct scope_decl::priv
7789
7790 /// Constructor of the @ref scope_decl type.
7791 ///
7792 /// @param the environment to use for the new instance.
7793 ///
7794 /// @param the name of the scope decl.
7795 ///
7796 /// @param locus the source location where the scope_decl is defined.
7797 ///
7798 /// @param vis the visibility of the declaration.
scope_decl(const environment & env,const string & name,const location & locus,visibility vis)7799 scope_decl::scope_decl(const environment& env,
7800 const string& name,
7801 const location& locus,
7802 visibility vis)
7803 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7804 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7805 priv_(new priv)
7806 {}
7807
7808 /// Constructor of the @ref scope_decl type.
7809 ///
7810 /// @param the environment to use for the new instance.
7811 ///
7812 /// @param l the source location where the scope_decl is defined.
7813 ///
7814 /// @param vis the visibility of the declaration.
scope_decl(const environment & env,location & l)7815 scope_decl::scope_decl(const environment& env, location& l)
7816 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7817 decl_base(env, "", l),
7818 priv_(new priv)
7819 {}
7820
7821 /// @eturn the set of canonical types of the the current scope.
7822 canonical_type_sptr_set_type&
get_canonical_types()7823 scope_decl::get_canonical_types()
7824 {return priv_->canonical_types_;}
7825
7826 /// @eturn the set of canonical types of the the current scope.
7827 const canonical_type_sptr_set_type&
get_canonical_types() const7828 scope_decl::get_canonical_types() const
7829 {return const_cast<scope_decl*>(this)->get_canonical_types();}
7830
7831 /// Return a vector of sorted canonical types of the current scope.
7832 ///
7833 /// The types are sorted "almost topologically". That means, they are
7834 /// sorted using the lexicographic order of the string representing
7835 /// the location their definition point. If a type doesn't have a
7836 /// location, then its pretty representation is used.
7837 ///
7838 /// @return a vector of sorted canonical types of the current scope.
7839 const type_base_sptrs_type&
get_sorted_canonical_types() const7840 scope_decl::get_sorted_canonical_types() const
7841 {
7842 if (priv_->sorted_canonical_types_.empty())
7843 {
7844 for (canonical_type_sptr_set_type::const_iterator e =
7845 get_canonical_types().begin();
7846 e != get_canonical_types().end();
7847 ++e)
7848 priv_->sorted_canonical_types_.push_back(*e);
7849
7850 type_topo_comp comp;
7851 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7852 priv_->sorted_canonical_types_.end(),
7853 comp);
7854 }
7855 return priv_->sorted_canonical_types_;
7856 }
7857
7858 /// Getter for the member declarations carried by the current @ref
7859 /// scope_decl.
7860 ///
7861 /// @return the member declarations carried by the current @ref
7862 /// scope_decl.
7863 const scope_decl::declarations&
get_member_decls() const7864 scope_decl::get_member_decls() const
7865 {return priv_->members_;}
7866
7867 /// Getter for the member declarations carried by the current @ref
7868 /// scope_decl.
7869 ///
7870 /// @return the member declarations carried by the current @ref
7871 /// scope_decl.
7872 scope_decl::declarations&
get_member_decls()7873 scope_decl::get_member_decls()
7874 {return priv_->members_;}
7875
7876 /// Getter for the sorted member declarations carried by the current
7877 /// @ref scope_decl.
7878 ///
7879 /// @return the sorted member declarations carried by the current @ref
7880 /// scope_decl. The declarations are sorted topologically.
7881 const scope_decl::declarations&
get_sorted_member_decls() const7882 scope_decl::get_sorted_member_decls() const
7883 {
7884 decl_topo_comp comp;
7885 if (priv_->sorted_members_.empty())
7886 {
7887 for (declarations::const_iterator i = get_member_decls().begin();
7888 i != get_member_decls().end();
7889 ++i)
7890 priv_->sorted_members_.push_back(*i);
7891
7892 std::stable_sort(priv_->sorted_members_.begin(),
7893 priv_->sorted_members_.end(),
7894 comp);
7895 }
7896 return priv_->sorted_members_;
7897 }
7898
7899 /// Getter for the number of anonymous classes contained in this
7900 /// scope.
7901 ///
7902 /// @return the number of anonymous classes contained in this scope.
7903 size_t
get_num_anonymous_member_classes() const7904 scope_decl::get_num_anonymous_member_classes() const
7905 {
7906 int result = 0;
7907 for (declarations::const_iterator it = get_member_decls().begin();
7908 it != get_member_decls().end();
7909 ++it)
7910 if (class_decl_sptr t = is_class_type(*it))
7911 if (t->get_is_anonymous())
7912 ++result;
7913
7914 return result;
7915 }
7916
7917 /// Getter for the number of anonymous unions contained in this
7918 /// scope.
7919 ///
7920 /// @return the number of anonymous unions contained in this scope.
7921 size_t
get_num_anonymous_member_unions() const7922 scope_decl::get_num_anonymous_member_unions() const
7923 {
7924 int result = 0;
7925 for (declarations::const_iterator it = get_member_decls().begin();
7926 it != get_member_decls().end();
7927 ++it)
7928 if (union_decl_sptr t = is_union_type(*it))
7929 if (t->get_is_anonymous())
7930 ++result;
7931
7932 return result;
7933 }
7934
7935 /// Getter for the number of anonymous enums contained in this
7936 /// scope.
7937 ///
7938 /// @return the number of anonymous enums contained in this scope.
7939 size_t
get_num_anonymous_member_enums() const7940 scope_decl::get_num_anonymous_member_enums() const
7941 {
7942 int result = 0;
7943 for (declarations::const_iterator it = get_member_decls().begin();
7944 it != get_member_decls().end();
7945 ++it)
7946 if (enum_type_decl_sptr t = is_enum_type(*it))
7947 if (t->get_is_anonymous())
7948 ++result;
7949
7950 return result;
7951 }
7952
7953 /// Getter for the scopes carried by the current scope.
7954 ///
7955 /// @return the scopes carried by the current scope.
7956 scope_decl::scopes&
get_member_scopes()7957 scope_decl::get_member_scopes()
7958 {return priv_->member_scopes_;}
7959
7960 /// Getter for the scopes carried by the current scope.
7961 ///
7962 /// @return the scopes carried by the current scope.
7963 const scope_decl::scopes&
get_member_scopes() const7964 scope_decl::get_member_scopes() const
7965 {return priv_->member_scopes_;}
7966
7967 /// Test if the current scope is empty.
7968 ///
7969 /// @return true iff the current scope is empty.
7970 bool
is_empty() const7971 scope_decl::is_empty() const
7972 {
7973 return (get_member_decls().empty()
7974 && get_canonical_types().empty());
7975 }
7976
7977 /// Add a member decl to this scope. Note that user code should not
7978 /// use this, but rather use add_decl_to_scope.
7979 ///
7980 /// Note that this function updates the qualified name of the member
7981 /// decl that is added. It also sets the scope of the member. Thus,
7982 /// it ABG_ASSERTs that member should not have its scope set, prior to
7983 /// calling this function.
7984 ///
7985 /// @param member the new member decl to add to this scope.
7986 decl_base_sptr
add_member_decl(const decl_base_sptr & member)7987 scope_decl::add_member_decl(const decl_base_sptr& member)
7988 {
7989 ABG_ASSERT(!has_scope(member));
7990
7991 member->set_scope(this);
7992 priv_->members_.push_back(member);
7993 if (is_type(member))
7994 priv_->member_types_.push_back(is_type(member));
7995
7996 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
7997 priv_->member_scopes_.push_back(m);
7998
7999 update_qualified_name(member);
8000
8001 if (translation_unit* tu = get_translation_unit())
8002 {
8003 if (translation_unit* existing_tu = member->get_translation_unit())
8004 ABG_ASSERT(tu == existing_tu);
8005 else
8006 member->set_translation_unit(tu);
8007 }
8008
8009 maybe_update_types_lookup_map(member);
8010
8011 return member;
8012 }
8013
8014 /// Get the member types of this @ref scope_decl.
8015 ///
8016 /// @return a vector of the member types of this ref class_or_union.
8017 const type_base_sptrs_type&
get_member_types() const8018 scope_decl::get_member_types() const
8019 {return priv_->member_types_;}
8020
8021 /// Find a member type of a given name, inside the current @ref
8022 /// scope_decl.
8023 ///
8024 /// @param name the name of the member type to look for.
8025 ///
8026 /// @return a pointer to the @ref type_base that represents the member
8027 /// type of name @p name, for the current scope.
8028 type_base_sptr
find_member_type(const string & name) const8029 scope_decl::find_member_type(const string& name) const
8030 {
8031 for (auto t : get_member_types())
8032 if (get_type_name(t, /*qualified*/false) == name)
8033 return t;
8034 return type_base_sptr();
8035 }
8036
8037 /// Insert a member type.
8038 ///
8039 /// @param t the type to insert in the @ref scope_decl type.
8040 ///
8041 /// @param an iterator right before which @p t has to be inserted.
8042 void
insert_member_type(type_base_sptr t,declarations::iterator before)8043 scope_decl::insert_member_type(type_base_sptr t,
8044 declarations::iterator before)
8045 {
8046 decl_base_sptr d = get_type_declaration(t);
8047 ABG_ASSERT(d);
8048 ABG_ASSERT(!has_scope(d));
8049
8050 priv_->member_types_.push_back(t);
8051 insert_member_decl(d, before);
8052 }
8053
8054 /// Add a member type to the current instance of class_or_union.
8055 ///
8056 /// @param t the member type to add. It must not have been added to a
8057 /// scope, otherwise this will violate an ABG_ASSERTion.
8058 void
add_member_type(type_base_sptr t)8059 scope_decl::add_member_type(type_base_sptr t)
8060 {insert_member_type(t, get_member_decls().end());}
8061
8062 /// Add a member type to the current instance of class_or_union.
8063 ///
8064 /// @param t the type to be added as a member type to the current
8065 /// instance of class_or_union. An instance of class_or_union::member_type
8066 /// will be created out of @p t and and added to the the class.
8067 ///
8068 /// @param a the access specifier for the member type to be created.
8069 type_base_sptr
add_member_type(type_base_sptr t,access_specifier a)8070 scope_decl::add_member_type(type_base_sptr t, access_specifier a)
8071 {
8072 decl_base_sptr d = get_type_declaration(t);
8073 ABG_ASSERT(d);
8074 ABG_ASSERT(!is_member_decl(d));
8075 add_member_type(t);
8076 set_member_access_specifier(d, a);
8077 return t;
8078 }
8079
8080 /// Remove a member type from the current @ref class_or_union scope.
8081 ///
8082 /// @param t the type to remove.
8083 void
remove_member_type(type_base_sptr t)8084 scope_decl::remove_member_type(type_base_sptr t)
8085 {
8086 for (auto i = priv_->member_types_.begin();
8087 i != priv_->member_types_.end();
8088 ++i)
8089 {
8090 if (*((*i)) == *t)
8091 {
8092 priv_->member_types_.erase(i);
8093 return;
8094 }
8095 }
8096 }
8097
8098 /// Get the sorted member types of this @ref scope_decl
8099 ///
8100 /// @return a vector of the sorted member types of this ref
8101 /// class_or_union.
8102 const type_base_sptrs_type&
get_sorted_member_types() const8103 scope_decl::get_sorted_member_types() const
8104 {
8105 if (priv_->sorted_member_types_.empty())
8106 {
8107 for (auto t : get_member_types())
8108 priv_->sorted_member_types_.push_back(t);
8109
8110 type_topo_comp comp;
8111 std::stable_sort(priv_->sorted_member_types_.begin(),
8112 priv_->sorted_member_types_.end(),
8113 comp);
8114 }
8115 return priv_->sorted_member_types_;
8116 }
8117
8118 /// Insert a member decl to this scope, right before an element
8119 /// pointed to by a given iterator. Note that user code should not
8120 /// use this, but rather use insert_decl_into_scope.
8121 ///
8122 /// Note that this function updates the qualified name of the inserted
8123 /// member.
8124 ///
8125 /// @param member the new member decl to add to this scope.
8126 ///
8127 /// @param before an interator pointing to the element before which
8128 /// the new member should be inserted.
8129 decl_base_sptr
insert_member_decl(decl_base_sptr member,declarations::iterator before)8130 scope_decl::insert_member_decl(decl_base_sptr member,
8131 declarations::iterator before)
8132 {
8133 ABG_ASSERT(!member->get_scope());
8134
8135 member->set_scope(this);
8136 priv_->members_.insert(before, member);
8137
8138 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
8139 priv_-> member_scopes_.push_back(m);
8140
8141 update_qualified_name(member);
8142
8143 if (translation_unit* tu = get_translation_unit())
8144 {
8145 if (translation_unit* existing_tu = member->get_translation_unit())
8146 ABG_ASSERT(tu == existing_tu);
8147 else
8148 member->set_translation_unit(tu);
8149 }
8150
8151 maybe_update_types_lookup_map(member);
8152
8153 return member;
8154 }
8155
8156 /// Remove a declaration from the current scope.
8157 ///
8158 /// @param member the declaration to remove from the scope.
8159 void
remove_member_decl(decl_base_sptr member)8160 scope_decl::remove_member_decl(decl_base_sptr member)
8161 {
8162 for (declarations::iterator i = priv_->members_.begin();
8163 i != priv_->members_.end();
8164 ++i)
8165 {
8166 if (**i == *member)
8167 {
8168 priv_->members_.erase(i);
8169 // Do not access i after this point as it's invalided by the
8170 // erase call.
8171 break;
8172 }
8173 }
8174
8175 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
8176 if (scope)
8177 {
8178 for (scopes::iterator i = priv_->member_scopes_.begin();
8179 i != priv_->member_scopes_.end();
8180 ++i)
8181 {
8182 if (**i == *member)
8183 {
8184 priv_->member_scopes_.erase(i);
8185 break;
8186 }
8187 }
8188 }
8189 }
8190
8191 /// Return the hash value for the current instance of scope_decl.
8192 ///
8193 /// This method can trigger the computing of the hash value, if need be.
8194 ///
8195 /// @return the hash value.
8196 size_t
get_hash() const8197 scope_decl::get_hash() const
8198 {
8199 scope_decl::hash hash_scope;
8200 return hash_scope(this);
8201 }
8202
8203 /// Compares two instances of @ref scope_decl.
8204 ///
8205 /// If the two intances are different, set a bitfield to give some
8206 /// insight about the kind of differences there are.
8207 ///
8208 /// @param l the first artifact of the comparison.
8209 ///
8210 /// @param r the second artifact of the comparison.
8211 ///
8212 /// @param k a pointer to a bitfield that gives information about the
8213 /// kind of changes there are between @p l and @p r. This one is set
8214 /// iff @p k is non-null and the function returns false.
8215 ///
8216 /// Please note that setting k to a non-null value does have a
8217 /// negative performance impact because even if @p l and @p r are not
8218 /// equal, the function keeps up the comparison in order to determine
8219 /// the different kinds of ways in which they are different.
8220 ///
8221 /// @return true if @p l equals @p r, false otherwise.
8222 bool
equals(const scope_decl & l,const scope_decl & r,change_kind * k)8223 equals(const scope_decl& l, const scope_decl& r, change_kind* k)
8224 {
8225 bool result = true;
8226
8227 if (!l.decl_base::operator==(r))
8228 {
8229 result = false;
8230 if (k)
8231 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
8232 else
8233 ABG_RETURN_FALSE;
8234 }
8235
8236 scope_decl::declarations::const_iterator i, j;
8237 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
8238 i != l.get_member_decls().end() && j != r.get_member_decls().end();
8239 ++i, ++j)
8240 {
8241 if (**i != **j)
8242 {
8243 result = false;
8244 if (k)
8245 {
8246 *k |= SUBTYPE_CHANGE_KIND;
8247 break;
8248 }
8249 else
8250 ABG_RETURN_FALSE;
8251 }
8252 }
8253
8254 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
8255 {
8256 result = false;
8257 if (k)
8258 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
8259 else
8260 ABG_RETURN_FALSE;
8261 }
8262
8263 ABG_RETURN(result);
8264 }
8265
8266 /// Return true iff both scopes have the same names and have the same
8267 /// member decls.
8268 ///
8269 /// This function doesn't check for equality of the scopes of its
8270 /// arguments.
8271 bool
operator ==(const decl_base & o) const8272 scope_decl::operator==(const decl_base& o) const
8273 {
8274 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
8275 if (!other)
8276 return false;
8277
8278 return equals(*this, *other, 0);
8279 }
8280
8281 /// Equality operator for @ref scope_decl_sptr.
8282 ///
8283 /// @param l the left hand side operand of the equality operator.
8284 ///
8285 /// @pram r the right hand side operand of the equalify operator.
8286 ///
8287 /// @return true iff @p l equals @p r.
8288 bool
operator ==(const scope_decl_sptr & l,const scope_decl_sptr & r)8289 operator==(const scope_decl_sptr& l, const scope_decl_sptr& r)
8290 {
8291 if (!!l != !!r)
8292 return false;
8293 if (l.get() == r.get())
8294 return true;
8295 return *l == *r;
8296 }
8297
8298 /// Inequality operator for @ref scope_decl_sptr.
8299 ///
8300 /// @param l the left hand side operand of the equality operator.
8301 ///
8302 /// @pram r the right hand side operand of the equalify operator.
8303 ///
8304 /// @return true iff @p l equals @p r.
8305 bool
operator !=(const scope_decl_sptr & l,const scope_decl_sptr & r)8306 operator!=(const scope_decl_sptr& l, const scope_decl_sptr& r)
8307 {return !operator==(l, r);}
8308
8309 /// Find a member of the current scope and return an iterator on it.
8310 ///
8311 /// @param decl the scope member to find.
8312 ///
8313 /// @param i the iterator to set to the member @p decl. This is set
8314 /// iff the function returns true.
8315 ///
8316 /// @return true if the member decl was found, false otherwise.
8317 bool
find_iterator_for_member(const decl_base * decl,declarations::iterator & i)8318 scope_decl::find_iterator_for_member(const decl_base* decl,
8319 declarations::iterator& i)
8320 {
8321 if (!decl)
8322 return false;
8323
8324 if (get_member_decls().empty())
8325 {
8326 i = get_member_decls().end();
8327 return false;
8328 }
8329
8330 for (declarations::iterator it = get_member_decls().begin();
8331 it != get_member_decls().end();
8332 ++it)
8333 {
8334 if ((*it).get() == decl)
8335 {
8336 i = it;
8337 return true;
8338 }
8339 }
8340
8341 return false;
8342 }
8343
8344 /// Find a member of the current scope and return an iterator on it.
8345 ///
8346 /// @param decl the scope member to find.
8347 ///
8348 /// @param i the iterator to set to the member @p decl. This is set
8349 /// iff the function returns true.
8350 ///
8351 /// @return true if the member decl was found, false otherwise.
8352 bool
find_iterator_for_member(const decl_base_sptr decl,declarations::iterator & i)8353 scope_decl::find_iterator_for_member(const decl_base_sptr decl,
8354 declarations::iterator& i)
8355 {return find_iterator_for_member(decl.get(), i);}
8356
8357 /// This implements the ir_traversable_base::traverse pure virtual
8358 /// function.
8359 ///
8360 /// @param v the visitor used on the current instance of scope_decl
8361 /// and on its member nodes.
8362 ///
8363 /// @return true if the traversal of the tree should continue, false
8364 /// otherwise.
8365 bool
traverse(ir_node_visitor & v)8366 scope_decl::traverse(ir_node_visitor &v)
8367 {
8368 if (visiting())
8369 return true;
8370
8371 if (v.visit_begin(this))
8372 {
8373 visiting(true);
8374 for (scope_decl::declarations::const_iterator i =
8375 get_member_decls().begin();
8376 i != get_member_decls ().end();
8377 ++i)
8378 if (!(*i)->traverse(v))
8379 break;
8380 visiting(false);
8381 }
8382 return v.visit_end(this);
8383 }
8384
~scope_decl()8385 scope_decl::~scope_decl()
8386 {}
8387
8388 /// Appends a declaration to a given scope, if the declaration
8389 /// doesn't already belong to one and if the declaration is not for a
8390 /// type that is supposed to be unique.
8391 ///
8392 /// @param decl the declaration to add to the scope
8393 ///
8394 /// @param scope the scope to append the declaration to
8395 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,scope_decl * scope)8396 add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
8397 {
8398 ABG_ASSERT(scope);
8399
8400 if (scope && decl && !decl->get_scope())
8401 decl = scope->add_member_decl(decl);
8402
8403 return decl;
8404 }
8405
8406 /// Appends a declaration to a given scope, if the declaration doesn't
8407 /// already belong to a scope.
8408 ///
8409 /// @param decl the declaration to add append to the scope
8410 ///
8411 /// @param scope the scope to append the decl to
8412 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,const scope_decl_sptr & scope)8413 add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
8414 {return add_decl_to_scope(decl, scope.get());}
8415
8416 /// Remove a given decl from its scope
8417 ///
8418 /// @param decl the decl to remove from its scope.
8419 void
remove_decl_from_scope(decl_base_sptr decl)8420 remove_decl_from_scope(decl_base_sptr decl)
8421 {
8422 if (!decl)
8423 return;
8424
8425 scope_decl* scope = decl->get_scope();
8426 scope->remove_member_decl(decl);
8427 decl->set_scope(0);
8428 }
8429
8430 /// Inserts a declaration into a given scope, before a given IR child
8431 /// node of the scope.
8432 ///
8433 /// @param decl the declaration to insert into the scope.
8434 ///
8435 /// @param before an iterator pointing to the child IR node before
8436 /// which to insert the declaration.
8437 ///
8438 /// @param scope the scope into which to insert the declaration.
8439 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl * scope)8440 insert_decl_into_scope(decl_base_sptr decl,
8441 scope_decl::declarations::iterator before,
8442 scope_decl* scope)
8443 {
8444 if (scope && decl && !decl->get_scope())
8445 {
8446 decl_base_sptr d = scope->insert_member_decl(decl, before);
8447 decl = d;
8448 }
8449 return decl;
8450 }
8451
8452 /// Inserts a declaration into a given scope, before a given IR child
8453 /// node of the scope.
8454 ///
8455 /// @param decl the declaration to insert into the scope.
8456 ///
8457 /// @param before an iterator pointing to the child IR node before
8458 /// which to insert the declaration.
8459 ///
8460 /// @param scope the scope into which to insert the declaration.
8461 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl_sptr scope)8462 insert_decl_into_scope(decl_base_sptr decl,
8463 scope_decl::declarations::iterator before,
8464 scope_decl_sptr scope)
8465 {return insert_decl_into_scope(decl, before, scope.get());}
8466
8467 /// Constructor of the @ref global_scope type.
8468 ///
8469 /// @param tu the translation unit the scope belongs to.
global_scope(translation_unit * tu)8470 global_scope::global_scope(translation_unit *tu)
8471 : type_or_decl_base(tu->get_environment(),
8472 GLOBAL_SCOPE_DECL
8473 | ABSTRACT_DECL_BASE
8474 | ABSTRACT_SCOPE_DECL),
8475 decl_base(tu->get_environment(), "", location()),
8476 scope_decl(tu->get_environment(), "", location()),
8477 translation_unit_(tu)
8478 {
8479 runtime_type_instance(this);
8480 }
8481
8482 /// return the global scope as seen by a given declaration.
8483 ///
8484 /// @param decl the declaration to consider.
8485 ///
8486 /// @return the global scope of the decl, or a null pointer if the
8487 /// decl is not yet added to a translation_unit.
8488 const global_scope*
get_global_scope(const decl_base & decl)8489 get_global_scope(const decl_base& decl)
8490 {
8491 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
8492 return s;
8493
8494 scope_decl* scope = decl.get_scope();
8495 while (scope && !dynamic_cast<global_scope*>(scope))
8496 scope = scope->get_scope();
8497
8498 return scope ? dynamic_cast<global_scope*> (scope) : 0;
8499 }
8500
8501 /// return the global scope as seen by a given declaration.
8502 ///
8503 /// @param decl the declaration to consider.
8504 ///
8505 /// @return the global scope of the decl, or a null pointer if the
8506 /// decl is not yet added to a translation_unit.
8507 const global_scope*
get_global_scope(const decl_base * decl)8508 get_global_scope(const decl_base* decl)
8509 {return get_global_scope(*decl);}
8510
8511 /// Return the global scope as seen by a given declaration.
8512 ///
8513 /// @param decl the declaration to consider.
8514 ///
8515 /// @return the global scope of the decl, or a null pointer if the
8516 /// decl is not yet added to a translation_unit.
8517 const global_scope*
get_global_scope(const shared_ptr<decl_base> decl)8518 get_global_scope(const shared_ptr<decl_base> decl)
8519 {return get_global_scope(decl.get());}
8520
8521 /// Return the a scope S containing a given declaration and that is
8522 /// right under a given scope P.
8523 ///
8524 /// Note that @p scope must come before @p decl in topological
8525 /// order.
8526 ///
8527 /// @param decl the decl for which to find a scope.
8528 ///
8529 /// @param scope the scope under which the resulting scope must be.
8530 ///
8531 /// @return the resulting scope.
8532 const scope_decl*
get_top_most_scope_under(const decl_base * decl,const scope_decl * scope)8533 get_top_most_scope_under(const decl_base* decl,
8534 const scope_decl* scope)
8535 {
8536 if (!decl)
8537 return 0;
8538
8539 if (scope == 0)
8540 return get_global_scope(decl);
8541
8542 // Handle the case where decl is a scope itself.
8543 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
8544 if (!s)
8545 s = decl->get_scope();
8546
8547 if (is_global_scope(s))
8548 return scope;
8549
8550 // Here, decl is in the scope 'scope', or decl and 'scope' are the
8551 // same. The caller needs to be prepared to deal with this case.
8552 if (s == scope)
8553 return s;
8554
8555 while (s && !is_global_scope(s) && s->get_scope() != scope)
8556 s = s->get_scope();
8557
8558 if (!s || is_global_scope(s))
8559 // SCOPE must come before decl in topological order, but I don't
8560 // know how to ensure that ...
8561 return scope;
8562 ABG_ASSERT(s);
8563
8564 return s;
8565 }
8566
8567 /// Return the a scope S containing a given declaration and that is
8568 /// right under a given scope P.
8569 ///
8570 /// @param decl the decl for which to find a scope.
8571 ///
8572 /// @param scope the scope under which the resulting scope must be.
8573 ///
8574 /// @return the resulting scope.
8575 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl * scope)8576 get_top_most_scope_under(const decl_base_sptr decl,
8577 const scope_decl* scope)
8578 {return get_top_most_scope_under(decl.get(), scope);}
8579
8580 /// Return the a scope S containing a given declaration and that is
8581 /// right under a given scope P.
8582 ///
8583 /// @param decl the decl for which to find a scope.
8584 ///
8585 /// @param scope the scope under which the resulting scope must be.
8586 ///
8587 /// @return the resulting scope.
8588 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl_sptr scope)8589 get_top_most_scope_under(const decl_base_sptr decl,
8590 const scope_decl_sptr scope)
8591 {return get_top_most_scope_under(decl, scope.get());}
8592
8593 // </scope_decl stuff>
8594
8595
8596 /// Get the string representation of a CV qualifier bitmap.
8597 ///
8598 /// @param cv_quals the bitmap of CV qualifiers to consider.
8599 ///
8600 /// @return the string representation.
8601 string
get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)8602 get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
8603 {
8604 string repr;
8605 if (cv_quals & qualified_type_def::CV_RESTRICT)
8606 repr = "restrict";
8607 if (cv_quals & qualified_type_def::CV_CONST)
8608 {
8609 if (!repr.empty())
8610 repr += ' ';
8611 repr += "const";
8612 }
8613 if (cv_quals & qualified_type_def::CV_VOLATILE)
8614 {
8615 if (!repr.empty())
8616 repr += ' ';
8617 repr += "volatile";
8618 }
8619 return repr;
8620 }
8621
8622 /// Build and return a copy of the name of an ABI artifact that is
8623 /// either a type or a decl.
8624 ///
8625 /// @param tod the ABI artifact to get the name for.
8626 ///
8627 /// @param qualified if yes, return the qualified name of @p tod;
8628 /// otherwise, return the non-qualified name;
8629 ///
8630 /// @return the name of @p tod.
8631 string
get_name(const type_or_decl_base * tod,bool qualified)8632 get_name(const type_or_decl_base *tod, bool qualified)
8633 {
8634 string result;
8635
8636 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8637
8638 if (type_base* t = dynamic_cast<type_base*>(a))
8639 result = get_type_name(t, qualified);
8640 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8641 {
8642 if (qualified)
8643 result = d->get_qualified_name();
8644 else
8645 result = d->get_name();
8646 }
8647 else
8648 // We should never reach this point.
8649 abort();
8650
8651 return result;
8652 }
8653
8654 /// Build and return a copy of the name of an ABI artifact that is
8655 /// either a type of a decl.
8656 ///
8657 /// @param tod the ABI artifact to get the name for.
8658 ///
8659 /// @param qualified if yes, return the qualified name of @p tod;
8660 /// otherwise, return the non-qualified name;
8661 ///
8662 /// @return the name of @p tod.
8663 string
get_name(const type_or_decl_base_sptr & tod,bool qualified)8664 get_name(const type_or_decl_base_sptr& tod, bool qualified)
8665 {return get_name(tod.get(), qualified);}
8666
8667 /// Build and return a qualified name from a name and its scope.
8668 ///
8669 /// The name is supposed to be for an entity that is part of the
8670 /// scope.
8671 ///
8672 /// @param the scope to consider.
8673 ///
8674 /// @param name of the name to consider.
8675 ///
8676 /// @return a copy of the string that represents the qualified name.
8677 string
build_qualified_name(const scope_decl * scope,const string & name)8678 build_qualified_name(const scope_decl* scope, const string& name)
8679 {
8680 if (name.empty())
8681 return "";
8682
8683 string qualified_name;
8684 if (scope)
8685 qualified_name = scope->get_qualified_name();
8686
8687 if (qualified_name.empty())
8688 qualified_name = name;
8689 else
8690 qualified_name = qualified_name + "::" + name;
8691
8692 return qualified_name;
8693 }
8694
8695 /// Build and return the qualified name of a type in its scope.
8696 ///
8697 /// @param scope the scope of the type to consider.
8698 ///
8699 /// @param type the type to consider.
8700 string
build_qualified_name(const scope_decl * scope,const type_base_sptr & type)8701 build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8702 {return build_qualified_name(scope, get_name((type)));}
8703
8704 // </scope_decl stuff>
8705
8706 /// Get the location of the declaration of a given type.
8707 ///
8708 /// @param type the type to consider.
8709 ///
8710 /// @return the location of the declaration of type @p type.
8711 location
get_location(const type_base_sptr & type)8712 get_location(const type_base_sptr& type)
8713 {
8714 if (decl_base_sptr decl = get_type_declaration(type))
8715 return get_location(decl);
8716 return location();
8717 }
8718
8719 /// Get the location of a given declaration.
8720 ///
8721 /// @param decl the declaration to consider.
8722 ///
8723 /// @return the location of the declaration @p decl.
8724 location
get_location(const decl_base_sptr & decl)8725 get_location(const decl_base_sptr& decl)
8726 {
8727 location loc = decl->get_location();
8728 if (!loc)
8729 {
8730 if (class_or_union_sptr c = is_class_or_union_type(decl))
8731 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8732 {
8733 c = is_class_or_union_type(c->get_definition_of_declaration());
8734 loc = c->get_location();
8735 }
8736 }
8737 return loc;
8738 }
8739
8740 /// Get the scope of a given type.
8741 ///
8742 /// @param t the type to consider.
8743 ///
8744 /// @return the scope of type @p t or 0 if the type has no scope yet.
8745 scope_decl*
get_type_scope(type_base * t)8746 get_type_scope(type_base* t)
8747 {
8748 if (!t)
8749 return 0;
8750
8751 decl_base* d = get_type_declaration(t);
8752 if (d)
8753 return d->get_scope();
8754 return 0;
8755 }
8756
8757 /// Get the scope of a given type.
8758 ///
8759 /// @param t the type to consider.
8760 ///
8761 /// @return the scope of type @p t or 0 if the type has no scope yet.
8762 scope_decl*
get_type_scope(const type_base_sptr & t)8763 get_type_scope(const type_base_sptr& t)
8764 {return get_type_scope(t.get());}
8765
8766 /// Get the name of a given type and return a copy of it.
8767 ///
8768 /// @param t the type to consider.
8769 ///
8770 /// @param qualified if true then return the qualified name of the
8771 /// type.
8772 ///
8773 /// @param internal set to true if the call is intended for an
8774 /// internal use (for technical use inside the library itself), false
8775 /// otherwise. If you don't know what this is for, then set it to
8776 /// false.
8777 ///
8778 /// @return a copy of the type name if the type has a name, or the
8779 /// empty string if it does not.
8780 interned_string
get_type_name(const type_base_sptr & t,bool qualified,bool internal)8781 get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8782 {return get_type_name(t.get(), qualified, internal);}
8783
8784 /// Return true iff a decl is for a type type that has a generic
8785 /// anonymous internal type name.
8786 ///
8787 /// @param d the decl to considier.
8788 ///
8789 /// @return true iff @p d is for a type type that has a generic
8790 /// anonymous internal type name.
8791 static bool
has_generic_anonymous_internal_type_name(const decl_base * d)8792 has_generic_anonymous_internal_type_name(const decl_base *d)
8793 {
8794 return (is_class_or_union_type(d)
8795 || is_enum_type(d)
8796 || is_subrange_type(d));
8797 }
8798
8799 /// Return the generic internal name of an anonymous type.
8800 ///
8801 /// For internal purposes, we want to define a generic name for all
8802 /// anonymous types of a certain kind. For instance, all anonymous
8803 /// structs will be have a generic name of "__anonymous_struct__", all
8804 /// anonymous unions will have a generic name of
8805 /// "__anonymous_union__", etc.
8806 ///
8807 /// That generic name can be used as a hash to put all anonymous types
8808 /// of a certain kind in the same hash table bucket, for instance.
8809 static interned_string
get_generic_anonymous_internal_type_name(const decl_base * d)8810 get_generic_anonymous_internal_type_name(const decl_base *d)
8811 {
8812 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8813
8814 const environment&env = d->get_environment();
8815
8816 interned_string result;
8817 if (is_class_type(d))
8818 result =
8819 env.intern(tools_utils::get_anonymous_struct_internal_name_prefix());
8820 else if (is_union_type(d))
8821 result =
8822 env.intern(tools_utils::get_anonymous_union_internal_name_prefix());
8823 else if (is_enum_type(d))
8824 result =
8825 env.intern(tools_utils::get_anonymous_enum_internal_name_prefix());
8826 else if (is_subrange_type(d))
8827 result =
8828 env.intern(tools_utils::get_anonymous_subrange_internal_name_prefix());
8829 else
8830 ABG_ASSERT_NOT_REACHED;
8831
8832 return result;
8833 }
8834
8835 /// Get the internal name for a given integral type.
8836 ///
8837 /// All integral types that have the modifiers 'short, long or long
8838 /// long' have the same internal name. This is so that they can all
8839 /// have the same canonical type if they are of the same size.
8840 /// Otherwise, 'long int' and 'long long int' would have different
8841 /// canonical types even though they are equivalent from an ABI point
8842 /// of view.
8843 ///
8844 /// @param t the integral type to consider
8845 ///
8846 /// @return the internal name for @p t if it's an integral type, or
8847 /// the empty string if @p t is not an integral type.
8848 static string
get_internal_integral_type_name(const type_base * t)8849 get_internal_integral_type_name(const type_base* t)
8850 {
8851 string name;
8852 type_decl *type = is_integral_type(t);
8853
8854 if (!type)
8855 return name;
8856
8857 integral_type int_type;
8858 if (parse_integral_type(type->get_name(), int_type))
8859 name = int_type.to_string(/*internal=*/true);
8860
8861 return name;
8862 }
8863
8864 /// Get the name of a given type and return a copy of it.
8865 ///
8866 /// @param t the type to consider.
8867 ///
8868 /// @param qualified if true then return the qualified name of the
8869 /// type.
8870 ///
8871 /// @param internal set to true if the call is intended for an
8872 /// internal use (for technical use inside the library itself), false
8873 /// otherwise. If you don't know what this is for, then set it to
8874 /// false.
8875 ///
8876 /// @return a copy of the type name if the type has a name, or the
8877 /// empty string if it does not.
8878 interned_string
get_type_name(const type_base * t,bool qualified,bool internal)8879 get_type_name(const type_base* t, bool qualified, bool internal)
8880 {
8881 const decl_base* d = dynamic_cast<const decl_base*>(t);
8882 if (!d)
8883 {
8884 const function_type* fn_type = is_function_type(t);
8885 ABG_ASSERT(fn_type);
8886 return fn_type->get_cached_name(internal);
8887 }
8888
8889 const environment&env = d->get_environment();
8890
8891 // All anonymous types of a given kind get to have the same internal
8892 // name for internal purpose. This to allow them to be compared
8893 // among themselves during type canonicalization.
8894 if (internal)
8895 {
8896 if (d->get_is_anonymous())
8897 {
8898 string r;
8899 r += get_generic_anonymous_internal_type_name(d);
8900 return t->get_environment().intern(r);
8901 }
8902
8903 if (is_typedef(t))
8904 return d->get_name();
8905
8906 if (qualified)
8907 return d->get_qualified_name(internal);
8908
8909 return env.intern(get_internal_integral_type_name(t));
8910 }
8911
8912 if (d->get_is_anonymous())
8913 {
8914 if (is_class_or_union_type(t) || is_enum_type(t))
8915 return env.intern
8916 (get_class_or_enum_flat_representation (*t, "",
8917 /*one_line=*/true,
8918 internal, qualified));
8919 }
8920
8921 if (qualified)
8922 return d->get_qualified_name(internal);
8923 return d->get_name();
8924 }
8925
8926 /// Get the name of a given type and return a copy of it.
8927 ///
8928 /// @param t the type to consider.
8929 ///
8930 /// @param qualified if true then return the qualified name of the
8931 /// type.
8932 ///
8933 /// @param internal set to true if the call is intended for an
8934 /// internal use (for technical use inside the library itself), false
8935 /// otherwise. If you don't know what this is for, then set it to
8936 /// false.
8937 ///
8938 /// @return a copy of the type name if the type has a name, or the
8939 /// empty string if it does not.
8940 interned_string
get_type_name(const type_base & t,bool qualified,bool internal)8941 get_type_name(const type_base& t, bool qualified, bool internal)
8942 {return get_type_name(&t, qualified, internal);}
8943
8944 /// Get the name of the pointer to a given type.
8945 ///
8946 /// @param pointed_to_type the pointed-to-type to consider.
8947 ///
8948 /// @param qualified this is true if the resulting name should be of a
8949 /// pointer to a *fully-qualified* pointed-to-type.
8950 ///
8951 /// @param internal true if the name is for libabigail-internal
8952 /// purposes.
8953 ///
8954 /// @return the name (string representation) of the pointer.
8955 interned_string
get_name_of_pointer_to_type(const type_base & pointed_to_type,bool qualified,bool internal)8956 get_name_of_pointer_to_type(const type_base& pointed_to_type,
8957 bool qualified, bool internal)
8958 {
8959 const environment& env = pointed_to_type.get_environment();
8960 string tn = get_type_name(pointed_to_type, qualified, internal);
8961 tn = tn + "*";
8962
8963 return env.intern(tn);
8964 }
8965
8966 /// Get the name of the reference to a given type.
8967 ///
8968 /// @param pointed_to_type the pointed-to-type to consider.
8969 ///
8970 /// @param qualified this is true if the resulting name should be of a
8971 /// reference to a *fully-qualified* pointed-to-type.
8972 ///
8973 /// @param internal true if the name is for libabigail-internal
8974 /// purposes.
8975 ///
8976 /// @return the name (string representation) of the reference.
8977 interned_string
get_name_of_reference_to_type(const type_base & pointed_to_type,bool lvalue_reference,bool qualified,bool internal)8978 get_name_of_reference_to_type(const type_base& pointed_to_type,
8979 bool lvalue_reference,
8980 bool qualified, bool internal)
8981 {
8982 const environment& env = pointed_to_type.get_environment();
8983
8984 string name = get_type_name(pointed_to_type, qualified, internal);
8985 if (lvalue_reference)
8986 name = name + "&";
8987 else
8988 name = name + "&&";
8989
8990 return env.intern(name);
8991 }
8992
8993 /// Get the name of a qualified type, given the underlying type and
8994 /// its qualifiers.
8995 ///
8996 /// @param underlying_type the underlying type to consider.
8997 ///
8998 /// @param quals the CV qualifiers of the name.
8999 ///
9000 /// @param qualified true if we should consider the fully qualified
9001 /// name of @p underlying_type.
9002 ///
9003 /// @param internal true if the result is to be used for
9004 /// libabigail-internal purposes.
9005 ///
9006 /// @return the name (string representation) of the qualified type.
9007 interned_string
get_name_of_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,bool qualified,bool internal)9008 get_name_of_qualified_type(const type_base_sptr& underlying_type,
9009 qualified_type_def::CV quals,
9010 bool qualified, bool internal)
9011 {
9012 const environment& env = underlying_type->get_environment();
9013
9014 string quals_repr = get_string_representation_of_cv_quals(quals);
9015 string name = get_type_name(underlying_type, qualified, internal);
9016
9017 if (quals_repr.empty() && internal)
9018 // We are asked to return the internal name, that might be used
9019 // for type canonicalization. For that canonicalization, we need
9020 // to make a difference between a no-op qualified type which
9021 // underlying type is foo (the qualified type is named "none
9022 // foo"), and the name of foo, which is just "foo".
9023 //
9024 // Please remember that this has to be kept in sync with what is
9025 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
9026 // change this code here, please change that code there too.
9027 quals_repr = "";
9028
9029 if (!quals_repr.empty())
9030 {
9031 if (is_pointer_type(peel_qualified_type(underlying_type))
9032 || is_reference_type(peel_qualified_type(underlying_type)))
9033 {
9034 name += " ";
9035 name += quals_repr;
9036 }
9037 else
9038 name = quals_repr + " " + name;
9039 }
9040
9041 return env.intern(name);
9042 }
9043
9044 /// Get the name of a given function type and return a copy of it.
9045 ///
9046 /// @param fn_type the function type to consider.
9047 ///
9048 /// @param internal set to true if the call is intended for an
9049 /// internal use (for technical use inside the library itself), false
9050 /// otherwise. If you don't know what this is for, then set it to
9051 /// false.
9052 ///
9053 /// @return a copy of the function type name
9054 interned_string
get_function_type_name(const function_type_sptr & fn_type,bool internal)9055 get_function_type_name(const function_type_sptr& fn_type,
9056 bool internal)
9057 {return get_function_type_name(fn_type.get(), internal);}
9058
9059 /// Get the name of a given function type and return a copy of it.
9060 ///
9061 /// @param fn_type the function type to consider.
9062 ///
9063 /// @param internal set to true if the call is intended for an
9064 /// internal use (for technical use inside the library itself), false
9065 /// otherwise. If you don't know what this is for, then set it to
9066 /// false.
9067 ///
9068 /// @return a copy of the function type name
9069 interned_string
get_function_type_name(const function_type * fn_type,bool internal)9070 get_function_type_name(const function_type* fn_type,
9071 bool internal)
9072 {
9073 ABG_ASSERT(fn_type);
9074
9075 if (const method_type* method = is_method_type(fn_type))
9076 return get_method_type_name(method, internal);
9077
9078 return get_function_type_name(*fn_type, internal);
9079 }
9080
9081 /// Get the name of a given function type and return a copy of it.
9082 ///
9083 /// @param fn_type the function type to consider.
9084 ///
9085 /// @param internal set to true if the call is intended for an
9086 /// internal use (for technical use inside the library itself), false
9087 /// otherwise. If you don't know what this is for, then set it to
9088 /// false.
9089 ///
9090 /// @return a copy of the function type name
9091 interned_string
get_function_type_name(const function_type & fn_type,bool internal)9092 get_function_type_name(const function_type& fn_type,
9093 bool internal)
9094 {
9095 std::ostringstream o;
9096 // When the function name is used for internal purposes (e.g, for
9097 // canonicalization), we want its representation to stay the same,
9098 // regardless of typedefs. So let's strip typedefs from the return
9099 // type.
9100 type_base_sptr return_type =
9101 internal
9102 ? peel_typedef_type(fn_type.get_return_type())
9103 : fn_type.get_return_type();
9104 const environment& env = fn_type.get_environment();
9105
9106 o << get_pretty_representation(return_type, internal);
9107
9108 o << " (";
9109 type_base_sptr type;
9110 for (function_type::parameters::const_iterator i =
9111 fn_type.get_parameters().begin();
9112 i != fn_type.get_parameters().end();
9113 ++i)
9114 {
9115 if (i != fn_type.get_parameters().begin())
9116 o << ", ";
9117 type = (*i)->get_type();
9118 if (internal)
9119 type = peel_typedef_type(type);
9120 o << get_pretty_representation(type, internal);
9121 }
9122 o <<")";
9123
9124 return env.intern(o.str());
9125 }
9126
9127 /// Get the ID of a function, or, if the ID can designate several
9128 /// different functions, get its pretty representation.
9129 ///
9130 /// @param fn the function to consider
9131 ///
9132 /// @return the function ID of pretty representation of @p fn.
9133 interned_string
get_function_id_or_pretty_representation(function_decl * fn)9134 get_function_id_or_pretty_representation(function_decl *fn)
9135 {
9136 ABG_ASSERT(fn);
9137
9138 interned_string result = fn->get_environment().intern(fn->get_id());
9139
9140 if (corpus *c = fn->get_corpus())
9141 {
9142 corpus::exported_decls_builder_sptr b =
9143 c->get_exported_decls_builder();
9144 if (b->fn_id_maps_to_several_fns(fn))
9145 result = fn->get_environment().intern(fn->get_pretty_representation());
9146 }
9147
9148 return result;
9149 }
9150
9151 /// Get the name of a given method type and return a copy of it.
9152 ///
9153 /// @param fn_type the function type to consider.
9154 ///
9155 /// @param internal set to true if the call is intended for an
9156 /// internal use (for technical use inside the library itself), false
9157 /// otherwise. If you don't know what this is for, then set it to
9158 /// false.
9159 ///
9160 /// @return a copy of the function type name
9161 interned_string
get_method_type_name(const method_type_sptr fn_type,bool internal)9162 get_method_type_name(const method_type_sptr fn_type,
9163 bool internal)
9164 {return get_method_type_name(fn_type.get(), internal);}
9165
9166 /// Get the name of a given method type and return a copy of it.
9167 ///
9168 /// @param fn_type the function type to consider.
9169 ///
9170 /// @param internal set to true if the call is intended for an
9171 /// internal use (for technical use inside the library itself), false
9172 /// otherwise. If you don't know what this is for, then set it to
9173 /// false.
9174 ///
9175 /// @return a copy of the function type name
9176 interned_string
get_method_type_name(const method_type * fn_type,bool internal)9177 get_method_type_name(const method_type* fn_type,
9178 bool internal)
9179 {
9180 if (fn_type)
9181 return get_method_type_name(*fn_type, internal);
9182
9183 return interned_string();
9184 }
9185
9186 /// Get the name of a given method type and return a copy of it.
9187 ///
9188 /// @param fn_type the function type to consider.
9189 ///
9190 /// @param internal set to true if the call is intended for an
9191 /// internal use (for technical use inside the library itself), false
9192 /// otherwise. If you don't know what this is for, then set it to
9193 /// false.
9194 ///
9195 /// @return a copy of the function type name
9196 interned_string
get_method_type_name(const method_type & fn_type,bool internal)9197 get_method_type_name(const method_type& fn_type,
9198 bool internal)
9199 {
9200 std::ostringstream o;
9201 // When the function name is used for internal purposes (e.g, for
9202 // canonicalization), we want its representation to stay the same,
9203 // regardless of typedefs. So let's strip typedefs from the return
9204 // type.
9205 type_base_sptr return_type =
9206 internal
9207 ? peel_typedef_type(fn_type.get_return_type())
9208 : fn_type.get_return_type();
9209 const environment& env = fn_type.get_environment();
9210
9211 if (return_type)
9212 o << return_type->get_cached_pretty_representation(internal);
9213 else
9214 // There are still some abixml files out there in which "void"
9215 // can be expressed as an empty type.
9216 o << "void";
9217
9218 class_or_union_sptr class_type = fn_type.get_class_type();
9219 ABG_ASSERT(class_type);
9220
9221 o << " (" << class_type->get_qualified_name(internal) << "::*)"
9222 << " (";
9223
9224 type_base_sptr type;
9225 for (function_type::parameters::const_iterator i =
9226 fn_type.get_parameters().begin();
9227 i != fn_type.get_parameters().end();
9228 ++i)
9229 {
9230 if (i != fn_type.get_parameters().begin())
9231 o << ", ";
9232 type = (*i)->get_type();
9233 if (internal)
9234 type = peel_typedef_type(type);
9235 if (*i)
9236 o << type->get_cached_pretty_representation(internal);
9237 else
9238 // There are still some abixml files out there in which "void"
9239 // can be expressed as an empty type.
9240 o << "void";
9241 }
9242 o <<")";
9243
9244 return env.intern(o.str());
9245 }
9246
9247 /// Build and return a copy of the pretty representation of an ABI
9248 /// artifact that could be either a type of a decl.
9249 ///
9250 /// param tod the ABI artifact to consider.
9251 ///
9252 /// @param internal set to true if the call is intended for an
9253 /// internal use (for technical use inside the library itself), false
9254 /// otherwise. If you don't know what this is for, then set it to
9255 /// false.
9256 ///
9257 /// @return a copy of the pretty representation of an ABI artifact
9258 /// that could be either a type of a decl.
9259 string
get_pretty_representation(const type_or_decl_base * tod,bool internal)9260 get_pretty_representation(const type_or_decl_base* tod, bool internal)
9261 {
9262 string result;
9263
9264 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
9265 result = get_pretty_representation(t, internal);
9266 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
9267 result = get_pretty_representation(d, internal);
9268 else
9269 // We should never reach this point
9270 abort();
9271
9272 return result;
9273 }
9274
9275 /// Build and return a copy of the pretty representation of an ABI
9276 /// artifact that could be either a type of a decl.
9277 ///
9278 /// param tod the ABI artifact to consider.
9279 ///
9280 /// @param internal set to true if the call is intended for an
9281 /// internal use (for technical use inside the library itself), false
9282 /// otherwise. If you don't know what this is for, then set it to
9283 /// false.
9284 ///
9285 /// @return a copy of the pretty representation of an ABI artifact
9286 /// that could be either a type of a decl.
9287 string
get_pretty_representation(const type_or_decl_base_sptr & tod,bool internal)9288 get_pretty_representation(const type_or_decl_base_sptr& tod, bool internal)
9289 {return get_pretty_representation(tod.get(), internal);}
9290
9291 /// Get a copy of the pretty representation of a decl.
9292 ///
9293 /// @param d the decl to consider.
9294 ///
9295 /// @param internal set to true if the call is intended for an
9296 /// internal use (for technical use inside the library itself), false
9297 /// otherwise. If you don't know what this is for, then set it to
9298 /// false.
9299 ///
9300 /// @return the pretty representation of the decl.
9301 string
get_pretty_representation(const decl_base * d,bool internal)9302 get_pretty_representation(const decl_base* d, bool internal)
9303 {
9304 if (!d)
9305 return "";
9306 return d->get_pretty_representation(internal);
9307 }
9308
9309 /// Get a copy of the pretty representation of a type.
9310 ///
9311 /// @param d the type to consider.
9312 ///
9313 /// @param internal set to true if the call is intended for an
9314 /// internal use (for technical use inside the library itself), false
9315 /// otherwise. If you don't know what this is for, then set it to
9316 /// false.
9317 ///
9318 /// @return the pretty representation of the type.
9319 string
get_pretty_representation(const type_base * t,bool internal)9320 get_pretty_representation(const type_base* t, bool internal)
9321 {
9322 if (!t)
9323 return "void";
9324 if (const function_type* fn_type = is_function_type(t))
9325 return get_pretty_representation(fn_type, internal);
9326
9327 const decl_base* d = get_type_declaration(t);
9328 ABG_ASSERT(d);
9329 return get_pretty_representation(d, internal);
9330 }
9331
9332 /// Get a copy of the pretty representation of a decl.
9333 ///
9334 /// @param d the decl to consider.
9335 ///
9336 /// @param internal set to true if the call is intended for an
9337 /// internal use (for technical use inside the library itself), false
9338 /// otherwise. If you don't know what this is for, then set it to
9339 /// false.
9340 ///
9341 /// @return the pretty representation of the decl.
9342 string
get_pretty_representation(const decl_base_sptr & d,bool internal)9343 get_pretty_representation(const decl_base_sptr& d, bool internal)
9344 {return get_pretty_representation(d.get(), internal);}
9345
9346 /// Get a copy of the pretty representation of a type.
9347 ///
9348 /// @param d the type to consider.
9349 ///
9350 /// @param internal set to true if the call is intended for an
9351 /// internal use (for technical use inside the library itself), false
9352 /// otherwise. If you don't know what this is for, then set it to
9353 /// false.
9354 ///
9355 /// @return the pretty representation of the type.
9356 string
get_pretty_representation(const type_base_sptr & t,bool internal)9357 get_pretty_representation(const type_base_sptr& t, bool internal)
9358 {return get_pretty_representation(t.get(), internal);}
9359
9360 /// Get the pretty representation of a function type.
9361 ///
9362 /// @param fn_type the function type to consider.
9363 ///
9364 /// @param internal set to true if the call is intended for an
9365 /// internal use (for technical use inside the library itself), false
9366 /// otherwise. If you don't know what this is for, then set it to
9367 /// false.
9368 ///
9369 /// @return the string represenation of the function type.
9370 string
get_pretty_representation(const function_type_sptr & fn_type,bool internal)9371 get_pretty_representation(const function_type_sptr& fn_type,
9372 bool internal)
9373 {return get_pretty_representation(fn_type.get(), internal);}
9374
9375 /// Get the pretty representation of a function type.
9376 ///
9377 /// @param fn_type the function type to consider.
9378 ///
9379 /// @param internal set to true if the call is intended for an
9380 /// internal use (for technical use inside the library itself), false
9381 /// otherwise. If you don't know what this is for, then set it to
9382 /// false.
9383 ///
9384 /// @return the string represenation of the function type.
9385 string
get_pretty_representation(const function_type * fn_type,bool internal)9386 get_pretty_representation(const function_type* fn_type, bool internal)
9387 {
9388 if (!fn_type)
9389 return "void";
9390
9391 if (const method_type* method = is_method_type(fn_type))
9392 return get_pretty_representation(method, internal);
9393
9394 return get_pretty_representation(*fn_type, internal);
9395 }
9396
9397 /// Get the pretty representation of a function type.
9398 ///
9399 /// @param fn_type the function type to consider.
9400 ///
9401 /// @param internal set to true if the call is intended for an
9402 /// internal use (for technical use inside the library itself), false
9403 /// otherwise. If you don't know what this is for, then set it to
9404 /// false.
9405 ///
9406 /// @return the string represenation of the function type.
9407 string
get_pretty_representation(const function_type & fn_type,bool internal)9408 get_pretty_representation(const function_type& fn_type, bool internal)
9409 {
9410 std::ostringstream o;
9411 o << "function type " << get_function_type_name(fn_type, internal);
9412 return o.str();
9413 }
9414
9415 /// Get the pretty representation of a method type.
9416 ///
9417 /// @param method the method type to consider.
9418 ///
9419 /// @param internal set to true if the call is intended for an
9420 /// internal use (for technical use inside the library itself), false
9421 /// otherwise. If you don't know what this is for, then set it to
9422 /// false.
9423 ///
9424 /// @return the string represenation of the method type.
9425 string
get_pretty_representation(const method_type & method,bool internal)9426 get_pretty_representation(const method_type& method, bool internal)
9427 {
9428 std::ostringstream o;
9429 o << "method type " << get_method_type_name(method, internal);
9430 return o.str();
9431 }
9432
9433 /// Get the pretty representation of a method type.
9434 ///
9435 /// @param method the method type to consider.
9436 ///
9437 /// @param internal set to true if the call is intended for an
9438 /// internal use (for technical use inside the library itself), false
9439 /// otherwise. If you don't know what this is for, then set it to
9440 /// false.
9441 ///
9442 /// @return the string represenation of the method type.
9443 string
get_pretty_representation(const method_type * method,bool internal)9444 get_pretty_representation(const method_type* method, bool internal)
9445 {
9446 if (!method)
9447 return "void";
9448 return get_pretty_representation(*method, internal);
9449 }
9450
9451 /// Get the pretty representation of a method type.
9452 ///
9453 /// @param method the method type to consider.
9454 ///
9455 /// @param internal set to true if the call is intended for an
9456 /// internal use (for technical use inside the library itself), false
9457 /// otherwise. If you don't know what this is for, then set it to
9458 /// false.
9459 ///
9460 /// @return the string represenation of the method type.
9461 string
get_pretty_representation(const method_type_sptr method,bool internal)9462 get_pretty_representation(const method_type_sptr method, bool internal)
9463 {return get_pretty_representation(method.get(), internal);}
9464
9465 /// Get the flat representation of an instance of @ref class_or_union
9466 /// type.
9467 ///
9468 /// The flat representation of a given @ref class_or_union type is the
9469 /// actual definition of the type, for instance:
9470 ///
9471 /// struct foo {int a; char b;}
9472 ///
9473 ///@param cou the instance of @ref class_or_union to consider.
9474 ///
9475 ///@param indent the identation spaces to use in the representation.
9476 ///
9477 ///@param one_line if true, then the flat representation stands on one
9478 ///line. Otherwise, it stands on multiple lines.
9479 ///
9480 ///@return the resulting flat representation.
9481 string
get_class_or_union_flat_representation(const class_or_union & cou,const string & indent,bool one_line,bool internal,bool qualified_names)9482 get_class_or_union_flat_representation(const class_or_union& cou,
9483 const string& indent,
9484 bool one_line,
9485 bool internal,
9486 bool qualified_names)
9487 {
9488 string repr;
9489 string local_indent = " ";
9490
9491 if (class_decl* clazz = is_class_type(&cou))
9492 {
9493 repr = indent;
9494 if (!internal && clazz->is_struct())
9495 repr += "struct";
9496 else
9497 repr += "class";
9498 }
9499 else if (is_union_type(cou))
9500 repr = indent + "union";
9501 else
9502 return "";
9503
9504 repr += " ";
9505
9506 string name = cou.get_qualified_name();
9507
9508 if (!cou.get_is_anonymous())
9509 repr += name;
9510
9511 repr += "{";
9512
9513 if (!one_line)
9514 repr += "\n";
9515
9516 string real_indent;
9517 const class_or_union::data_members &dmems = cou.get_data_members();
9518 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9519 dm != dmems.end();
9520 ++dm)
9521 {
9522 if (dm != dmems.begin())
9523 {
9524 if (one_line)
9525 real_indent = " ";
9526 else
9527 real_indent = "\n" + indent + local_indent;
9528 }
9529
9530 if (var_decl_sptr v = is_anonymous_data_member(*dm))
9531 repr +=
9532 get_class_or_union_flat_representation
9533 (anonymous_data_member_to_class_or_union(*dm),
9534 real_indent, one_line, internal, qualified_names);
9535 else
9536 {
9537 if (one_line)
9538 {
9539 if (dm != dmems.begin())
9540 repr += real_indent;
9541 repr += (*dm)->get_pretty_representation(internal,
9542 qualified_names);
9543 }
9544 else
9545 repr +=
9546 real_indent+ (*dm)->get_pretty_representation(internal,
9547 qualified_names);
9548 }
9549 repr += ";";
9550 }
9551
9552 if (one_line)
9553 repr += "}";
9554 else
9555 repr += indent + "}";
9556
9557 return repr;
9558 }
9559
9560 /// Get the flat representation of an instance of @ref class_or_union
9561 /// type.
9562 ///
9563 /// The flat representation of a given @ref class_or_union type is the
9564 /// actual definition of the type, for instance:
9565 ///
9566 /// struct foo {int a; char b;}
9567 ///
9568 ///@param cou the instance of @ref class_or_union to consider.
9569 ///
9570 ///@param indent the identation spaces to use in the representation.
9571 ///
9572 ///@param one_line if true, then the flat representation stands on one
9573 ///line. Otherwise, it stands on multiple lines.
9574 ///
9575 ///@return the resulting flat representation.
9576 string
get_class_or_union_flat_representation(const class_or_union * cou,const string & indent,bool one_line,bool internal,bool qualified_names)9577 get_class_or_union_flat_representation(const class_or_union* cou,
9578 const string& indent,
9579 bool one_line,
9580 bool internal,
9581 bool qualified_names)
9582 {
9583 if (cou)
9584 return get_class_or_union_flat_representation(*cou, indent, one_line,
9585 internal, qualified_names);
9586 return "";
9587 }
9588
9589 /// Get the flat representation of an instance of @ref class_or_union
9590 /// type.
9591 ///
9592 /// The flat representation of a given @ref class_or_union type is the
9593 /// actual definition of the type, for instance:
9594 ///
9595 /// struct foo {int a; char b;}
9596 ///
9597 ///@param cou the instance of @ref class_or_union to consider.
9598 ///
9599 ///@param indent the identation spaces to use in the representation.
9600 ///
9601 ///@param one_line if true, then the flat representation stands on one
9602 ///line. Otherwise, it stands on multiple lines.
9603 ///
9604 ///@return the resulting flat representation.
9605 string
get_class_or_union_flat_representation(const class_or_union_sptr & cou,const string & indent,bool one_line,bool internal,bool qualified_names)9606 get_class_or_union_flat_representation(const class_or_union_sptr& cou,
9607 const string& indent,
9608 bool one_line,
9609 bool internal,
9610 bool qualified_names)
9611 {return get_class_or_union_flat_representation(cou.get(),
9612 indent,
9613 one_line,
9614 internal,
9615 qualified_names);}
9616
9617 /// Get the flat representation of an instance of @ref enum_type_decl
9618 /// type.
9619 ///
9620 /// The flat representation of a given @ref enum_type_decl type is the
9621 /// actual definition of the type, for instance:
9622 ///
9623 /// enum {E_0 =0, E_1 = 1}
9624 ///
9625 ///@param enum_type the enum type to consider.
9626 ///
9627 ///@param indent the identation spaces to use in the representation.
9628 ///
9629 ///@param one_line if true, then the flat representation stands on one
9630 ///line. Otherwise, it stands on multiple lines.
9631 ///
9632 ///@param qualified_names use qualified names when applicable.
9633 ///Typically, if this is true, the name of the enum is going to be
9634 ///qualified.
9635 ///
9636 ///@return the resulting flat representation.
9637 string
get_enum_flat_representation(const enum_type_decl & enum_type,const string & indent,bool one_line,bool qualified_names)9638 get_enum_flat_representation(const enum_type_decl& enum_type,
9639 const string& indent, bool one_line,
9640 bool qualified_names)
9641 {
9642 string repr;
9643 std::ostringstream o;
9644 string local_indent = " ";
9645
9646 repr = indent + "enum ";
9647
9648 if (!enum_type.get_is_anonymous())
9649 o << (qualified_names
9650 ? enum_type.get_qualified_name()
9651 : enum_type.get_name()) + " ";
9652
9653 o << "{";
9654
9655 if (!one_line)
9656 o << "\n";
9657
9658 for (const auto &enumerator : enum_type.get_sorted_enumerators())
9659 {
9660 if (!one_line)
9661 o << "\n" + indent;
9662
9663 o << enumerator.get_name() + "=" << enumerator.get_value() << ", ";
9664 }
9665
9666 if (!one_line)
9667 o << "\n" + indent << "}";
9668 else
9669 o << "}";
9670
9671 repr =o.str();
9672
9673 return repr;
9674 }
9675
9676 /// Get the flat representation of an instance of @ref enum_type_decl
9677 /// type.
9678 ///
9679 /// The flat representation of a given @ref enum_type_decl type is the
9680 /// actual definition of the type, for instance:
9681 ///
9682 /// enum {E_0 =0, E_1 = 1}
9683 ///
9684 ///@param enum_type the enum type to consider.
9685 ///
9686 ///@param indent the identation spaces to use in the representation.
9687 ///
9688 ///@param one_line if true, then the flat representation stands on one
9689 ///line. Otherwise, it stands on multiple lines.
9690 ///
9691 ///@param qualified_names use qualified names when applicable.
9692 ///Typically, if this is true, the name of the enum is going to be
9693 ///qualified.
9694 ///
9695 ///@return the resulting flat representation.
9696 string
get_enum_flat_representation(const enum_type_decl * enum_type,const string & indent,bool one_line,bool qualified_names)9697 get_enum_flat_representation(const enum_type_decl* enum_type,
9698 const string& indent, bool one_line,
9699 bool qualified_names)
9700 {
9701 if (!enum_type)
9702 return "";
9703
9704 return get_enum_flat_representation(*enum_type, indent,
9705 one_line, qualified_names);
9706 }
9707
9708 /// Get the flat representation of an instance of @ref enum_type_decl
9709 /// type.
9710 ///
9711 /// The flat representation of a given @ref enum_type_decl type is the
9712 /// actual definition of the type, for instance:
9713 ///
9714 /// enum {E_0 =0, E_1 = 1}
9715 ///
9716 ///@param enum_type the enum type to consider.
9717 ///
9718 ///@param indent the identation spaces to use in the representation.
9719 ///
9720 ///@param one_line if true, then the flat representation stands on one
9721 ///line. Otherwise, it stands on multiple lines.
9722 ///
9723 ///@param qualified_names use qualified names when applicable.
9724 ///Typically, if this is true, the name of the enum is going to be
9725 ///qualified.
9726 ///
9727 ///@return the resulting flat representation.
9728 string
get_enum_flat_representation(const enum_type_decl_sptr & enum_type,const string & indent,bool one_line,bool qualified_names)9729 get_enum_flat_representation(const enum_type_decl_sptr& enum_type,
9730 const string& indent, bool one_line,
9731 bool qualified_names)
9732 {
9733 return get_enum_flat_representation(enum_type.get(),
9734 indent, one_line,
9735 qualified_names);
9736 }
9737
9738 /// Get the flat representation of an instance of @ref enum_type_decl
9739 /// type.
9740 ///
9741 /// The flat representation of a given @ref enum_type_decl type is the
9742 /// actual definition of the type, for instance:
9743 ///
9744 /// enum {E_0 =0, E_1 = 1}
9745 ///
9746 ///@param enum_type the enum type to consider.
9747 ///
9748 ///@param indent the identation spaces to use in the representation.
9749 ///
9750 ///@param one_line if true, then the flat representation stands on one
9751 ///line. Otherwise, it stands on multiple lines.
9752 ///
9753 ///@param qualified_names use qualified names when applicable.
9754 ///Typically, if this is true, the name of the enum is going to be
9755 ///qualified.
9756 ///
9757 ///@return the resulting flat representation.
9758 string
get_class_or_enum_flat_representation(const type_base & coe,const string & indent,bool one_line,bool internal,bool qualified_name)9759 get_class_or_enum_flat_representation(const type_base& coe,
9760 const string& indent,
9761 bool one_line,
9762 bool internal,
9763 bool qualified_name)
9764
9765 {
9766 string repr;
9767 if (const class_or_union* cou = is_class_or_union_type(&coe))
9768 repr = get_class_or_union_flat_representation(cou, indent, one_line,
9769 internal, qualified_name);
9770 else if (const enum_type_decl* enom = is_enum_type(&coe))
9771 repr = get_enum_flat_representation(*enom, indent, one_line, qualified_name);
9772
9773 return repr;
9774 }
9775
9776 /// Get the textual representation of a type for debugging purposes.
9777 ///
9778 /// If the type is a class/union, this shows the data members, virtual
9779 /// member functions, size, pointer value of its canonical type, etc.
9780 /// Otherwise, this just shows the name of the artifact as returned by
9781 /// type_or_decl_base:get_pretty_representation().
9782 ///
9783 /// @param artifact the artifact to show a debugging representation of.
9784 ///
9785 /// @return a debugging string representation of @p artifact.
9786 string
get_debug_representation(const type_or_decl_base * artifact)9787 get_debug_representation(const type_or_decl_base* artifact)
9788 {
9789 if (!artifact)
9790 return string("");
9791
9792 class_or_union * c = is_class_or_union_type(artifact);
9793 if (c)
9794 {
9795 class_decl *clazz = is_class_type(c);
9796 string name = c->get_qualified_name();
9797 std::ostringstream o;
9798 if (clazz)
9799 {
9800 if (clazz->is_struct())
9801 o << "struct ";
9802 else
9803 o << "class ";
9804 }
9805 else if (is_union_type(c))
9806 o << "union ";
9807 o << name;
9808
9809 if (clazz)
9810 {
9811 if (!clazz->get_base_specifiers().empty())
9812 o << " :" << std::endl;
9813 for (auto &b : clazz->get_base_specifiers())
9814 {
9815 o << " ";
9816 if (b->get_is_virtual())
9817 o << "virtual ";
9818 o << b->get_base_class()->get_qualified_name()
9819 << std::endl;
9820 }
9821 }
9822 o << std::endl
9823 << "{"
9824 << " // size in bits: " << c->get_size_in_bits() << "\n"
9825 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
9826 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
9827 << " // translation unit: " << c->get_translation_unit()->get_absolute_path() << std::endl
9828 << " // @: " << std::hex << is_type(c)
9829 << ", @canonical: " << c->get_canonical_type().get() << std::dec
9830 << "\n\n";
9831
9832 for (auto m : c->get_data_members())
9833 {
9834 type_base_sptr t = m->get_type();
9835 t = peel_typedef_pointer_or_reference_type(t);
9836
9837 o << " "
9838 << m->get_pretty_representation(/*internal=*/false,
9839 /*qualified=*/false)
9840 << ";";
9841
9842 if (t && t->get_canonical_type())
9843 o << " // uses canonical type '@"
9844 << std::hex << t->get_canonical_type().get() << std::dec;
9845
9846 o << "'" << std::endl;
9847 }
9848
9849 if (clazz && clazz->has_vtable())
9850 {
9851 o << " // virtual member functions\n\n";
9852 for (auto f : clazz->get_virtual_mem_fns())
9853 o << " " << f->get_pretty_representation(/*internal=*/false,
9854 /*qualified=*/false)
9855 << ";" << std::endl;
9856 }
9857
9858 o << "};" << std::endl;
9859
9860 return o.str();
9861 }
9862 else if (const enum_type_decl* e = is_enum_type(artifact))
9863 {
9864 string name = e->get_qualified_name();
9865 std::ostringstream o;
9866 o << "enum " << name
9867 << " : "
9868 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9869 true)
9870 << "\n"
9871 << "{\n"
9872 << " // size in bits: " << e->get_size_in_bits() << "\n"
9873 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9874 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9875 << " // translation unit: "
9876 << e->get_translation_unit()->get_absolute_path() << "\n"
9877 << " // @: " << std::hex << is_type(e)
9878 << ", @canonical: " << e->get_canonical_type().get() << std::dec
9879 << "\n\n";
9880
9881 for (const auto &enom : e->get_enumerators())
9882 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9883
9884 o << "};\n";
9885
9886 return o.str();
9887 }
9888 return artifact->get_pretty_representation(/*internal=*/true,
9889 /*qualified=*/true);
9890 }
9891
9892 /// Get a given data member, referred to by its name, of a class type.
9893 ///
9894 /// @param clazz the class to consider.
9895 ///
9896 /// @param member_name name of the data member to get.
9897 ///
9898 /// @return the resulting data member or nullptr if none was found.
9899 var_decl_sptr
get_data_member(class_or_union * clazz,const char * member_name)9900 get_data_member(class_or_union *clazz, const char* member_name)
9901 {
9902 if (!clazz)
9903 return var_decl_sptr();
9904 return clazz->find_data_member(member_name);
9905 }
9906
9907 /// Get a given data member, referred to by its name, of a class type.
9908 ///
9909 /// @param clazz the class to consider.
9910 ///
9911 /// @param member_name name of the data member to get.
9912 ///
9913 /// @return the resulting data member or nullptr if none was found.
9914 var_decl_sptr
get_data_member(type_base * clazz,const char * member_name)9915 get_data_member(type_base *clazz, const char* member_name)
9916 {return get_data_member(is_class_or_union_type(clazz), member_name);}
9917
9918 /// Get the non-artificial (natural) location of a decl.
9919 ///
9920 /// If the decl doesn't have a natural location then return its
9921 /// artificial one.
9922 ///
9923 /// @param decl the decl to consider.
9924 ///
9925 /// @return the natural location @p decl if it has one; otherwise,
9926 /// return its artificial one.
9927 const location&
get_natural_or_artificial_location(const decl_base * decl)9928 get_natural_or_artificial_location(const decl_base* decl)
9929 {
9930 ABG_ASSERT(decl);
9931
9932 if (decl->get_location())
9933 return decl->get_location();
9934 return decl->get_artificial_location();
9935 }
9936
9937 /// Get the artificial location of a decl.
9938 ///
9939 /// If the decl doesn't have an artificial location then return its
9940 /// natural one.
9941 ///
9942 /// @param decl the decl to consider.
9943 ///
9944 /// @return the artificial location @p decl if it has one; otherwise,
9945 /// return its natural one.
9946 const location&
get_artificial_or_natural_location(const decl_base * decl)9947 get_artificial_or_natural_location(const decl_base* decl)
9948 {
9949 ABG_ASSERT(decl);
9950
9951 if (decl->has_artificial_location())
9952 return decl->get_artificial_location();
9953 return decl->get_location();
9954 }
9955
9956 /// Emit a textual representation of an artifact to std error stream
9957 /// for debugging purposes.
9958 ///
9959 /// This is useful to invoke from within a command line debugger like
9960 /// GDB to help make sense of a given ABI artifact.
9961 ///
9962 /// @param artifact the ABI artifact to emit the debugging
9963 /// representation for.
9964 ///
9965 /// @return the artifact @p artifact.
9966 type_or_decl_base*
debug(const type_or_decl_base * artifact)9967 debug(const type_or_decl_base* artifact)
9968 {
9969 std::cerr << get_debug_representation(artifact) << std::endl;
9970 return const_cast<type_or_decl_base*>(artifact);
9971 }
9972
9973 /// Emit a textual representation of an artifact to std error stream
9974 /// for debugging purposes.
9975 ///
9976 /// This is useful to invoke from within a command line debugger like
9977 /// GDB to help make sense of a given ABI artifact.
9978 ///
9979 /// @param artifact the ABI artifact to emit the debugging
9980 /// representation for.
9981 ///
9982 /// @return the artifact @p artifact.
9983 type_base*
debug(const type_base * artifact)9984 debug(const type_base* artifact)
9985 {
9986 debug(static_cast<const type_or_decl_base*>(artifact));
9987 return const_cast<type_base*>(artifact);
9988 }
9989
9990 /// Emit a textual representation of an artifact to std error stream
9991 /// for debugging purposes.
9992 ///
9993 /// This is useful to invoke from within a command line debugger like
9994 /// GDB to help make sense of a given ABI artifact.
9995 ///
9996 /// @param artifact the ABI artifact to emit the debugging
9997 /// representation for.
9998 ///
9999 /// @return the artifact @p artifact.
10000 decl_base*
debug(const decl_base * artifact)10001 debug(const decl_base* artifact)
10002 {
10003 debug(static_cast<const type_or_decl_base*>(artifact));
10004 return const_cast<decl_base*>(artifact);
10005 }
10006
10007 /// Test if two ABI artifacts are equal.
10008 ///
10009 /// This can be useful when used from the command line of a debugger
10010 /// like GDB.
10011 ///
10012 /// @param l the first ABI artifact to consider in the comparison.
10013 ///
10014 /// @param r the second ABI artifact to consider in the comparison.
10015 ///
10016 /// @return true iff @p l equals @p r.
10017 bool
debug_equals(const type_or_decl_base * l,const type_or_decl_base * r)10018 debug_equals(const type_or_decl_base *l, const type_or_decl_base *r)
10019 {
10020 if (!!l != !!r)
10021 return false;
10022 if (!l && !r)
10023 return true;
10024
10025 return (*l == *r);
10026 }
10027
10028 /// Emit a trace of a comparison operand stack.
10029 ///
10030 /// @param vect the operand stack to emit the trace for.
10031 ///
10032 /// @param o the output stream to emit the trace to.
10033 static void
debug_comp_vec(const vector<const type_base * > & vect,std::ostringstream & o)10034 debug_comp_vec(const vector<const type_base*>& vect, std::ostringstream& o)
10035 {
10036 for (auto t : vect)
10037 {
10038 o << "|" << t->get_pretty_representation()
10039 << "@" << std::hex << t << std::dec;
10040 }
10041 if (!vect.empty())
10042 o << "|";
10043 }
10044
10045 /// Construct a trace of the two comparison operand stacks.
10046 ///
10047 /// @param the environment in which the comparison operand stacks are.
10048 ///
10049 /// @return a string representing the trace.
10050 static string
print_comp_stack(const environment & env)10051 print_comp_stack(const environment& env)
10052 {
10053 std::ostringstream o;
10054 o << "left-operands: ";
10055 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10056 o << "\n" << "right-operands: ";
10057 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10058 o << "\n";
10059 return o.str();
10060 }
10061
10062 /// Emit a trace of the two comparison operands stack on the standard
10063 /// error stream.
10064 ///
10065 /// @param env the environment the comparison operands stack belong
10066 /// to.
10067 void
debug_comp_stack(const environment & env)10068 debug_comp_stack(const environment& env)
10069 {
10070 std::cerr << print_comp_stack(env);
10071 std::cerr << std::endl;
10072 }
10073
10074 /// By looking at the language of the TU a given ABI artifact belongs
10075 /// to, test if the ONE Definition Rule should apply.
10076 ///
10077 /// To date, it applies to c++, java and ada.
10078 ///
10079 /// @param artifact the ABI artifact to consider.
10080 ///
10081 /// @return true iff the One Definition Rule should apply.
10082 bool
odr_is_relevant(const type_or_decl_base & artifact)10083 odr_is_relevant(const type_or_decl_base& artifact)
10084 {
10085 translation_unit::language l =
10086 artifact.get_translation_unit()->get_language();
10087
10088 if (is_cplus_plus_language(l)
10089 || is_java_language(l)
10090 || is_ada_language(l))
10091 return true;
10092
10093 return false;
10094 }
10095
10096 /// Get the declaration for a given type.
10097 ///
10098 /// @param t the type to consider.
10099 ///
10100 /// @return the declaration for the type to return.
10101 const decl_base*
get_type_declaration(const type_base * t)10102 get_type_declaration(const type_base* t)
10103 {return dynamic_cast<const decl_base*>(t);}
10104
10105 /// Get the declaration for a given type.
10106 ///
10107 /// @param t the type to consider.
10108 ///
10109 /// @return the declaration for the type to return.
10110 decl_base*
get_type_declaration(type_base * t)10111 get_type_declaration(type_base* t)
10112 {return dynamic_cast<decl_base*>(t);}
10113
10114 /// Get the declaration for a given type.
10115 ///
10116 /// @param t the type to consider.
10117 ///
10118 /// @return the declaration for the type to return.
10119 decl_base_sptr
get_type_declaration(const type_base_sptr t)10120 get_type_declaration(const type_base_sptr t)
10121 {return dynamic_pointer_cast<decl_base>(t);}
10122
10123 /// Test if two types are equal modulo a typedef.
10124 ///
10125 /// Type A and B are compatible if
10126 ///
10127 /// - A and B are equal
10128 /// - or if one type is a typedef of the other one.
10129 ///
10130 /// @param type1 the first type to consider.
10131 ///
10132 /// @param type2 the second type to consider.
10133 ///
10134 /// @return true iff @p type1 and @p type2 are compatible.
10135 bool
types_are_compatible(const type_base_sptr type1,const type_base_sptr type2)10136 types_are_compatible(const type_base_sptr type1,
10137 const type_base_sptr type2)
10138 {
10139 if (!type1 || !type2)
10140 return false;
10141
10142 if (type1 == type2)
10143 return true;
10144
10145 // Normally we should strip typedefs entirely, but this is
10146 // potentially costly, especially on binaries with huge changesets
10147 // like the Linux Kernel. So we just get the leaf types for now.
10148 //
10149 // Maybe there should be an option by which users accepts to pay the
10150 // CPU usage toll in exchange for finer filtering?
10151
10152 // type_base_sptr t1 = strip_typedef(type1);
10153 // type_base_sptr t2 = strip_typedef(type2);
10154
10155 type_base_sptr t1 = peel_typedef_type(type1);
10156 type_base_sptr t2 = peel_typedef_type(type2);
10157
10158 return t1 == t2;
10159 }
10160
10161 /// Test if two types are equal modulo a typedef.
10162 ///
10163 /// Type A and B are compatible if
10164 ///
10165 /// - A and B are equal
10166 /// - or if one type is a typedef of the other one.
10167 ///
10168 /// @param type1 the declaration of the first type to consider.
10169 ///
10170 /// @param type2 the declaration of the second type to consider.
10171 ///
10172 /// @return true iff @p type1 and @p type2 are compatible.
10173 bool
types_are_compatible(const decl_base_sptr d1,const decl_base_sptr d2)10174 types_are_compatible(const decl_base_sptr d1,
10175 const decl_base_sptr d2)
10176 {return types_are_compatible(is_type(d1), is_type(d2));}
10177
10178 /// Return the translation unit a declaration belongs to.
10179 ///
10180 /// @param decl the declaration to consider.
10181 ///
10182 /// @return the resulting translation unit, or null if the decl is not
10183 /// yet added to a translation unit.
10184 translation_unit*
get_translation_unit(const decl_base & decl)10185 get_translation_unit(const decl_base& decl)
10186 {return const_cast<translation_unit*>(decl.get_translation_unit());}
10187
10188 /// Return the translation unit a declaration belongs to.
10189 ///
10190 /// @param decl the declaration to consider.
10191 ///
10192 /// @return the resulting translation unit, or null if the decl is not
10193 /// yet added to a translation unit.
10194 translation_unit*
get_translation_unit(const decl_base * decl)10195 get_translation_unit(const decl_base* decl)
10196 {return decl ? get_translation_unit(*decl) : 0;}
10197
10198 /// Return the translation unit a declaration belongs to.
10199 ///
10200 /// @param decl the declaration to consider.
10201 ///
10202 /// @return the resulting translation unit, or null if the decl is not
10203 /// yet added to a translation unit.
10204 translation_unit*
get_translation_unit(const shared_ptr<decl_base> decl)10205 get_translation_unit(const shared_ptr<decl_base> decl)
10206 {return get_translation_unit(decl.get());}
10207
10208 /// Tests whether if a given scope is the global scope.
10209 ///
10210 /// @param scope the scope to consider.
10211 ///
10212 /// @return true iff the current scope is the global one.
10213 bool
is_global_scope(const scope_decl & scope)10214 is_global_scope(const scope_decl& scope)
10215 {return !!dynamic_cast<const global_scope*>(&scope);}
10216
10217 /// Tests whether if a given scope is the global scope.
10218 ///
10219 /// @param scope the scope to consider.
10220 ///
10221 /// @return the @ref global_scope* representing the scope @p scope or
10222 /// 0 if @p scope is not a global scope.
10223 const global_scope*
is_global_scope(const scope_decl * scope)10224 is_global_scope(const scope_decl* scope)
10225 {return dynamic_cast<const global_scope*>(scope);}
10226
10227 /// Tests whether if a given scope is the global scope.
10228 ///
10229 /// @param scope the scope to consider.
10230 ///
10231 /// @return true iff the current scope is the global one.
10232 bool
is_global_scope(const shared_ptr<scope_decl> scope)10233 is_global_scope(const shared_ptr<scope_decl>scope)
10234 {return is_global_scope(scope.get());}
10235
10236 /// Tests whether a given declaration is at global scope.
10237 ///
10238 /// @param decl the decl to consider.
10239 ///
10240 /// @return true iff decl is at global scope.
10241 bool
is_at_global_scope(const decl_base & decl)10242 is_at_global_scope(const decl_base& decl)
10243 {return (is_global_scope(decl.get_scope()));}
10244
10245 /// Tests whether a given declaration is at global scope.
10246 ///
10247 /// @param decl the decl to consider.
10248 ///
10249 /// @return true iff decl is at global scope.
10250 bool
is_at_global_scope(const decl_base_sptr decl)10251 is_at_global_scope(const decl_base_sptr decl)
10252 {return (decl && is_global_scope(decl->get_scope()));}
10253
10254 /// Tests whether a given declaration is at global scope.
10255 ///
10256 /// @param decl the decl to consider.
10257 ///
10258 /// @return true iff decl is at global scope.
10259 bool
is_at_global_scope(const decl_base * decl)10260 is_at_global_scope(const decl_base* decl)
10261 {return is_at_global_scope(*decl);}
10262
10263 /// Tests whether a given decl is at class scope.
10264 ///
10265 /// @param decl the decl to consider.
10266 ///
10267 /// @return true iff decl is at class scope.
10268 class_or_union*
is_at_class_scope(const decl_base_sptr decl)10269 is_at_class_scope(const decl_base_sptr decl)
10270 {return is_at_class_scope(decl.get());}
10271
10272 /// Tests whether a given decl is at class scope.
10273 ///
10274 /// @param decl the decl to consider.
10275 ///
10276 /// @return true iff decl is at class scope.
10277 class_or_union*
is_at_class_scope(const decl_base * decl)10278 is_at_class_scope(const decl_base* decl)
10279 {
10280 if (!decl)
10281 return 0;
10282
10283 return is_at_class_scope(*decl);
10284 }
10285
10286 /// Tests whether a given decl is at class scope.
10287 ///
10288 /// @param decl the decl to consider.
10289 ///
10290 /// @return true iff decl is at class scope.
10291 class_or_union*
is_at_class_scope(const decl_base & decl)10292 is_at_class_scope(const decl_base& decl)
10293 {
10294 scope_decl* scope = decl.get_scope();
10295 if (class_or_union* cl = is_class_type(scope))
10296 return cl;
10297 if (class_or_union* cl = is_union_type(scope))
10298 return cl;
10299 return 0;
10300 }
10301
10302 /// Find a data member inside an anonymous data member.
10303 ///
10304 /// An anonymous data member has a type which is a class or union.
10305 /// This function looks for a data member inside the type of that
10306 /// anonymous data member.
10307 ///
10308 /// @param anon_dm the anonymous data member to consider.
10309 ///
10310 /// @param name the name of the data member to look for.
10311 var_decl_sptr
find_data_member_from_anonymous_data_member(const var_decl_sptr & anon_dm,const string & name)10312 find_data_member_from_anonymous_data_member(const var_decl_sptr& anon_dm,
10313 const string& name)
10314 {
10315 const class_or_union* containing_class_or_union =
10316 anonymous_data_member_to_class_or_union(anon_dm.get());
10317
10318 if (!containing_class_or_union)
10319 return var_decl_sptr();
10320
10321 var_decl_sptr result = containing_class_or_union->find_data_member(name);
10322 return result;
10323 }
10324
10325 /// Tests whether a given decl is at template scope.
10326 ///
10327 /// Note that only template parameters , types that are compositions,
10328 /// and template patterns (function or class) can be at template scope.
10329 ///
10330 /// @param decl the decl to consider.
10331 ///
10332 /// @return true iff the decl is at template scope.
10333 bool
is_at_template_scope(const shared_ptr<decl_base> decl)10334 is_at_template_scope(const shared_ptr<decl_base> decl)
10335 {return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
10336
10337 /// Tests whether a decl is a template parameter.
10338 ///
10339 /// @param decl the decl to consider.
10340 ///
10341 /// @return true iff decl is a template parameter.
10342 bool
is_template_parameter(const shared_ptr<decl_base> decl)10343 is_template_parameter(const shared_ptr<decl_base> decl)
10344 {
10345 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10346 || dynamic_pointer_cast<non_type_tparameter>(decl)
10347 || dynamic_pointer_cast<template_tparameter>(decl)));
10348 }
10349
10350 /// Test whether a declaration is a @ref function_decl.
10351 ///
10352 /// @param d the declaration to test for.
10353 ///
10354 /// @return a shared pointer to @ref function_decl if @p d is a @ref
10355 /// function_decl. Otherwise, a nil shared pointer.
10356 function_decl*
is_function_decl(const type_or_decl_base * d)10357 is_function_decl(const type_or_decl_base* d)
10358 {return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
10359
10360 /// Test whether a declaration is a @ref function_decl.
10361 ///
10362 /// @param d the declaration to test for.
10363 ///
10364 /// @return true if @p d is a function_decl.
10365 bool
is_function_decl(const type_or_decl_base & d)10366 is_function_decl(const type_or_decl_base& d)
10367 {return is_function_decl(&d);}
10368
10369 /// Test whether a declaration is a @ref function_decl.
10370 ///
10371 /// @param d the declaration to test for.
10372 ///
10373 /// @return a shared pointer to @ref function_decl if @p d is a @ref
10374 /// function_decl. Otherwise, a nil shared pointer.
10375 function_decl_sptr
is_function_decl(const type_or_decl_base_sptr & d)10376 is_function_decl(const type_or_decl_base_sptr& d)
10377 {return dynamic_pointer_cast<function_decl>(d);}
10378
10379 /// Test whether a declaration is a @ref function_decl.
10380 ///
10381 /// @param d the declaration to test for.
10382 ///
10383 /// @return a pointer to @ref function_decl if @p d is a @ref
10384 /// function_decl. Otherwise, a nil shared pointer.
10385 function_decl::parameter*
is_function_parameter(const type_or_decl_base * tod)10386 is_function_parameter(const type_or_decl_base* tod)
10387 {
10388 return dynamic_cast<function_decl::parameter*>
10389 (const_cast<type_or_decl_base*>(tod));
10390 }
10391
10392 /// Test whether an ABI artifact is a @ref function_decl.
10393 ///
10394 /// @param tod the declaration to test for.
10395 ///
10396 /// @return a pointer to @ref function_decl if @p d is a @ref
10397 /// function_decl. Otherwise, a nil shared pointer.
10398 function_decl::parameter_sptr
is_function_parameter(const type_or_decl_base_sptr tod)10399 is_function_parameter(const type_or_decl_base_sptr tod)
10400 {return dynamic_pointer_cast<function_decl::parameter>(tod);}
10401
10402 /// Test if an ABI artifact is a declaration.
10403 ///
10404 /// @param d the artifact to consider.
10405 ///
10406 /// @param return the declaration sub-object of @p d if it's a
10407 /// declaration, or NULL if it is not.
10408 decl_base*
is_decl(const type_or_decl_base * d)10409 is_decl(const type_or_decl_base* d)
10410 {
10411 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10412 {
10413 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10414 // The artifact is a decl-only (like a function or a
10415 // variable). That is, it's not a type that also has a
10416 // declaration. In this case, we are in the fast path and we
10417 // have a pointer to the decl sub-object handy. Just return
10418 // it ...
10419 return reinterpret_cast<decl_base*>
10420 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
10421
10422 // ... Otherwise, we are in the slow path, which is that the
10423 // artifact is a type which has a declaration. In that case,
10424 // let's use the slow dynamic_cast because we don't have the
10425 // pointer to the decl sub-object handily present.
10426 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
10427 }
10428 return 0;
10429 }
10430
10431 /// Test if an ABI artifact is a declaration.
10432 ///
10433 /// @param d the artifact to consider.
10434 ///
10435 /// @param return the declaration sub-object of @p d if it's a
10436 /// declaration, or NULL if it is not.
10437 decl_base_sptr
is_decl(const type_or_decl_base_sptr & d)10438 is_decl(const type_or_decl_base_sptr& d)
10439 {return dynamic_pointer_cast<decl_base>(d);}
10440
10441 /// Test if an ABI artifact is a declaration.
10442 ///
10443 /// This is done using a slow path that uses dynamic_cast.
10444 ///
10445 /// @param d the artifact to consider.
10446 ///
10447 /// @param return the declaration sub-object of @p d if it's a
10448 decl_base*
is_decl_slow(const type_or_decl_base * t)10449 is_decl_slow(const type_or_decl_base* t)
10450 {return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
10451
10452 /// Test if an ABI artifact is a declaration.
10453 ///
10454 /// This is done using a slow path that uses dynamic_cast.
10455 ///
10456 /// @param d the artifact to consider.
10457 ///
10458 /// @param return the declaration sub-object of @p d if it's a
10459 decl_base_sptr
is_decl_slow(const type_or_decl_base_sptr & t)10460 is_decl_slow(const type_or_decl_base_sptr& t)
10461 {return dynamic_pointer_cast<decl_base>(t);}
10462
10463 /// Test whether a declaration is a type.
10464 ///
10465 /// @param d the IR artefact to test for.
10466 ///
10467 /// @return true if the artifact is a type, false otherwise.
10468 bool
is_type(const type_or_decl_base & tod)10469 is_type(const type_or_decl_base& tod)
10470 {
10471 if (dynamic_cast<const type_base*>(&tod))
10472 return true;
10473 return false;
10474 }
10475
10476 /// Test whether a declaration is a type.
10477 ///
10478 /// @param d the IR artefact to test for.
10479 ///
10480 /// @return true if the artifact is a type, false otherwise.
10481 type_base*
is_type(const type_or_decl_base * t)10482 is_type(const type_or_decl_base* t)
10483 {
10484 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10485 return reinterpret_cast<type_base*>
10486 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
10487
10488 return 0;
10489 }
10490
10491 /// Test whether a declaration is a type.
10492 ///
10493 /// @param d the IR artefact to test for.
10494 ///
10495 /// @return true if the artifact is a type, false otherwise.
10496 type_base_sptr
is_type(const type_or_decl_base_sptr & tod)10497 is_type(const type_or_decl_base_sptr& tod)
10498 {return dynamic_pointer_cast<type_base>(tod);}
10499
10500 /// Test whether a declaration is a type.
10501 ///
10502 /// @param d the declaration to test for.
10503 ///
10504 /// @return true if the declaration is a type, false otherwise.
10505
10506 /// Test if a given type is anonymous.
10507 ///
10508 /// Note that this function considers that an anonymous class that is
10509 /// named by a typedef is not anonymous anymore. This is the C idiom:
10510 ///
10511 /// typedef struct {int member;} s_type;
10512 ///
10513 /// The typedef s_type becomes the name of the originally anonymous
10514 /// struct.
10515 ///
10516 /// @param t the type to consider.
10517 ///
10518 /// @return true iff @p t is anonymous.
10519 bool
is_anonymous_type(const type_base * t)10520 is_anonymous_type(const type_base* t)
10521 {
10522 const decl_base* d = get_type_declaration(t);
10523 if (d)
10524 if (d->get_is_anonymous())
10525 {
10526 if (class_or_union *cou = is_class_or_union_type(t))
10527 {
10528 // An anonymous class that is named by a typedef is not
10529 // considered anonymous anymore.
10530 if (!cou->get_naming_typedef())
10531 return true;
10532 }
10533 else
10534 return true;
10535 }
10536 return false;
10537 }
10538
10539 /// Test if a given type is anonymous.
10540 ///
10541 /// @param t the type to consider.
10542 ///
10543 /// @return true iff @p t is anonymous.
10544 bool
is_anonymous_type(const type_base_sptr & t)10545 is_anonymous_type(const type_base_sptr& t)
10546 {return is_anonymous_type(t.get());}
10547
10548 /// Test whether a type is a type_decl (a builtin type).
10549 ///
10550 /// @return the type_decl* for @t if it's type_decl, otherwise, return
10551 /// nil.
10552 const type_decl*
is_type_decl(const type_or_decl_base * t)10553 is_type_decl(const type_or_decl_base* t)
10554 {return dynamic_cast<const type_decl*>(t);}
10555
10556 /// Test whether a type is a type_decl (a builtin type).
10557 ///
10558 /// @return the type_decl_sptr for @t if it's type_decl, otherwise,
10559 /// return nil.
10560 type_decl_sptr
is_type_decl(const type_or_decl_base_sptr & t)10561 is_type_decl(const type_or_decl_base_sptr& t)
10562 {return dynamic_pointer_cast<type_decl>(t);}
10563
10564 /// Test if a type is an integral type.
10565 ///
10566 /// @param t the type to test.
10567 ///
10568 /// @return the integral type @p t can be converted to, or nil if @p
10569 /// is not an integral type.
10570 type_decl*
is_integral_type(const type_or_decl_base * t)10571 is_integral_type(const type_or_decl_base* t)
10572 {
10573 type_decl *type = const_cast<type_decl*>(is_type_decl(t));
10574 if (!type)
10575 return nullptr;
10576
10577 integral_type int_type;
10578 if (!parse_integral_type(type->get_name(), int_type))
10579 return nullptr;
10580
10581 return type;
10582 }
10583
10584 /// Test if a type is an integral type.
10585 ///
10586 /// @param t the type to test.
10587 ///
10588 /// @return the integral type @p t can be converted to, or nil if @p
10589 /// is not an integral type.
10590 type_decl_sptr
is_integral_type(const type_or_decl_base_sptr & t)10591 is_integral_type(const type_or_decl_base_sptr& t)
10592 {
10593 const type_decl_sptr type = is_type_decl(t);
10594 if (!type)
10595 return type_decl_sptr();
10596
10597 integral_type int_type;
10598 if (!parse_integral_type(type->get_name(), int_type))
10599 return type_decl_sptr();
10600
10601 return type;
10602 }
10603
10604 /// Test whether a type is a typedef.
10605 ///
10606 /// @param t the type to test for.
10607 ///
10608 /// @return the typedef declaration of the @p t, or NULL if it's not a
10609 /// typedef.
10610 typedef_decl_sptr
is_typedef(const type_or_decl_base_sptr t)10611 is_typedef(const type_or_decl_base_sptr t)
10612 {return dynamic_pointer_cast<typedef_decl>(t);}
10613
10614 /// Test whether a type is a typedef.
10615 ///
10616 /// @param t the declaration of the type to test for.
10617 ///
10618 /// @return the typedef declaration of the @p t, or NULL if it's not a
10619 /// typedef.
10620 const typedef_decl*
is_typedef(const type_base * t)10621 is_typedef(const type_base* t)
10622 {return dynamic_cast<const typedef_decl*>(t);}
10623
10624 /// Test whether a type is a typedef.
10625 ///
10626 /// @param t the declaration of the type to test for.
10627 ///
10628 /// @return the typedef declaration of the @p t, or NULL if it's not a
10629 /// typedef.
10630 typedef_decl*
is_typedef(type_base * t)10631 is_typedef(type_base* t)
10632 {return dynamic_cast<typedef_decl*>(t);}
10633
10634 /// Test whether a type is a typedef.
10635 ///
10636 /// @param t the declaration of the type to test for.
10637 ///
10638 /// @return the typedef declaration of the @p t, or NULL if it's not a
10639 /// typedef.
10640 const typedef_decl*
is_typedef(const type_or_decl_base * t)10641 is_typedef(const type_or_decl_base* t)
10642 {return dynamic_cast<const typedef_decl*>(t);}
10643 /// Test if a type is an enum. This function looks through typedefs.
10644 ///
10645 /// @parm t the type to consider.
10646 ///
10647 /// @return the enum_decl if @p t is an @ref enum_decl or null
10648 /// otherwise.
10649 enum_type_decl_sptr
is_compatible_with_enum_type(const type_base_sptr & t)10650 is_compatible_with_enum_type(const type_base_sptr& t)
10651 {
10652 if (!t)
10653 return enum_type_decl_sptr();
10654
10655 // Normally we should strip typedefs entirely, but this is
10656 // potentially costly, especially on binaries with huge changesets
10657 // like the Linux Kernel. So we just get the leaf types for now.
10658 //
10659 // Maybe there should be an option by which users accepts to pay the
10660 // CPU usage toll in exchange for finer filtering?
10661
10662 // type_base_sptr ty = strip_typedef(t);
10663 type_base_sptr ty = peel_typedef_type(t);;
10664 return is_enum_type(ty);
10665 }
10666
10667 /// Test if a type is an enum. This function looks through typedefs.
10668 ///
10669 /// @parm t the type to consider.
10670 ///
10671 /// @return the enum_decl if @p t is an @ref enum_decl or null
10672 /// otherwise.
10673 enum_type_decl_sptr
is_compatible_with_enum_type(const decl_base_sptr & t)10674 is_compatible_with_enum_type(const decl_base_sptr& t)
10675 {return is_compatible_with_enum_type(is_type(t));}
10676
10677 /// Test if a decl is an enum_type_decl
10678 ///
10679 /// @param d the decl to test for.
10680 ///
10681 /// @return the enum_type_decl* if @p d is an enum, nil otherwise.
10682 const enum_type_decl*
is_enum_type(const type_or_decl_base * d)10683 is_enum_type(const type_or_decl_base* d)
10684 {return dynamic_cast<const enum_type_decl*>(d);}
10685
10686 /// Test if a decl is an enum_type_decl
10687 ///
10688 /// @param d the decl to test for.
10689 ///
10690 /// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
10691 enum_type_decl_sptr
is_enum_type(const type_or_decl_base_sptr & d)10692 is_enum_type(const type_or_decl_base_sptr& d)
10693 {return dynamic_pointer_cast<enum_type_decl>(d);}
10694
10695 /// Test if a type is a class. This function looks through typedefs.
10696 ///
10697 /// @parm t the type to consider.
10698 ///
10699 /// @return the class_decl if @p t is a class_decl or null otherwise.
10700 class_decl_sptr
is_compatible_with_class_type(const type_base_sptr & t)10701 is_compatible_with_class_type(const type_base_sptr& t)
10702 {
10703 if (!t)
10704 return class_decl_sptr();
10705
10706 // Normally we should strip typedefs entirely, but this is
10707 // potentially costly, especially on binaries with huge changesets
10708 // like the Linux Kernel. So we just get the leaf types for now.
10709 //
10710 // Maybe there should be an option by which users accepts to pay the
10711 // CPU usage toll in exchange for finer filtering?
10712
10713 // type_base_sptr ty = strip_typedef(t);
10714 type_base_sptr ty = peel_typedef_type(t);
10715 return is_class_type(ty);
10716 }
10717
10718 /// Test if a type is a class. This function looks through typedefs.
10719 ///
10720 /// @parm t the type to consider.
10721 ///
10722 /// @return the class_decl if @p t is a class_decl or null otherwise.
10723 class_decl_sptr
is_compatible_with_class_type(const decl_base_sptr & t)10724 is_compatible_with_class_type(const decl_base_sptr& t)
10725 {return is_compatible_with_class_type(is_type(t));}
10726
10727 /// Test whether a type is a class.
10728 ///
10729 /// @parm t the type to consider.
10730 ///
10731 /// @return true iff @p t is a class_decl.
10732 bool
is_class_type(const type_or_decl_base & t)10733 is_class_type(const type_or_decl_base& t)
10734 {return is_class_type(&t);}
10735
10736 /// Test whether a type is a class.
10737 ///
10738 /// @parm t the type to consider.
10739 ///
10740 /// @return the class_decl if @p t is a class_decl or null otherwise.
10741 class_decl*
is_class_type(const type_or_decl_base * t)10742 is_class_type(const type_or_decl_base* t)
10743 {
10744 if (!t)
10745 return 0;
10746
10747 if (t->kind() & type_or_decl_base::CLASS_TYPE)
10748 return reinterpret_cast<class_decl*>
10749 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10750
10751 return 0;
10752 }
10753
10754 /// Test whether a type is a class.
10755 ///
10756 /// @parm t the type to consider.
10757 ///
10758 /// @return the class_decl if @p t is a class_decl or null otherwise.
10759 class_decl_sptr
is_class_type(const type_or_decl_base_sptr & d)10760 is_class_type(const type_or_decl_base_sptr& d)
10761 {return dynamic_pointer_cast<class_decl>(d);}
10762
10763 /// Test if the last data member of a class is an array with
10764 /// non-finite data member.
10765 ///
10766 /// The flexible data member idiom is a well known C idiom:
10767 /// https://en.wikipedia.org/wiki/Flexible_array_member.
10768 ///
10769 /// @param klass the class to consider.
10770 ///
10771 /// @return the data member which type is a flexible array, if any, or
10772 /// nil.
10773 var_decl_sptr
has_flexible_array_data_member(const class_decl & klass)10774 has_flexible_array_data_member(const class_decl& klass)
10775 {
10776 var_decl_sptr nil;
10777 const class_or_union::data_members& dms = klass.get_data_members();
10778 if (dms.empty())
10779 return nil;
10780
10781 if (array_type_def_sptr array = is_array_type(dms.back()->get_type()))
10782 {// The type of the last data member is an array.
10783 if (array->is_infinite())
10784 // The array has a non-finite size. We are thus looking at a
10785 // flexible array data member. Let's return it.
10786 return dms.back();
10787 }
10788
10789 return nil;
10790 }
10791
10792 /// Test if the last data member of a class is an array with
10793 /// non-finite data member.
10794 ///
10795 /// The flexible data member idiom is a well known C idiom:
10796 /// https://en.wikipedia.org/wiki/Flexible_array_member.
10797 ///
10798 /// @param klass the class to consider.
10799 ///
10800 /// @return the data member which type is a flexible array, if any, or
10801 /// nil.
10802 var_decl_sptr
has_flexible_array_data_member(const class_decl * klass)10803 has_flexible_array_data_member(const class_decl* klass)
10804 {
10805 if (!klass)
10806 return var_decl_sptr();
10807
10808 return has_flexible_array_data_member(*klass);
10809 }
10810
10811 /// Test if the last data member of a class is an array with
10812 /// non-finite data member.
10813 ///
10814 /// The flexible data member idiom is a well known C idiom:
10815 /// https://en.wikipedia.org/wiki/Flexible_array_member.
10816 ///
10817 /// @param klass the class to consider.
10818 ///
10819 /// @return the data member which type is a flexible array, if any, or
10820 /// nil.
10821 var_decl_sptr
has_flexible_array_data_member(const class_decl_sptr & klass)10822 has_flexible_array_data_member(const class_decl_sptr& klass)
10823 {return has_flexible_array_data_member(klass.get());}
10824
10825 /// Test wheter a type is a declaration-only class.
10826 ///
10827 /// @param t the type to considier.
10828 ///
10829 /// @param look_through_decl_only if true, then look through the
10830 /// decl-only class to see if it actually has a class definition in
10831 /// the same ABI corpus.
10832 ///
10833 /// @return true iff @p t is a declaration-only class.
10834 bool
is_declaration_only_class_or_union_type(const type_base * t,bool look_through_decl_only)10835 is_declaration_only_class_or_union_type(const type_base *t,
10836 bool look_through_decl_only)
10837 {
10838 if (class_or_union *klass = is_class_or_union_type(t))
10839 {
10840 if (look_through_decl_only)
10841 klass = look_through_decl_only_class(klass);
10842 return klass->get_is_declaration_only();
10843 }
10844 return false;
10845 }
10846
10847
10848 /// Test wheter a type is a declaration-only class.
10849 ///
10850 /// @param t the type to considier.
10851 ///
10852 /// @param look_through_decl_only if true, then look through the
10853 /// decl-only class to see if it actually has a class definition in
10854 /// the same ABI corpus.
10855 ///
10856 /// @return true iff @p t is a declaration-only class.
10857 bool
is_declaration_only_class_or_union_type(const type_base_sptr & t,bool look_through_decl_only)10858 is_declaration_only_class_or_union_type(const type_base_sptr& t,
10859 bool look_through_decl_only)
10860 {return is_declaration_only_class_or_union_type(t.get(), look_through_decl_only);}
10861
10862 /// Test wheter a type is a declaration-only class.
10863 ///
10864 /// @param t the type to considier.
10865 ///
10866 /// @param look_through_decl_only if true, then look through the
10867 /// decl-only class to see if it actually has a class definition in
10868 /// the same ABI corpus.
10869 ///
10870 /// @return true iff @p t is a declaration-only class.
10871 bool
is_declaration_only_class_type(const type_base_sptr & t,bool look_through_decl_only)10872 is_declaration_only_class_type(const type_base_sptr& t,
10873 bool look_through_decl_only)
10874 {return is_declaration_only_class_or_union_type(t.get(), look_through_decl_only);}
10875
10876 /// Test if a type is a @ref class_or_union.
10877 ///
10878 /// @param t the type to consider.
10879 ///
10880 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
10881 /// nil otherwise.
10882 class_or_union*
is_class_or_union_type(const type_or_decl_base * t)10883 is_class_or_union_type(const type_or_decl_base* t)
10884 {return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
10885
10886 /// Test if a type is a @ref class_or_union.
10887 ///
10888 /// @param t the type to consider.
10889 ///
10890 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
10891 /// nil otherwise.
10892 shared_ptr<class_or_union>
is_class_or_union_type(const shared_ptr<type_or_decl_base> & t)10893 is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
10894 {return dynamic_pointer_cast<class_or_union>(t);}
10895
10896 /// Test if two class or union types are of the same kind.
10897 ///
10898 /// @param first the first type to consider.
10899 ///
10900 /// @param second the second type to consider.
10901 ///
10902 /// @return true iff @p first is of the same kind as @p second.
10903 bool
class_or_union_types_of_same_kind(const class_or_union * first,const class_or_union * second)10904 class_or_union_types_of_same_kind(const class_or_union* first,
10905 const class_or_union* second)
10906 {
10907 if ((is_class_type(first) && is_class_type(second))
10908 || (is_union_type(first) && is_union_type(second)))
10909 return true;
10910
10911 return false;
10912 }
10913
10914 /// Test if two class or union types are of the same kind.
10915 ///
10916 /// @param first the first type to consider.
10917 ///
10918 /// @param second the second type to consider.
10919 ///
10920 /// @return true iff @p first is of the same kind as @p second.
10921 bool
class_or_union_types_of_same_kind(const class_or_union_sptr & first,const class_or_union_sptr & second)10922 class_or_union_types_of_same_kind(const class_or_union_sptr& first,
10923 const class_or_union_sptr& second)
10924 {return class_or_union_types_of_same_kind(first.get(), second.get());}
10925
10926 /// Test if a type is a @ref union_decl.
10927 ///
10928 /// @param t the type to consider.
10929 ///
10930 /// @return true iff @p t is a union_decl.
10931 bool
is_union_type(const type_or_decl_base & t)10932 is_union_type(const type_or_decl_base& t)
10933 {return is_union_type(&t);}
10934
10935 /// Test if a type is a @ref union_decl.
10936 ///
10937 /// @param t the type to consider.
10938 ///
10939 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
10940 /// otherwise.
10941 union_decl*
is_union_type(const type_or_decl_base * t)10942 is_union_type(const type_or_decl_base* t)
10943 {return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
10944
10945 /// Test if a type is a @ref union_decl.
10946 ///
10947 /// @param t the type to consider.
10948 ///
10949 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
10950 /// otherwise.
10951 union_decl_sptr
is_union_type(const shared_ptr<type_or_decl_base> & t)10952 is_union_type(const shared_ptr<type_or_decl_base>& t)
10953 {return dynamic_pointer_cast<union_decl>(t);}
10954
10955 /// Test whether a type is a pointer_type_def.
10956 ///
10957 /// @param t the type to test.
10958 ///
10959 /// @return the @ref pointer_type_def_sptr if @p t is a
10960 /// pointer_type_def, null otherwise.
10961 pointer_type_def*
is_pointer_type(type_or_decl_base * t)10962 is_pointer_type(type_or_decl_base* t)
10963 {
10964 if (!t)
10965 return 0;
10966
10967 if (t->kind() & type_or_decl_base::POINTER_TYPE)
10968 return reinterpret_cast<pointer_type_def*>
10969 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
10970
10971 return 0;
10972 }
10973
10974 /// Test whether a type is a pointer_type_def.
10975 ///
10976 /// @param t the type to test.
10977 ///
10978 /// @return the @ref pointer_type_def_sptr if @p t is a
10979 /// pointer_type_def, null otherwise.
10980 const pointer_type_def*
is_pointer_type(const type_or_decl_base * t)10981 is_pointer_type(const type_or_decl_base* t)
10982 {
10983 return is_pointer_type(const_cast<type_or_decl_base*>(t));
10984 }
10985
10986 /// Test whether a type is a pointer_type_def.
10987 ///
10988 /// @param t the type to test.
10989 ///
10990 /// @return the @ref pointer_type_def_sptr if @p t is a
10991 /// pointer_type_def, null otherwise.
10992 pointer_type_def_sptr
is_pointer_type(const type_or_decl_base_sptr & t)10993 is_pointer_type(const type_or_decl_base_sptr &t)
10994 {return dynamic_pointer_cast<pointer_type_def>(t);}
10995
10996
10997 /// Test if a type is a typedef, pointer or reference to a decl-only
10998 /// class/union.
10999 ///
11000 /// This looks into qualified types too.
11001 ///
11002 /// @param t the type to consider.
11003 ///
11004 /// @return true iff @p t is a type is a typedef, pointer or reference
11005 /// to a decl-only class/union.
11006 bool
is_typedef_ptr_or_ref_to_decl_only_class_or_union_type(const type_base * t)11007 is_typedef_ptr_or_ref_to_decl_only_class_or_union_type(const type_base* t)
11008 {
11009 const type_base * type =
11010 peel_typedef_pointer_or_reference_type(t, /*peel_qual_type=*/true);
11011
11012 if (is_declaration_only_class_or_union_type(type,
11013 /*look_through_decl_only=*/true))
11014 return true;
11015
11016 return false;
11017 }
11018
11019 /// Test whether a type is a reference_type_def.
11020 ///
11021 /// @param t the type to test.
11022 ///
11023 /// @return the @ref reference_type_def_sptr if @p t is a
11024 /// reference_type_def, null otherwise.
11025 reference_type_def*
is_reference_type(type_or_decl_base * t)11026 is_reference_type(type_or_decl_base* t)
11027 {return dynamic_cast<reference_type_def*>(t);}
11028
11029 /// Test whether a type is a reference_type_def.
11030 ///
11031 /// @param t the type to test.
11032 ///
11033 /// @return the @ref reference_type_def_sptr if @p t is a
11034 /// reference_type_def, null otherwise.
11035 const reference_type_def*
is_reference_type(const type_or_decl_base * t)11036 is_reference_type(const type_or_decl_base* t)
11037 {return dynamic_cast<const reference_type_def*>(t);}
11038
11039 /// Test whether a type is a reference_type_def.
11040 ///
11041 /// @param t the type to test.
11042 ///
11043 /// @return the @ref reference_type_def_sptr if @p t is a
11044 /// reference_type_def, null otherwise.
11045 reference_type_def_sptr
is_reference_type(const type_or_decl_base_sptr & t)11046 is_reference_type(const type_or_decl_base_sptr& t)
11047 {return dynamic_pointer_cast<reference_type_def>(t);}
11048
11049 /// Test if a type is equivalent to a pointer to void type.
11050 ///
11051 /// Note that this looks trough typedefs or CV qualifiers to look for
11052 /// the void pointer.
11053 ///
11054 /// @param type the type to consider.
11055 ///
11056 /// @return the actual void pointer if @p is eqivalent to a void
11057 /// pointer or NULL if it's not.
11058 const type_base*
is_void_pointer_type_equivalent(const type_base * type)11059 is_void_pointer_type_equivalent(const type_base* type)
11060 {
11061 type = peel_qualified_or_typedef_type(type);
11062
11063 const pointer_type_def * t = is_pointer_type(type);
11064 if (!t)
11065 return 0;
11066
11067 // Look through typedefs in the pointed-to type as well.
11068 type_base * ty = t->get_pointed_to_type().get();
11069 ty = peel_qualified_or_typedef_type(ty);
11070 if (ty && ty->get_environment().is_void_type(ty))
11071 return ty;
11072
11073 return 0;
11074 }
11075
11076 /// Test if a type is equivalent to a pointer to void type.
11077 ///
11078 /// Note that this looks trough typedefs or CV qualifiers to look for
11079 /// the void pointer.
11080 ///
11081 /// @param type the type to consider.
11082 ///
11083 /// @return the actual void pointer if @p is eqivalent to a void
11084 /// pointer or NULL if it's not.
11085 const type_base*
is_void_pointer_type_equivalent(const type_base & type)11086 is_void_pointer_type_equivalent(const type_base& type)
11087 {return is_void_pointer_type_equivalent(&type);}
11088
11089 /// Test if a type is a pointer to void type.
11090 ///
11091 /// @param type the type to consider.
11092 ///
11093 /// @return the actual void pointer if @p is a void pointer or NULL if
11094 /// it's not.
11095 const type_base*
is_void_pointer_type(const type_base * t)11096 is_void_pointer_type(const type_base* t)
11097 {
11098 if (!t)
11099 return nullptr;
11100
11101 if (t->get_environment().get_void_pointer_type().get() == t)
11102 return t;
11103
11104 const pointer_type_def* ptr = is_pointer_type(t);
11105 if (!ptr)
11106 return nullptr;
11107
11108 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11109 return t;
11110
11111 return nullptr;
11112 }
11113
11114 /// Test if a type is a pointer to void type.
11115 ///
11116 /// @param type the type to consider.
11117 ///
11118 /// @return the actual void pointer if @p is a void pointer or NULL if
11119 /// it's not.
11120 const type_base_sptr
is_void_pointer_type(const type_base_sptr & t)11121 is_void_pointer_type(const type_base_sptr& t)
11122 {
11123 type_base_sptr nil;
11124 if (!t)
11125 return nil;
11126
11127 if (t->get_environment().get_void_pointer_type().get() == t.get())
11128 return t;
11129
11130 pointer_type_def* ptr = is_pointer_type(t.get());
11131 if (!ptr)
11132 return nil;
11133
11134 if (t->get_environment().is_void_type(ptr->get_pointed_to_type()))
11135 return t;
11136
11137 return nil;
11138 }
11139
11140 /// Test whether a type is a reference_type_def.
11141 ///
11142 /// @param t the type to test.
11143 ///
11144 /// @return the @ref reference_type_def_sptr if @p t is a
11145 /// reference_type_def, null otherwise.
11146 qualified_type_def*
is_qualified_type(const type_or_decl_base * t)11147 is_qualified_type(const type_or_decl_base* t)
11148 {return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
11149
11150 /// Test whether a type is a qualified_type_def.
11151 ///
11152 /// @param t the type to test.
11153 ///
11154 /// @return the @ref qualified_type_def_sptr if @p t is a
11155 /// qualified_type_def, null otherwise.
11156 qualified_type_def_sptr
is_qualified_type(const type_or_decl_base_sptr & t)11157 is_qualified_type(const type_or_decl_base_sptr& t)
11158 {return dynamic_pointer_cast<qualified_type_def>(t);}
11159
11160 /// Test whether a type is a function_type.
11161 ///
11162 /// @param t the type to test.
11163 ///
11164 /// @return the @ref function_type_sptr if @p t is a
11165 /// function_type, null otherwise.
11166 function_type_sptr
is_function_type(const type_or_decl_base_sptr & t)11167 is_function_type(const type_or_decl_base_sptr& t)
11168 {return dynamic_pointer_cast<function_type>(t);}
11169
11170 /// Test whether a type is a function_type.
11171 ///
11172 /// @param t the type to test.
11173 ///
11174 /// @return the @ref function_type_sptr if @p t is a
11175 /// function_type, null otherwise.
11176 function_type*
is_function_type(type_or_decl_base * t)11177 is_function_type(type_or_decl_base* t)
11178 {return dynamic_cast<function_type*>(t);}
11179
11180 /// Test whether a type is a function_type.
11181 ///
11182 /// @param t the type to test.
11183 ///
11184 /// @return the @ref function_type_sptr if @p t is a
11185 /// function_type, null otherwise.
11186 const function_type*
is_function_type(const type_or_decl_base * t)11187 is_function_type(const type_or_decl_base* t)
11188 {return dynamic_cast<const function_type*>(t);}
11189
11190 /// Test whether a type is a method_type.
11191 ///
11192 /// @param t the type to test.
11193 ///
11194 /// @return the @ref method_type_sptr if @p t is a
11195 /// method_type, null otherwise.
11196 method_type_sptr
is_method_type(const type_or_decl_base_sptr & t)11197 is_method_type(const type_or_decl_base_sptr& t)
11198 {return dynamic_pointer_cast<method_type>(t);}
11199
11200 /// Test whether a type is a method_type.
11201 ///
11202 /// @param t the type to test.
11203 ///
11204 /// @return the @ref method_type_sptr if @p t is a
11205 /// method_type, null otherwise.
11206 const method_type*
is_method_type(const type_or_decl_base * t)11207 is_method_type(const type_or_decl_base* t)
11208 {return dynamic_cast<const method_type*>(t);}
11209
11210 /// Test whether a type is a method_type.
11211 ///
11212 /// @param t the type to test.
11213 ///
11214 /// @return the @ref method_type_sptr if @p t is a
11215 /// method_type, null otherwise.
11216 method_type*
is_method_type(type_or_decl_base * t)11217 is_method_type(type_or_decl_base* t)
11218 {return dynamic_cast<method_type*>(t);}
11219
11220 /// If a class (or union) is a decl-only class, get its definition.
11221 /// Otherwise, just return the initial class.
11222 ///
11223 /// @param the_class the class (or union) to consider.
11224 ///
11225 /// @return either the definition of the class, or the class itself.
11226 class_or_union*
look_through_decl_only_class(class_or_union * the_class)11227 look_through_decl_only_class(class_or_union* the_class)
11228 {return is_class_or_union_type(look_through_decl_only(the_class));}
11229
11230 /// If a class (or union) is a decl-only class, get its definition.
11231 /// Otherwise, just return the initial class.
11232 ///
11233 /// @param the_class the class (or union) to consider.
11234 ///
11235 /// @return either the definition of the class, or the class itself.
11236 class_or_union_sptr
look_through_decl_only_class(const class_or_union & the_class)11237 look_through_decl_only_class(const class_or_union& the_class)
11238 {return is_class_or_union_type(look_through_decl_only(the_class));}
11239
11240 /// If a class (or union) is a decl-only class, get its definition.
11241 /// Otherwise, just return the initial class.
11242 ///
11243 /// @param klass the class (or union) to consider.
11244 ///
11245 /// @return either the definition of the class, or the class itself.
11246 class_or_union_sptr
look_through_decl_only_class(class_or_union_sptr klass)11247 look_through_decl_only_class(class_or_union_sptr klass)
11248 {return is_class_or_union_type(look_through_decl_only(klass));}
11249
11250 /// If an enum is a decl-only enum, get its definition.
11251 /// Otherwise, just return the initial enum.
11252 ///
11253 /// @param the_enum the enum to consider.
11254 ///
11255 /// @return either the definition of the enum, or the enum itself.
11256 enum_type_decl_sptr
look_through_decl_only_enum(const enum_type_decl & the_enum)11257 look_through_decl_only_enum(const enum_type_decl& the_enum)
11258 {return is_enum_type(look_through_decl_only(the_enum));}
11259
11260 /// If an enum is a decl-only enum, get its definition.
11261 /// Otherwise, just return the initial enum.
11262 ///
11263 /// @param enom the enum to consider.
11264 ///
11265 /// @return either the definition of the enum, or the enum itself.
11266 enum_type_decl_sptr
look_through_decl_only_enum(enum_type_decl_sptr enom)11267 look_through_decl_only_enum(enum_type_decl_sptr enom)
11268 {return is_enum_type(look_through_decl_only(enom));}
11269
11270 /// If a decl is decl-only get its definition. Otherwise, just return nil.
11271 ///
11272 /// @param d the decl to consider.
11273 ///
11274 /// @return either the definition of the decl, or nil.
11275 decl_base_sptr
look_through_decl_only(const decl_base & d)11276 look_through_decl_only(const decl_base& d)
11277 {
11278 decl_base_sptr decl;
11279 if (d.get_is_declaration_only())
11280 decl = d.get_definition_of_declaration();
11281
11282 if (!decl)
11283 return decl;
11284
11285 while (decl->get_is_declaration_only()
11286 && decl->get_definition_of_declaration())
11287 decl = decl->get_definition_of_declaration();
11288
11289 return decl;
11290 }
11291
11292 /// If a decl is decl-only enum, get its definition. Otherwise, just
11293 /// return the initial decl.
11294 ///
11295 /// @param d the decl to consider.
11296 ///
11297 /// @return either the definition of the enum, or the decl itself.
11298 decl_base*
look_through_decl_only(decl_base * d)11299 look_through_decl_only(decl_base* d)
11300 {
11301 if (!d)
11302 return d;
11303
11304 decl_base* result = look_through_decl_only(*d).get();
11305 if (!result)
11306 result = d;
11307
11308 return result;
11309 }
11310
11311 /// If a decl is decl-only get its definition. Otherwise, just return nil.
11312 ///
11313 /// @param d the decl to consider.
11314 ///
11315 /// @return either the definition of the decl, or nil.
11316 decl_base_sptr
look_through_decl_only(const decl_base_sptr & d)11317 look_through_decl_only(const decl_base_sptr& d)
11318 {
11319 if (!d)
11320 return d;
11321
11322 decl_base_sptr result = look_through_decl_only(*d);
11323 if (!result)
11324 result = d;
11325
11326 return result;
11327 }
11328
11329 /// If a type is is decl-only, then get its definition. Otherwise,
11330 /// just return the initial type.
11331 ///
11332 /// @param d the decl to consider.
11333 ///
11334 /// @return either the definition of the decl, or the initial type.
11335 type_base*
look_through_decl_only(type_base * t)11336 look_through_decl_only(type_base* t)
11337 {
11338 decl_base* d = is_decl(t);
11339 if (!d)
11340 return t;
11341 d = look_through_decl_only(d);
11342 return is_type(d);
11343 }
11344
11345 /// If a type is is decl-only, then get its definition. Otherwise,
11346 /// just return the initial type.
11347 ///
11348 /// @param d the decl to consider.
11349 ///
11350 /// @return either the definition of the decl, or the initial type.
11351 type_base_sptr
look_through_decl_only(const type_base_sptr & t)11352 look_through_decl_only(const type_base_sptr& t)
11353 {
11354 decl_base_sptr d = is_decl(t);
11355 if (!d)
11356 return t;
11357 d = look_through_decl_only(d);
11358 return is_type(d);
11359 }
11360
11361 /// Tests if a declaration is a variable declaration.
11362 ///
11363 /// @param decl the decl to test.
11364 ///
11365 /// @return the var_decl_sptr iff decl is a variable declaration; nil
11366 /// otherwise.
11367 var_decl*
is_var_decl(const type_or_decl_base * tod)11368 is_var_decl(const type_or_decl_base* tod)
11369 {return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
11370
11371 /// Tests if a declaration is a variable declaration.
11372 ///
11373 /// @param decl the decl to test.
11374 ///
11375 /// @return the var_decl_sptr iff decl is a variable declaration; nil
11376 /// otherwise.
11377 var_decl_sptr
is_var_decl(const type_or_decl_base_sptr & decl)11378 is_var_decl(const type_or_decl_base_sptr& decl)
11379 {return dynamic_pointer_cast<var_decl>(decl);}
11380
11381 /// Tests if a declaration is a namespace declaration.
11382 ///
11383 /// @param d the decalration to consider.
11384 ///
11385 /// @return the namespace declaration if @p d is a namespace.
11386 namespace_decl_sptr
is_namespace(const decl_base_sptr & d)11387 is_namespace(const decl_base_sptr& d)
11388 {return dynamic_pointer_cast<namespace_decl>(d);}
11389
11390 /// Tests if a declaration is a namespace declaration.
11391 ///
11392 /// @param d the decalration to consider.
11393 ///
11394 /// @return the namespace declaration if @p d is a namespace.
11395 namespace_decl*
is_namespace(const decl_base * d)11396 is_namespace(const decl_base* d)
11397 {return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
11398
11399 /// Tests whether a decl is a template parameter composition type.
11400 ///
11401 /// @param decl the declaration to consider.
11402 ///
11403 /// @return true iff decl is a template parameter composition type.
11404 bool
is_template_parm_composition_type(const shared_ptr<decl_base> decl)11405 is_template_parm_composition_type(const shared_ptr<decl_base> decl)
11406 {
11407 return (decl
11408 && is_at_template_scope(decl)
11409 && is_type(decl)
11410 && !is_template_parameter(decl));
11411 }
11412
11413 /// Test whether a decl is the pattern of a function template.
11414 ///
11415 /// @param decl the decl to consider.
11416 ///
11417 /// @return true iff decl is the pattern of a function template.
11418 bool
is_function_template_pattern(const shared_ptr<decl_base> decl)11419 is_function_template_pattern(const shared_ptr<decl_base> decl)
11420 {
11421 return (decl
11422 && dynamic_pointer_cast<function_decl>(decl)
11423 && dynamic_cast<template_decl*>(decl->get_scope()));
11424 }
11425
11426 /// Test if a type is an array_type_def.
11427 ///
11428 /// @param type the type to consider.
11429 ///
11430 /// @return true iff @p type is an array_type_def.
11431 array_type_def*
is_array_type(const type_or_decl_base * type)11432 is_array_type(const type_or_decl_base* type)
11433 {return dynamic_cast<array_type_def*>(const_cast<type_or_decl_base*>(type));}
11434
11435 /// Test if a type is an array_type_def.
11436 ///
11437 /// @param type the type to consider.
11438 ///
11439 /// @return true iff @p type is an array_type_def.
11440 array_type_def_sptr
is_array_type(const type_or_decl_base_sptr & type)11441 is_array_type(const type_or_decl_base_sptr& type)
11442 {return dynamic_pointer_cast<array_type_def>(type);}
11443
11444 /// Tests if the element of a given array is a qualified type.
11445 ///
11446 /// @param array the array type to consider.
11447 ///
11448 /// @return the qualified element of the array iff it's a qualified
11449 /// type. Otherwise, return a nil object.
11450 qualified_type_def_sptr
is_array_of_qualified_element(const array_type_def_sptr & array)11451 is_array_of_qualified_element(const array_type_def_sptr& array)
11452 {
11453 if (!array)
11454 return qualified_type_def_sptr();
11455
11456 return is_qualified_type(array->get_element_type());
11457 }
11458
11459 /// Test if an array type is an array to a qualified element type.
11460 ///
11461 /// @param type the array type to consider.
11462 ///
11463 /// @return true the array @p type iff it's an array to a qualified
11464 /// element type.
11465 array_type_def_sptr
is_array_of_qualified_element(const type_base_sptr & type)11466 is_array_of_qualified_element(const type_base_sptr& type)
11467 {
11468 if (array_type_def_sptr array = is_array_type(type))
11469 if (is_array_of_qualified_element(array))
11470 return array;
11471
11472 return array_type_def_sptr();
11473 }
11474
11475 /// Test if a type is a typedef of an array.
11476 ///
11477 /// Note that the function looks through qualified and typedefs types
11478 /// of the underlying type of the current typedef. In other words, if
11479 /// we are looking at a typedef of a CV-qualified array, or at a
11480 /// typedef of a CV-qualified typedef of an array, this function will
11481 /// still return TRUE.
11482 ///
11483 /// @param t the type to consider.
11484 ///
11485 /// @return true if t is a typedef which underlying type is an array.
11486 /// That array might be either cv-qualified array or a typedef'ed
11487 /// array, or a combination of both.
11488 array_type_def_sptr
is_typedef_of_array(const type_base_sptr & t)11489 is_typedef_of_array(const type_base_sptr& t)
11490 {
11491 array_type_def_sptr result;
11492
11493 if (typedef_decl_sptr typdef = is_typedef(t))
11494 {
11495 type_base_sptr u =
11496 peel_qualified_or_typedef_type(typdef->get_underlying_type());
11497 result = is_array_type(u);
11498 }
11499
11500 return result;
11501 }
11502
11503 /// Test if a type is an array_type_def::subrange_type.
11504 ///
11505 /// @param type the type to consider.
11506 ///
11507 /// @return the array_type_def::subrange_type which @p type is a type
11508 /// of, or nil if it's not of that type.
11509 array_type_def::subrange_type*
is_subrange_type(const type_or_decl_base * type)11510 is_subrange_type(const type_or_decl_base *type)
11511 {
11512 return dynamic_cast<array_type_def::subrange_type*>
11513 (const_cast<type_or_decl_base*>(type));
11514 }
11515
11516 /// Test if a type is an array_type_def::subrange_type.
11517 ///
11518 /// @param type the type to consider.
11519 ///
11520 /// @return the array_type_def::subrange_type which @p type is a type
11521 /// of, or nil if it's not of that type.
11522 array_type_def::subrange_sptr
is_subrange_type(const type_or_decl_base_sptr & type)11523 is_subrange_type(const type_or_decl_base_sptr &type)
11524 {return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
11525
11526 /// Tests whether a decl is a template.
11527 ///
11528 /// @param decl the decl to consider.
11529 ///
11530 /// @return true iff decl is a function template, class template, or
11531 /// template template parameter.
11532 bool
is_template_decl(const decl_base_sptr & decl)11533 is_template_decl(const decl_base_sptr& decl)
11534 {return decl && dynamic_pointer_cast<template_decl>(decl);}
11535
11536 /// This enum describe the kind of entity to lookup, while using the
11537 /// lookup API.
11538 enum lookup_entity_kind
11539 {
11540 LOOKUP_ENTITY_TYPE,
11541 LOOKUP_ENTITY_VAR,
11542 };
11543
11544 /// Find the first relevant delimiter (the "::" string) in a fully
11545 /// qualified C++ type name, starting from a given position. The
11546 /// delimiter returned separates a type name from the name of its
11547 /// context.
11548 ///
11549 /// This is supposed to work correctly on names in cases like this:
11550 ///
11551 /// foo<ns1::name1, ns2::name2>
11552 ///
11553 /// In that case when called with with parameter @p begin set to 0, no
11554 /// delimiter is returned, because the type name in this case is:
11555 /// 'foo<ns1::name1, ns2::name2>'.
11556 ///
11557 /// But in this case:
11558 ///
11559 /// foo<p1, bar::name>::some_type
11560 ///
11561 /// The "::" returned is the one right before 'some_type'.
11562 ///
11563 /// @param fqn the fully qualified name of the type to consider.
11564 ///
11565 /// @param begin the position from which to look for the delimiter.
11566 ///
11567 /// @param delim_pos out parameter. Is set to the position of the
11568 /// delimiter iff the function returned true.
11569 ///
11570 /// @return true iff the function found and returned the delimiter.
11571 static bool
find_next_delim_in_cplus_type(const string & fqn,size_t begin,size_t & delim_pos)11572 find_next_delim_in_cplus_type(const string& fqn,
11573 size_t begin,
11574 size_t& delim_pos)
11575 {
11576 int angle_count = 0;
11577 bool found = false;
11578 size_t i = begin;
11579 for (; i < fqn.size(); ++i)
11580 {
11581 if (fqn[i] == '<')
11582 ++angle_count;
11583 else if (fqn[i] == '>')
11584 --angle_count;
11585 else if (i + 1 < fqn.size()
11586 && !angle_count
11587 && fqn[i] == ':'
11588 && fqn[i+1] == ':')
11589 {
11590 delim_pos = i;
11591 found = true;
11592 break;
11593 }
11594 }
11595 return found;
11596 }
11597
11598 /// Decompose a fully qualified name into the list of its components.
11599 ///
11600 /// @param fqn the fully qualified name to decompose.
11601 ///
11602 /// @param comps the resulting list of component to fill.
11603 void
fqn_to_components(const string & fqn,list<string> & comps)11604 fqn_to_components(const string& fqn,
11605 list<string>& comps)
11606 {
11607 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
11608 do
11609 {
11610 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
11611 comp_end = fqn_size;
11612
11613 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
11614 comps.push_back(comp);
11615
11616 comp_begin = comp_end + 2;
11617 if (comp_begin >= fqn_size)
11618 break;
11619 } while (true);
11620 }
11621
11622 /// Turn a set of qualified name components (that name a type) into a
11623 /// qualified name string.
11624 ///
11625 /// @param comps the name components
11626 ///
11627 /// @return the resulting string, which would be the qualified name of
11628 /// a type.
11629 string
components_to_type_name(const list<string> & comps)11630 components_to_type_name(const list<string>& comps)
11631 {
11632 string result;
11633 for (list<string>::const_iterator c = comps.begin();
11634 c != comps.end();
11635 ++c)
11636 if (c == comps.begin())
11637 result = *c;
11638 else
11639 result += "::" + *c;
11640 return result;
11641 }
11642
11643 /// This predicate returns true if a given container iterator points
11644 /// to the last element of the container, false otherwise.
11645 ///
11646 /// @tparam T the type of the container of the iterator.
11647 ///
11648 /// @param container the container the iterator points into.
11649 ///
11650 /// @param i the iterator to consider.
11651 ///
11652 /// @return true iff the iterator points to the last element of @p
11653 /// container.
11654 template<typename T>
11655 static bool
iterator_is_last(T & container,typename T::const_iterator i)11656 iterator_is_last(T& container,
11657 typename T::const_iterator i)
11658 {
11659 typename T::const_iterator next = i;
11660 ++next;
11661 return (next == container.end());
11662 }
11663
11664 //--------------------------------
11665 // <type and decls lookup stuff>
11666 // ------------------------------
11667
11668 /// Lookup all the type*s* that have a given fully qualified name.
11669 ///
11670 /// @param type_name the fully qualified name of the type to
11671 /// lookup.
11672 ///
11673 /// @param type_map the map to look into.
11674 ///
11675 /// @return the vector containing the types named @p type_name. If
11676 /// the lookup didn't yield any type, then this function returns nil.
11677 static const type_base_wptrs_type*
lookup_types_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)11678 lookup_types_in_map(const interned_string& type_name,
11679 const istring_type_base_wptrs_map_type& type_map)
11680 {
11681 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
11682 if (i != type_map.end())
11683 return &i->second;
11684 return 0;
11685 }
11686
11687 /// Lookup a type (with a given name) in a map that associates a type
11688 /// name to a type. If there are several types with a given name,
11689 /// then try to return the first one that is not decl-only.
11690 /// Otherwise, return the last of such types, that is, the last one
11691 /// that got registered.
11692 ///
11693 /// @tparam TypeKind the type of the type this function is supposed to
11694 /// return.
11695 ///
11696 /// @param type_name the name of the type to lookup.
11697 ///
11698 /// @param type_map the map in which to look.
11699 ///
11700 /// @return a shared_ptr to the type found. If no type was found or
11701 /// if the type found was not of type @p TypeKind then the function
11702 /// returns nil.
11703 template <class TypeKind>
11704 static shared_ptr<TypeKind>
lookup_type_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)11705 lookup_type_in_map(const interned_string& type_name,
11706 const istring_type_base_wptrs_map_type& type_map)
11707 {
11708 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
11709 if (i != type_map.end())
11710 {
11711 // Walk the types that have the name "type_name" and return the
11712 // first one that is not declaration-only ...
11713 for (auto j : i->second)
11714 {
11715 type_base_sptr t(j);
11716 decl_base_sptr d = is_decl(t);
11717 if (d && !d->get_is_declaration_only())
11718 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
11719 }
11720 // ... or return the last type with the name "type_name" that
11721 // was recorded. It's likely to be declaration-only if we
11722 // reached this point.
11723 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
11724 }
11725 return shared_ptr<TypeKind>();
11726 }
11727
11728 /// Lookup a basic type from a translation unit.
11729 ///
11730 /// This is done by looking the type up in the type map that is
11731 /// maintained in the translation unit. So this is as fast as
11732 /// possible.
11733 ///
11734 /// @param type_name the name of the basic type to look for.
11735 ///
11736 /// @param tu the translation unit to look into.
11737 ///
11738 /// @return the basic type found or nil if no basic type was found.
11739 type_decl_sptr
lookup_basic_type(const interned_string & type_name,const translation_unit & tu)11740 lookup_basic_type(const interned_string& type_name, const translation_unit& tu)
11741 {
11742 return lookup_type_in_map<type_decl>(type_name,
11743 tu.get_types().basic_types());
11744 }
11745
11746 /// Lookup a basic type from a translation unit.
11747 ///
11748 /// This is done by looking the type up in the type map that is
11749 /// maintained in the translation unit. So this is as fast as
11750 /// possible.
11751 ///
11752 /// @param type_name the name of the basic type to look for.
11753 ///
11754 /// @param tu the translation unit to look into.
11755 ///
11756 /// @return the basic type found or nil if no basic type was found.
11757 type_decl_sptr
lookup_basic_type(const string & type_name,const translation_unit & tu)11758 lookup_basic_type(const string& type_name, const translation_unit& tu)
11759 {
11760 const environment& env = tu.get_environment();
11761
11762 interned_string s = env.intern(type_name);
11763 return lookup_basic_type(s, tu);
11764 }
11765
11766 /// Lookup a class type from a translation unit.
11767 ///
11768 /// This is done by looking the type up in the type map that is
11769 /// maintained in the translation unit. So this is as fast as
11770 /// possible.
11771 ///
11772 /// @param fqn the fully qualified name of the class type node to look
11773 /// up.
11774 ///
11775 /// @param tu the translation unit to perform lookup from.
11776 ///
11777 /// @return the declaration of the class type IR node found, NULL
11778 /// otherwise.
11779 class_decl_sptr
lookup_class_type(const string & fqn,const translation_unit & tu)11780 lookup_class_type(const string& fqn, const translation_unit& tu)
11781 {
11782 const environment& env = tu.get_environment();
11783 interned_string s = env.intern(fqn);
11784 return lookup_class_type(s, tu);
11785 }
11786
11787 /// Lookup a class type from a translation unit.
11788 ///
11789 /// This is done by looking the type up in the type map that is
11790 /// maintained in the translation unit. So this is as fast as
11791 /// possible.
11792 ///
11793 /// @param type_name the name of the class type to look for.
11794 ///
11795 /// @param tu the translation unit to look into.
11796 ///
11797 /// @return the class type found or nil if no class type was found.
11798 class_decl_sptr
lookup_class_type(const interned_string & type_name,const translation_unit & tu)11799 lookup_class_type(const interned_string& type_name, const translation_unit& tu)
11800 {
11801 return lookup_type_in_map<class_decl>(type_name,
11802 tu.get_types().class_types());
11803 }
11804
11805 /// Lookup a union type from a translation unit.
11806 ///
11807 /// This is done by looking the type up in the type map that is
11808 /// maintained in the translation unit. So this is as fast as
11809 /// possible.
11810 ///
11811 /// @param type_name the name of the union type to look for.
11812 ///
11813 /// @param tu the translation unit to look into.
11814 ///
11815 /// @return the union type found or nil if no union type was found.
11816 union_decl_sptr
lookup_union_type(const interned_string & type_name,const translation_unit & tu)11817 lookup_union_type(const interned_string& type_name, const translation_unit& tu)
11818 {
11819 return lookup_type_in_map<union_decl>(type_name,
11820 tu.get_types().union_types());
11821 }
11822
11823 /// Lookup a union type from a translation unit.
11824 ///
11825 /// This is done by looking the type up in the type map that is
11826 /// maintained in the translation unit. So this is as fast as
11827 /// possible.
11828 ///
11829 /// @param fqn the fully qualified name of the type to lookup.
11830 ///
11831 /// @param tu the translation unit to look into.
11832 ///
11833 /// @return the union type found or nil if no union type was found.
11834 union_decl_sptr
lookup_union_type(const string & fqn,const translation_unit & tu)11835 lookup_union_type(const string& fqn, const translation_unit& tu)
11836 {
11837 const environment& env = tu.get_environment();
11838 interned_string s = env.intern(fqn);
11839 return lookup_union_type(s, tu);
11840 }
11841
11842 /// Lookup a union type in a given corpus, from its location.
11843 ///
11844 /// @param loc the location of the union type to look for.
11845 ///
11846 /// @param corp the corpus to look it from.
11847 ///
11848 /// @return the resulting union_decl.
11849 union_decl_sptr
lookup_union_type_per_location(const interned_string & loc,const corpus & corp)11850 lookup_union_type_per_location(const interned_string &loc, const corpus& corp)
11851 {
11852 const istring_type_base_wptrs_map_type& m =
11853 corp.get_type_per_loc_map().union_types();
11854 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
11855
11856 return result;
11857 }
11858
11859 /// Lookup a union type in a given corpus, from its location.
11860 ///
11861 /// @param loc the location of the union type to look for.
11862 ///
11863 /// @param corp the corpus to look it from.
11864 ///
11865 /// @return the resulting union_decl.
11866 union_decl_sptr
lookup_union_type_per_location(const string & loc,const corpus & corp)11867 lookup_union_type_per_location(const string& loc, const corpus& corp)
11868 {
11869 const environment& env = corp.get_environment();
11870 return lookup_union_type_per_location(env.intern(loc), corp);
11871 }
11872
11873 /// Lookup an enum type from a translation unit.
11874 ///
11875 /// This is done by looking the type up in the type map that is
11876 /// maintained in the translation unit. So this is as fast as
11877 /// possible.
11878 ///
11879 /// @param type_name the name of the enum type to look for.
11880 ///
11881 /// @param tu the translation unit to look into.
11882 ///
11883 /// @return the enum type found or nil if no enum type was found.
11884 enum_type_decl_sptr
lookup_enum_type(const interned_string & type_name,const translation_unit & tu)11885 lookup_enum_type(const interned_string& type_name, const translation_unit& tu)
11886 {
11887 return lookup_type_in_map<enum_type_decl>(type_name,
11888 tu.get_types().enum_types());
11889 }
11890
11891 /// Lookup an enum type from a translation unit.
11892 ///
11893 /// This is done by looking the type up in the type map that is
11894 /// maintained in the translation unit. So this is as fast as
11895 /// possible.
11896 ///
11897 /// @param type_name the name of the enum type to look for.
11898 ///
11899 /// @param tu the translation unit to look into.
11900 ///
11901 /// @return the enum type found or nil if no enum type was found.
11902 enum_type_decl_sptr
lookup_enum_type(const string & type_name,const translation_unit & tu)11903 lookup_enum_type(const string& type_name, const translation_unit& tu)
11904 {
11905 const environment& env = tu.get_environment();
11906 interned_string s = env.intern(type_name);
11907 return lookup_enum_type(s, tu);
11908 }
11909
11910 /// Lookup a typedef type from a translation unit.
11911 ///
11912 /// This is done by looking the type up in the type map that is
11913 /// maintained in the translation unit. So this is as fast as
11914 /// possible.
11915 ///
11916 /// @param type_name the name of the typedef type to look for.
11917 ///
11918 /// @param tu the translation unit to look into.
11919 ///
11920 /// @return the typedef type found or nil if no typedef type was
11921 /// found.
11922 typedef_decl_sptr
lookup_typedef_type(const interned_string & type_name,const translation_unit & tu)11923 lookup_typedef_type(const interned_string& type_name,
11924 const translation_unit& tu)
11925 {
11926 return lookup_type_in_map<typedef_decl>(type_name,
11927 tu.get_types().typedef_types());
11928 }
11929
11930 /// Lookup a typedef type from a translation unit.
11931 ///
11932 /// This is done by looking the type up in the type map that is
11933 /// maintained in the translation unit. So this is as fast as
11934 /// possible.
11935 ///
11936 /// @param type_name the name of the typedef type to look for.
11937 ///
11938 /// @param tu the translation unit to look into.
11939 ///
11940 /// @return the typedef type found or nil if no typedef type was
11941 /// found.
11942 typedef_decl_sptr
lookup_typedef_type(const string & type_name,const translation_unit & tu)11943 lookup_typedef_type(const string& type_name, const translation_unit& tu)
11944 {
11945 const environment& env = tu.get_environment();
11946 interned_string s = env.intern(type_name);
11947 return lookup_typedef_type(s, tu);
11948 }
11949
11950 /// Lookup a qualified type from a translation unit.
11951 ///
11952 /// This is done by looking the type up in the type map that is
11953 /// maintained in the translation unit. So this is as fast as
11954 /// possible.
11955 ///
11956 /// @param type_name the name of the qualified type to look for.
11957 ///
11958 /// @param tu the translation unit to look into.
11959 ///
11960 /// @return the qualified type found or nil if no qualified type was
11961 /// found.
11962 qualified_type_def_sptr
lookup_qualified_type(const interned_string & type_name,const translation_unit & tu)11963 lookup_qualified_type(const interned_string& type_name,
11964 const translation_unit& tu)
11965 {
11966 const type_maps& m = tu.get_types();
11967 return lookup_type_in_map<qualified_type_def>(type_name,
11968 m.qualified_types());
11969 }
11970
11971 /// Lookup a qualified type from a translation unit.
11972 ///
11973 /// This is done by looking the type up in the type map that is
11974 /// maintained in the translation unit. So this is as fast as
11975 /// possible.
11976 ///
11977 /// @param underlying_type the underying type of the qualified type to
11978 /// look up.
11979 ///
11980 /// @param quals the CV-qualifiers of the qualified type to look for.
11981 ///
11982 /// @param tu the translation unit to look into.
11983 ///
11984 /// @return the qualified type found or nil if no qualified type was
11985 /// found.
11986 qualified_type_def_sptr
lookup_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,const translation_unit & tu)11987 lookup_qualified_type(const type_base_sptr& underlying_type,
11988 qualified_type_def::CV quals,
11989 const translation_unit& tu)
11990 {
11991 interned_string type_name = get_name_of_qualified_type(underlying_type,
11992 quals);
11993 return lookup_qualified_type(type_name, tu);
11994 }
11995
11996 /// Lookup a pointer type from a translation unit.
11997 ///
11998 /// This is done by looking the type up in the type map that is
11999 /// maintained in the translation unit. So this is as fast as
12000 /// possible.
12001 ///
12002 /// @param type_name the name of the pointer type to look for.
12003 ///
12004 /// @param tu the translation unit to look into.
12005 ///
12006 /// @return the pointer type found or nil if no pointer type was
12007 /// found.
12008 pointer_type_def_sptr
lookup_pointer_type(const interned_string & type_name,const translation_unit & tu)12009 lookup_pointer_type(const interned_string& type_name,
12010 const translation_unit& tu)
12011 {
12012 const type_maps& m = tu.get_types();
12013 return lookup_type_in_map<pointer_type_def>(type_name,
12014 m.pointer_types());
12015 }
12016
12017 /// Lookup a pointer type from a translation unit.
12018 ///
12019 /// This is done by looking the type up in the type map that is
12020 /// maintained in the translation unit. So this is as fast as
12021 /// possible.
12022 ///
12023 /// @param type_name the name of the pointer type to look for.
12024 ///
12025 /// @param tu the translation unit to look into.
12026 ///
12027 /// @return the pointer type found or nil if no pointer type was
12028 /// found.
12029 pointer_type_def_sptr
lookup_pointer_type(const string & type_name,const translation_unit & tu)12030 lookup_pointer_type(const string& type_name, const translation_unit& tu)
12031 {
12032 const environment& env = tu.get_environment();
12033 interned_string s = env.intern(type_name);
12034 return lookup_pointer_type(s, tu);
12035 }
12036
12037 /// Lookup a pointer type from a translation unit.
12038 ///
12039 /// This is done by looking the type up in the type map that is
12040 /// maintained in the translation unit. So this is as fast as
12041 /// possible.
12042 ///
12043 /// @param pointed_to_type the pointed-to-type of the pointer to look for.
12044 ///
12045 /// @param tu the translation unit to look into.
12046 ///
12047 /// @return the pointer type found or nil if no pointer type was
12048 /// found.
12049 pointer_type_def_sptr
lookup_pointer_type(const type_base_sptr & pointed_to_type,const translation_unit & tu)12050 lookup_pointer_type(const type_base_sptr& pointed_to_type,
12051 const translation_unit& tu)
12052 {
12053 type_base_sptr t = look_through_decl_only(pointed_to_type);
12054 interned_string type_name = get_name_of_pointer_to_type(*t);
12055 return lookup_pointer_type(type_name, tu);
12056 }
12057
12058 /// Lookup a reference type from a translation unit.
12059 ///
12060 /// This is done by looking the type up in the type map that is
12061 /// maintained in the translation unit. So this is as fast as
12062 /// possible.
12063 ///
12064 /// @param type_name the name of the reference type to look for.
12065 ///
12066 /// @param tu the translation unit to look into.
12067 ///
12068 /// @return the reference type found or nil if no reference type was
12069 /// found.
12070 reference_type_def_sptr
lookup_reference_type(const interned_string & type_name,const translation_unit & tu)12071 lookup_reference_type(const interned_string& type_name,
12072 const translation_unit& tu)
12073 {
12074 const type_maps& m = tu.get_types();
12075 return lookup_type_in_map<reference_type_def>(type_name,
12076 m.reference_types());
12077 }
12078
12079 /// Lookup a reference type from a translation unit.
12080 ///
12081 /// This is done by looking the type up in the type map that is
12082 /// maintained in the translation unit. So this is as fast as
12083 /// possible.
12084 ///
12085 /// @param pointed_to_type the pointed-to-type of the reference to
12086 /// look up.
12087 ///
12088 /// @param tu the translation unit to look into.
12089 ///
12090 /// @return the reference type found or nil if no reference type was
12091 /// found.
12092 const reference_type_def_sptr
lookup_reference_type(const type_base_sptr & pointed_to_type,bool lvalue_reference,const translation_unit & tu)12093 lookup_reference_type(const type_base_sptr& pointed_to_type,
12094 bool lvalue_reference,
12095 const translation_unit& tu)
12096 {
12097 interned_string type_name =
12098 get_name_of_reference_to_type(*look_through_decl_only(pointed_to_type),
12099 lvalue_reference);
12100 return lookup_reference_type(type_name, tu);
12101 }
12102
12103 /// Lookup an array type from a translation unit.
12104 ///
12105 /// This is done by looking the type up in the type map that is
12106 /// maintained in the translation unit. So this is as fast as
12107 /// possible.
12108 ///
12109 /// @param type_name the name of the array type to look for.
12110 ///
12111 /// @param tu the translation unit to look into.
12112 ///
12113 /// @return the array type found or nil if no array type was found.
12114 array_type_def_sptr
lookup_array_type(const interned_string & type_name,const translation_unit & tu)12115 lookup_array_type(const interned_string& type_name,
12116 const translation_unit& tu)
12117 {
12118 const type_maps& m = tu.get_types();
12119 return lookup_type_in_map<array_type_def>(type_name,
12120 m.array_types());
12121 }
12122
12123 /// Lookup a function type from a translation unit.
12124 ///
12125 /// This is done by looking the type up in the type map that is
12126 /// maintained in the translation unit. So this is as fast as
12127 /// possible.
12128 ///
12129 /// @param type_name the name of the type to lookup.
12130 ///
12131 /// @param tu the translation unit to look into.
12132 ///
12133 /// @return the function type found, or NULL of none was found.
12134 function_type_sptr
lookup_function_type(const interned_string & type_name,const translation_unit & tu)12135 lookup_function_type(const interned_string& type_name,
12136 const translation_unit& tu)
12137 {
12138 const type_maps& m = tu.get_types();
12139 return lookup_type_in_map<function_type>(type_name,
12140 m.function_types());
12141 }
12142
12143 /// Lookup a function type from a translation unit.
12144 ///
12145 /// This walks all the function types held by the translation unit and
12146 /// compare their sub-type *names*. If the names match then return
12147 /// the function type found in the translation unit.
12148 ///
12149 /// @param t the function type to look for.
12150 ///
12151 /// @param tu the translation unit to look into.
12152 ///
12153 /// @return the function type found, or NULL of none was found.
12154 function_type_sptr
lookup_function_type(const function_type & t,const translation_unit & tu)12155 lookup_function_type(const function_type& t,
12156 const translation_unit& tu)
12157 {
12158 interned_string type_name = get_type_name(t);
12159 return lookup_function_type(type_name, tu);
12160 }
12161
12162 /// Lookup a function type from a translation unit.
12163 ///
12164 /// This is done by looking the type up in the type map that is
12165 /// maintained in the translation unit. So this is as fast as
12166 /// possible.
12167 ///
12168 /// @param t the function type to look for.
12169 ///
12170 /// @param tu the translation unit to look into.
12171 ///
12172 /// @return the function type found, or NULL of none was found.
12173 function_type_sptr
lookup_function_type(const function_type_sptr & t,const translation_unit & tu)12174 lookup_function_type(const function_type_sptr& t,
12175 const translation_unit& tu)
12176 {return lookup_function_type(*t, tu);}
12177
12178 /// Lookup a type in a translation unit.
12179 ///
12180 /// @param fqn the fully qualified name of the type to lookup.
12181 ///
12182 /// @param tu the translation unit to consider.
12183 ///
12184 /// @return the declaration of the type if found, NULL otherwise.
12185 const type_base_sptr
lookup_type(const interned_string & fqn,const translation_unit & tu)12186 lookup_type(const interned_string& fqn,
12187 const translation_unit& tu)
12188 {
12189 type_base_sptr result;
12190 ((result = lookup_typedef_type(fqn, tu))
12191 || (result = lookup_class_type(fqn, tu))
12192 || (result = lookup_union_type(fqn, tu))
12193 || (result = lookup_enum_type(fqn, tu))
12194 || (result = lookup_qualified_type(fqn, tu))
12195 || (result = lookup_pointer_type(fqn, tu))
12196 || (result = lookup_reference_type(fqn, tu))
12197 || (result = lookup_array_type(fqn, tu))
12198 || (result = lookup_function_type(fqn, tu))
12199 || (result = lookup_basic_type(fqn, tu)));
12200
12201 return result;
12202 }
12203
12204 /// Lookup a type in a translation unit, starting from the global
12205 /// namespace.
12206 ///
12207 /// @param fqn the fully qualified name of the type to lookup.
12208 ///
12209 /// @param tu the translation unit to consider.
12210 ///
12211 /// @return the declaration of the type if found, NULL otherwise.
12212 type_base_sptr
lookup_type(const string & fqn,const translation_unit & tu)12213 lookup_type(const string& fqn, const translation_unit& tu)
12214 {
12215 const environment&env = tu.get_environment();
12216 interned_string ifqn = env.intern(fqn);
12217 return lookup_type(ifqn, tu);
12218 }
12219
12220 /// Lookup a type from a translation unit.
12221 ///
12222 /// @param fqn the components of the fully qualified name of the node
12223 /// to look up.
12224 ///
12225 /// @param tu the translation unit to perform lookup from.
12226 ///
12227 /// @return the declaration of the IR node found, NULL otherwise.
12228 const type_base_sptr
lookup_type(const type_base_sptr type,const translation_unit & tu)12229 lookup_type(const type_base_sptr type,
12230 const translation_unit& tu)
12231 {
12232 interned_string type_name = get_type_name(type);
12233 return lookup_type(type_name, tu);
12234 }
12235
12236 /// Lookup a type in a scope.
12237 ///
12238 /// This is really slow as it walks the member types of the scope in
12239 /// sequence to find the type with a given name.
12240 ///
12241 /// If possible, users should prefer looking up types from the
12242 /// enclosing translation unit or even ABI corpus because both the
12243 /// translation unit and the corpus have a map of type, indexed by
12244 /// their name. Looking up a type from those maps is thus much
12245 /// faster.
12246 ///
12247 /// @param fqn the fully qualified name of the type to lookup.
12248 ///
12249 /// @param skope the scope to look into.
12250 ///
12251 /// @return the declaration of the type if found, NULL otherwise.
12252 const type_base_sptr
lookup_type_in_scope(const string & fqn,const scope_decl_sptr & skope)12253 lookup_type_in_scope(const string& fqn,
12254 const scope_decl_sptr& skope)
12255 {
12256 list<string> comps;
12257 fqn_to_components(fqn, comps);
12258 return lookup_type_in_scope(comps, skope);
12259 }
12260
12261 /// Lookup a @ref var_decl in a scope.
12262 ///
12263 /// @param fqn the fuly qualified name of the @var_decl to lookup.
12264 ///
12265 /// @param skope the scope to look into.
12266 ///
12267 /// @return the declaration of the @ref var_decl if found, NULL
12268 /// otherwise.
12269 const decl_base_sptr
lookup_var_decl_in_scope(const string & fqn,const scope_decl_sptr & skope)12270 lookup_var_decl_in_scope(const string& fqn,
12271 const scope_decl_sptr& skope)
12272 {
12273 list<string> comps;
12274 fqn_to_components(fqn, comps);
12275 return lookup_var_decl_in_scope(comps, skope);
12276 }
12277
12278 /// A generic function (template) to get the name of a node, whatever
12279 /// node it is. This has to be specialized for the kind of node we
12280 /// want.
12281 ///
12282 /// Note that a node is a member of a scope.
12283 ///
12284 /// @tparam NodeKind the kind of node to consider.
12285 ///
12286 /// @param node the node to get the name from.
12287 ///
12288 /// @return the name of the node.
12289 template<typename NodeKind>
12290 static const interned_string&
12291 get_node_name(shared_ptr<NodeKind> node);
12292
12293 /// Gets the name of a class_decl node.
12294 ///
12295 /// @param node the decl_base node to get the name from.
12296 ///
12297 /// @return the name of the node.
12298 template<>
12299 const interned_string&
get_node_name(class_decl_sptr node)12300 get_node_name(class_decl_sptr node)
12301 {return node->get_name();}
12302
12303 /// Gets the name of a type_base node.
12304 ///
12305 /// @param node the type_base node to get the name from.
12306 ///
12307 /// @return the name of the node.
12308 template<>
12309 const interned_string&
get_node_name(type_base_sptr node)12310 get_node_name(type_base_sptr node)
12311 {return get_type_declaration(node)->get_name();}
12312
12313 /// Gets the name of a var_decl node.
12314 ///
12315 /// @param node the var_decl node to get the name from.
12316 ///
12317 /// @return the name of the node.
12318 template<>
12319 const interned_string&
get_node_name(var_decl_sptr node)12320 get_node_name(var_decl_sptr node)
12321 {return node->get_name();}
12322
12323 /// Generic function to get the declaration of a given node, whatever
12324 /// it is. There has to be specializations for the kind of the nodes
12325 /// we want to support.
12326 ///
12327 /// @tparam NodeKind the type of the node we are looking at.
12328 ///
12329 /// @return the declaration.
12330 template<typename NodeKind>
12331 static decl_base_sptr
12332 convert_node_to_decl(shared_ptr<NodeKind> node);
12333
12334 /// Lookup a node in a given scope.
12335 ///
12336 /// @tparam the type of the node to lookup.
12337 ///
12338 /// @param fqn the components of the fully qualified name of the node
12339 /// to lookup.
12340 ///
12341 /// @param skope the scope to look into.
12342 ///
12343 /// @return the declaration of the looked up node, or NULL if it
12344 /// wasn't found.
12345 template<typename NodeKind>
12346 static const type_or_decl_base_sptr
lookup_node_in_scope(const list<string> & fqn,const scope_decl_sptr & skope)12347 lookup_node_in_scope(const list<string>& fqn,
12348 const scope_decl_sptr& skope)
12349 {
12350 type_or_decl_base_sptr resulting_decl;
12351 shared_ptr<NodeKind> node;
12352 bool it_is_last = false;
12353 scope_decl_sptr cur_scope = skope, new_scope, scope;
12354
12355 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
12356 {
12357 new_scope.reset();
12358 it_is_last = iterator_is_last(fqn, c);
12359 for (scope_decl::declarations::const_iterator m =
12360 cur_scope->get_member_decls().begin();
12361 m != cur_scope->get_member_decls().end();
12362 ++m)
12363 {
12364 if (!it_is_last)
12365 {
12366 // looking for a scope
12367 scope = dynamic_pointer_cast<scope_decl>(*m);
12368 if (scope && scope->get_name() == *c)
12369 {
12370 new_scope = scope;
12371 break;
12372 }
12373 }
12374 else
12375 {
12376 //looking for a final type.
12377 node = dynamic_pointer_cast<NodeKind>(*m);
12378 if (node && get_node_name(node) == *c)
12379 {
12380 if (class_decl_sptr cl =
12381 dynamic_pointer_cast<class_decl>(node))
12382 if (cl->get_is_declaration_only()
12383 && !cl->get_definition_of_declaration())
12384 continue;
12385 resulting_decl = node;
12386 break;
12387 }
12388 }
12389 }
12390 if (!new_scope && !resulting_decl)
12391 return decl_base_sptr();
12392 cur_scope = new_scope;
12393 }
12394 ABG_ASSERT(resulting_decl);
12395 return resulting_decl;
12396 }
12397
12398 /// lookup a type in a scope.
12399 ///
12400 ///
12401 /// This is really slow as it walks the member types of the scope in
12402 /// sequence to find the type with a given name.
12403 ///
12404 /// If possible, users should prefer looking up types from the
12405 /// enclosing translation unit or even ABI corpus because both the
12406 /// translation unit and the corpus have a map of type, indexed by
12407 /// their name. Looking up a type from those maps is thus much
12408 /// faster.
12409 ///
12410 /// @param comps the components of the fully qualified name of the
12411 /// type to lookup.
12412 ///
12413 /// @param skope the scope to look into.
12414 ///
12415 /// @return the declaration of the type found.
12416 const type_base_sptr
lookup_type_in_scope(const list<string> & comps,const scope_decl_sptr & scope)12417 lookup_type_in_scope(const list<string>& comps,
12418 const scope_decl_sptr& scope)
12419 {return is_type(lookup_node_in_scope<type_base>(comps, scope));}
12420
12421 /// lookup a type in a scope.
12422 ///
12423 /// This is really slow as it walks the member types of the scope in
12424 /// sequence to find the type with a given name.
12425 ///
12426 /// If possible, users should prefer looking up types from the
12427 /// enclosing translation unit or even ABI corpus because both the
12428 /// translation unit and the corpus have a map of type, indexed by
12429 /// their name. Looking up a type from those maps is thus much
12430 /// faster.
12431 ///
12432 /// @param type the type to look for.
12433 ///
12434 /// @param access_path a vector of scopes the path of scopes to follow
12435 /// before reaching the scope into which to look for @p type. Note
12436 /// that the deepest scope (the one immediately containing @p type) is
12437 /// at index 0 of this vector, and the top-most scope is the last
12438 /// element of the vector.
12439 ///
12440 /// @param scope the top-most scope into which to look for @p type.
12441 ///
12442 /// @return the scope found in @p scope, or NULL if it wasn't found.
12443 static const type_base_sptr
lookup_type_in_scope(const type_base & type,const vector<scope_decl * > & access_path,const scope_decl * scope)12444 lookup_type_in_scope(const type_base& type,
12445 const vector<scope_decl*>& access_path,
12446 const scope_decl* scope)
12447 {
12448 vector<scope_decl*> a = access_path;
12449 type_base_sptr result;
12450
12451 scope_decl* first_scope = 0;
12452 if (!a.empty())
12453 {
12454 first_scope = a.back();
12455 ABG_ASSERT(first_scope->get_name() == scope->get_name());
12456 a.pop_back();
12457 }
12458
12459 if (a.empty())
12460 {
12461 interned_string n = get_type_name(type, false);
12462 for (scope_decl::declarations::const_iterator i =
12463 scope->get_member_decls().begin();
12464 i != scope->get_member_decls().end();
12465 ++i)
12466 if (is_type(*i) && (*i)->get_name() == n)
12467 {
12468 result = is_type(*i);
12469 break;
12470 }
12471 }
12472 else
12473 {
12474 first_scope = a.back();
12475 interned_string scope_name, cur_scope_name = first_scope->get_name();
12476 for (scope_decl::scopes::const_iterator i =
12477 scope->get_member_scopes().begin();
12478 i != scope->get_member_scopes().end();
12479 ++i)
12480 {
12481 scope_name = (*i)->get_name();
12482 if (scope_name == cur_scope_name)
12483 {
12484 result = lookup_type_in_scope(type, a, (*i).get());
12485 break;
12486 }
12487 }
12488 }
12489 return result;
12490 }
12491
12492 /// lookup a type in a scope.
12493 ///
12494 /// This is really slow as it walks the member types of the scope in
12495 /// sequence to find the type with a given name.
12496 ///
12497 /// If possible, users should prefer looking up types from the
12498 /// enclosing translation unit or even ABI corpus because both the
12499 /// translation unit and the corpus have a map of type, indexed by
12500 /// their name. Looking up a type from those maps is thus much
12501 /// faster.
12502 ///
12503 /// @param type the type to look for.
12504 ///
12505 /// @param scope the top-most scope into which to look for @p type.
12506 ///
12507 /// @return the scope found in @p scope, or NULL if it wasn't found.
12508 static const type_base_sptr
lookup_type_in_scope(const type_base_sptr type,const scope_decl * scope)12509 lookup_type_in_scope(const type_base_sptr type,
12510 const scope_decl* scope)
12511 {
12512 if (!type || is_function_type(type))
12513 return type_base_sptr();
12514
12515 decl_base_sptr type_decl = get_type_declaration(type);
12516 ABG_ASSERT(type_decl);
12517 vector<scope_decl*> access_path;
12518 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
12519 {
12520 access_path.push_back(s);
12521 if (is_global_scope(s))
12522 break;
12523 }
12524 return lookup_type_in_scope(*type, access_path, scope);
12525 }
12526
12527 /// Lookup a type from a translation unit by walking the scopes of the
12528 /// translation unit in sequence and looking into them.
12529 ///
12530 /// This is really slow as it walks the member types of the scopes in
12531 /// sequence to find the type with a given name.
12532 ///
12533 /// If possible, users should prefer looking up types from the
12534 /// translation unit or even ABI corpus in a more direct way, by using
12535 /// the lookup_type() functins.
12536 ///
12537 ///
12538 /// This is because both the translation unit and the corpus have a
12539 /// map of types, indexed by their name. Looking up a type from those
12540 /// maps is thus much faster. @param fqn the components of the fully
12541 /// qualified name of the node to look up.
12542 ///
12543 /// @param tu the translation unit to perform lookup from.
12544 ///
12545 /// @return the declaration of the IR node found, NULL otherwise.
12546 const type_base_sptr
lookup_type_through_scopes(const type_base_sptr type,const translation_unit & tu)12547 lookup_type_through_scopes(const type_base_sptr type,
12548 const translation_unit& tu)
12549 {
12550 if (function_type_sptr fn_type = is_function_type(type))
12551 return lookup_function_type(fn_type, tu);
12552 return lookup_type_in_scope(type, tu.get_global_scope().get());
12553 }
12554
12555 /// lookup a var_decl in a scope.
12556 ///
12557 /// @param comps the components of the fully qualified name of the
12558 /// var_decl to lookup.
12559 ///
12560 /// @param skope the scope to look into.
12561 const decl_base_sptr
lookup_var_decl_in_scope(const std::list<string> & comps,const scope_decl_sptr & skope)12562 lookup_var_decl_in_scope(const std::list<string>& comps,
12563 const scope_decl_sptr& skope)
12564 {return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
12565
12566 /// Lookup an IR node from a translation unit.
12567 ///
12568 /// @tparam NodeKind the type of the IR node to lookup from the
12569 /// translation unit.
12570 ///
12571 /// @param fqn the components of the fully qualified name of the node
12572 /// to look up.
12573 ///
12574 /// @param tu the translation unit to perform lookup from.
12575 ///
12576 /// @return the declaration of the IR node found, NULL otherwise.
12577 template<typename NodeKind>
12578 static const type_or_decl_base_sptr
lookup_node_in_translation_unit(const list<string> & fqn,const translation_unit & tu)12579 lookup_node_in_translation_unit(const list<string>& fqn,
12580 const translation_unit& tu)
12581 {return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
12582
12583 /// Lookup a type from a translation unit by walking its scopes in
12584 /// sequence and by looking into them.
12585 ///
12586 /// This is much slower than using the lookup_type() function.
12587 ///
12588 /// @param fqn the components of the fully qualified name of the node
12589 /// to look up.
12590 ///
12591 /// @param tu the translation unit to perform lookup from.
12592 ///
12593 /// @return the declaration of the IR node found, NULL otherwise.
12594 type_base_sptr
lookup_type_through_scopes(const list<string> & fqn,const translation_unit & tu)12595 lookup_type_through_scopes(const list<string>& fqn,
12596 const translation_unit& tu)
12597 {return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
12598
12599
12600 /// Lookup a class type from a translation unit by walking its scopes
12601 /// in sequence and by looking into them.
12602 ///
12603 /// This is much slower than using the lookup_class_type() function
12604 /// because it walks all the scopes of the translation unit in
12605 /// sequence and lookup the types to find one that has a given name.
12606 ///
12607 /// @param fqn the components of the fully qualified name of the class
12608 /// type node to look up.
12609 ///
12610 /// @param tu the translation unit to perform lookup from.
12611 ///
12612 /// @return the declaration of the class type IR node found, NULL
12613 /// otherwise.
12614 class_decl_sptr
lookup_class_type_through_scopes(const list<string> & fqn,const translation_unit & tu)12615 lookup_class_type_through_scopes(const list<string>& fqn,
12616 const translation_unit& tu)
12617 {return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
12618
12619 /// Lookup a basic type from all the translation units of a given
12620 /// corpus.
12621 ///
12622 /// @param fqn the components of the fully qualified name of the basic
12623 /// type node to look up.
12624 ///
12625 /// @param tu the translation unit to perform lookup from.
12626 ///
12627 /// @return the declaration of the basic type IR node found, NULL
12628 /// otherwise.
12629 static type_decl_sptr
lookup_basic_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12630 lookup_basic_type_through_translation_units(const interned_string& type_name,
12631 const corpus& abi_corpus)
12632 {
12633 type_decl_sptr result;
12634
12635 for (translation_units::const_iterator tu =
12636 abi_corpus.get_translation_units().begin();
12637 tu != abi_corpus.get_translation_units().end();
12638 ++tu)
12639 if ((result = lookup_basic_type(type_name, **tu)))
12640 break;
12641
12642 return result;
12643 }
12644
12645 /// Lookup a union type from all the translation units of a given
12646 /// corpus.
12647 ///
12648 /// @param fqn the components of the fully qualified name of the union
12649 /// type node to look up.
12650 ///
12651 /// @param tu the translation unit to perform lookup from.
12652 ///
12653 /// @return the declaration of the union type IR node found, NULL
12654 /// otherwise.
12655 static union_decl_sptr
lookup_union_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12656 lookup_union_type_through_translation_units(const interned_string& type_name,
12657 const corpus & abi_corpus)
12658 {
12659 union_decl_sptr result;
12660
12661 for (translation_units::const_iterator tu =
12662 abi_corpus.get_translation_units().begin();
12663 tu != abi_corpus.get_translation_units().end();
12664 ++tu)
12665 if ((result = lookup_union_type(type_name, **tu)))
12666 break;
12667
12668 return result;
12669 }
12670
12671 /// Lookup an enum type from all the translation units of a given
12672 /// corpus.
12673 ///
12674 /// @param fqn the components of the fully qualified name of the enum
12675 /// type node to look up.
12676 ///
12677 /// @param tu the translation unit to perform lookup from.
12678 ///
12679 /// @return the declaration of the enum type IR node found, NULL
12680 /// otherwise.
12681 static enum_type_decl_sptr
lookup_enum_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12682 lookup_enum_type_through_translation_units(const interned_string& type_name,
12683 const corpus & abi_corpus)
12684 {
12685 enum_type_decl_sptr result;
12686
12687 for (translation_units::const_iterator tu =
12688 abi_corpus.get_translation_units().begin();
12689 tu != abi_corpus.get_translation_units().end();
12690 ++tu)
12691 if ((result = lookup_enum_type(type_name, **tu)))
12692 break;
12693
12694 return result;
12695 }
12696
12697 /// Lookup a typedef type definition in all the translation units of a
12698 /// given ABI corpus.
12699 ///
12700 /// @param @param qn the fully qualified name of the typedef type to lookup.
12701 ///
12702 /// @param abi_corpus the ABI corpus which to look the type up in.
12703 ///
12704 /// @return the type definition if any was found, or a NULL pointer.
12705 static typedef_decl_sptr
lookup_typedef_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12706 lookup_typedef_type_through_translation_units(const interned_string& type_name,
12707 const corpus & abi_corpus)
12708 {
12709 typedef_decl_sptr result;
12710
12711 for (translation_units::const_iterator tu =
12712 abi_corpus.get_translation_units().begin();
12713 tu != abi_corpus.get_translation_units().end();
12714 ++tu)
12715 if ((result = lookup_typedef_type(type_name, **tu)))
12716 break;
12717
12718 return result;
12719 }
12720
12721 /// Lookup a qualified type definition in all the translation units of a
12722 /// given ABI corpus.
12723 ///
12724 /// @param @param qn the fully qualified name of the qualified type to
12725 /// lookup.
12726 ///
12727 /// @param abi_corpus the ABI corpus which to look the type up in.
12728 ///
12729 /// @return the type definition if any was found, or a NULL pointer.
12730 static qualified_type_def_sptr
lookup_qualified_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)12731 lookup_qualified_type_through_translation_units(const interned_string& t_name,
12732 const corpus & abi_corpus)
12733 {
12734 qualified_type_def_sptr result;
12735
12736 for (translation_units::const_iterator tu =
12737 abi_corpus.get_translation_units().begin();
12738 tu != abi_corpus.get_translation_units().end();
12739 ++tu)
12740 if ((result = lookup_qualified_type(t_name, **tu)))
12741 break;
12742
12743 return result;
12744 }
12745
12746 /// Lookup a pointer type definition in all the translation units of a
12747 /// given ABI corpus.
12748 ///
12749 /// @param @param qn the fully qualified name of the pointer type to
12750 /// lookup.
12751 ///
12752 /// @param abi_corpus the ABI corpus which to look the type up in.
12753 ///
12754 /// @return the type definition if any was found, or a NULL pointer.
12755 static pointer_type_def_sptr
lookup_pointer_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12756 lookup_pointer_type_through_translation_units(const interned_string& type_name,
12757 const corpus & abi_corpus)
12758 {
12759 pointer_type_def_sptr result;
12760
12761 for (translation_units::const_iterator tu =
12762 abi_corpus.get_translation_units().begin();
12763 tu != abi_corpus.get_translation_units().end();
12764 ++tu)
12765 if ((result = lookup_pointer_type(type_name, **tu)))
12766 break;
12767
12768 return result;
12769 }
12770
12771 /// Lookup a reference type definition in all the translation units of a
12772 /// given ABI corpus.
12773 ///
12774 /// @param @param qn the fully qualified name of the reference type to
12775 /// lookup.
12776 ///
12777 /// @param abi_corpus the ABI corpus which to look the type up in.
12778 ///
12779 /// @return the type definition if any was found, or a NULL pointer.
12780 static reference_type_def_sptr
lookup_reference_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)12781 lookup_reference_type_through_translation_units(const interned_string& t_name,
12782 const corpus & abi_corpus)
12783 {
12784 reference_type_def_sptr result;
12785
12786 for (translation_units::const_iterator tu =
12787 abi_corpus.get_translation_units().begin();
12788 tu != abi_corpus.get_translation_units().end();
12789 ++tu)
12790 if ((result = lookup_reference_type(t_name, **tu)))
12791 break;
12792
12793 return result;
12794 }
12795
12796 /// Lookup a array type definition in all the translation units of a
12797 /// given ABI corpus.
12798 ///
12799 /// @param @param qn the fully qualified name of the array type to
12800 /// lookup.
12801 ///
12802 /// @param abi_corpus the ABI corpus which to look the type up in.
12803 ///
12804 /// @return the type definition if any was found, or a NULL pointer.
12805 static array_type_def_sptr
lookup_array_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12806 lookup_array_type_through_translation_units(const interned_string& type_name,
12807 const corpus & abi_corpus)
12808 {
12809 array_type_def_sptr result;
12810
12811 for (translation_units::const_iterator tu =
12812 abi_corpus.get_translation_units().begin();
12813 tu != abi_corpus.get_translation_units().end();
12814 ++tu)
12815 if ((result = lookup_array_type(type_name, **tu)))
12816 break;
12817
12818 return result;
12819 }
12820
12821 /// Lookup a function type definition in all the translation units of
12822 /// a given ABI corpus.
12823 ///
12824 /// @param @param qn the fully qualified name of the function type to
12825 /// lookup.
12826 ///
12827 /// @param abi_corpus the ABI corpus which to look the type up in.
12828 ///
12829 /// @return the type definition if any was found, or a NULL pointer.
12830 static function_type_sptr
lookup_function_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)12831 lookup_function_type_through_translation_units(const interned_string& type_name,
12832 const corpus & abi_corpus)
12833 {
12834 function_type_sptr result;
12835
12836 for (translation_units::const_iterator tu =
12837 abi_corpus.get_translation_units().begin();
12838 tu != abi_corpus.get_translation_units().end();
12839 ++tu)
12840 if ((result = lookup_function_type(type_name, **tu)))
12841 break;
12842
12843 return result;
12844 }
12845
12846 /// Lookup a type definition in all the translation units of a given
12847 /// ABI corpus.
12848 ///
12849 /// @param @param qn the fully qualified name of the type to lookup.
12850 ///
12851 /// @param abi_corpus the ABI corpus which to look the type up in.
12852 ///
12853 /// @return the type definition if any was found, or a NULL pointer.
12854 type_base_sptr
lookup_type_through_translation_units(const string & qn,const corpus & abi_corpus)12855 lookup_type_through_translation_units(const string& qn,
12856 const corpus& abi_corpus)
12857 {
12858 type_base_sptr result;
12859
12860 for (translation_units::const_iterator tu =
12861 abi_corpus.get_translation_units().begin();
12862 tu != abi_corpus.get_translation_units().end();
12863 ++tu)
12864 if ((result = lookup_type(qn, **tu)))
12865 break;
12866
12867 return result;
12868 }
12869
12870 /// Lookup a type from a given translation unit present in a give corpus.
12871 ///
12872 /// @param type_name the name of the type to look for.
12873 ///
12874 /// @parm tu_path the path of the translation unit to consider.
12875 ///
12876 /// @param corp the corpus to consider.
12877 ///
12878 /// @return the resulting type, if any.
12879 type_base_sptr
lookup_type_from_translation_unit(const string & type_name,const string & tu_path,const corpus & corp)12880 lookup_type_from_translation_unit(const string& type_name,
12881 const string& tu_path,
12882 const corpus& corp)
12883 {
12884 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
12885 if (i == corp.priv_->path_tu_map.end())
12886 return type_base_sptr();
12887
12888 translation_unit_sptr tu = i->second;
12889 ABG_ASSERT(tu);
12890
12891 type_base_sptr t = lookup_type(type_name, *tu);
12892 return t;
12893 }
12894
12895 /// Look into an ABI corpus for a function type.
12896 ///
12897 /// @param fn_type the function type to be looked for in the ABI
12898 /// corpus.
12899 ///
12900 /// @param corpus the ABI corpus into which to look for the function
12901 /// type.
12902 ///
12903 /// @return the function type found in the corpus.
12904 function_type_sptr
lookup_or_synthesize_fn_type(const function_type_sptr & fn_t,const corpus & corpus)12905 lookup_or_synthesize_fn_type(const function_type_sptr& fn_t,
12906 const corpus& corpus)
12907 {
12908 ABG_ASSERT(fn_t);
12909
12910 function_type_sptr result;
12911
12912 if ((result = lookup_function_type(fn_t, corpus)))
12913 return result;
12914
12915 for (translation_units::const_iterator i =
12916 corpus.get_translation_units().begin();
12917 i != corpus.get_translation_units().end();
12918 ++i)
12919 if ((result = synthesize_function_type_from_translation_unit(*fn_t,
12920 **i)))
12921 return result;
12922
12923 return result;
12924 }
12925
12926 /// Look into a given corpus to find a type which has the same
12927 /// qualified name as a giventype.
12928 ///
12929 /// If the per-corpus type map is non-empty (because the corpus allows
12930 /// the One Definition Rule) then the type islooked up in that
12931 /// per-corpus type map. Otherwise, the type is looked-up in each
12932 /// translation unit.
12933 ///
12934 /// @param t the type which has the same qualified name as the type we
12935 /// are looking for.
12936 ///
12937 /// @param corp the ABI corpus to look into for the type.
12938 type_decl_sptr
lookup_basic_type(const type_decl & t,const corpus & corp)12939 lookup_basic_type(const type_decl& t, const corpus& corp)
12940 {return lookup_basic_type(t.get_name(), corp);}
12941
12942 /// Look into a given corpus to find a basic type which has a given
12943 /// qualified name.
12944 ///
12945 /// If the per-corpus type map is non-empty (because the corpus allows
12946 /// the One Definition Rule) then the type islooked up in that
12947 /// per-corpus type map. Otherwise, the type is looked-up in each
12948 /// translation unit.
12949 ///
12950 /// @param qualified_name the qualified name of the basic type to look
12951 /// for.
12952 ///
12953 /// @param corp the corpus to look into.
12954 type_decl_sptr
lookup_basic_type(const interned_string & qualified_name,const corpus & corp)12955 lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
12956 {
12957 const istring_type_base_wptrs_map_type& m = corp.get_types().basic_types();
12958 type_decl_sptr result;
12959
12960 if (!m.empty())
12961 result = lookup_type_in_map<type_decl>(qualified_name, m);
12962 else
12963 result = lookup_basic_type_through_translation_units(qualified_name, corp);
12964
12965 return result;
12966 }
12967
12968 /// Lookup a @ref type_decl type from a given corpus, by its location.
12969 ///
12970 /// @param loc the location to consider.
12971 ///
12972 /// @param corp the corpus to consider.
12973 ///
12974 /// @return the resulting basic type, if any.
12975 type_decl_sptr
lookup_basic_type_per_location(const interned_string & loc,const corpus & corp)12976 lookup_basic_type_per_location(const interned_string &loc,
12977 const corpus &corp)
12978 {
12979 const istring_type_base_wptrs_map_type& m =
12980 corp.get_type_per_loc_map().basic_types();
12981 type_decl_sptr result;
12982
12983 result = lookup_type_in_map<type_decl>(loc, m);
12984
12985 return result;
12986 }
12987
12988 /// Lookup a @ref type_decl type from a given corpus, by its location.
12989 ///
12990 /// @param loc the location to consider.
12991 ///
12992 /// @param corp the corpus to consider.
12993 ///
12994 /// @return the resulting basic type, if any.
12995 type_decl_sptr
lookup_basic_type_per_location(const string & loc,const corpus & corp)12996 lookup_basic_type_per_location(const string &loc, const corpus &corp)
12997 {
12998 const environment& env = corp.get_environment();
12999 return lookup_basic_type_per_location(env.intern(loc), corp);
13000 }
13001
13002 /// Look into a given corpus to find a basic type which has a given
13003 /// qualified name.
13004 ///
13005 /// If the per-corpus type map is non-empty (because the corpus allows
13006 /// the One Definition Rule) then the type islooked up in that
13007 /// per-corpus type map. Otherwise, the type is looked-up in each
13008 /// translation unit.
13009 ///
13010 /// @param qualified_name the qualified name of the basic type to look
13011 /// for.
13012 ///
13013 /// @param corp the corpus to look into.
13014 type_decl_sptr
lookup_basic_type(const string & qualified_name,const corpus & corp)13015 lookup_basic_type(const string& qualified_name, const corpus& corp)
13016 {
13017 return lookup_basic_type(corp.get_environment().intern(qualified_name),
13018 corp);
13019 }
13020
13021 /// Look into a given corpus to find a class type which has the same
13022 /// qualified name as a given type.
13023 ///
13024 /// If the per-corpus type map is non-empty (because the corpus allows
13025 /// the One Definition Rule) then the type islooked up in that
13026 /// per-corpus type map. Otherwise, the type is looked-up in each
13027 /// translation unit.
13028 ///
13029 /// @param t the class decl type which has the same qualified name as
13030 /// the type we are looking for.
13031 ///
13032 /// @param corp the corpus to look into.
13033 class_decl_sptr
lookup_class_type(const class_decl & t,const corpus & corp)13034 lookup_class_type(const class_decl& t, const corpus& corp)
13035 {
13036 interned_string s = get_type_name(t);
13037 return lookup_class_type(s, corp);
13038 }
13039
13040 /// Look into a given corpus to find a class type which has a given
13041 /// qualified name.
13042 ///
13043 /// If the per-corpus type map is non-empty (because the corpus allows
13044 /// the One Definition Rule) then the type islooked up in that
13045 /// per-corpus type map. Otherwise, the type is looked-up in each
13046 /// translation unit.
13047 ///
13048 /// @param qualified_name the qualified name of the type to look for.
13049 ///
13050 /// @param corp the corpus to look into.
13051 class_decl_sptr
lookup_class_type(const string & qualified_name,const corpus & corp)13052 lookup_class_type(const string& qualified_name, const corpus& corp)
13053 {
13054 interned_string s = corp.get_environment().intern(qualified_name);
13055 return lookup_class_type(s, corp);
13056 }
13057
13058 /// Look into a given corpus to find a class type which has a given
13059 /// qualified name.
13060 ///
13061 /// If the per-corpus type map is non-empty (because the corpus allows
13062 /// the One Definition Rule) then the type islooked up in that
13063 /// per-corpus type map. Otherwise, the type is looked-up in each
13064 /// translation unit.
13065 ///
13066 /// @param qualified_name the qualified name of the type to look for.
13067 ///
13068 /// @param corp the corpus to look into.
13069 class_decl_sptr
lookup_class_type(const interned_string & qualified_name,const corpus & corp)13070 lookup_class_type(const interned_string& qualified_name, const corpus& corp)
13071 {
13072 const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
13073
13074 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13075
13076 return result;
13077 }
13078
13079 /// Look into a given corpus to find the class type*s* that have a
13080 /// given qualified name.
13081 ///
13082 /// @param qualified_name the qualified name of the type to look for.
13083 ///
13084 /// @param corp the corpus to look into.
13085 ///
13086 /// @return the vector of class types named @p qualified_name.
13087 const type_base_wptrs_type *
lookup_class_types(const interned_string & qualified_name,const corpus & corp)13088 lookup_class_types(const interned_string& qualified_name, const corpus& corp)
13089 {
13090 const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
13091
13092 return lookup_types_in_map(qualified_name, m);
13093 }
13094
13095 /// Look into a given corpus to find the class type*s* that have a
13096 /// given qualified name and that are declaration-only.
13097 ///
13098 /// @param qualified_name the qualified name of the type to look for.
13099 ///
13100 /// @param corp the corpus to look into.
13101 ///
13102 /// @param result the vector of decl-only class types named @p
13103 /// qualified_name. This is populated iff the function returns true.
13104 ///
13105 /// @return true iff @p result was populated with the decl-only
13106 /// classes named @p qualified_name.
13107 bool
lookup_decl_only_class_types(const interned_string & qualified_name,const corpus & corp,type_base_wptrs_type & result)13108 lookup_decl_only_class_types(const interned_string& qualified_name,
13109 const corpus& corp,
13110 type_base_wptrs_type& result)
13111 {
13112 const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
13113
13114 const type_base_wptrs_type *v = lookup_types_in_map(qualified_name, m);
13115 if (!v)
13116 return false;
13117
13118 for (auto type : *v)
13119 {
13120 type_base_sptr t(type);
13121 class_decl_sptr c = is_class_type(t);
13122 if (c->get_is_declaration_only()
13123 && !c->get_definition_of_declaration())
13124 result.push_back(type);
13125 }
13126
13127 return !result.empty();
13128 }
13129
13130 /// Look into a given corpus to find the union type*s* that have a
13131 /// given qualified name.
13132 ///
13133 /// @param qualified_name the qualified name of the type to look for.
13134 ///
13135 /// @param corp the corpus to look into.
13136 ///
13137 /// @return the vector of union types named @p qualified_name.
13138 const type_base_wptrs_type *
lookup_union_types(const interned_string & qualified_name,const corpus & corp)13139 lookup_union_types(const interned_string& qualified_name, const corpus& corp)
13140 {
13141 const istring_type_base_wptrs_map_type& m = corp.get_types().union_types();
13142
13143 return lookup_types_in_map(qualified_name, m);
13144 }
13145
13146 /// Look into a given corpus to find the class type*s* that have a
13147 /// given qualified name.
13148 ///
13149 /// @param qualified_name the qualified name of the type to look for.
13150 ///
13151 /// @param corp the corpus to look into.
13152 ///
13153 /// @return the vector of class types which name is @p qualified_name.
13154 const type_base_wptrs_type*
lookup_class_types(const string & qualified_name,const corpus & corp)13155 lookup_class_types(const string& qualified_name, const corpus& corp)
13156 {
13157 interned_string s = corp.get_environment().intern(qualified_name);
13158 return lookup_class_types(s, corp);
13159 }
13160
13161 /// Look into a given corpus to find the union types that have a given
13162 /// qualified name.
13163 ///
13164 /// @param qualified_name the qualified name of the type to look for.
13165 ///
13166 /// @param corp the corpus to look into.
13167 ///
13168 /// @return the vector of union types which name is @p qualified_name.
13169 const type_base_wptrs_type *
lookup_union_types(const string & qualified_name,const corpus & corp)13170 lookup_union_types(const string& qualified_name, const corpus& corp)
13171 {
13172 interned_string s = corp.get_environment().intern(qualified_name);
13173 return lookup_union_types(s, corp);
13174 }
13175
13176 /// Look up a @ref class_decl from a given corpus by its location.
13177 ///
13178 /// @param loc the location to consider.
13179 ///
13180 /// @param corp the corpus to consider.
13181 ///
13182 /// @return the resulting class decl, if any.
13183 class_decl_sptr
lookup_class_type_per_location(const interned_string & loc,const corpus & corp)13184 lookup_class_type_per_location(const interned_string& loc,
13185 const corpus& corp)
13186 {
13187 const istring_type_base_wptrs_map_type& m =
13188 corp.get_type_per_loc_map().class_types();
13189 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
13190
13191 return result;
13192 }
13193
13194 /// Look up a @ref class_decl from a given corpus by its location.
13195 ///
13196 /// @param loc the location to consider.
13197 ///
13198 /// @param corp the corpus to consider.
13199 ///
13200 /// @return the resulting class decl, if any.
13201 class_decl_sptr
lookup_class_type_per_location(const string & loc,const corpus & corp)13202 lookup_class_type_per_location(const string &loc, const corpus &corp)
13203 {
13204 const environment& env = corp.get_environment();
13205 return lookup_class_type_per_location(env.intern(loc), corp);
13206 }
13207
13208 /// Look into a given corpus to find a union type which has a given
13209 /// qualified name.
13210 ///
13211 /// If the per-corpus type map is non-empty (because the corpus allows
13212 /// the One Definition Rule) then the type islooked up in that
13213 /// per-corpus type map. Otherwise, the type is looked-up in each
13214 /// translation unit.
13215 ///
13216 /// @param qualified_name the qualified name of the type to look for.
13217 ///
13218 /// @param corp the corpus to look into.
13219 union_decl_sptr
lookup_union_type(const interned_string & type_name,const corpus & corp)13220 lookup_union_type(const interned_string& type_name, const corpus& corp)
13221 {
13222 const istring_type_base_wptrs_map_type& m = corp.get_types().union_types();
13223
13224 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13225 if (!result)
13226 result = lookup_union_type_through_translation_units(type_name, corp);
13227
13228 return result;
13229 }
13230
13231 /// Look into a given corpus to find a union type which has a given
13232 /// qualified name.
13233 ///
13234 /// If the per-corpus type map is non-empty (because the corpus allows
13235 /// the One Definition Rule) then the type islooked up in that
13236 /// per-corpus type map. Otherwise, the type is looked-up in each
13237 /// translation unit.
13238 ///
13239 /// @param qualified_name the qualified name of the type to look for.
13240 ///
13241 /// @param corp the corpus to look into.
13242 union_decl_sptr
lookup_union_type(const string & type_name,const corpus & corp)13243 lookup_union_type(const string& type_name, const corpus& corp)
13244 {
13245 interned_string s = corp.get_environment().intern(type_name);
13246 return lookup_union_type(s, corp);
13247 }
13248
13249 /// Look into a given corpus to find an enum type which has the same
13250 /// qualified name as a given enum type.
13251 ///
13252 /// If the per-corpus type map is non-empty (because the corpus allows
13253 /// the One Definition Rule) then the type islooked up in that
13254 /// per-corpus type map. Otherwise, the type is looked-up in each
13255 /// translation unit.
13256 ///
13257 /// @param t the enum type which has the same qualified name as the
13258 /// type we are looking for.
13259 ///
13260 /// @param corp the corpus to look into.
13261 enum_type_decl_sptr
lookup_enum_type(const enum_type_decl & t,const corpus & corp)13262 lookup_enum_type(const enum_type_decl& t, const corpus& corp)
13263 {
13264 interned_string s = get_type_name(t);
13265 return lookup_enum_type(s, corp);
13266 }
13267
13268 /// Look into a given corpus to find an enum type which has a given
13269 /// qualified name.
13270 ///
13271 /// If the per-corpus type map is non-empty (because the corpus allows
13272 /// the One Definition Rule) then the type islooked up in that
13273 /// per-corpus type map. Otherwise, the type is looked-up in each
13274 /// translation unit.
13275 ///
13276 /// @param qualified_name the qualified name of the enum type to look
13277 /// for.
13278 ///
13279 /// @param corp the corpus to look into.
13280 enum_type_decl_sptr
lookup_enum_type(const string & qualified_name,const corpus & corp)13281 lookup_enum_type(const string& qualified_name, const corpus& corp)
13282 {
13283 interned_string s = corp.get_environment().intern(qualified_name);
13284 return lookup_enum_type(s, corp);
13285 }
13286
13287 /// Look into a given corpus to find an enum type which has a given
13288 /// qualified name.
13289 ///
13290 /// If the per-corpus type map is non-empty (because the corpus allows
13291 /// the One Definition Rule) then the type islooked up in that
13292 /// per-corpus type map. Otherwise, the type is looked-up in each
13293 /// translation unit.
13294 ///
13295 /// @param qualified_name the qualified name of the enum type to look
13296 /// for.
13297 ///
13298 /// @param corp the corpus to look into.
13299 enum_type_decl_sptr
lookup_enum_type(const interned_string & qualified_name,const corpus & corp)13300 lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
13301 {
13302 const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
13303
13304 enum_type_decl_sptr result =
13305 lookup_type_in_map<enum_type_decl>(qualified_name, m);
13306 if (!result)
13307 result = lookup_enum_type_through_translation_units(qualified_name, corp);
13308
13309 return result;
13310 }
13311
13312 /// Look into a given corpus to find the enum type*s* that have a
13313 /// given qualified name.
13314 ///
13315 /// @param qualified_name the qualified name of the type to look for.
13316 ///
13317 /// @param corp the corpus to look into.
13318 ///
13319 /// @return the vector of enum types that which name is @p qualified_name.
13320 const type_base_wptrs_type *
lookup_enum_types(const interned_string & qualified_name,const corpus & corp)13321 lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
13322 {
13323 const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
13324
13325 return lookup_types_in_map(qualified_name, m);
13326 }
13327
13328 /// Look into a given corpus to find the enum type*s* that have a
13329 /// given qualified name.
13330 ///
13331 /// @param qualified_name the qualified name of the type to look for.
13332 ///
13333 /// @param corp the corpus to look into.
13334 ///
13335 /// @return the vector of enum types that which name is @p qualified_name.
13336 const type_base_wptrs_type*
lookup_enum_types(const string & qualified_name,const corpus & corp)13337 lookup_enum_types(const string& qualified_name, const corpus& corp)
13338 {
13339 interned_string s = corp.get_environment().intern(qualified_name);
13340 return lookup_enum_types(s, corp);
13341 }
13342
13343 /// Look up an @ref enum_type_decl from a given corpus, by its location.
13344 ///
13345 /// @param loc the location to consider.
13346 ///
13347 /// @param corp the corpus to look the type from.
13348 ///
13349 /// @return the resulting enum type, if any.
13350 enum_type_decl_sptr
lookup_enum_type_per_location(const interned_string & loc,const corpus & corp)13351 lookup_enum_type_per_location(const interned_string &loc, const corpus& corp)
13352 {
13353 const istring_type_base_wptrs_map_type& m =
13354 corp.get_type_per_loc_map().enum_types();
13355 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
13356
13357 return result;
13358 }
13359
13360 /// Look up an @ref enum_type_decl from a given corpus, by its location.
13361 ///
13362 /// @param loc the location to consider.
13363 ///
13364 /// @param corp the corpus to look the type from.
13365 ///
13366 /// @return the resulting enum type, if any.
13367 enum_type_decl_sptr
lookup_enum_type_per_location(const string & loc,const corpus & corp)13368 lookup_enum_type_per_location(const string &loc, const corpus &corp)
13369 {
13370 const environment& env = corp.get_environment();
13371 return lookup_enum_type_per_location(env.intern(loc), corp);
13372 }
13373
13374 /// Look into a given corpus to find a typedef type which has the
13375 /// same qualified name as a given typedef type.
13376 ///
13377 /// If the per-corpus type map is non-empty (because the corpus allows
13378 /// the One Definition Rule) then the type islooked up in that
13379 /// per-corpus type map. Otherwise, the type is looked-up in each
13380 /// translation unit.
13381 ///
13382 /// @param t the typedef type which has the same qualified name as the
13383 /// typedef type we are looking for.
13384 ///
13385 /// @param corp the corpus to look into.
13386 typedef_decl_sptr
lookup_typedef_type(const typedef_decl & t,const corpus & corp)13387 lookup_typedef_type(const typedef_decl& t, const corpus& corp)
13388 {
13389 interned_string s = get_type_name(t);
13390 return lookup_typedef_type(s, corp);
13391 }
13392
13393 /// Look into a given corpus to find a typedef type which has the
13394 /// same qualified name as a given typedef type.
13395 ///
13396 /// If the per-corpus type map is non-empty (because the corpus allows
13397 /// the One Definition Rule) then the type islooked up in that
13398 /// per-corpus type map. Otherwise, the type is looked-up in each
13399 /// translation unit.
13400 ///
13401 /// @param t the typedef type which has the same qualified name as the
13402 /// typedef type we are looking for.
13403 ///
13404 /// @param corp the corpus to look into.
13405 typedef_decl_sptr
lookup_typedef_type(const string & qualified_name,const corpus & corp)13406 lookup_typedef_type(const string& qualified_name, const corpus& corp)
13407 {
13408 interned_string s = corp.get_environment().intern(qualified_name);
13409 return lookup_typedef_type(s, corp);
13410 }
13411
13412 /// Look into a given corpus to find a typedef type which has a
13413 /// given qualified name.
13414 ///
13415 /// If the per-corpus type map is non-empty (because the corpus allows
13416 /// the One Definition Rule) then the type islooked up in that
13417 /// per-corpus type map. Otherwise, the type is looked-up in each
13418 /// translation unit.
13419 ///
13420 /// @param qualified_name the qualified name of the typedef type to
13421 /// look for.
13422 ///
13423 /// @param corp the corpus to look into.
13424 typedef_decl_sptr
lookup_typedef_type(const interned_string & qualified_name,const corpus & corp)13425 lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
13426 {
13427 const istring_type_base_wptrs_map_type& m = corp.get_types().typedef_types();
13428
13429 typedef_decl_sptr result =
13430 lookup_type_in_map<typedef_decl>(qualified_name, m);
13431 if (!result)
13432 result = lookup_typedef_type_through_translation_units(qualified_name,
13433 corp);
13434
13435 return result;
13436 }
13437
13438 /// Lookup a @ref typedef_decl from a corpus, by its location.
13439 ///
13440 /// @param loc the location to consider.
13441 ///
13442 /// @param corp the corpus to consider.
13443 ///
13444 /// @return the typedef_decl found, if any.
13445 typedef_decl_sptr
lookup_typedef_type_per_location(const interned_string & loc,const corpus & corp)13446 lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
13447 {
13448 const istring_type_base_wptrs_map_type& m =
13449 corp.get_type_per_loc_map().typedef_types();
13450 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
13451
13452 return result;
13453 }
13454
13455 /// Lookup a @ref typedef_decl from a corpus, by its location.
13456 ///
13457 /// @param loc the location to consider.
13458 ///
13459 /// @param corp the corpus to consider.
13460 ///
13461 /// @return the typedef_decl found, if any.
13462 typedef_decl_sptr
lookup_typedef_type_per_location(const string & loc,const corpus & corp)13463 lookup_typedef_type_per_location(const string &loc, const corpus &corp)
13464 {
13465 const environment& env = corp.get_environment();
13466 return lookup_typedef_type_per_location(env.intern(loc), corp);
13467 }
13468
13469 /// Look into a corpus to find a class, union or typedef type which
13470 /// has a given qualified name.
13471 ///
13472 /// If the per-corpus type map is non-empty (because the corpus allows
13473 /// the One Definition Rule) then the type islooked up in that
13474 /// per-corpus type map. Otherwise, the type is looked-up in each
13475 /// translation unit.
13476 ///
13477 /// @param qualified_name the name of the type to find.
13478 ///
13479 /// @param corp the corpus to look into.
13480 ///
13481 /// @return the typedef or class type found.
13482 type_base_sptr
lookup_class_or_typedef_type(const string & qualified_name,const corpus & corp)13483 lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
13484 {
13485 type_base_sptr result = lookup_class_type(qualified_name, corp);
13486 if (!result)
13487 result = lookup_union_type(qualified_name, corp);
13488
13489 if (!result)
13490 result = lookup_typedef_type(qualified_name, corp);
13491 return result;
13492 }
13493
13494 /// Look into a corpus to find a class, typedef or enum type which has
13495 /// a given qualified name.
13496 ///
13497 /// If the per-corpus type map is non-empty (because the corpus allows
13498 /// the One Definition Rule) then the type islooked up in that
13499 /// per-corpus type map. Otherwise, the type is looked-up in each
13500 /// translation unit.
13501 ///
13502 /// @param qualified_name the qualified name of the type to look for.
13503 ///
13504 /// @param corp the corpus to look into.
13505 ///
13506 /// @return the typedef, class or enum type found.
13507 type_base_sptr
lookup_class_typedef_or_enum_type(const string & qualified_name,const corpus & corp)13508 lookup_class_typedef_or_enum_type(const string& qualified_name,
13509 const corpus& corp)
13510 {
13511 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
13512 if (!result)
13513 result = lookup_enum_type(qualified_name, corp);
13514
13515 return result;
13516 }
13517
13518 /// Look into a given corpus to find a qualified type which has the
13519 /// same qualified name as a given type.
13520 ///
13521 /// @param t the type which has the same qualified name as the
13522 /// qualified type we are looking for.
13523 ///
13524 /// @param corp the corpus to look into.
13525 ///
13526 /// @return the qualified type found.
13527 qualified_type_def_sptr
lookup_qualified_type(const qualified_type_def & t,const corpus & corp)13528 lookup_qualified_type(const qualified_type_def& t, const corpus& corp)
13529 {
13530 interned_string s = get_type_name(t);
13531 return lookup_qualified_type(s, corp);
13532 }
13533
13534 /// Look into a given corpus to find a qualified type which has a
13535 /// given qualified name.
13536 ///
13537 /// @param qualified_name the qualified name of the type to look for.
13538 ///
13539 /// @param corp the corpus to look into.
13540 ///
13541 /// @return the type found.
13542 qualified_type_def_sptr
lookup_qualified_type(const interned_string & qualified_name,const corpus & corp)13543 lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
13544 {
13545 const istring_type_base_wptrs_map_type& m =
13546 corp.get_types().qualified_types();
13547
13548 qualified_type_def_sptr result =
13549 lookup_type_in_map<qualified_type_def>(qualified_name, m);
13550
13551 if (!result)
13552 result = lookup_qualified_type_through_translation_units(qualified_name,
13553 corp);
13554
13555 return result;
13556 }
13557
13558 /// Look into a given corpus to find a pointer type which has the same
13559 /// qualified name as a given pointer type.
13560 ///
13561 /// @param t the pointer type which has the same qualified name as the
13562 /// type we are looking for.
13563 ///
13564 /// @param corp the corpus to look into.
13565 ///
13566 /// @return the pointer type found.
13567 pointer_type_def_sptr
lookup_pointer_type(const pointer_type_def & t,const corpus & corp)13568 lookup_pointer_type(const pointer_type_def& t, const corpus& corp)
13569 {
13570 interned_string s = get_type_name(t);
13571 return lookup_pointer_type(s, corp);
13572 }
13573
13574 /// Look into a given corpus to find a pointer type which has a given
13575 /// qualified name.
13576 ///
13577 /// If the per-corpus type map is non-empty (because the corpus allows
13578 /// the One Definition Rule) then the type islooked up in that
13579 /// per-corpus type map. Otherwise, the type is looked-up in each
13580 /// translation unit.
13581 ///
13582 /// @param qualified_name the qualified name of the pointer type to
13583 /// look for.
13584 ///
13585 /// @param corp the corpus to look into.
13586 ///
13587 /// @return the pointer type found.
13588 pointer_type_def_sptr
lookup_pointer_type(const interned_string & qualified_name,const corpus & corp)13589 lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
13590 {
13591 const istring_type_base_wptrs_map_type& m = corp.get_types().pointer_types();
13592
13593 pointer_type_def_sptr result =
13594 lookup_type_in_map<pointer_type_def>(qualified_name, m);
13595 if (!result)
13596 result = lookup_pointer_type_through_translation_units(qualified_name,
13597 corp);
13598
13599 return result;
13600 }
13601
13602 /// Look into a given corpus to find a reference type which has the
13603 /// same qualified name as a given reference type.
13604 ///
13605 /// If the per-corpus type map is non-empty (because the corpus allows
13606 /// the One Definition Rule) then the type islooked up in that
13607 /// per-corpus type map. Otherwise, the type is looked-up in each
13608 /// translation unit.
13609 ///
13610 /// @param t the reference type which has the same qualified name as
13611 /// the reference type we are looking for.
13612 ///
13613 /// @param corp the corpus to look into.
13614 ///
13615 /// @return the reference type found.
13616 reference_type_def_sptr
lookup_reference_type(const reference_type_def & t,const corpus & corp)13617 lookup_reference_type(const reference_type_def& t, const corpus& corp)
13618 {
13619 interned_string s = get_type_name(t);
13620 return lookup_reference_type(s, corp);
13621 }
13622
13623 /// Look into a given corpus to find a reference type which has a
13624 /// given qualified name.
13625 ///
13626 /// If the per-corpus type map is non-empty (because the corpus allows
13627 /// the One Definition Rule) then the type islooked up in that
13628 /// per-corpus type map. Otherwise, the type is looked-up in each
13629 /// translation unit.
13630 ///
13631 /// @param qualified_name the qualified name of the reference type to
13632 /// look for.
13633 ///
13634 /// @param corp the corpus to look into.
13635 ///
13636 /// @return the reference type found.
13637 reference_type_def_sptr
lookup_reference_type(const interned_string & qualified_name,const corpus & corp)13638 lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
13639 {
13640 const istring_type_base_wptrs_map_type& m =
13641 corp.get_types().reference_types();
13642
13643 reference_type_def_sptr result =
13644 lookup_type_in_map<reference_type_def>(qualified_name, m);
13645 if (!result)
13646 result = lookup_reference_type_through_translation_units(qualified_name,
13647 corp);
13648
13649 return result;
13650 }
13651
13652 /// Look into a given corpus to find an array type which has a given
13653 /// qualified name.
13654 ///
13655 /// If the per-corpus type map is non-empty (because the corpus allows
13656 /// the One Definition Rule) then the type islooked up in that
13657 /// per-corpus type map. Otherwise, the type is looked-up in each
13658 /// translation unit.
13659 ///
13660 /// @param qualified_name the qualified name of the array type to look
13661 /// for.
13662 ///
13663 /// @param corp the corpus to look into.
13664 ///
13665 /// @return the array type found.
13666 array_type_def_sptr
lookup_array_type(const array_type_def & t,const corpus & corp)13667 lookup_array_type(const array_type_def& t, const corpus& corp)
13668 {
13669 interned_string s = get_type_name(t);
13670 return lookup_array_type(s, corp);
13671 }
13672
13673 /// Look into a given corpus to find an array type which has the same
13674 /// qualified name as a given array type.
13675 ///
13676 /// If the per-corpus type map is non-empty (because the corpus allows
13677 /// the One Definition Rule) then the type islooked up in that
13678 /// per-corpus type map. Otherwise, the type is looked-up in each
13679 /// translation unit.
13680 ///
13681 /// @param t the type which has the same qualified name as the type we
13682 /// are looking for.
13683 ///
13684 /// @param corp the corpus to look into.
13685 ///
13686 /// @return the type found.
13687 array_type_def_sptr
lookup_array_type(const interned_string & qualified_name,const corpus & corp)13688 lookup_array_type(const interned_string& qualified_name, const corpus& corp)
13689 {
13690 const istring_type_base_wptrs_map_type& m = corp.get_types().array_types();
13691
13692 array_type_def_sptr result =
13693 lookup_type_in_map<array_type_def>(qualified_name, m);
13694 if (!result)
13695 result = lookup_array_type_through_translation_units(qualified_name, corp);
13696
13697 return result;
13698 }
13699
13700 /// Look into a given corpus to find a function type which has the same
13701 /// qualified name as a given function type.
13702 ///
13703 /// If the per-corpus type map is non-empty (because the corpus allows
13704 /// the One Definition Rule) then the type islooked up in that
13705 /// per-corpus type map. Otherwise, the type is looked-up in each
13706 /// translation unit.
13707 ///
13708 /// @param t the function type which has the same qualified name as
13709 /// the function type we are looking for.
13710 ///
13711 /// @param corp the corpus to look into.
13712 ///
13713 /// @return the function type found.
13714 function_type_sptr
lookup_function_type(const function_type & t,const corpus & corp)13715 lookup_function_type(const function_type&t, const corpus& corp)
13716 {
13717 interned_string type_name = get_type_name(t);
13718 return lookup_function_type(type_name, corp);
13719 }
13720
13721 /// Look into a given corpus to find a function type which has the same
13722 /// qualified name as a given function type.
13723 ///
13724 /// If the per-corpus type map is non-empty (because the corpus allows
13725 /// the One Definition Rule) then the type islooked up in that
13726 /// per-corpus type map. Otherwise, the type is looked-up in each
13727 /// translation unit.
13728 ///
13729 /// @param t the function type which has the same qualified name as
13730 /// the function type we are looking for.
13731 ///
13732 /// @param corp the corpus to look into.
13733 ///
13734 /// @return the function type found.
13735 function_type_sptr
lookup_function_type(const function_type_sptr & fn_t,const corpus & corpus)13736 lookup_function_type(const function_type_sptr& fn_t,
13737 const corpus& corpus)
13738 {
13739 if (fn_t)
13740 return lookup_function_type(*fn_t, corpus);
13741 return function_type_sptr();
13742 }
13743
13744 /// Look into a given corpus to find a function type which has a given
13745 /// qualified name.
13746 ///
13747 /// If the per-corpus type map is non-empty (because the corpus allows
13748 /// the One Definition Rule) then the type islooked up in that
13749 /// per-corpus type map. Otherwise, the type is looked-up in each
13750 /// translation unit.
13751 ///
13752 /// @param qualified_name the qualified name of the function type to
13753 /// look for.
13754 ///
13755 /// @param corp the corpus to look into.
13756 ///
13757 /// @return the function type found.
13758 function_type_sptr
lookup_function_type(const interned_string & qualified_name,const corpus & corp)13759 lookup_function_type(const interned_string& qualified_name, const corpus& corp)
13760 {
13761 const istring_type_base_wptrs_map_type& m = corp.get_types().function_types();
13762
13763 function_type_sptr result =
13764 lookup_type_in_map<function_type>(qualified_name, m);
13765 if (!result)
13766 result = lookup_function_type_through_translation_units(qualified_name,
13767 corp);
13768
13769 return result;
13770 }
13771
13772 /// Look into a given corpus to find a type which has a given
13773 /// qualified name.
13774 ///
13775 /// If the per-corpus type map is non-empty (because the corpus allows
13776 /// the One Definition Rule) then the type islooked up in that
13777 /// per-corpus type map. Otherwise, the type is looked-up in each
13778 /// translation unit.
13779 ///
13780 /// @param qualified_name the qualified name of the function type to
13781 /// look for.
13782 ///
13783 /// @param corp the corpus to look into.
13784 ///
13785 /// @return the function type found.
13786 type_base_sptr
lookup_type(const interned_string & n,const corpus & corp)13787 lookup_type(const interned_string& n, const corpus& corp)
13788 {
13789 type_base_sptr result;
13790
13791 ((result = lookup_basic_type(n, corp))
13792 || (result = lookup_class_type(n, corp))
13793 || (result = lookup_union_type(n, corp))
13794 || (result = lookup_enum_type(n, corp))
13795 || (result = lookup_typedef_type(n, corp))
13796 || (result = lookup_qualified_type(n, corp))
13797 || (result = lookup_pointer_type(n, corp))
13798 || (result = lookup_reference_type(n, corp))
13799 || (result = lookup_array_type(n, corp))
13800 || (result= lookup_function_type(n, corp)));
13801
13802 return result;
13803 }
13804
13805 /// Lookup a type from a corpus, by its location.
13806 ///
13807 /// @param loc the location to consider.
13808 ///
13809 /// @param corp the corpus to look the type from.
13810 ///
13811 /// @return the resulting type, if any found.
13812 type_base_sptr
lookup_type_per_location(const interned_string & loc,const corpus & corp)13813 lookup_type_per_location(const interned_string& loc, const corpus& corp)
13814 {
13815 // TODO: finish this.
13816
13817 //TODO: when we fully support types indexed by their location, this
13818 //function should return a vector of types because at each location,
13819 //there can be several types that are defined (yay, C and C++,
13820 //*sigh*).
13821
13822 type_base_sptr result;
13823 ((result = lookup_basic_type_per_location(loc, corp))
13824 || (result = lookup_class_type_per_location(loc, corp))
13825 || (result = lookup_union_type_per_location(loc, corp))
13826 || (result = lookup_enum_type_per_location(loc, corp))
13827 || (result = lookup_typedef_type_per_location(loc, corp)));
13828
13829 return result;
13830 }
13831
13832 /// Look into a given corpus to find a type
13833 ///
13834 /// If the per-corpus type map is non-empty (because the corpus allows
13835 /// the One Definition Rule) then the type islooked up in that
13836 /// per-corpus type map. Otherwise, the type is looked-up in each
13837 /// translation unit.
13838 ///
13839 /// @param qualified_name the qualified name of the function type to
13840 /// look for.
13841 ///
13842 /// @param corp the corpus to look into.
13843 ///
13844 /// @return the function type found.
13845 type_base_sptr
lookup_type(const type_base & t,const corpus & corp)13846 lookup_type(const type_base&t, const corpus& corp)
13847 {
13848 interned_string n = get_type_name(t);
13849 return lookup_type(n, corp);
13850 }
13851
13852 /// Look into a given corpus to find a type
13853 ///
13854 /// If the per-corpus type map is non-empty (because the corpus allows
13855 /// the One Definition Rule) then the type islooked up in that
13856 /// per-corpus type map. Otherwise, the type is looked-up in each
13857 /// translation unit.
13858 ///
13859 /// @param qualified_name the qualified name of the function type to
13860 /// look for.
13861 ///
13862 /// @param corp the corpus to look into.
13863 ///
13864 /// @return the function type found.
13865 type_base_sptr
lookup_type(const type_base_sptr & t,const corpus & corp)13866 lookup_type(const type_base_sptr&t, const corpus& corp)
13867 {
13868 if (t)
13869 return lookup_type(*t, corp);
13870 return type_base_sptr();
13871 }
13872
13873 /// Update the map that associates a fully qualified name of a given
13874 /// type to that type.
13875 ///
13876 ///
13877 /// @param type the type we are considering.
13878 ///
13879 /// @param types_map the map to update. It's a map that assciates a
13880 /// fully qualified name of a type to the type itself.
13881 ///
13882 /// @param use_type_name_as_key if true, use the name of the type as
13883 /// the key to look it up later. If false, then use the location of
13884 /// the type as a key to look it up later.
13885 ///
13886 /// @return true iff the type was added to the map.
13887 template<typename TypeKind>
13888 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)13889 maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
13890 istring_type_base_wptrs_map_type& types_map,
13891 bool use_type_name_as_key = true)
13892 {
13893 interned_string s;
13894
13895 if (use_type_name_as_key)
13896 s = get_type_name(type);
13897 else if (location l = type->get_location())
13898 {
13899 string str = l.expand();
13900 s = type->get_environment().intern(str);
13901 }
13902
13903 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
13904 bool result = false;
13905
13906 if (i == types_map.end())
13907 {
13908 types_map[s].push_back(type);
13909 result = true;
13910 }
13911 else
13912 i->second.push_back(type);
13913
13914 return result;
13915 }
13916
13917 /// This is the specialization for type @ref class_decl of the
13918 /// function template:
13919 ///
13920 /// maybe_update_types_lookup_map<T>(scope_decl*,
13921 /// const shared_ptr<T>&,
13922 /// istring_type_base_wptrs_map_type&)
13923 ///
13924 /// @param class_type the type to consider.
13925 ///
13926 /// @param types_map the type map to update.
13927 ///
13928 /// @return true iff the type was added to the map.
13929 template<>
13930 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)13931 maybe_update_types_lookup_map<class_decl>(const class_decl_sptr& class_type,
13932 istring_type_base_wptrs_map_type& map,
13933 bool use_type_name_as_key)
13934 {
13935 class_decl_sptr type = class_type;
13936
13937 bool update_qname_map = true;
13938 if (type->get_is_declaration_only())
13939 {
13940 // Let's try to look through decl-only classes to get their
13941 // definition. But if the class doesn't have a definition then
13942 // we'll keep it.
13943 if (class_decl_sptr def =
13944 is_class_type(class_type->get_definition_of_declaration()))
13945 type = def;
13946 }
13947
13948 if (!update_qname_map)
13949 return false;
13950
13951 interned_string s;
13952 if (use_type_name_as_key)
13953 {
13954 string qname = type->get_qualified_name();
13955 s = type->get_environment().intern(qname);
13956 }
13957 else if (location l = type->get_location())
13958 {
13959 string str = l.expand();
13960 s = type->get_environment().intern(str);
13961 }
13962
13963 bool result = false;
13964 istring_type_base_wptrs_map_type::iterator i = map.find(s);
13965 if (i == map.end())
13966 {
13967 map[s].push_back(type);
13968 result = true;
13969 }
13970 else
13971 i->second.push_back(type);
13972
13973 return result;
13974 }
13975
13976 /// This is the specialization for type @ref function_type of the
13977 /// function template:
13978 ///
13979 /// maybe_update_types_lookup_map<T>(scope_decl*,
13980 /// const shared_ptr<T>&,
13981 /// istring_type_base_wptrs_map_type&)
13982 ///
13983 /// @param scope the scope of the type to consider.
13984 ///
13985 /// @param class_type the type to consider.
13986 ///
13987 /// @param types_map the type map to update.
13988 ///
13989 /// @return true iff the type was added to the map.
13990 template<>
13991 bool
maybe_update_types_lookup_map(const function_type_sptr & type,istring_type_base_wptrs_map_type & types_map,bool)13992 maybe_update_types_lookup_map<function_type>
13993 (const function_type_sptr& type,
13994 istring_type_base_wptrs_map_type& types_map,
13995 bool /*use_type_name_as_key*/)
13996 {
13997 bool result = false;
13998 interned_string s = get_type_name(type);
13999 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14000 if (i == types_map.end())
14001 {
14002 types_map[s].push_back(type);
14003 result = true;
14004 }
14005 else
14006 i->second.push_back(type);
14007
14008 return result;
14009 }
14010
14011 /// Update the map that associates the fully qualified name of a basic
14012 /// type with the type itself.
14013 ///
14014 /// The per-translation unit type map is updated if no type with this
14015 /// name was already existing in that map.
14016 ///
14017 /// If no type with this name did already exist in the per-corpus type
14018 /// map, then that per-corpus type map is updated. Otherwise, that
14019 /// type is erased from that per-corpus map.
14020 ///
14021 /// @param basic_type the basic type to consider.
14022 void
maybe_update_types_lookup_map(const type_decl_sptr & basic_type)14023 maybe_update_types_lookup_map(const type_decl_sptr& basic_type)
14024 {
14025 if (translation_unit *tu = basic_type->get_translation_unit())
14026 maybe_update_types_lookup_map<type_decl>
14027 (basic_type, tu->get_types().basic_types());
14028
14029 if (corpus *type_corpus = basic_type->get_corpus())
14030 {
14031 maybe_update_types_lookup_map<type_decl>
14032 (basic_type,
14033 type_corpus->priv_->get_types().basic_types());
14034
14035 maybe_update_types_lookup_map<type_decl>
14036 (basic_type,
14037 type_corpus->get_type_per_loc_map().basic_types(),
14038 /*use_type_name_as_key*/false);
14039
14040 if (corpus *group = type_corpus->get_group())
14041 {
14042 maybe_update_types_lookup_map<type_decl>
14043 (basic_type,
14044 group->priv_->get_types().basic_types());
14045
14046 maybe_update_types_lookup_map<type_decl>
14047 (basic_type,
14048 group->get_type_per_loc_map().basic_types(),
14049 /*use_type_name_as_key*/false);
14050 }
14051 }
14052
14053 }
14054
14055 /// Update the map that associates the fully qualified name of a class
14056 /// type with the type itself.
14057 ///
14058 /// The per-translation unit type map is updated if no type with this
14059 /// name was already existing in that map.
14060 ///
14061 /// If no type with this name did already exist in the per-corpus type
14062 /// map, then that per-corpus type map is updated. Otherwise, that
14063 /// type is erased from that per-corpus map.
14064 ///
14065 /// @param class_type the class type to consider.
14066 void
maybe_update_types_lookup_map(const class_decl_sptr & class_type)14067 maybe_update_types_lookup_map(const class_decl_sptr& class_type)
14068 {
14069 if (translation_unit *tu = class_type->get_translation_unit())
14070 maybe_update_types_lookup_map<class_decl>
14071 (class_type, tu->get_types().class_types());
14072
14073 if (corpus *type_corpus = class_type->get_corpus())
14074 {
14075 maybe_update_types_lookup_map<class_decl>
14076 (class_type,
14077 type_corpus->priv_->get_types().class_types());
14078
14079 maybe_update_types_lookup_map<class_decl>
14080 (class_type,
14081 type_corpus->get_type_per_loc_map().class_types(),
14082 /*use_type_name_as_key*/false);
14083
14084 if (corpus *group = type_corpus->get_group())
14085 {
14086 maybe_update_types_lookup_map<class_decl>
14087 (class_type,
14088 group->priv_->get_types().class_types());
14089
14090 maybe_update_types_lookup_map<class_decl>
14091 (class_type,
14092 group->get_type_per_loc_map().class_types(),
14093 /*use_type_name_as_key*/false);
14094 }
14095 }
14096 }
14097
14098 /// Update the map that associates the fully qualified name of a union
14099 /// type with the type itself.
14100 ///
14101 /// The per-translation unit type map is updated if no type with this
14102 /// name was already existing in that map.
14103 ///
14104 /// If no type with this name did already exist in the per-corpus type
14105 /// map, then that per-corpus type map is updated. Otherwise, that
14106 /// type is erased from that per-corpus map.
14107 ///
14108 /// @param union_type the union type to consider.
14109 void
maybe_update_types_lookup_map(const union_decl_sptr & union_type)14110 maybe_update_types_lookup_map(const union_decl_sptr& union_type)
14111 {
14112 if (translation_unit *tu = union_type->get_translation_unit())
14113 maybe_update_types_lookup_map<union_decl>
14114 (union_type, tu->get_types().union_types());
14115
14116 if (corpus *type_corpus = union_type->get_corpus())
14117 {
14118 maybe_update_types_lookup_map<union_decl>
14119 (union_type,
14120 type_corpus->priv_->get_types().union_types());
14121
14122 maybe_update_types_lookup_map<union_decl>
14123 (union_type,
14124 type_corpus->get_type_per_loc_map().union_types(),
14125 /*use_type_name_as_key*/false);
14126
14127 if (corpus *group = type_corpus->get_group())
14128 {
14129 maybe_update_types_lookup_map<union_decl>
14130 (union_type,
14131 group->priv_->get_types().union_types());
14132
14133 maybe_update_types_lookup_map<union_decl>
14134 (union_type,
14135 group->get_type_per_loc_map().union_types(),
14136 /*use_type_name_as_key*/false);
14137 }
14138 }
14139 }
14140
14141 /// Update the map that associates the fully qualified name of an enum
14142 /// type with the type itself.
14143 ///
14144 /// The per-translation unit type map is updated if no type with this
14145 /// name was already existing in that map.
14146 ///
14147 /// If no type with this name did already exist in the per-corpus type
14148 /// map, then that per-corpus type map is updated. Otherwise, that
14149 /// type is erased from that per-corpus map.
14150 ///
14151 /// @param enum_type the type to consider.
14152 void
maybe_update_types_lookup_map(const enum_type_decl_sptr & enum_type)14153 maybe_update_types_lookup_map(const enum_type_decl_sptr& enum_type)
14154 {
14155 if (translation_unit *tu = enum_type->get_translation_unit())
14156 maybe_update_types_lookup_map<enum_type_decl>
14157 (enum_type, tu->get_types().enum_types());
14158
14159 if (corpus *type_corpus = enum_type->get_corpus())
14160 {
14161 maybe_update_types_lookup_map<enum_type_decl>
14162 (enum_type,
14163 type_corpus->priv_->get_types().enum_types());
14164
14165 maybe_update_types_lookup_map<enum_type_decl>
14166 (enum_type,
14167 type_corpus->get_type_per_loc_map().enum_types(),
14168 /*use_type_name_as_key*/false);
14169
14170 if (corpus *group = type_corpus->get_group())
14171 {
14172 maybe_update_types_lookup_map<enum_type_decl>
14173 (enum_type,
14174 group->priv_->get_types().enum_types());
14175
14176 maybe_update_types_lookup_map<enum_type_decl>
14177 (enum_type,
14178 group->get_type_per_loc_map().enum_types(),
14179 /*use_type_name_as_key*/false);
14180 }
14181 }
14182
14183 }
14184
14185 /// Update the map that associates the fully qualified name of a
14186 /// typedef type with the type itself.
14187 ///
14188 /// The per-translation unit type map is updated if no type with this
14189 /// name was already existing in that map.
14190 ///
14191 /// If no type with this name did already exist in the per-corpus type
14192 /// map, then that per-corpus type map is updated. Otherwise, that
14193 /// type is erased from that per-corpus map.
14194 ///
14195 /// @param typedef_type the type to consider.
14196 void
maybe_update_types_lookup_map(const typedef_decl_sptr & typedef_type)14197 maybe_update_types_lookup_map(const typedef_decl_sptr& typedef_type)
14198 {
14199 if (translation_unit *tu = typedef_type->get_translation_unit())
14200 maybe_update_types_lookup_map<typedef_decl>
14201 (typedef_type, tu->get_types().typedef_types());
14202
14203 if (corpus *type_corpus = typedef_type->get_corpus())
14204 {
14205 maybe_update_types_lookup_map<typedef_decl>
14206 (typedef_type,
14207 type_corpus->priv_->get_types().typedef_types());
14208
14209 maybe_update_types_lookup_map<typedef_decl>
14210 (typedef_type,
14211 type_corpus->get_type_per_loc_map().typedef_types(),
14212 /*use_type_name_as_key*/false);
14213
14214 if (corpus *group = type_corpus->get_group())
14215 {
14216 maybe_update_types_lookup_map<typedef_decl>
14217 (typedef_type,
14218 group->priv_->get_types().typedef_types());
14219
14220 maybe_update_types_lookup_map<typedef_decl>
14221 (typedef_type,
14222 group->get_type_per_loc_map().typedef_types(),
14223 /*use_type_name_as_key*/false);
14224 }
14225 }
14226 }
14227
14228 /// Update the map that associates the fully qualified name of a
14229 /// qualified type with the type itself.
14230 ///
14231 /// The per-translation unit type map is updated if no type with this
14232 /// name was already existing in that map.
14233 ///
14234 /// If no type with this name did already exist in the per-corpus type
14235 /// map, then that per-corpus type map is updated. Otherwise, that
14236 /// type is erased from that per-corpus map.
14237 ///
14238 /// @param qualified_type the type to consider.
14239 void
maybe_update_types_lookup_map(const qualified_type_def_sptr & qualified_type)14240 maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
14241 {
14242 if (translation_unit *tu = qualified_type->get_translation_unit())
14243 maybe_update_types_lookup_map<qualified_type_def>
14244 (qualified_type, tu->get_types().qualified_types());
14245
14246 if (corpus *type_corpus = qualified_type->get_corpus())
14247 {
14248 maybe_update_types_lookup_map<qualified_type_def>
14249 (qualified_type,
14250 type_corpus->priv_->get_types().qualified_types());
14251
14252 if (corpus *group = type_corpus->get_group())
14253 {
14254 maybe_update_types_lookup_map<qualified_type_def>
14255 (qualified_type,
14256 group->priv_->get_types().qualified_types());
14257 }
14258 }
14259 }
14260
14261 /// Update the map that associates the fully qualified name of a
14262 /// pointer type with the type itself.
14263 ///
14264 /// The per-translation unit type map is updated if no type with this
14265 /// name was already existing in that map.
14266 ///
14267 /// If no type with this name did already exist in the per-corpus type
14268 /// map, then that per-corpus type map is updated. Otherwise, that
14269 /// type is erased from that per-corpus map.
14270 ///
14271 /// @param pointer_type the type to consider.
14272 void
maybe_update_types_lookup_map(const pointer_type_def_sptr & pointer_type)14273 maybe_update_types_lookup_map(const pointer_type_def_sptr& pointer_type)
14274 {
14275 if (translation_unit *tu = pointer_type->get_translation_unit())
14276 maybe_update_types_lookup_map<pointer_type_def>
14277 (pointer_type, tu->get_types().pointer_types());
14278
14279 if (corpus *type_corpus = pointer_type->get_corpus())
14280 {
14281 maybe_update_types_lookup_map<pointer_type_def>
14282 (pointer_type,
14283 type_corpus->priv_->get_types().pointer_types());
14284
14285 if (corpus *group = type_corpus->get_group())
14286 {
14287 maybe_update_types_lookup_map<pointer_type_def>
14288 (pointer_type,
14289 group->priv_->get_types().pointer_types());
14290 }
14291 }
14292 }
14293
14294 /// Update the map that associates the fully qualified name of a
14295 /// reference type with the type itself.
14296 ///
14297 /// The per-translation unit type map is updated if no type with this
14298 /// name was already existing in that map.
14299 ///
14300 /// If no type with this name did already exist in the per-corpus type
14301 /// map, then that per-corpus type map is updated. Otherwise, that
14302 /// type is erased from that per-corpus map.
14303 ///
14304 /// @param reference_type the type to consider.
14305 void
maybe_update_types_lookup_map(const reference_type_def_sptr & reference_type)14306 maybe_update_types_lookup_map(const reference_type_def_sptr& reference_type)
14307 {
14308 if (translation_unit *tu = reference_type->get_translation_unit())
14309 maybe_update_types_lookup_map<reference_type_def>
14310 (reference_type, tu->get_types().reference_types());
14311
14312 if (corpus *type_corpus = reference_type->get_corpus())
14313 {
14314 maybe_update_types_lookup_map<reference_type_def>
14315 (reference_type,
14316 type_corpus->priv_->get_types().reference_types());
14317
14318 if (corpus *group = type_corpus->get_group())
14319 {
14320 maybe_update_types_lookup_map<reference_type_def>
14321 (reference_type,
14322 group->priv_->get_types().reference_types());
14323 }
14324 }
14325 }
14326
14327 /// Update the map that associates the fully qualified name of a type
14328 /// with the type itself.
14329 ///
14330 /// The per-translation unit type map is updated if no type with this
14331 /// name was already existing in that map.
14332 ///
14333 /// If no type with this name did already exist in the per-corpus type
14334 /// map, then that per-corpus type map is updated. Otherwise, that
14335 /// type is erased from that per-corpus map.
14336 ///
14337 /// @param array_type the type to consider.
14338 void
maybe_update_types_lookup_map(const array_type_def_sptr & array_type)14339 maybe_update_types_lookup_map(const array_type_def_sptr& array_type)
14340 {
14341 if (translation_unit *tu = array_type->get_translation_unit())
14342 maybe_update_types_lookup_map<array_type_def>
14343 (array_type, tu->get_types().array_types());
14344
14345 if (corpus *type_corpus = array_type->get_corpus())
14346 {
14347 maybe_update_types_lookup_map<array_type_def>
14348 (array_type,
14349 type_corpus->priv_->get_types().array_types());
14350
14351 maybe_update_types_lookup_map<array_type_def>
14352 (array_type,
14353 type_corpus->get_type_per_loc_map().array_types(),
14354 /*use_type_name_as_key*/false);
14355
14356 if (corpus *group = type_corpus->get_group())
14357 {
14358 maybe_update_types_lookup_map<array_type_def>
14359 (array_type,
14360 group->priv_->get_types().array_types());
14361
14362 maybe_update_types_lookup_map<array_type_def>
14363 (array_type,
14364 group->get_type_per_loc_map().array_types(),
14365 /*use_type_name_as_key*/false);
14366 }
14367 }
14368 }
14369
14370 /// Update the map that associates the fully qualified name of a type
14371 /// with the type itself.
14372 ///
14373 /// The per-translation unit type map is updated if no type with this
14374 /// name was already existing in that map.
14375 ///
14376 /// If no type with this name did already exist in the per-corpus type
14377 /// map, then that per-corpus type map is updated. Otherwise, that
14378 /// type is erased from that per-corpus map.
14379 ///
14380 /// @param subrange_type the type to consider.
14381 void
maybe_update_types_lookup_map(const array_type_def::subrange_sptr & subrange_type)14382 maybe_update_types_lookup_map
14383 (const array_type_def::subrange_sptr& subrange_type)
14384 {
14385 if (translation_unit *tu = subrange_type->get_translation_unit())
14386 maybe_update_types_lookup_map<array_type_def::subrange_type>
14387 (subrange_type, tu->get_types().subrange_types());
14388
14389 if (corpus *type_corpus = subrange_type->get_corpus())
14390 {
14391 maybe_update_types_lookup_map<array_type_def::subrange_type>
14392 (subrange_type,
14393 type_corpus->priv_->get_types().subrange_types());
14394
14395 maybe_update_types_lookup_map<array_type_def::subrange_type>
14396 (subrange_type,
14397 type_corpus->get_type_per_loc_map().subrange_types(),
14398 /*use_type_name_as_key*/false);
14399
14400 if (corpus *group = subrange_type->get_corpus())
14401 {
14402 maybe_update_types_lookup_map<array_type_def::subrange_type>
14403 (subrange_type,
14404 group->priv_->get_types().subrange_types());
14405
14406 maybe_update_types_lookup_map<array_type_def::subrange_type>
14407 (subrange_type,
14408 group->get_type_per_loc_map().subrange_types(),
14409 /*use_type_name_as_key*/false);
14410 }
14411 }
14412 }
14413
14414 /// Update the map that associates the fully qualified name of a
14415 /// function type with the type itself.
14416 ///
14417 /// The per-translation unit type map is updated if no type with this
14418 /// name was already existing in that map.
14419 ///
14420 /// If no type with this name did already exist in the per-corpus type
14421 /// map, then that per-corpus type map is updated. Otherwise, that
14422 /// type is erased from that per-corpus map.
14423 ///
14424 /// @param scope the scope of the function type.
14425 /// @param fn_type the type to consider.
14426 void
maybe_update_types_lookup_map(const function_type_sptr & fn_type)14427 maybe_update_types_lookup_map(const function_type_sptr& fn_type)
14428 {
14429 if (translation_unit *tu = fn_type->get_translation_unit())
14430 maybe_update_types_lookup_map<function_type>
14431 (fn_type, tu->get_types().function_types());
14432
14433 if (corpus *type_corpus = fn_type->get_corpus())
14434 {
14435 maybe_update_types_lookup_map<function_type>
14436 (fn_type,
14437 type_corpus->priv_->get_types().function_types());
14438
14439 if (corpus *group = fn_type->get_corpus())
14440 {
14441 maybe_update_types_lookup_map<function_type>
14442 (fn_type,
14443 group->priv_->get_types().function_types());
14444 }
14445 }
14446 }
14447
14448 /// Update the map that associates the fully qualified name of a type
14449 /// declaration with the type itself.
14450 ///
14451 /// The per-translation unit type map is updated if no type with this
14452 /// name was already existing in that map.
14453 ///
14454 /// If no type with this name did already exist in the per-corpus type
14455 /// map, then that per-corpus type map is updated. Otherwise, that
14456 /// type is erased from that per-corpus map.
14457 ///
14458 /// @param decl the declaration of the type to consider.
14459 void
maybe_update_types_lookup_map(const decl_base_sptr & decl)14460 maybe_update_types_lookup_map(const decl_base_sptr& decl)
14461 {
14462 if (!is_type(decl))
14463 return;
14464
14465 if (type_decl_sptr basic_type = is_type_decl(decl))
14466 maybe_update_types_lookup_map(basic_type);
14467 else if (class_decl_sptr class_type = is_class_type(decl))
14468 maybe_update_types_lookup_map(class_type);
14469 else if (union_decl_sptr union_type = is_union_type(decl))
14470 maybe_update_types_lookup_map(union_type);
14471 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
14472 maybe_update_types_lookup_map(enum_type);
14473 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
14474 maybe_update_types_lookup_map(typedef_type);
14475 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
14476 maybe_update_types_lookup_map(qualified_type);
14477 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
14478 maybe_update_types_lookup_map(pointer_type);
14479 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
14480 maybe_update_types_lookup_map(reference_type);
14481 else if (array_type_def_sptr array_type = is_array_type(decl))
14482 maybe_update_types_lookup_map(array_type);
14483 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
14484 maybe_update_types_lookup_map(subrange_type);
14485 else if (function_type_sptr fn_type = is_function_type(decl))
14486 maybe_update_types_lookup_map(fn_type);
14487 else
14488 ABG_ASSERT_NOT_REACHED;
14489 }
14490
14491 /// Update the map that associates the fully qualified name of a type
14492 /// with the type itself.
14493 ///
14494 /// The per-translation unit type map is updated if no type with this
14495 /// name was already existing in that map.
14496 ///
14497 /// If no type with this name did already exist in the per-corpus type
14498 /// map, then that per-corpus type map is updated. Otherwise, that
14499 /// type is erased from that per-corpus map.
14500 ///
14501 /// @param type the type to consider.
14502 void
maybe_update_types_lookup_map(const type_base_sptr & type)14503 maybe_update_types_lookup_map(const type_base_sptr& type)
14504 {
14505 if (decl_base_sptr decl = get_type_declaration(type))
14506 maybe_update_types_lookup_map(decl);
14507 else if (function_type_sptr fn_type = is_function_type(type))
14508 maybe_update_types_lookup_map(fn_type);
14509 else
14510 ABG_ASSERT_NOT_REACHED;
14511 }
14512
14513 //--------------------------------
14514 // </type and decls lookup stuff>
14515 // ------------------------------
14516
14517 /// In a translation unit, lookup a given type or synthesize it if
14518 /// it's a qualified type.
14519 ///
14520 /// So this function first looks the type up in the translation unit.
14521 /// If it's found, then OK, it's returned. Otherwise, if it's a
14522 /// qualified, reference or pointer or function type (a composite
14523 /// type), lookup the underlying type, synthesize the type we want
14524 /// from it and return it.
14525 ///
14526 /// If the underlying types is not not found, then give up and return
14527 /// nil.
14528 ///
14529 /// @return the type that was found or the synthesized type.
14530 type_base_sptr
synthesize_type_from_translation_unit(const type_base_sptr & type,translation_unit & tu)14531 synthesize_type_from_translation_unit(const type_base_sptr& type,
14532 translation_unit& tu)
14533 {
14534 type_base_sptr result;
14535
14536 result = lookup_type(type, tu);
14537
14538 if (!result)
14539 {
14540 if (qualified_type_def_sptr qual = is_qualified_type(type))
14541 {
14542 type_base_sptr underlying_type =
14543 synthesize_type_from_translation_unit(qual->get_underlying_type(),
14544 tu);
14545 if (underlying_type)
14546 {
14547 result.reset(new qualified_type_def(underlying_type,
14548 qual->get_cv_quals(),
14549 qual->get_location()));
14550 }
14551 }
14552 else if (pointer_type_def_sptr p = is_pointer_type(type))
14553 {
14554 type_base_sptr pointed_to_type =
14555 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
14556 tu);
14557 if (pointed_to_type)
14558 {
14559 result.reset(new pointer_type_def(pointed_to_type,
14560 p->get_size_in_bits(),
14561 p->get_alignment_in_bits(),
14562 p->get_location()));
14563 }
14564 }
14565 else if (reference_type_def_sptr r = is_reference_type(type))
14566 {
14567 type_base_sptr pointed_to_type =
14568 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
14569 if (pointed_to_type)
14570 {
14571 result.reset(new reference_type_def(pointed_to_type,
14572 r->is_lvalue(),
14573 r->get_size_in_bits(),
14574 r->get_alignment_in_bits(),
14575 r->get_location()));
14576 }
14577 }
14578 else if (function_type_sptr f = is_function_type(type))
14579 result = synthesize_function_type_from_translation_unit(*f, tu);
14580
14581 if (result)
14582 {
14583 add_decl_to_scope(is_decl(result), tu.get_global_scope());
14584 canonicalize(result);
14585 }
14586 }
14587
14588 if (result)
14589 tu.priv_->synthesized_types_.push_back(result);
14590
14591 return result;
14592 }
14593
14594 /// In a translation unit, lookup the sub-types that make up a given
14595 /// function type and if the sub-types are all found, synthesize and
14596 /// return a function_type with them.
14597 ///
14598 /// This function is like lookup_function_type_in_translation_unit()
14599 /// execept that it constructs the function type from the sub-types
14600 /// found in the translation, rather than just looking for the
14601 /// function types held by the translation unit. This can be useful
14602 /// if the translation unit doesnt hold the function type we are
14603 /// looking for (i.e, lookup_function_type_in_translation_unit()
14604 /// returned NULL) but we still want to see if the sub-types of the
14605 /// function types are present in the translation unit.
14606 ///
14607 /// @param fn_type the function type to consider.
14608 ///
14609 /// @param tu the translation unit to look into.
14610 ///
14611 /// @return the resulting synthesized function type if all its
14612 /// sub-types have been found, NULL otherwise.
14613 function_type_sptr
synthesize_function_type_from_translation_unit(const function_type & fn_type,translation_unit & tu)14614 synthesize_function_type_from_translation_unit(const function_type& fn_type,
14615 translation_unit& tu)
14616 {
14617 function_type_sptr nil = function_type_sptr();
14618
14619 const environment& env = tu.get_environment();
14620
14621 type_base_sptr return_type = fn_type.get_return_type();
14622 type_base_sptr result_return_type;
14623 if (!return_type || env.is_void_type(return_type))
14624 result_return_type = env.get_void_type();
14625 else
14626 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
14627 if (!result_return_type)
14628 return nil;
14629
14630 function_type::parameters parms;
14631 type_base_sptr parm_type;
14632 function_decl::parameter_sptr parm;
14633 for (function_type::parameters::const_iterator i =
14634 fn_type.get_parameters().begin();
14635 i != fn_type.get_parameters().end();
14636 ++i)
14637 {
14638 type_base_sptr t = (*i)->get_type();
14639 parm_type = synthesize_type_from_translation_unit(t, tu);
14640 if (!parm_type)
14641 return nil;
14642 parm.reset(new function_decl::parameter(parm_type,
14643 (*i)->get_index(),
14644 (*i)->get_name(),
14645 (*i)->get_location(),
14646 (*i)->get_variadic_marker(),
14647 (*i)->get_is_artificial()));
14648 parms.push_back(parm);
14649 }
14650
14651 class_or_union_sptr class_type;
14652 const method_type* method = is_method_type(&fn_type);
14653 if (method)
14654 {
14655 class_type = is_class_or_union_type
14656 (synthesize_type_from_translation_unit(method->get_class_type(), tu));
14657 ABG_ASSERT(class_type);
14658 }
14659
14660 function_type_sptr result_fn_type;
14661
14662 if (class_type)
14663 result_fn_type.reset(new method_type(result_return_type,
14664 class_type,
14665 parms,
14666 method->get_is_const(),
14667 fn_type.get_size_in_bits(),
14668 fn_type.get_alignment_in_bits()));
14669 else
14670 result_fn_type.reset(new function_type(result_return_type,
14671 parms,
14672 fn_type.get_size_in_bits(),
14673 fn_type.get_alignment_in_bits()));
14674
14675 tu.priv_->synthesized_types_.push_back(result_fn_type);
14676 tu.bind_function_type_life_time(result_fn_type);
14677
14678 canonicalize(result_fn_type);
14679 return result_fn_type;
14680 }
14681
14682 /// Demangle a C++ mangled name and return the resulting string
14683 ///
14684 /// @param mangled_name the C++ mangled name to demangle.
14685 ///
14686 /// @return the resulting mangled name.
14687 string
demangle_cplus_mangled_name(const string & mangled_name)14688 demangle_cplus_mangled_name(const string& mangled_name)
14689 {
14690 if (mangled_name.empty())
14691 return "";
14692
14693 size_t l = 0;
14694 int status = 0;
14695 char * str = abi::__cxa_demangle(mangled_name.c_str(),
14696 NULL, &l, &status);
14697 string demangled_name = mangled_name;
14698 if (str)
14699 {
14700 ABG_ASSERT(status == 0);
14701 demangled_name = str;
14702 free(str);
14703 str = 0;
14704 }
14705 return demangled_name;
14706 }
14707
14708 /// Return either the type given in parameter if it's non-null, or the
14709 /// void type.
14710 ///
14711 /// @param t the type to consider.
14712 ///
14713 /// @param env the environment to use. If NULL, just abort the
14714 /// process.
14715 ///
14716 /// @return either @p t if it is non-null, or the void type.
14717 type_base_sptr
type_or_void(const type_base_sptr t,const environment & env)14718 type_or_void(const type_base_sptr t, const environment& env)
14719 {
14720 type_base_sptr r;
14721
14722 if (t)
14723 r = t;
14724 else
14725 r = type_base_sptr(env.get_void_type());
14726
14727 return r;
14728 }
14729
~global_scope()14730 global_scope::~global_scope()
14731 {
14732 }
14733
14734 static bool
14735 maybe_propagate_canonical_type(const type_base& lhs_type,
14736 const type_base& rhs_type);
14737
14738 /// Test if two types are eligible to the "Linux Kernel Fast Type
14739 /// Comparison Optimization", a.k.a LKFTCO.
14740 ///
14741 /// Two types T1 and T2 (who are presumably of the same name and kind)
14742 /// are eligible to the LKFTCO if they fulfill the following criteria/
14743 ///
14744 /// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
14745 /// either class, union or enums.
14746 ///
14747 /// 2/ They are defined in the same translation unit.
14748 ///
14749 /// @param t1 the first type to consider.
14750 ///
14751 /// @param t2 the second type to consider.
14752 ///
14753 /// @return true iff t1 and t2 are eligible to the LKFTCO.
14754 static bool
types_defined_same_linux_kernel_corpus_public(const type_base & t1,const type_base & t2)14755 types_defined_same_linux_kernel_corpus_public(const type_base& t1,
14756 const type_base& t2)
14757 {
14758 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
14759 string t1_file_path, t2_file_path;
14760
14761 /// If the t1 (and t2) are classes/unions/enums from the same linux
14762 /// kernel corpus, let's move on. Otherwise bail out.
14763 if (!(t1_corpus && t2_corpus
14764 && t1_corpus == t2_corpus
14765 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
14766 && (is_class_or_union_type(&t1)
14767 || is_enum_type(&t1))))
14768 return false;
14769
14770 class_or_union *c1 = 0, *c2 = 0;
14771 c1 = is_class_or_union_type(&t1);
14772 c2 = is_class_or_union_type(&t2);
14773
14774 // Two anonymous class types with no naming typedefs cannot be
14775 // eligible to this optimization.
14776 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
14777 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
14778 return false;
14779
14780 // Two anonymous classes with naming typedefs should have the same
14781 // typedef name.
14782 if (c1
14783 && c2
14784 && c1->get_is_anonymous() && c1->get_naming_typedef()
14785 && c2->get_is_anonymous() && c2->get_naming_typedef())
14786 if (c1->get_naming_typedef()->get_name()
14787 != c2->get_naming_typedef()->get_name())
14788 return false;
14789
14790 // Two anonymous enum types cannot be eligible to this optimization.
14791 if (const enum_type_decl *e1 = is_enum_type(&t1))
14792 if (const enum_type_decl *e2 = is_enum_type(&t2))
14793 if (e1->get_is_anonymous() || e2->get_is_anonymous())
14794 return false;
14795
14796 // Look through declaration-only types. That is, get the associated
14797 // definition type.
14798 c1 = look_through_decl_only_class(c1);
14799 c2 = look_through_decl_only_class(c2);
14800
14801 if (c1 && c2)
14802 {
14803 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
14804 {
14805 if (c1->get_environment().decl_only_class_equals_definition())
14806 // At least one of classes/union is declaration-only.
14807 // Because we are in a context in which a declaration-only
14808 // class/union is equal to all definitions of that
14809 // class/union, we can assume that the two types are
14810 // equal.
14811 return true;
14812 }
14813 }
14814
14815 if (t1.get_size_in_bits() != t2.get_size_in_bits())
14816 return false;
14817
14818 // Look at the file names of the locations of t1 and t2. If they
14819 // are equal, then t1 and t2 are defined in the same file.
14820 {
14821 location l;
14822
14823 if (c1)
14824 l = c1->get_location();
14825 else
14826 l = dynamic_cast<const decl_base&>(t1).get_location();
14827
14828 unsigned line = 0, col = 0;
14829 if (l)
14830 l.expand(t1_file_path, line, col);
14831 if (c2)
14832 l = c2->get_location();
14833 else
14834 l = dynamic_cast<const decl_base&>(t2).get_location();
14835 if (l)
14836 l.expand(t2_file_path, line, col);
14837 }
14838
14839 if (t1_file_path.empty() || t2_file_path.empty())
14840 return false;
14841
14842 if (t1_file_path == t2_file_path)
14843 return true;
14844
14845 return false;
14846 }
14847
14848
14849 /// Compare a type T against a canonical type.
14850 ///
14851 /// This function is called during the canonicalization process of the
14852 /// type T. T is called the "candidate type" because it's in the
14853 /// process of being canonicalized. Meaning, it's going to be
14854 /// compared to a canonical type C. If T equals C, then the canonical
14855 /// type of T is C.
14856 ///
14857 /// The purpose of this function is to allow the debugging of the
14858 /// canonicalization of T, if that debugging is activated by
14859 /// configuring the libabigail package with
14860 /// --enable-debug-type-canonicalization and by running "abidw
14861 /// --debug-tc". In that case, T is going to be compared to C twice:
14862 /// once with canonical equality and once with structural equality.
14863 /// The two comparisons must be equal. Otherwise, the
14864 /// canonicalization process is said to be faulty and this function
14865 /// aborts.
14866 ///
14867 /// This is a sub-routine of type_base::get_canonical_type_for.
14868 ///
14869 /// @param canonical_type the canonical type to compare the candidate
14870 /// type against.
14871 ///
14872 /// @param candidate_type the candidate type to compare against the
14873 /// canonical type.
14874 ///
14875 /// @return true iff @p canonical_type equals @p candidate_type.
14876 ///
14877 static bool
compare_types_during_canonicalization(const type_base & canonical_type,const type_base & candidate_type)14878 compare_types_during_canonicalization(const type_base& canonical_type,
14879 const type_base& candidate_type)
14880 {
14881 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
14882 const environment& env = canonical_type.get_environment();
14883 if (env.debug_type_canonicalization_is_on())
14884 {
14885 bool canonical_equality = false, structural_equality = false;
14886 env.priv_->use_canonical_type_comparison_ = false;
14887 structural_equality = canonical_type == candidate_type;
14888 env.priv_->use_canonical_type_comparison_ = true;
14889 canonical_equality = canonical_type == candidate_type;
14890 if (canonical_equality != structural_equality)
14891 {
14892 std::cerr << "structural & canonical equality different for type: "
14893 << canonical_type.get_pretty_representation(true, true)
14894 << std::endl;
14895 ABG_ASSERT_NOT_REACHED;
14896 }
14897 return structural_equality;
14898 }
14899 #endif //end WITH_DEBUG_TYPE_CANONICALIZATION
14900 return canonical_type == candidate_type;
14901 }
14902
14903 /// Compare a canonical type against a candidate canonical type.
14904 ///
14905 /// This is ultimately a sub-routine of the
14906 /// type_base::get_canonical_type_for().
14907 ///
14908 /// The goal of this function is to ease debugging because it can be
14909 /// called from within type_base::get_canonical_type_for() from the
14910 /// prompt of the debugger (with some breakpoint appropriately set) to
14911 /// debug the comparison that happens during type canonicalization,
14912 /// between a candidate type being canonicalized, and an existing
14913 /// canonical type that is registered in the system, in as returned by
14914 /// environment::get_canonical_types()
14915 ///
14916 /// @param canonical_type the canonical type to consider.
14917 ///
14918 /// @param candidate_type the candidate type that is being
14919 /// canonicalized, and thus compared to @p canonical_type.
14920 ///
14921 /// @return true iff @p canonical_type compares equal to @p
14922 /// candidate_type.
14923 static bool
compare_canonical_type_against_candidate(const type_base & canonical_type,const type_base & candidate_type)14924 compare_canonical_type_against_candidate(const type_base& canonical_type,
14925 const type_base& candidate_type)
14926 {
14927 environment& env = const_cast<environment&>(canonical_type.get_environment());
14928
14929 // Before the "*it == it" comparison below is done, let's
14930 // perform on-the-fly-canonicalization. For C types, let's
14931 // consider that an unresolved struct declaration 'struct S'
14932 // is different from a definition 'struct S'. This is
14933 // because normally, at this point all the declarations of
14934 // struct S that are compatible with the definition of
14935 // struct S have already been resolved to that definition,
14936 // during the DWARF parsing. The remaining unresolved
14937 // declaration are thus considered different. With this
14938 // setup we can properly handle cases of two *different*
14939 // struct S being defined in the same binary (in different
14940 // translation units), and a third struct S being only
14941 // declared as an opaque type in a third translation unit of
14942 // its own, with no definition in there. In that case, the
14943 // declaration-only struct S should be left alone and not
14944 // resolved to any of the two definitions of struct S.
14945 bool saved_decl_only_class_equals_definition =
14946 env.decl_only_class_equals_definition();
14947 env.do_on_the_fly_canonicalization(true);
14948 // Compare types by considering that decl-only classes don't
14949 // equal their definition.
14950 env.decl_only_class_equals_definition(false);
14951 env.priv_->allow_type_comparison_results_caching(true);
14952 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
14953 candidate_type)
14954 || compare_types_during_canonicalization(canonical_type,
14955 candidate_type));
14956 // Restore the state of the on-the-fly-canonicalization and
14957 // the decl-only-class-being-equal-to-a-matching-definition
14958 // flags.
14959 env.priv_->clear_type_comparison_results_cache();
14960 env.priv_->allow_type_comparison_results_caching(false);
14961 env.do_on_the_fly_canonicalization(false);
14962 env.decl_only_class_equals_definition
14963 (saved_decl_only_class_equals_definition);
14964 return equal;
14965 }
14966
14967 /// Compare a canonical type against a candidate canonical type.
14968 ///
14969 /// This is ultimately a sub-routine of the
14970 /// type_base::get_canonical_type_for().
14971 ///
14972 /// The goal of this function is to ease debugging because it can be
14973 /// called from within type_base::get_canonical_type_for() from the
14974 /// prompt of the debugger (with some breakpoint appropriately set) to
14975 /// debug the comparison that happens during type canonicalization,
14976 /// between a candidate type being canonicalized, and an existing
14977 /// canonical type that is registered in the system, in as returned by
14978 /// environment::get_canonical_types()
14979 ///
14980 /// @param canonical_type the canonical type to consider.
14981 ///
14982 /// @param candidate_type the candidate type that is being
14983 /// canonicalized, and thus compared to @p canonical_type.
14984 ///
14985 /// @return true iff @p canonical_type compares equal to @p
14986 /// candidate_type.
14987 static bool
compare_canonical_type_against_candidate(const type_base * canonical_type,const type_base * candidate_type)14988 compare_canonical_type_against_candidate(const type_base* canonical_type,
14989 const type_base* candidate_type)
14990 {
14991 return compare_canonical_type_against_candidate(*canonical_type,
14992 *candidate_type);
14993 }
14994
14995 /// Compare a canonical type against a candidate canonical type.
14996 ///
14997 /// This is ultimately a sub-routine of the
14998 /// type_base::get_canonical_type_for().
14999 ///
15000 /// The goal of this function is to ease debugging because it can be
15001 /// called from within type_base::get_canonical_type_for() from the
15002 /// prompt of the debugger (with some breakpoint appropriately set) to
15003 /// debug the comparison that happens during type canonicalization,
15004 /// between a candidate type being canonicalized, and an existing
15005 /// canonical type that is registered in the system, in as returned by
15006 /// environment::get_canonical_types()
15007 ///
15008 /// @param canonical_type the canonical type to consider.
15009 ///
15010 /// @param candidate_type the candidate type that is being
15011 /// canonicalized, and thus compared to @p canonical_type.
15012 ///
15013 /// @return true iff @p canonical_type compares equal to @p
15014 /// candidate_type.
15015 static bool
compare_canonical_type_against_candidate(const type_base_sptr & canonical_type,const type_base_sptr & candidate_type)15016 compare_canonical_type_against_candidate(const type_base_sptr& canonical_type,
15017 const type_base_sptr& candidate_type)
15018 {
15019 return compare_canonical_type_against_candidate(canonical_type.get(),
15020 candidate_type.get());
15021 }
15022
15023 /// Compute the canonical type for a given instance of @ref type_base.
15024 ///
15025 /// Consider two types T and T'. The canonical type of T, denoted
15026 /// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
15027 /// otherwise, to compare two types, one just needs to compare their
15028 /// canonical types using pointer equality. That makes type
15029 /// comparison faster than the structural comparison performed by the
15030 /// abigail::ir::equals() overloads.
15031 ///
15032 /// If there is not yet any canonical type for @p t, then @p t is its
15033 /// own canonical type. Otherwise, this function returns the
15034 /// canonical type of @p t which is the canonical type that has the
15035 /// same hash value as @p t and that structurally equals @p t. Note
15036 /// that after invoking this function, the life time of the returned
15037 /// canonical time is then equals to the life time of the current
15038 /// process.
15039 ///
15040 /// @param t a smart pointer to instance of @ref type_base we want to
15041 /// compute a canonical type for.
15042 ///
15043 /// @return the canonical type for the current instance of @ref
15044 /// type_base.
15045 type_base_sptr
get_canonical_type_for(type_base_sptr t)15046 type_base::get_canonical_type_for(type_base_sptr t)
15047 {
15048 if (!t)
15049 return t;
15050
15051 environment& env = const_cast<environment&>(t->get_environment());
15052
15053 if (is_non_canonicalized_type(t))
15054 // This type should not be canonicalized!
15055 return type_base_sptr();
15056
15057 if (is_decl(t))
15058 t = is_type(look_through_decl_only(is_decl(t)));
15059
15060 // Look through decl-only types (classes, unions and enums)
15061 bool decl_only_class_equals_definition =
15062 (odr_is_relevant(*t) || env.decl_only_class_equals_definition());
15063
15064 class_or_union_sptr class_or_union = is_class_or_union_type(t);
15065
15066 // In the context of types from C++ or languages where we assume the
15067 // "One Definition Rule", we assume that a declaration-only
15068 // non-anonymous class equals all fully defined classes of the same
15069 // name.
15070 //
15071 // Otherwise, all classes, including declaration-only classes are
15072 // canonicalized and only canonical comparison is going to be used
15073 // in the system.
15074 if (decl_only_class_equals_definition)
15075 if (class_or_union)
15076 if (class_or_union->get_is_declaration_only())
15077 return type_base_sptr();
15078
15079 class_decl_sptr is_class = is_class_type(t);
15080 if (t->get_canonical_type())
15081 return t->get_canonical_type();
15082
15083 // For classes and union, ensure that an anonymous class doesn't
15084 // have a linkage name. If it does in the future, then me must be
15085 // mindful that the linkage name respects the type identity
15086 // constraints which states that "if two linkage names are different
15087 // then the two types are different".
15088 ABG_ASSERT(!class_or_union
15089 || !class_or_union->get_is_anonymous()
15090 || class_or_union->get_linkage_name().empty());
15091
15092 // We want the pretty representation of the type, but for an
15093 // internal use, not for a user-facing purpose.
15094 //
15095 // If two classe types Foo are declared, one as a class and the
15096 // other as a struct, but are otherwise equivalent, we want their
15097 // pretty representation to be the same. Hence the 'internal'
15098 // argument of ir::get_pretty_representation() is set to true here.
15099 // So in this case, the pretty representation of Foo is going to be
15100 // "class Foo", regardless of its struct-ness. This also applies to
15101 // composite types which would have "class Foo" as a sub-type.
15102 string repr = t->get_cached_pretty_representation(/*internal=*/true);
15103
15104 // If 't' already has a canonical type 'inside' its corpus
15105 // (t_corpus), then this variable is going to contain that canonical
15106 // type.
15107 type_base_sptr canonical_type_present_in_corpus;
15108 environment::canonical_types_map_type& types =
15109 env.get_canonical_types_map();
15110
15111 type_base_sptr result;
15112 environment::canonical_types_map_type::iterator i = types.find(repr);
15113 if (i == types.end())
15114 {
15115 vector<type_base_sptr> v;
15116 v.push_back(t);
15117 types[repr] = v;
15118 result = t;
15119 }
15120 else
15121 {
15122 vector<type_base_sptr> &v = i->second;
15123 // Let's compare 't' structurally (i.e, compare its sub-types
15124 // recursively) against the canonical types of the system. If it
15125 // equals a given canonical type C, then it means C is the
15126 // canonical type of 't'. Otherwise, if 't' is different from
15127 // all the canonical types of the system, then it means 't' is a
15128 // canonical type itself.
15129 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15130 it != v.rend();
15131 ++it)
15132 {
15133 bool equal = compare_canonical_type_against_candidate(*it, t);
15134 if (equal)
15135 {
15136 result = *it;
15137 break;
15138 }
15139 }
15140 #ifdef WITH_DEBUG_SELF_COMPARISON
15141 if (env.self_comparison_debug_is_on())
15142 {
15143 // So we are debugging the canonicalization process,
15144 // possibly via the use of 'abidw --debug-abidiff <binary>'.
15145 corpus_sptr corp1, corp2;
15146 env.get_self_comparison_debug_inputs(corp1, corp2);
15147 if (corp1 && corp2 && t->get_corpus() == corp2.get())
15148 {
15149 // If 't' comes from the second corpus, then it *must*
15150 // be equal to its matching canonical type coming from
15151 // the first corpus because the second corpus is the
15152 // abixml representation of the first corpus. In other
15153 // words, all types coming from the second corpus must
15154 // have canonical types coming from the first corpus.
15155 if (result)
15156 {
15157 if (!env.priv_->
15158 check_canonical_type_from_abixml_during_self_comp(t,
15159 result))
15160 {
15161 // The canonical type of the type re-read from abixml
15162 // type doesn't match the canonical type that was
15163 // initially serialized down.
15164 uintptr_t should_have_canonical_type = 0;
15165 string type_id = env.get_type_id_from_type(t.get());
15166 if (type_id.empty())
15167 type_id = "type-id-<not-found>";
15168 else
15169 should_have_canonical_type =
15170 env.get_canonical_type_from_type_id(type_id.c_str());
15171 std::cerr << "error: wrong canonical type for '"
15172 << repr
15173 << "' / type: @"
15174 << std::hex
15175 << t.get()
15176 << "/ canon: @"
15177 << result.get()
15178 << ", type-id: '"
15179 << type_id
15180 << "'. Should have had canonical type: "
15181 << std::hex
15182 << should_have_canonical_type
15183 << std::endl;
15184 }
15185 }
15186 else //!result
15187 {
15188 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
15189 string type_id = env.get_type_id_from_pointer(ptr_val);
15190 if (type_id.empty())
15191 type_id = "type-id-<not-found>";
15192 // We are in the case where 't' is different from all
15193 // the canonical types of the same name that come from
15194 // the first corpus.
15195 //
15196 // If 't' indeed comes from the second corpus then this
15197 // clearly is a canonicalization failure.
15198 //
15199 // There was a problem either during the serialization
15200 // of 't' into abixml, or during the de-serialization
15201 // from abixml into abigail::ir. Further debugging is
15202 // needed to determine what that root cause problem is.
15203 //
15204 // Note that the first canonicalization problem of this
15205 // kind must be fixed before looking at the subsequent
15206 // ones, because the later might well just be
15207 // consequences of the former.
15208 std::cerr << "error: wrong induced canonical type for '"
15209 << repr
15210 << "' from second corpus"
15211 << ", ptr: " << std::hex << t.get()
15212 << " type-id: " << type_id
15213 << std::endl;
15214 }
15215 }
15216 }
15217 #endif //WITH_DEBUG_SELF_COMPARISON
15218
15219 if (!result)
15220 {
15221 v.push_back(t);
15222 result = t;
15223 }
15224 }
15225
15226 return result;
15227 }
15228
15229 /// This method is invoked automatically right after the current
15230 /// instance of @ref class_decl has been canonicalized.
15231 void
on_canonical_type_set()15232 type_base::on_canonical_type_set()
15233 {}
15234
15235 /// This is a subroutine of the canonicalize() function.
15236 ///
15237 /// When the canonical type C of type T has just been computed, there
15238 /// can be cases where T has member functions that C doesn't have.
15239 ///
15240 /// This is possible because non virtual member functions are not
15241 /// taken in account when comparing two types.
15242 ///
15243 /// In that case, this function updates C so that it contains the
15244 /// member functions.
15245 ///
15246 /// There can also be cases where C has a method M which is not linked
15247 /// to any underlying symbol, whereas in T, M is to link to an
15248 /// underlying symbol. In that case, this function updates M in C so
15249 /// that it's linked to the same underlying symbol as for M in T.
15250 static void
maybe_adjust_canonical_type(const type_base_sptr & canonical,const type_base_sptr & type)15251 maybe_adjust_canonical_type(const type_base_sptr& canonical,
15252 const type_base_sptr& type)
15253 {
15254 if (!canonical
15255 // If 'type' is *NOT* a newly canonicalized type ...
15256 || type->get_naked_canonical_type()
15257 // ... or if 'type' is it's own canonical type, then get out.
15258 || type.get() == canonical.get())
15259 return;
15260
15261 if (class_decl_sptr cl = is_class_type(type))
15262 {
15263 class_decl_sptr canonical_class = is_class_type(canonical);
15264
15265 if (canonical_class)
15266 {
15267 // Set symbols of member functions that might be missing
15268 // theirs.
15269 for (class_decl::member_functions::const_iterator i =
15270 cl->get_member_functions().begin();
15271 i != cl->get_member_functions().end();
15272 ++i)
15273 if ((*i)->get_symbol())
15274 {
15275 if (method_decl *m = canonical_class->
15276 find_member_function((*i)->get_linkage_name()))
15277 {
15278 elf_symbol_sptr s1 = (*i)->get_symbol();
15279 if (s1 && !m->get_symbol())
15280 // Method 'm' in the canonical type is not
15281 // linked to the underlying symbol of '*i'.
15282 // Let's link it now. have th
15283 m->set_symbol(s1);
15284 }
15285 else
15286 // There is a member function defined and publicly
15287 // exported in the other class, and the canonical
15288 // class doesn't have that member function. Let's
15289 // copy that member function to the canonical class
15290 // then.
15291 {
15292 method_decl_sptr method =
15293 copy_member_function (canonical_class, *i);
15294 canonicalize(method->get_type());
15295 }
15296 }
15297 }
15298 }
15299
15300 // If an artificial function type equals a non-artfificial one in
15301 // the system, then the canonical type of both should be deemed
15302 // non-artificial. This is important because only non-artificial
15303 // canonical function types are emitted out into abixml, so if don't
15304 // do this we risk missing to emit some function types.
15305 if (is_function_type(type))
15306 if (type->get_is_artificial() != canonical->get_is_artificial())
15307 canonical->set_is_artificial(false);
15308 }
15309
15310 /// Compute the canonical type of a given type.
15311 ///
15312 /// It means that after invoking this function, comparing the intance
15313 /// instance @ref type_base and another one (on which
15314 /// type_base::enable_canonical_equality() would have been invoked as
15315 /// well) is performed by just comparing the pointer values of the
15316 /// canonical types of both types. That equality comparison is
15317 /// supposedly faster than structural comparison of the types.
15318 ///
15319 /// @param t a smart pointer to the instance of @ref type_base for
15320 /// which to compute the canonical type. After this call,
15321 /// t->get_canonical_type() will return the newly computed canonical
15322 /// type.
15323 ///
15324 /// @return the canonical type computed for @p t.
15325 type_base_sptr
canonicalize(type_base_sptr t)15326 canonicalize(type_base_sptr t)
15327 {
15328 if (!t)
15329 return t;
15330
15331 if (t->get_canonical_type())
15332 return t->get_canonical_type();
15333
15334 if (t->get_environment().priv_->do_log())
15335 std::cerr << "Canonicalization of type '"
15336 << t->get_pretty_representation(true, true)
15337 << "/@#" << std::hex << t.get() << ": ";
15338
15339 tools_utils::timer tmr;
15340
15341 if (t->get_environment().priv_->do_log())
15342 tmr.start();
15343 type_base_sptr canonical = type_base::get_canonical_type_for(t);
15344
15345 if (t->get_environment().priv_->do_log())
15346 tmr.stop();
15347
15348 if (t->get_environment().priv_->do_log())
15349 std::cerr << tmr << "\n";
15350
15351 maybe_adjust_canonical_type(canonical, t);
15352
15353 t->priv_->canonical_type = canonical;
15354 t->priv_->naked_canonical_type = canonical.get();
15355
15356 // So this type is now canonicalized.
15357 //
15358 // It means that:
15359 //
15360 // 1/ Either the canonical type was not propagated during the
15361 // comparison of another type that was being canonicalized
15362 //
15363 // 2/ Or the canonical type has been propagated during the
15364 // comparison of another type that was being canonicalized and
15365 // that propagated canonical type has been confirmed, because
15366 // it was depending on a recursive type which comparison
15367 // succeeded.
15368 ABG_ASSERT(!t->priv_->canonical_type_propagated()
15369 || t->priv_->propagated_canonical_type_confirmed());
15370
15371 if (class_decl_sptr cl = is_class_type(t))
15372 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
15373 if ((canonical = d->get_canonical_type()))
15374 {
15375 d->priv_->canonical_type = canonical;
15376 d->priv_->naked_canonical_type = canonical.get();
15377 }
15378
15379 if (canonical)
15380 {
15381 if (decl_base_sptr d = is_decl_slow(canonical))
15382 {
15383 scope_decl *scope = d->get_scope();
15384 // Add the canonical type to the set of canonical types
15385 // belonging to its scope.
15386 if (scope)
15387 {
15388 if (is_type(scope))
15389 // The scope in question is itself a type (e.g, a class
15390 // or union). Let's call that type ST. We want to add
15391 // 'canonical' to the set of canonical types belonging
15392 // to ST.
15393 if (type_base_sptr c = is_type(scope)->get_canonical_type())
15394 // We want to add 'canonical' to set of canonical
15395 // types belonging to the canonical type of ST. That
15396 // way, just looking at the canonical type of ST is
15397 // enough to get the types that belong to the scope of
15398 // the class of equivalence of ST.
15399 scope = is_scope_decl(is_decl(c)).get();
15400 scope->get_canonical_types().insert(canonical);
15401 }
15402 // else, if the type doesn't have a scope, it's not meant to be
15403 // emitted. This can be the case for the result of the
15404 // function strip_typedef, for instance.
15405 }
15406
15407 #ifdef WITH_DEBUG_CT_PROPAGATION
15408 // Update the book-keeping of the set of the types which
15409 // propagated canonical type has been cleared.
15410 //
15411 // If this type 't' which has just been canonicalized was
15412 // previously in the set of types which propagated canonical
15413 // type has been cleared, then remove it from that set because
15414 // its canonical type is now computed and definitely set.
15415 const environment& env = t->get_environment();
15416 env.priv_->erase_type_with_cleared_propagated_canonical_type(t.get());
15417 #endif
15418 }
15419
15420 t->on_canonical_type_set();
15421 return canonical;
15422 }
15423
15424 /// Set the definition of this declaration-only @ref decl_base.
15425 ///
15426 /// @param d the new definition to set.
15427 void
set_definition_of_declaration(const decl_base_sptr & d)15428 decl_base::set_definition_of_declaration(const decl_base_sptr& d)
15429 {
15430 ABG_ASSERT(get_is_declaration_only());
15431 priv_->definition_of_declaration_ = d;
15432 if (type_base *t = is_type(this))
15433 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
15434 t->priv_->canonical_type = canonical_type;
15435
15436 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
15437 }
15438
15439 /// The constructor of @ref type_base.
15440 ///
15441 /// @param s the size of the type, in bits.
15442 ///
15443 /// @param a the alignment of the type, in bits.
type_base(const environment & e,size_t s,size_t a)15444 type_base::type_base(const environment& e, size_t s, size_t a)
15445 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
15446 priv_(new priv(s, a))
15447 {}
15448
15449 /// Getter of the canonical type of the current instance of @ref
15450 /// type_base.
15451 ///
15452 /// @return a smart pointer to the canonical type of the current
15453 /// intance of @ref type_base, or an empty smart pointer if the
15454 /// current instance of @ref type_base doesn't have any canonical
15455 /// type.
15456 type_base_sptr
get_canonical_type() const15457 type_base::get_canonical_type() const
15458 {return priv_->canonical_type.lock();}
15459
15460 /// Getter of the canonical type pointer.
15461 ///
15462 /// Note that this function doesn't return a smart pointer, but rather
15463 /// the underlying pointer managed by the smart pointer. So it's as
15464 /// fast as possible. This getter is to be used in code paths that
15465 /// are proven to be performance hot spots; especially, when comparing
15466 /// sensitive types like class, function, pointers and reference
15467 /// types. Those are compared extremely frequently and thus, their
15468 /// accessing the canonical type must be fast.
15469 ///
15470 /// @return the canonical type pointer, not managed by a smart
15471 /// pointer.
15472 type_base*
get_naked_canonical_type() const15473 type_base::get_naked_canonical_type() const
15474 {return priv_->naked_canonical_type;}
15475
15476 /// Get the pretty representation of the current type.
15477 ///
15478 /// The pretty representation is retrieved from a cache. If the cache
15479 /// is empty, this function computes the pretty representation, put it
15480 /// in the cache and returns it.
15481 ///
15482 /// Note that if the type is *NOT* canonicalized, the pretty
15483 /// representation is never cached.
15484 ///
15485 /// @param internal if true, then the pretty representation is to be
15486 /// used for purpuses that are internal to the libabigail library
15487 /// itself. If you don't know what this means, then you probably
15488 /// should set this parameter to "false".
15489 const interned_string&
get_cached_pretty_representation(bool internal) const15490 type_base::get_cached_pretty_representation(bool internal) const
15491 {
15492 if (internal)
15493 {
15494 if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
15495 {
15496 string r = ir::get_pretty_representation(this, internal);
15497 priv_->internal_cached_repr_ = get_environment().intern(r);
15498 }
15499 return priv_->internal_cached_repr_;
15500 }
15501
15502 if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
15503 {
15504 string r = ir::get_pretty_representation(this, internal);
15505 priv_->cached_repr_ = get_environment().intern(r);
15506 }
15507
15508 return priv_->cached_repr_;
15509 }
15510
15511 /// Compares two instances of @ref type_base.
15512 ///
15513 /// If the two intances are different, set a bitfield to give some
15514 /// insight about the kind of differences there are.
15515 ///
15516 /// @param l the first artifact of the comparison.
15517 ///
15518 /// @param r the second artifact of the comparison.
15519 ///
15520 /// @param k a pointer to a bitfield that gives information about the
15521 /// kind of changes there are between @p l and @p r. This one is set
15522 /// iff @p is non-null and if the function returns false.
15523 ///
15524 /// Please note that setting k to a non-null value does have a
15525 /// negative performance impact because even if @p l and @p r are not
15526 /// equal, the function keeps up the comparison in order to determine
15527 /// the different kinds of ways in which they are different.
15528 ///
15529 /// @return true if @p l equals @p r, false otherwise.
15530 bool
equals(const type_base & l,const type_base & r,change_kind * k)15531 equals(const type_base& l, const type_base& r, change_kind* k)
15532 {
15533 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
15534 && l.get_alignment_in_bits() == r.get_alignment_in_bits());
15535 if (!result)
15536 if (k)
15537 *k |= LOCAL_TYPE_CHANGE_KIND;
15538 ABG_RETURN(result);
15539 }
15540
15541 /// Return true iff both type declarations are equal.
15542 ///
15543 /// Note that this doesn't test if the scopes of both types are equal.
15544 bool
operator ==(const type_base & other) const15545 type_base::operator==(const type_base& other) const
15546 {return equals(*this, other, 0);}
15547
15548 /// Inequality operator.
15549 ///
15550 ///@param other the instance of @ref type_base to compare the current
15551 /// instance against.
15552 ///
15553 /// @return true iff the current instance is different from @p other.
15554 bool
operator !=(const type_base & other) const15555 type_base::operator!=(const type_base& other) const
15556 {return !operator==(other);}
15557
15558 /// Setter for the size of the type.
15559 ///
15560 /// @param s the new size -- in bits.
15561 void
set_size_in_bits(size_t s)15562 type_base::set_size_in_bits(size_t s)
15563 {priv_->size_in_bits = s;}
15564
15565 /// Getter for the size of the type.
15566 ///
15567 /// @return the size in bits of the type.
15568 size_t
get_size_in_bits() const15569 type_base::get_size_in_bits() const
15570 {return priv_->size_in_bits;}
15571
15572 /// Setter for the alignment of the type.
15573 ///
15574 /// @param a the new alignment -- in bits.
15575 void
set_alignment_in_bits(size_t a)15576 type_base::set_alignment_in_bits(size_t a)
15577 {priv_->alignment_in_bits = a;}
15578
15579 /// Getter for the alignment of the type.
15580 ///
15581 /// @return the alignment of the type in bits.
15582 size_t
get_alignment_in_bits() const15583 type_base::get_alignment_in_bits() const
15584 {return priv_->alignment_in_bits;}
15585
15586 /// Default implementation of traversal for types. This function does
15587 /// nothing. It must be implemented by every single new type that is
15588 /// written.
15589 ///
15590 /// Please look at e.g, class_decl::traverse() for an example of how
15591 /// to implement this.
15592 ///
15593 /// @param v the visitor used to visit the type.
15594 bool
traverse(ir_node_visitor & v)15595 type_base::traverse(ir_node_visitor& v)
15596 {
15597 if (v.type_node_has_been_visited(this))
15598 return true;
15599
15600 v.visit_begin(this);
15601 bool result = v.visit_end(this);
15602 v.mark_type_node_as_visited(this);
15603
15604 return result;
15605 }
15606
~type_base()15607 type_base::~type_base()
15608 {delete priv_;}
15609
15610 // </type_base definitions>
15611
15612 // <integral_type definitions>
15613
15614 /// Bitwise OR operator for integral_type::modifiers_type.
15615 ///
15616 /// @param l the left-hand side operand.
15617 ///
15618 /// @param r the right-hand side operand.
15619 ///
15620 /// @return the result of the bitwise OR.
15621 integral_type::modifiers_type
operator |(integral_type::modifiers_type l,integral_type::modifiers_type r)15622 operator|(integral_type::modifiers_type l, integral_type::modifiers_type r)
15623 {
15624 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
15625 |
15626 static_cast<unsigned>(r));
15627 }
15628
15629 /// Bitwise AND operator for integral_type::modifiers_type.
15630 ///
15631 /// @param l the left-hand side operand.
15632 ///
15633 /// @param r the right-hand side operand.
15634 ///
15635 /// @return the result of the bitwise AND.
15636 integral_type::modifiers_type
operator &(integral_type::modifiers_type l,integral_type::modifiers_type r)15637 operator&(integral_type::modifiers_type l, integral_type::modifiers_type r)
15638 {
15639 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
15640 &
15641 static_cast<unsigned>(r));
15642 }
15643
15644 /// Bitwise one's complement operator for integral_type::modifiers_type.
15645 ///
15646 /// @param l the left-hand side operand.
15647 ///
15648 /// @param r the right-hand side operand.
15649 ///
15650 /// @return the result of the bitwise one's complement operator.
15651 integral_type::modifiers_type
operator ~(integral_type::modifiers_type l)15652 operator~(integral_type::modifiers_type l)
15653 {
15654 return static_cast<integral_type::modifiers_type>(~static_cast<unsigned>(l));
15655 }
15656
15657 /// Bitwise |= operator for integral_type::modifiers_type.
15658 ///
15659 /// @param l the left-hand side operand.
15660 ///
15661 /// @param r the right-hand side operand.
15662 ///
15663 /// @return the result of the bitwise |=.
15664 integral_type::modifiers_type&
operator |=(integral_type::modifiers_type & l,integral_type::modifiers_type r)15665 operator|=(integral_type::modifiers_type& l, integral_type::modifiers_type r)
15666 {
15667 l = l | r;
15668 return l;
15669 }
15670
15671 /// Bitwise &= operator for integral_type::modifiers_type.
15672 ///
15673 /// @param l the left-hand side operand.
15674 ///
15675 /// @param r the right-hand side operand.
15676 ///
15677 /// @return the result of the bitwise &=.
15678 integral_type::modifiers_type&
operator &=(integral_type::modifiers_type & l,integral_type::modifiers_type r)15679 operator&=(integral_type::modifiers_type& l, integral_type::modifiers_type r)
15680 {
15681 l = l & r;
15682 return l;
15683 }
15684
15685 /// Parse a word containing one integral type modifier.
15686 ///
15687 /// A word is considered to be a string of characters that doesn't
15688 /// contain any white space.
15689 ///
15690 /// @param word the word to parse. It is considered to be a string of
15691 /// characters that doesn't contain any white space.
15692 ///
15693 /// @param modifiers out parameter. It's set by this function to the
15694 /// parsed modifier iff the function returned true.
15695 ///
15696 /// @return true iff @word was successfully parsed.
15697 static bool
parse_integral_type_modifier(const string & word,integral_type::modifiers_type & modifiers)15698 parse_integral_type_modifier(const string& word,
15699 integral_type::modifiers_type &modifiers)
15700 {
15701 if (word == "signed")
15702 modifiers |= integral_type::SIGNED_MODIFIER;
15703 else if (word == "unsigned")
15704 modifiers |= integral_type::UNSIGNED_MODIFIER;
15705 else if (word == "short")
15706 modifiers |= integral_type::SHORT_MODIFIER;
15707 else if (word == "long")
15708 modifiers |= integral_type::LONG_MODIFIER;
15709 else if (word == "long long")
15710 modifiers |= integral_type::LONG_LONG_MODIFIER;
15711 else
15712 return false;
15713
15714 return true;
15715 }
15716
15717 /// Parse a base type of an integral type from a string.
15718 ///
15719 /// @param type_name the type name to parse.
15720 ///
15721 /// @param base out parameter. This is set to the resulting base type
15722 /// parsed, iff the function returned true.
15723 ///
15724 /// @return true iff the function could successfully parse the base
15725 /// type.
15726 static bool
parse_base_integral_type(const string & type_name,integral_type::base_type & base)15727 parse_base_integral_type(const string& type_name,
15728 integral_type::base_type& base)
15729 {
15730 if (type_name == "int")
15731 base = integral_type::INT_BASE_TYPE;
15732 else if (type_name == "char")
15733 base = integral_type::CHAR_BASE_TYPE;
15734 else if (type_name == "bool" || type_name == "_Bool")
15735 base = integral_type::BOOL_BASE_TYPE;
15736 else if (type_name == "double")
15737 base = integral_type::DOUBLE_BASE_TYPE;
15738 else if (type_name =="float")
15739 base = integral_type::FLOAT_BASE_TYPE;
15740 else if (type_name == "char16_t")
15741 base = integral_type::CHAR16_T_BASE_TYPE;
15742 else if (type_name == "char32_t")
15743 base = integral_type::CHAR32_T_BASE_TYPE;
15744 else if (type_name == "wchar_t")
15745 base = integral_type::WCHAR_T_BASE_TYPE;
15746 else
15747 return false;
15748
15749 return true;
15750 }
15751
15752 /// Parse an integral type from a string.
15753 ///
15754 /// @param type_name the string containing the integral type to parse.
15755 ///
15756 /// @param base out parameter. Is set by this function to the base
15757 /// type of the integral type, iff the function returned true.
15758 ///
15759 /// @param modifiers out parameter If set by this function to the
15760 /// modifier of the integral type, iff the function returned true.
15761 ///
15762 /// @return true iff the function could parse an integral type from @p
15763 /// type_name.
15764 static bool
parse_integral_type(const string & type_name,integral_type::base_type & base,integral_type::modifiers_type & modifiers)15765 parse_integral_type(const string& type_name,
15766 integral_type::base_type& base,
15767 integral_type::modifiers_type& modifiers)
15768 {
15769 string input = type_name;
15770 string::size_type len = input.length();
15771 string::size_type cur_pos = 0, prev_pos = 0;
15772 string cur_word, prev_word;
15773 bool ok = false;
15774
15775 while (cur_pos < len)
15776 {
15777 if (cur_pos < len && isspace(input[cur_pos]))
15778 do
15779 ++cur_pos;
15780 while (cur_pos < len && isspace(input[cur_pos]));
15781
15782 prev_pos = cur_pos;
15783 cur_pos = input.find(' ', prev_pos);
15784 prev_word = cur_word;
15785 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
15786
15787 if (cur_pos < len
15788 && cur_word == "long"
15789 && prev_word != "long")
15790 {
15791 if (cur_pos < len && isspace(input[cur_pos]))
15792 do
15793 ++cur_pos;
15794 while (cur_pos < len && isspace(input[cur_pos]));
15795 prev_pos = cur_pos;
15796
15797 cur_pos = input.find(' ', prev_pos);
15798 string saved_prev_word = prev_word;
15799 prev_word = cur_word;
15800 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
15801 if (cur_word == "long")
15802 cur_word = "long long";
15803 else
15804 {
15805 cur_pos = prev_pos;
15806 cur_word = prev_word;
15807 prev_word = saved_prev_word;
15808 }
15809 }
15810
15811 if (!parse_integral_type_modifier(cur_word, modifiers))
15812 {
15813 if (!parse_base_integral_type(cur_word, base))
15814 return false;
15815 else
15816 ok = true;
15817 }
15818 else
15819 ok = true;
15820 }
15821
15822 return ok;
15823 }
15824
15825 /// Parse an integral type from a string.
15826 ///
15827 /// @param str the string containing the integral type to parse.
15828 ///
15829 ///@param type the resulting @ref integral_type. Is set to the result
15830 ///of the parse, iff the function returns true.
15831 ///
15832 /// @return true iff the function could parse an integral type from @p
15833 /// str.
15834 bool
parse_integral_type(const string & str,integral_type & type)15835 parse_integral_type(const string& str, integral_type& type)
15836 {
15837 integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
15838 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
15839
15840 if (!parse_integral_type(str, base_type, modifiers))
15841 return false;
15842
15843 // So this is an integral type.
15844 integral_type int_type(base_type, modifiers);
15845 type = int_type;
15846 return true;
15847 }
15848
15849 /// Default constructor of the @ref integral_type.
integral_type()15850 integral_type::integral_type()
15851 : base_(INT_BASE_TYPE),
15852 modifiers_(NO_MODIFIER)
15853 {}
15854
15855 /// Constructor of the @ref integral_type.
15856 ///
15857 /// @param b the base type of the integral type.
15858 ///
15859 /// @param m the modifiers of the integral type.
integral_type(base_type b,modifiers_type m)15860 integral_type::integral_type(base_type b, modifiers_type m)
15861 : base_(b), modifiers_(m)
15862 {}
15863
15864 /// Constructor of the @ref integral_type.
15865 ///
15866 /// @param the name of the integral type to parse to initialize the
15867 /// current instance of @ref integral_type.
integral_type(const string & type_name)15868 integral_type::integral_type(const string& type_name)
15869 : base_(INT_BASE_TYPE),
15870 modifiers_(NO_MODIFIER)
15871 {
15872 bool could_parse = parse_integral_type(type_name, base_, modifiers_);
15873 ABG_ASSERT(could_parse);
15874 }
15875
15876 /// Getter of the base type of the @ref integral_type.
15877 ///
15878 /// @return the base type of the @ref integral_type.
15879 integral_type::base_type
get_base_type() const15880 integral_type::get_base_type() const
15881 {return base_;}
15882
15883 /// Getter of the modifiers bitmap of the @ref integral_type.
15884 ///
15885 /// @return the modifiers bitmap of the @ref integral_type.
15886 integral_type::modifiers_type
get_modifiers() const15887 integral_type::get_modifiers() const
15888 {return modifiers_;}
15889
15890 /// Setter of the modifiers bitmap of the @ref integral_type.
15891 ///
15892 /// @param m the new modifiers.
15893 void
set_modifiers(modifiers_type m)15894 integral_type::set_modifiers(modifiers_type m)
15895 {modifiers_ = m;}
15896
15897 /// Equality operator for the @ref integral_type.
15898 ///
15899 /// @param other the other integral type to compare against.
15900 ///
15901 /// @return true iff @p other equals the current instance of @ref
15902 /// integral_type.
15903 bool
operator ==(const integral_type & other) const15904 integral_type::operator==(const integral_type&other) const
15905 {return base_ == other.base_ && modifiers_ == other.modifiers_;}
15906
15907 /// Return the string representation of the current instance of @ref
15908 /// integral_type.
15909 ///
15910 /// @param internal if true the string representation is to be used
15911 /// for internal purposes. In general, it means it's for type
15912 /// canonicalization purposes.
15913 ///
15914 /// @return the string representation of the current instance of @ref
15915 /// integral_type.
15916 string
to_string(bool internal) const15917 integral_type::to_string(bool internal) const
15918 {
15919 string result;
15920
15921 // Look at modifiers ...
15922 if (modifiers_ & SIGNED_MODIFIER)
15923 result += "signed ";
15924 if (modifiers_ & UNSIGNED_MODIFIER)
15925 result += "unsigned ";
15926 if (!internal)
15927 {
15928 // For canonicalization purposes, we won't emit the "short, long, or
15929 // long long" modifiers. This is because on some platforms, "long
15930 // int" and "long long int" might have the same size. In those
15931 // cases, we want the two types to be equivalent if they have the
15932 // same size. If they don't have the same internal string
15933 // representation, they'd automatically have different canonical
15934 // types and thus be canonically different.
15935 if (modifiers_ & SHORT_MODIFIER)
15936 result += "short ";
15937 if (modifiers_ & LONG_MODIFIER)
15938 result += "long ";
15939 if (modifiers_ & LONG_LONG_MODIFIER)
15940 result += "long long ";
15941 }
15942
15943 // ... and look at base types.
15944 if (base_ == INT_BASE_TYPE)
15945 result += "int";
15946 else if (base_ == CHAR_BASE_TYPE)
15947 result += "char";
15948 else if (base_ == BOOL_BASE_TYPE)
15949 result += "bool";
15950 else if (base_ == DOUBLE_BASE_TYPE)
15951 result += "double";
15952 else if (base_ == FLOAT_BASE_TYPE)
15953 result += "float";
15954 else if (base_ == CHAR16_T_BASE_TYPE)
15955 result += "char16_t";
15956 else if (base_ == CHAR32_T_BASE_TYPE)
15957 result += "char32_t";
15958 else if (base_ == WCHAR_T_BASE_TYPE)
15959 result += "wchar_t";
15960
15961 return result;
15962 }
15963
15964 /// Convert the current instance of @ref integral_type into its string
15965 /// representation.
15966 ///
15967 /// @return the string representation of the current instance of @ref
15968 /// integral_type.
operator string() const15969 integral_type::operator string() const
15970 {return to_string();}
15971
15972 // </integral_type definitions>
15973
15974 //<type_decl definitions>
15975
15976 /// Constructor.
15977 ///
15978 /// @param env the environment we are operating from.
15979 ///
15980 /// @param name the name of the type declaration.
15981 ///
15982 /// @param size_in_bits the size of the current type_decl, in bits.
15983 ///
15984 /// @param alignment_in_bits the alignment of the current typ, in
15985 /// bits.
15986 ///
15987 /// @param locus the source location of the current type declaration.
15988 ///
15989 /// @param linkage_name the linkage_name of the current type declaration.
15990 ///
15991 /// @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)15992 type_decl::type_decl(const environment& env,
15993 const string& name,
15994 size_t size_in_bits,
15995 size_t alignment_in_bits,
15996 const location& locus,
15997 const string& linkage_name,
15998 visibility vis)
15999
16000 : type_or_decl_base(env,
16001 BASIC_TYPE
16002 | ABSTRACT_TYPE_BASE
16003 | ABSTRACT_DECL_BASE),
16004 decl_base(env, name, locus, linkage_name, vis),
16005 type_base(env, size_in_bits, alignment_in_bits)
16006 {
16007 runtime_type_instance(this);
16008
16009 integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
16010 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
16011 integral_type int_type(base_type, modifiers);
16012 if (parse_integral_type(name, int_type))
16013 {
16014 // Convert the integral_type into its canonical string
16015 // representation.
16016 string integral_type_name = int_type;
16017
16018 // Set the name of this type_decl to the canonical string
16019 // representation above
16020 set_name(integral_type_name);
16021 set_qualified_name(get_name());
16022
16023 if (!get_linkage_name().empty())
16024 set_linkage_name(integral_type_name);
16025 }
16026 }
16027
16028 /// Compares two instances of @ref type_decl.
16029 ///
16030 /// If the two intances are different, set a bitfield to give some
16031 /// insight about the kind of differences there are.
16032 ///
16033 /// @param l the first artifact of the comparison.
16034 ///
16035 /// @param r the second artifact of the comparison.
16036 ///
16037 /// @param k a pointer to a bitfield that gives information about the
16038 /// kind of changes there are between @p l and @p r. This one is set
16039 /// iff @p k is non-null and the function returns false.
16040 ///
16041 /// Please note that setting k to a non-null value does have a
16042 /// negative performance impact because even if @p l and @p r are not
16043 /// equal, the function keeps up the comparison in order to determine
16044 /// the different kinds of ways in which they are different.
16045 ///
16046 /// @return true if @p l equals @p r, false otherwise.
16047 bool
equals(const type_decl & l,const type_decl & r,change_kind * k)16048 equals(const type_decl& l, const type_decl& r, change_kind* k)
16049 {
16050 bool result = false;
16051
16052 // Consider the types as decls to compare their decls-related
16053 // properties.
16054 result = equals(static_cast<const decl_base&>(l),
16055 static_cast<const decl_base&>(r),
16056 k);
16057 if (!k && !result)
16058 ABG_RETURN_FALSE;
16059
16060 // Now consider the types a "types' to compare their size-related
16061 // properties.
16062 result &= equals(static_cast<const type_base&>(l),
16063 static_cast<const type_base&>(r),
16064 k);
16065 ABG_RETURN(result);
16066 }
16067
16068 /// Return true if both types equals.
16069 ///
16070 /// This operator re-uses the overload that takes a decl_base.
16071 ///
16072 /// Note that this does not check the scopes of any of the types.
16073 ///
16074 /// @param o the other type_decl to check agains.
16075 bool
operator ==(const type_base & o) const16076 type_decl::operator==(const type_base& o) const
16077 {
16078 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16079 if (!other)
16080 return false;
16081 return *this == *other;
16082 }
16083
16084 /// Return true if both types equals.
16085 ///
16086 /// Note that this does not check the scopes of any of the types.
16087 ///
16088 /// @param o the other type_decl to check against.
16089 bool
operator ==(const decl_base & o) const16090 type_decl::operator==(const decl_base& o) const
16091 {
16092 const type_decl* other = dynamic_cast<const type_decl*>(&o);
16093 if (!other)
16094 return false;
16095 return try_canonical_compare(this, other);
16096 }
16097
16098 /// Return true if both types equals.
16099 ///
16100 /// Note that this does not check the scopes of any of the types.
16101 ///
16102 /// @param o the other type_decl to check against.
16103 ///
16104 /// @return true iff the current isntance equals @p o
16105 bool
operator ==(const type_decl & o) const16106 type_decl::operator==(const type_decl& o) const
16107 {
16108 const decl_base& other = o;
16109 return *this == other;
16110 }
16111
16112 /// Return true if both types equals.
16113 ///
16114 /// Note that this does not check the scopes of any of the types.
16115 ///
16116 /// @param o the other type_decl to check against.
16117 ///
16118 /// @return true iff the current isntance equals @p o
16119 bool
operator !=(const type_base & o) const16120 type_decl::operator!=(const type_base&o)const
16121 {return !operator==(o);}
16122
16123 /// Return true if both types equals.
16124 ///
16125 /// Note that this does not check the scopes of any of the types.
16126 ///
16127 /// @param o the other type_decl to check against.
16128 ///
16129 /// @return true iff the current isntance equals @p o
16130 bool
operator !=(const decl_base & o) const16131 type_decl::operator!=(const decl_base&o)const
16132 {return !operator==(o);}
16133
16134 /// Inequality operator.
16135 ///
16136 /// @param o the other type to compare against.
16137 ///
16138 /// @return true iff the current instance is different from @p o.
16139 bool
operator !=(const type_decl & o) const16140 type_decl::operator!=(const type_decl& o) const
16141 {return !operator==(o);}
16142
16143 /// Equality operator for @ref type_decl_sptr.
16144 ///
16145 /// @param l the first operand to compare.
16146 ///
16147 /// @param r the second operand to compare.
16148 ///
16149 /// @return true iff @p l equals @p r.
16150 bool
operator ==(const type_decl_sptr & l,const type_decl_sptr & r)16151 operator==(const type_decl_sptr& l, const type_decl_sptr& r)
16152 {
16153 if (!!l != !!r)
16154 return false;
16155 if (l.get() == r.get())
16156 return true;
16157 return *l == *r;
16158 }
16159
16160 /// Inequality operator for @ref type_decl_sptr.
16161 ///
16162 /// @param l the first operand to compare.
16163 ///
16164 /// @param r the second operand to compare.
16165 ///
16166 /// @return true iff @p l is different from @p r.
16167 bool
operator !=(const type_decl_sptr & l,const type_decl_sptr & r)16168 operator!=(const type_decl_sptr& l, const type_decl_sptr& r)
16169 {return !operator==(l, r);}
16170
16171 /// Implementation for the virtual qualified name builder for @ref
16172 /// type_decl.
16173 ///
16174 /// @param qualified_name the output parameter to hold the resulting
16175 /// qualified name.
16176 ///
16177 /// @param internal set to true if the call is intended for an
16178 /// internal use (for technical use inside the library itself), false
16179 /// otherwise. If you don't know what this is for, then set it to
16180 /// false.
16181 void
get_qualified_name(interned_string & qualified_name,bool internal) const16182 type_decl::get_qualified_name(interned_string& qualified_name,
16183 bool internal) const
16184 {qualified_name = get_qualified_name(internal);}
16185
16186 /// Implementation for the virtual qualified name builder for @ref
16187 /// type_decl.
16188 ///
16189 /// @param qualified_name the output parameter to hold the resulting
16190 /// qualified name.
16191 ///
16192 /// @param internal set to true if the call is intended for an
16193 /// internal use (for technical use inside the library itself), false
16194 /// otherwise. If you don't know what this is for, then set it to
16195 /// false.
16196 const interned_string&
get_qualified_name(bool internal) const16197 type_decl::get_qualified_name(bool internal) const
16198 {
16199 const environment& env = get_environment();
16200
16201
16202 if (internal)
16203 if (is_integral_type(this))
16204 {
16205 if (get_naked_canonical_type())
16206 {
16207 if (decl_base::priv_->internal_qualified_name_.empty())
16208 decl_base::priv_->internal_qualified_name_ =
16209 env.intern(get_internal_integral_type_name(this));
16210 return decl_base::priv_->internal_qualified_name_;
16211 }
16212 else
16213 {
16214 decl_base::priv_->temporary_internal_qualified_name_ =
16215 env.intern(get_internal_integral_type_name(this));
16216 return decl_base::priv_->temporary_internal_qualified_name_;
16217 }
16218 }
16219
16220 return decl_base::get_qualified_name(/*internal=*/false);
16221 }
16222
16223 /// Get the pretty representation of the current instance of @ref
16224 /// type_decl.
16225 ///
16226 /// @param internal set to true if the call is intended to get a
16227 /// representation of the decl (or type) for the purpose of canonical
16228 /// type comparison. This is mainly used in the function
16229 /// type_base::get_canonical_type_for().
16230 ///
16231 /// In other words if the argument for this parameter is true then the
16232 /// call is meant for internal use (for technical use inside the
16233 /// library itself), false otherwise. If you don't know what this is
16234 /// for, then set it to false.
16235 ///
16236 /// @param qualified_name if true, names emitted in the pretty
16237 /// representation are fully qualified.
16238 ///
16239 /// @return the pretty representatin of the @ref type_decl.
16240 string
get_pretty_representation(bool internal,bool qualified_name) const16241 type_decl::get_pretty_representation(bool internal,
16242 bool qualified_name) const
16243 {
16244 if (internal)
16245 if (is_integral_type(this))
16246 return get_internal_integral_type_name(this);
16247
16248 if (qualified_name)
16249 return get_qualified_name(internal);
16250 return get_name();
16251 }
16252
16253 /// This implements the ir_traversable_base::traverse pure virtual
16254 /// function.
16255 ///
16256 /// @param v the visitor used on the current instance.
16257 ///
16258 /// @return true if the entire IR node tree got traversed, false
16259 /// otherwise.
16260 bool
traverse(ir_node_visitor & v)16261 type_decl::traverse(ir_node_visitor& v)
16262 {
16263 if (v.type_node_has_been_visited(this))
16264 return true;
16265
16266 v.visit_begin(this);
16267 bool result = v.visit_end(this);
16268 v.mark_type_node_as_visited(this);
16269
16270 return result;
16271 }
16272
~type_decl()16273 type_decl::~type_decl()
16274 {}
16275 //</type_decl definitions>
16276
16277 // <scope_type_decl definitions>
16278
16279 /// Constructor.
16280 ///
16281 /// @param env the environment we are operating from.
16282 ///
16283 /// @param name the name of the type.
16284 ///
16285 /// @param size_in_bits the size of the type, in bits.
16286 ///
16287 /// @param alignment_in_bits the alignment of the type, in bits.
16288 ///
16289 /// @param locus the source location where the type is defined.
16290 ///
16291 /// @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)16292 scope_type_decl::scope_type_decl(const environment& env,
16293 const string& name,
16294 size_t size_in_bits,
16295 size_t alignment_in_bits,
16296 const location& locus,
16297 visibility vis)
16298 : type_or_decl_base(env,
16299 ABSTRACT_SCOPE_TYPE_DECL
16300 | ABSTRACT_TYPE_BASE
16301 | ABSTRACT_DECL_BASE),
16302 decl_base(env, name, locus, "", vis),
16303 type_base(env, size_in_bits, alignment_in_bits),
16304 scope_decl(env, name, locus)
16305 {}
16306
16307 /// Compares two instances of @ref scope_type_decl.
16308 ///
16309 /// If the two intances are different, set a bitfield to give some
16310 /// insight about the kind of differences there are.
16311 ///
16312 /// @param l the first artifact of the comparison.
16313 ///
16314 /// @param r the second artifact of the comparison.
16315 ///
16316 /// @param k a pointer to a bitfield that gives information about the
16317 /// kind of changes there are between @p l and @p r. This one is set
16318 /// iff @p k is non-null and the function returns false.
16319 ///
16320 /// Please note that setting k to a non-null value does have a
16321 /// negative performance impact because even if @p l and @p r are not
16322 /// equal, the function keeps up the comparison in order to determine
16323 /// the different kinds of ways in which they are different.
16324 ///
16325 /// @return true if @p l equals @p r, false otherwise.
16326 bool
equals(const scope_type_decl & l,const scope_type_decl & r,change_kind * k)16327 equals(const scope_type_decl& l, const scope_type_decl& r, change_kind* k)
16328 {
16329 bool result = equals(static_cast<const scope_decl&>(l),
16330 static_cast<const scope_decl&>(r),
16331 k);
16332
16333 if (!k && !result)
16334 ABG_RETURN_FALSE;
16335
16336 result &= equals(static_cast<const type_base&>(l),
16337 static_cast<const type_base&>(r),
16338 k);
16339
16340 ABG_RETURN(result);
16341 }
16342
16343 /// Equality operator between two scope_type_decl.
16344 ///
16345 /// Note that this function does not consider the scope of the scope
16346 /// types themselves.
16347 ///
16348 /// @return true iff both scope types are equal.
16349 bool
operator ==(const decl_base & o) const16350 scope_type_decl::operator==(const decl_base& o) const
16351 {
16352 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
16353 if (!other)
16354 return false;
16355 return try_canonical_compare(this, other);
16356 }
16357
16358 /// Equality operator between two scope_type_decl.
16359 ///
16360 /// This re-uses the equality operator that takes a decl_base.
16361 ///
16362 /// @param o the other scope_type_decl to compare against.
16363 ///
16364 /// @return true iff both scope types are equal.
16365 bool
operator ==(const type_base & o) const16366 scope_type_decl::operator==(const type_base& o) const
16367 {
16368 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16369 if (!other)
16370 return false;
16371
16372 return *this == *other;
16373 }
16374
16375 /// Traverses an instance of @ref scope_type_decl, visiting all the
16376 /// sub-types and decls that it might contain.
16377 ///
16378 /// @param v the visitor that is used to visit every IR sub-node of
16379 /// the current node.
16380 ///
16381 /// @return true if either
16382 /// - all the children nodes of the current IR node were traversed
16383 /// and the calling code should keep going with the traversing.
16384 /// - or the current IR node is already being traversed.
16385 /// Otherwise, returning false means that the calling code should not
16386 /// keep traversing the tree.
16387 bool
traverse(ir_node_visitor & v)16388 scope_type_decl::traverse(ir_node_visitor& v)
16389 {
16390 if (visiting())
16391 return true;
16392
16393 if (v.type_node_has_been_visited(this))
16394 return true;
16395
16396 if (v.visit_begin(this))
16397 {
16398 visiting(true);
16399 for (scope_decl::declarations::const_iterator i =
16400 get_member_decls().begin();
16401 i != get_member_decls ().end();
16402 ++i)
16403 if (!(*i)->traverse(v))
16404 break;
16405 visiting(false);
16406 }
16407
16408 bool result = v.visit_end(this);
16409 v.mark_type_node_as_visited(this);
16410
16411 return result;
16412 }
16413
~scope_type_decl()16414 scope_type_decl::~scope_type_decl()
16415 {}
16416 // </scope_type_decl definitions>
16417
16418 // <namespace_decl>
16419
16420 /// Constructor.
16421 ///
16422 /// @param the environment we are operatin from.
16423 ///
16424 /// @param name the name of the namespace.
16425 ///
16426 /// @param locus the source location where the namespace is defined.
16427 ///
16428 /// @param vis the visibility of the namespace.
namespace_decl(const environment & env,const string & name,const location & locus,visibility vis)16429 namespace_decl::namespace_decl(const environment& env,
16430 const string& name,
16431 const location& locus,
16432 visibility vis)
16433 // We need to call the constructor of decl_base directly here
16434 // because it is virtually inherited by scope_decl. Note that we
16435 // just implicitely call the default constructor for scope_decl
16436 // here, as what we really want is to initialize the decl_base
16437 // subobject. Wow, virtual inheritance is useful, but setting it
16438 // up is ugly.
16439 : type_or_decl_base(env,
16440 NAMESPACE_DECL
16441 | ABSTRACT_DECL_BASE
16442 | ABSTRACT_SCOPE_DECL),
16443 decl_base(env, name, locus, "", vis),
16444 scope_decl(env, name, locus)
16445 {
16446 runtime_type_instance(this);
16447 }
16448
16449 /// Build and return a copy of the pretty representation of the
16450 /// namespace.
16451 ///
16452 /// @param internal set to true if the call is intended to get a
16453 /// representation of the decl (or type) for the purpose of canonical
16454 /// type comparison. This is mainly used in the function
16455 /// type_base::get_canonical_type_for().
16456 ///
16457 /// In other words if the argument for this parameter is true then the
16458 /// call is meant for internal use (for technical use inside the
16459 /// library itself), false otherwise. If you don't know what this is
16460 /// for, then set it to false.
16461 ///
16462 /// @param qualified_name if true, names emitted in the pretty
16463 /// representation are fully qualified.
16464 ///
16465 /// @return a copy of the pretty representation of the namespace.
16466 string
get_pretty_representation(bool internal,bool qualified_name) const16467 namespace_decl::get_pretty_representation(bool internal,
16468 bool qualified_name) const
16469 {
16470 string r =
16471 "namespace " + scope_decl::get_pretty_representation(internal,
16472 qualified_name);
16473 return r;
16474 }
16475
16476 /// Return true iff both namespaces and their members are equal.
16477 ///
16478 /// Note that this function does not check if the scope of these
16479 /// namespaces are equal.
16480 bool
operator ==(const decl_base & o) const16481 namespace_decl::operator==(const decl_base& o) const
16482 {
16483 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
16484 if (!other)
16485 return false;
16486 return scope_decl::operator==(*other);
16487 }
16488
16489 /// Test if the current namespace_decl is empty or contains empty
16490 /// namespaces itself.
16491 ///
16492 /// @return true iff the current namespace_decl is empty or contains
16493 /// empty itself.
16494 bool
is_empty_or_has_empty_sub_namespaces() const16495 namespace_decl::is_empty_or_has_empty_sub_namespaces() const
16496 {
16497 if (is_empty())
16498 return true;
16499
16500 for (declarations::const_iterator i = get_member_decls().begin();
16501 i != get_member_decls().end();
16502 ++i)
16503 {
16504 if (!is_namespace(*i))
16505 return false;
16506
16507 namespace_decl_sptr ns = is_namespace(*i);
16508 ABG_ASSERT(ns);
16509
16510 if (!ns->is_empty_or_has_empty_sub_namespaces())
16511 return false;
16512 }
16513
16514 return true;
16515 }
16516
16517 /// This implements the ir_traversable_base::traverse pure virtual
16518 /// function.
16519 ///
16520 /// @param v the visitor used on the current instance and on its
16521 /// member nodes.
16522 ///
16523 /// @return true if the entire IR node tree got traversed, false
16524 /// otherwise.
16525 bool
traverse(ir_node_visitor & v)16526 namespace_decl::traverse(ir_node_visitor& v)
16527 {
16528 if (visiting())
16529 return true;
16530
16531 if (v.visit_begin(this))
16532 {
16533 visiting(true);
16534 scope_decl::declarations::const_iterator i;
16535 for (i = get_member_decls().begin();
16536 i != get_member_decls ().end();
16537 ++i)
16538 {
16539 ir_traversable_base_sptr t =
16540 dynamic_pointer_cast<ir_traversable_base>(*i);
16541 if (t)
16542 if (!t->traverse (v))
16543 break;
16544 }
16545 visiting(false);
16546 }
16547 return v.visit_end(this);
16548 }
16549
~namespace_decl()16550 namespace_decl::~namespace_decl()
16551 {
16552 }
16553
16554 // </namespace_decl>
16555
16556 // <qualified_type_def>
16557
16558 /// Type of the private data of qualified_type_def.
16559 class qualified_type_def::priv
16560 {
16561 friend class qualified_type_def;
16562
16563 qualified_type_def::CV cv_quals_;
16564 // Before the type is canonicalized, this is used as a temporary
16565 // internal name.
16566 interned_string temporary_internal_name_;
16567 // Once the type is canonicalized, this is used as the internal
16568 // name.
16569 interned_string internal_name_;
16570 weak_ptr<type_base> underlying_type_;
16571
priv()16572 priv()
16573 : cv_quals_(CV_NONE)
16574 {}
16575
priv(qualified_type_def::CV quals,type_base_sptr t)16576 priv(qualified_type_def::CV quals,
16577 type_base_sptr t)
16578 : cv_quals_(quals),
16579 underlying_type_(t)
16580 {}
16581
priv(qualified_type_def::CV quals)16582 priv(qualified_type_def::CV quals)
16583 : cv_quals_(quals)
16584 {}
16585 };// end class qualified_type_def::priv
16586
16587 /// Build the name of the current instance of qualified type.
16588 ///
16589 /// @param fully_qualified if true, build a fully qualified name.
16590 ///
16591 /// @param internal set to true if the call is intended for an
16592 /// internal use (for technical use inside the library itself), false
16593 /// otherwise. If you don't know what this is for, then set it to
16594 /// false.
16595 ///
16596 /// @return a copy of the newly-built name.
16597 string
build_name(bool fully_qualified,bool internal) const16598 qualified_type_def::build_name(bool fully_qualified, bool internal) const
16599 {
16600 type_base_sptr t = get_underlying_type();
16601 if (!t)
16602 // The qualified type might temporarily have no underlying type,
16603 // especially during the construction of the type, while the
16604 // underlying type is not yet constructed. In that case, let's do
16605 // like if the underlying type is the 'void' type.
16606 t = get_environment().get_void_type();
16607
16608 return get_name_of_qualified_type(t, get_cv_quals(),
16609 fully_qualified,
16610 internal);
16611 }
16612
16613 /// This function is automatically invoked whenever an instance of
16614 /// this type is canonicalized.
16615 ///
16616 /// It's an overload of the virtual type_base::on_canonical_type_set.
16617 ///
16618 /// We put here what is thus meant to be executed only at the point of
16619 /// type canonicalization.
16620 void
on_canonical_type_set()16621 qualified_type_def::on_canonical_type_set()
16622 {clear_qualified_name();}
16623
16624 /// Constructor of the qualified_type_def
16625 ///
16626 /// @param type the underlying type
16627 ///
16628 /// @param quals a bitfield representing the const/volatile qualifiers
16629 ///
16630 /// @param locus the location of the qualified type definition
qualified_type_def(type_base_sptr type,CV quals,const location & locus)16631 qualified_type_def::qualified_type_def(type_base_sptr type,
16632 CV quals,
16633 const location& locus)
16634 : type_or_decl_base(type->get_environment(),
16635 QUALIFIED_TYPE
16636 | ABSTRACT_TYPE_BASE
16637 | ABSTRACT_DECL_BASE),
16638 type_base(type->get_environment(), type->get_size_in_bits(),
16639 type->get_alignment_in_bits()),
16640 decl_base(type->get_environment(), "", locus, "",
16641 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
16642 priv_(new priv(quals, type))
16643 {
16644 runtime_type_instance(this);
16645 interned_string name = type->get_environment().intern(build_name(false));
16646 set_name(name);
16647 }
16648
16649 /// Constructor of the qualified_type_def
16650 ///
16651 /// @param env the environment of the type.
16652 ///
16653 /// @param quals a bitfield representing the const/volatile qualifiers
16654 ///
16655 /// @param locus the location of the qualified type definition
qualified_type_def(const environment & env,CV quals,const location & locus)16656 qualified_type_def::qualified_type_def(const environment& env,
16657 CV quals,
16658 const location& locus)
16659 : type_or_decl_base(env,
16660 QUALIFIED_TYPE
16661 | ABSTRACT_TYPE_BASE
16662 | ABSTRACT_DECL_BASE),
16663 type_base(env, /*size_in_bits=*/0,
16664 /*alignment_in_bits=*/0),
16665 decl_base(env, "", locus, ""),
16666 priv_(new priv(quals))
16667 {
16668 runtime_type_instance(this);
16669 // We don't yet have an underlying type. So for naming purpose,
16670 // let's temporarily pretend the underlying type is 'void'.
16671 interned_string name = env.intern("void");
16672 set_name(name);
16673 }
16674
16675 /// Get the size of the qualified type def.
16676 ///
16677 /// This is an overload for type_base::get_size_in_bits().
16678 ///
16679 /// @return the size of the qualified type.
16680 size_t
get_size_in_bits() const16681 qualified_type_def::get_size_in_bits() const
16682 {
16683 size_t s = 0;
16684 if (type_base_sptr ut = get_underlying_type())
16685 {
16686 // We do have the underlying type properly set, so let's make
16687 // the size of the qualified type match the size of its
16688 // underlying type.
16689 s = ut->get_size_in_bits();
16690 if (s != type_base::get_size_in_bits())
16691 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
16692 }
16693 return type_base::get_size_in_bits();
16694 }
16695
16696 /// Compares two instances of @ref qualified_type_def.
16697 ///
16698 /// If the two intances are different, set a bitfield to give some
16699 /// insight about the kind of differences there are.
16700 ///
16701 /// @param l the first artifact of the comparison.
16702 ///
16703 /// @param r the second artifact of the comparison.
16704 ///
16705 /// @param k a pointer to a bitfield that gives information about the
16706 /// kind of changes there are between @p l and @p r. This one is set
16707 /// iff @p k is non-null and the function returns false.
16708 ///
16709 /// Please note that setting k to a non-null value does have a
16710 /// negative performance impact because even if @p l and @p r are not
16711 /// equal, the function keeps up the comparison in order to determine
16712 /// the different kinds of ways in which they are different.
16713 ///
16714 /// @return true if @p l equals @p r, false otherwise.
16715 bool
equals(const qualified_type_def & l,const qualified_type_def & r,change_kind * k)16716 equals(const qualified_type_def& l, const qualified_type_def& r, change_kind* k)
16717 {
16718 bool result = true;
16719 if (l.get_cv_quals() != r.get_cv_quals())
16720 {
16721 result = false;
16722 if (k)
16723 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
16724 else
16725 ABG_RETURN_FALSE;
16726 }
16727
16728 if (l.get_underlying_type() != r.get_underlying_type())
16729 {
16730 result = false;
16731 if (k)
16732 {
16733 if (!types_have_similar_structure(l.get_underlying_type().get(),
16734 r.get_underlying_type().get()))
16735 // Underlying type changes in which the structure of the
16736 // type changed are considered local changes to the
16737 // qualified type.
16738 *k |= LOCAL_TYPE_CHANGE_KIND;
16739 else
16740 *k |= SUBTYPE_CHANGE_KIND;
16741 }
16742 else
16743 // okay strictly speaking this is not necessary, but I am
16744 // putting it here to maintenance; that is, so that adding
16745 // subsequent clauses needed to compare two qualified types
16746 // later still works.
16747 ABG_RETURN_FALSE;
16748 }
16749
16750 ABG_RETURN(result);
16751 }
16752
16753 /// Equality operator for qualified types.
16754 ///
16755 /// Note that this function does not check for equality of the scopes.
16756 ///
16757 ///@param o the other qualified type to compare against.
16758 ///
16759 /// @return true iff both qualified types are equal.
16760 bool
operator ==(const decl_base & o) const16761 qualified_type_def::operator==(const decl_base& o) const
16762 {
16763 const qualified_type_def* other =
16764 dynamic_cast<const qualified_type_def*>(&o);
16765 if (!other)
16766 return false;
16767 return try_canonical_compare(this, other);
16768 }
16769
16770 /// Equality operator for qualified types.
16771 ///
16772 /// Note that this function does not check for equality of the scopes.
16773 /// Also, this re-uses the equality operator above that takes a
16774 /// decl_base.
16775 ///
16776 ///@param o the other qualified type to compare against.
16777 ///
16778 /// @return true iff both qualified types are equal.
16779 bool
operator ==(const type_base & o) const16780 qualified_type_def::operator==(const type_base& o) const
16781 {
16782 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16783 if (!other)
16784 return false;
16785 return *this == *other;
16786 }
16787
16788 /// Equality operator for qualified types.
16789 ///
16790 /// Note that this function does not check for equality of the scopes.
16791 /// Also, this re-uses the equality operator above that takes a
16792 /// decl_base.
16793 ///
16794 ///@param o the other qualified type to compare against.
16795 ///
16796 /// @return true iff both qualified types are equal.
16797 bool
operator ==(const qualified_type_def & o) const16798 qualified_type_def::operator==(const qualified_type_def& o) const
16799 {
16800 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16801 if (!other)
16802 return false;
16803 return *this == *other;
16804 }
16805
16806 /// Implementation for the virtual qualified name builder for @ref
16807 /// qualified_type_def.
16808 ///
16809 /// @param qualified_name the output parameter to hold the resulting
16810 /// qualified name.
16811 ///
16812 /// @param internal set to true if the call is intended for an
16813 /// internal use (for technical use inside the library itself), false
16814 /// otherwise. If you don't know what this is for, then set it to
16815 /// false.
16816 void
get_qualified_name(interned_string & qualified_name,bool internal) const16817 qualified_type_def::get_qualified_name(interned_string& qualified_name,
16818 bool internal) const
16819 {qualified_name = get_qualified_name(internal);}
16820
16821 /// Implementation of the virtual qualified name builder/getter.
16822 ///
16823 /// @param internal set to true if the call is intended for an
16824 /// internal use (for technical use inside the library itself), false
16825 /// otherwise. If you don't know what this is for, then set it to
16826 /// false.
16827 ///
16828 /// @return the resulting qualified name.
16829 const interned_string&
get_qualified_name(bool internal) const16830 qualified_type_def::get_qualified_name(bool internal) const
16831 {
16832 const environment& env = get_environment();
16833
16834
16835 if (!get_canonical_type())
16836 {
16837 // The type hasn't been canonicalized yet. We want to return a
16838 // temporary name that is not cached because the structure of
16839 // this type (and so its name) can change until its
16840 // canonicalized.
16841 if (internal)
16842 {
16843 // We are asked to return a temporary *internal* name.
16844 // Lets compute it and return a reference to where it's
16845 // stored.
16846 priv_->temporary_internal_name_ =
16847 env.intern(build_name(true, /*internal=*/true));
16848 return priv_->temporary_internal_name_;
16849 }
16850 else
16851 {
16852 // We are asked to return a temporary non-internal name.
16853 set_temporary_qualified_name
16854 (env.intern(build_name(true, /*internal=*/false)));
16855 return peek_temporary_qualified_name();
16856 }
16857 }
16858 else
16859 {
16860 // The type has already been canonicalized. We want to return
16861 // the definitive name and cache it.
16862 if (internal)
16863 {
16864 if (priv_->internal_name_.empty())
16865 priv_->internal_name_ =
16866 env.intern(build_name(/*qualified=*/true,
16867 /*internal=*/true));
16868 return priv_->internal_name_;
16869 }
16870 else
16871 {
16872 if (peek_qualified_name().empty())
16873 set_qualified_name
16874 (env.intern(build_name(/*qualified=*/true,
16875 /*internal=*/false)));
16876 return peek_qualified_name();
16877 }
16878 }
16879 }
16880
16881 /// This implements the ir_traversable_base::traverse pure virtual
16882 /// function.
16883 ///
16884 /// @param v the visitor used on the current instance.
16885 ///
16886 /// @return true if the entire IR node tree got traversed, false
16887 /// otherwise.
16888 bool
traverse(ir_node_visitor & v)16889 qualified_type_def::traverse(ir_node_visitor& v)
16890 {
16891 if (v.type_node_has_been_visited(this))
16892 return true;
16893
16894 if (visiting())
16895 return true;
16896
16897 if (v.visit_begin(this))
16898 {
16899 visiting(true);
16900 if (type_base_sptr t = get_underlying_type())
16901 t->traverse(v);
16902 visiting(false);
16903 }
16904 bool result = v.visit_end(this);
16905 v.mark_type_node_as_visited(this);
16906 return result;
16907 }
16908
~qualified_type_def()16909 qualified_type_def::~qualified_type_def()
16910 {
16911 }
16912
16913 /// Getter of the const/volatile qualifier bit field
16914 qualified_type_def::CV
get_cv_quals() const16915 qualified_type_def::get_cv_quals() const
16916 {return priv_->cv_quals_;}
16917
16918 /// Setter of the const/value qualifiers bit field
16919 void
set_cv_quals(CV cv_quals)16920 qualified_type_def::set_cv_quals(CV cv_quals)
16921 {priv_->cv_quals_ = cv_quals;}
16922
16923 /// Compute and return the string prefix or suffix representing the
16924 /// qualifiers hold by the current instance of @ref
16925 /// qualified_type_def.
16926 ///
16927 /// @return the newly-built cv string.
16928 string
get_cv_quals_string_prefix() const16929 qualified_type_def::get_cv_quals_string_prefix() const
16930 {return get_string_representation_of_cv_quals(priv_->cv_quals_);}
16931
16932 /// Getter of the underlying type
16933 type_base_sptr
get_underlying_type() const16934 qualified_type_def::get_underlying_type() const
16935 {return priv_->underlying_type_.lock();}
16936
16937 /// Setter of the underlying type.
16938 ///
16939 /// @param t the new underlying type.
16940 void
set_underlying_type(const type_base_sptr & t)16941 qualified_type_def::set_underlying_type(const type_base_sptr& t)
16942 {
16943 ABG_ASSERT(t);
16944 priv_->underlying_type_ = t;
16945 // Now we need to update other properties that depend on the new underlying type.
16946 set_size_in_bits(t->get_size_in_bits());
16947 set_alignment_in_bits(t->get_alignment_in_bits());
16948 interned_string name = get_environment().intern(build_name(false));
16949 set_name(name);
16950 if (scope_decl* s = get_scope())
16951 {
16952 // Now that the name has been updated, we need to update the
16953 // lookup maps accordingly.
16954 scope_decl::declarations::iterator i;
16955 if (s->find_iterator_for_member(this, i))
16956 maybe_update_types_lookup_map(*i);
16957 else
16958 ABG_ASSERT_NOT_REACHED;
16959 }
16960 }
16961
16962 /// Non-member equality operator for @ref qualified_type_def
16963 ///
16964 /// @param l the left-hand side of the equality operator
16965 ///
16966 /// @param r the right-hand side of the equality operator
16967 ///
16968 /// @return true iff @p l and @p r equals.
16969 bool
operator ==(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)16970 operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
16971 {
16972 if (l.get() == r.get())
16973 return true;
16974 if (!!l != !!r)
16975 return false;
16976
16977 return *l == *r;
16978 }
16979
16980 /// Non-member inequality operator for @ref qualified_type_def
16981 ///
16982 /// @param l the left-hand side of the equality operator
16983 ///
16984 /// @param r the right-hand side of the equality operator
16985 ///
16986 /// @return true iff @p l and @p r equals.
16987 bool
operator !=(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)16988 operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
16989 {return ! operator==(l, r);}
16990
16991 /// Overloaded bitwise OR operator for cv qualifiers.
16992 qualified_type_def::CV
operator |(qualified_type_def::CV lhs,qualified_type_def::CV rhs)16993 operator|(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
16994 {
16995 return static_cast<qualified_type_def::CV>
16996 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
16997 }
16998
16999 /// Overloaded bitwise |= operator for cv qualifiers.
17000 qualified_type_def::CV&
operator |=(qualified_type_def::CV & l,qualified_type_def::CV r)17001 operator|=(qualified_type_def::CV& l, qualified_type_def::CV r)
17002 {
17003 l = l | r;
17004 return l;
17005 }
17006
17007 /// Overloaded bitwise &= operator for cv qualifiers.
17008 qualified_type_def::CV&
operator &=(qualified_type_def::CV & l,qualified_type_def::CV r)17009 operator&=(qualified_type_def::CV& l, qualified_type_def::CV r)
17010 {
17011 l = l & r;
17012 return l;
17013 }
17014
17015 /// Overloaded bitwise AND operator for CV qualifiers.
17016 qualified_type_def::CV
operator &(qualified_type_def::CV lhs,qualified_type_def::CV rhs)17017 operator&(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
17018 {
17019 return static_cast<qualified_type_def::CV>
17020 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
17021 }
17022
17023 /// Overloaded bitwise inverting operator for CV qualifiers.
17024 qualified_type_def::CV
operator ~(qualified_type_def::CV q)17025 operator~(qualified_type_def::CV q)
17026 {return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
17027
17028 /// Streaming operator for qualified_type_decl::CV
17029 ///
17030 /// @param o the output stream to serialize the cv qualifier to.
17031 ///
17032 /// @param cv the cv qualifier to serialize.
17033 ///
17034 /// @return the output stream used.
17035 std::ostream&
operator <<(std::ostream & o,qualified_type_def::CV cv)17036 operator<<(std::ostream& o, qualified_type_def::CV cv)
17037 {
17038 string str;
17039
17040 switch (cv)
17041 {
17042 case qualified_type_def::CV_NONE:
17043 str = "none";
17044 break;
17045 case qualified_type_def::CV_CONST:
17046 str = "const";
17047 break;
17048 case qualified_type_def::CV_VOLATILE:
17049 str = "volatile";
17050 break;
17051 case qualified_type_def::CV_RESTRICT:
17052 str = "restrict";
17053 break;
17054 }
17055
17056 o << str;
17057 return o;
17058 }
17059
17060 // </qualified_type_def>
17061
17062 //<pointer_type_def definitions>
17063
17064 /// Private data structure of the @ref pointer_type_def.
17065 struct pointer_type_def::priv
17066 {
17067 type_base_wptr pointed_to_type_;
17068 type_base* naked_pointed_to_type_;
17069 interned_string internal_qualified_name_;
17070 interned_string temp_internal_qualified_name_;
17071
privabigail::ir::pointer_type_def::priv17072 priv(const type_base_sptr& t)
17073 : pointed_to_type_(type_or_void(t, t->get_environment())),
17074 naked_pointed_to_type_(t.get())
17075 {}
17076
privabigail::ir::pointer_type_def::priv17077 priv()
17078 : naked_pointed_to_type_()
17079 {}
17080 }; //end struct pointer_type_def
17081
17082 /// This function is automatically invoked whenever an instance of
17083 /// this type is canonicalized.
17084 ///
17085 /// It's an overload of the virtual type_base::on_canonical_type_set.
17086 ///
17087 /// We put here what is thus meant to be executed only at the point of
17088 /// type canonicalization.
17089 void
on_canonical_type_set()17090 pointer_type_def::on_canonical_type_set()
17091 {clear_qualified_name();}
17092
17093
17094 ///Constructor of @ref pointer_type_def.
17095 ///
17096 /// @param pointed_to the pointed-to type.
17097 ///
17098 /// @param size_in_bits the size of the type, in bits.
17099 ///
17100 /// @param align_in_bits the alignment of the type, in bits.
17101 ///
17102 /// @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)17103 pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
17104 size_t size_in_bits,
17105 size_t align_in_bits,
17106 const location& locus)
17107 : type_or_decl_base(pointed_to->get_environment(),
17108 POINTER_TYPE
17109 | ABSTRACT_TYPE_BASE
17110 | ABSTRACT_DECL_BASE),
17111 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17112 decl_base(pointed_to->get_environment(), "", locus, ""),
17113 priv_(new priv(pointed_to))
17114 {
17115 runtime_type_instance(this);
17116 try
17117 {
17118 ABG_ASSERT(pointed_to);
17119 const environment& env = pointed_to->get_environment();
17120 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17121 string name = (pto ? pto->get_name() : string("void")) + "*";
17122 set_name(env.intern(name));
17123 if (pto)
17124 set_visibility(pto->get_visibility());
17125 }
17126 catch (...)
17127 {}
17128 }
17129
17130 ///Constructor of @ref pointer_type_def.
17131 ///
17132 /// @param env the environment of the type.
17133 ///
17134 /// @param size_in_bits the size of the type, in bits.
17135 ///
17136 /// @param align_in_bits the alignment of the type, in bits.
17137 ///
17138 /// @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)17139 pointer_type_def::pointer_type_def(const environment& env, size_t size_in_bits,
17140 size_t alignment_in_bits,
17141 const location& locus)
17142 : type_or_decl_base(env,
17143 POINTER_TYPE
17144 | ABSTRACT_TYPE_BASE
17145 | ABSTRACT_DECL_BASE),
17146 type_base(env, size_in_bits, alignment_in_bits),
17147 decl_base(env, "", locus, ""),
17148 priv_(new priv())
17149 {
17150 runtime_type_instance(this);
17151 string name = string("void") + "*";
17152 set_name(env.intern(name));
17153 }
17154
17155 /// Set the pointed-to type of the pointer.
17156 ///
17157 /// @param t the new pointed-to type.
17158 void
set_pointed_to_type(const type_base_sptr & t)17159 pointer_type_def::set_pointed_to_type(const type_base_sptr& t)
17160 {
17161 ABG_ASSERT(t);
17162 priv_->pointed_to_type_ = t;
17163 priv_->naked_pointed_to_type_ = t.get();
17164
17165 try
17166 {
17167 const environment& env = t->get_environment();
17168 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
17169 string name = (pto ? pto->get_name() : string("void")) + "*";
17170 set_name(env.intern(name));
17171 if (pto)
17172 set_visibility(pto->get_visibility());
17173 }
17174 catch (...)
17175 {}
17176 }
17177
17178 /// Compares two instances of @ref pointer_type_def.
17179 ///
17180 /// If the two intances are different, set a bitfield to give some
17181 /// insight about the kind of differences there are.
17182 ///
17183 /// @param l the first artifact of the comparison.
17184 ///
17185 /// @param r the second artifact of the comparison.
17186 ///
17187 /// @param k a pointer to a bitfield that gives information about the
17188 /// kind of changes there are between @p l and @p r. This one is set
17189 /// iff @p k is non-null and the function returns false.
17190 ///
17191 /// Please note that setting k to a non-null value does have a
17192 /// negative performance impact because even if @p l and @p r are not
17193 /// equal, the function keeps up the comparison in order to determine
17194 /// the different kinds of ways in which they are different.
17195 ///
17196 /// @return true if @p l equals @p r, false otherwise.
17197 bool
equals(const pointer_type_def & l,const pointer_type_def & r,change_kind * k)17198 equals(const pointer_type_def& l, const pointer_type_def& r, change_kind* k)
17199 {
17200 // In C and C++ languages, a pointer to void equals all other
17201 // pointers.
17202 if (l.get_translation_unit()
17203 && r.get_translation_unit()
17204 && is_c_language(l.get_translation_unit()->get_language())
17205 && is_c_language(r.get_translation_unit()->get_language())
17206 && (is_void_pointer_type_equivalent(&l)
17207 || is_void_pointer_type_equivalent(&r)))
17208 return true;
17209
17210 bool result = l.get_pointed_to_type() == r.get_pointed_to_type();
17211 if (!result)
17212 if (k)
17213 {
17214 if (!types_have_similar_structure(&l, &r))
17215 // pointed-to type changes in which the structure of the
17216 // type changed are considered local changes to the pointer
17217 // type.
17218 *k |= LOCAL_TYPE_CHANGE_KIND;
17219 *k |= SUBTYPE_CHANGE_KIND;
17220 }
17221
17222 ABG_RETURN(result);
17223 }
17224
17225 /// Return true iff both instances of pointer_type_def are equal.
17226 ///
17227 /// Note that this function does not check for the scopes of the this
17228 /// types.
17229 bool
operator ==(const decl_base & o) const17230 pointer_type_def::operator==(const decl_base& o) const
17231 {
17232 const pointer_type_def* other = is_pointer_type(&o);
17233 if (!other)
17234 return false;
17235 return try_canonical_compare(this, other);
17236 }
17237
17238 /// Return true iff both instances of pointer_type_def are equal.
17239 ///
17240 /// Note that this function does not check for the scopes of the
17241 /// types.
17242 ///
17243 /// @param other the other type to compare against.
17244 ///
17245 /// @return true iff @p other equals the current instance.
17246 bool
operator ==(const type_base & other) const17247 pointer_type_def::operator==(const type_base& other) const
17248 {
17249 const decl_base* o = is_decl(&other);
17250 if (!o)
17251 return false;
17252 return *this == *o;
17253 }
17254
17255 /// Return true iff both instances of pointer_type_def are equal.
17256 ///
17257 /// Note that this function does not check for the scopes of the
17258 /// types.
17259 ///
17260 /// @param other the other type to compare against.
17261 ///
17262 /// @return true iff @p other equals the current instance.
17263 bool
operator ==(const pointer_type_def & other) const17264 pointer_type_def::operator==(const pointer_type_def& other) const
17265 {
17266 const decl_base& o = other;
17267 return *this == o;
17268 }
17269
17270 /// Getter of the pointed-to type.
17271 ///
17272 /// @return the pointed-to type.
17273 const type_base_sptr
get_pointed_to_type() const17274 pointer_type_def::get_pointed_to_type() const
17275 {return priv_->pointed_to_type_.lock();}
17276
17277 /// Getter of a naked pointer to the pointed-to type.
17278 ///
17279 /// @return a naked pointed to the pointed-to type.
17280 type_base*
get_naked_pointed_to_type() const17281 pointer_type_def::get_naked_pointed_to_type() const
17282 {return priv_->naked_pointed_to_type_;}
17283
17284 /// Build and return the qualified name of the current instance of
17285 /// @ref pointer_type_def.
17286 ///
17287 /// @param qn output parameter. The resulting qualified name.
17288 ///
17289 /// @param internal set to true if the call is intended for an
17290 /// internal use (for technical use inside the library itself), false
17291 /// otherwise. If you don't know what this is for, then set it to
17292 /// false.
17293 void
get_qualified_name(interned_string & qn,bool internal) const17294 pointer_type_def::get_qualified_name(interned_string& qn, bool internal) const
17295 {qn = get_qualified_name(internal);}
17296
17297 /// Build, cache and return the qualified name of the current instance
17298 /// of @ref pointer_type_def. Subsequent invocations of this function
17299 /// return the cached value.
17300 ///
17301 /// Note that this function should work even if the underlying type is
17302 /// momentarily empty.
17303 ///
17304 /// @param internal set to true if the call is intended for an
17305 /// internal use (for technical use inside the library itself), false
17306 /// otherwise. If you don't know what this is for, then set it to
17307 /// false.
17308 ///
17309 /// @return the resulting qualified name.
17310 const interned_string&
get_qualified_name(bool internal) const17311 pointer_type_def::get_qualified_name(bool internal) const
17312 {
17313 type_base* pointed_to_type = get_naked_pointed_to_type();
17314 pointed_to_type = look_through_decl_only(pointed_to_type);
17315
17316 if (internal)
17317 {
17318 if (get_canonical_type())
17319 {
17320 if (priv_->internal_qualified_name_.empty())
17321 if (pointed_to_type)
17322 priv_->internal_qualified_name_ =
17323 get_name_of_pointer_to_type(*pointed_to_type,
17324 /*qualified_name=*/
17325 is_typedef(pointed_to_type)
17326 ? false
17327 : true,
17328 /*internal=*/true);
17329 return priv_->internal_qualified_name_;
17330 }
17331 else
17332 {
17333 // As the type hasn't yet been canonicalized, its structure
17334 // (and so its name) can change. So let's invalidate the
17335 // cache where we store its name at each invocation of this
17336 // function.
17337 if (pointed_to_type)
17338 priv_->temp_internal_qualified_name_ =
17339 get_name_of_pointer_to_type(*pointed_to_type,
17340 /*qualified_name=*/
17341 is_typedef(pointed_to_type)
17342 ? false
17343 : true,
17344 /*internal=*/true);
17345 return priv_->temp_internal_qualified_name_;
17346 }
17347 }
17348 else
17349 {
17350 if (get_naked_canonical_type())
17351 {
17352 if (decl_base::peek_qualified_name().empty())
17353 set_qualified_name
17354 (get_name_of_pointer_to_type(*pointed_to_type,
17355 /*qualified_name=*/true,
17356 /*internal=*/false));
17357 return decl_base::peek_qualified_name();
17358 }
17359 else
17360 {
17361 // As the type hasn't yet been canonicalized, its structure
17362 // (and so its name) can change. So let's invalidate the
17363 // cache where we store its name at each invocation of this
17364 // function.
17365 if (pointed_to_type)
17366 set_qualified_name
17367 (get_name_of_pointer_to_type(*pointed_to_type,
17368 /*qualified_name=*/true,
17369 /*internal=*/false));
17370 return decl_base::peek_qualified_name();
17371 }
17372 }
17373 }
17374
17375 /// This implements the ir_traversable_base::traverse pure virtual
17376 /// function.
17377 ///
17378 /// @param v the visitor used on the current instance.
17379 ///
17380 /// @return true if the entire IR node tree got traversed, false
17381 /// otherwise.
17382 bool
traverse(ir_node_visitor & v)17383 pointer_type_def::traverse(ir_node_visitor& v)
17384 {
17385 if (v.type_node_has_been_visited(this))
17386 return true;
17387
17388 if (visiting())
17389 return true;
17390
17391 if (v.visit_begin(this))
17392 {
17393 visiting(true);
17394 if (type_base_sptr t = get_pointed_to_type())
17395 t->traverse(v);
17396 visiting(false);
17397 }
17398
17399 bool result = v.visit_end(this);
17400 v.mark_type_node_as_visited(this);
17401 return result;
17402 }
17403
~pointer_type_def()17404 pointer_type_def::~pointer_type_def()
17405 {}
17406
17407 /// Turn equality of shared_ptr of @ref pointer_type_def into a deep
17408 /// equality; that is, make it compare the pointed to objects too.
17409 ///
17410 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17411 /// of the equality.
17412 ///
17413 /// @param r the shared_ptr of @ref pointer_type_def on
17414 /// right-hand-side of the equality.
17415 ///
17416 /// @return true if the @ref pointer_type_def pointed to by the
17417 /// shared_ptrs are equal, false otherwise.
17418 bool
operator ==(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)17419 operator==(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
17420 {
17421 if (l.get() == r.get())
17422 return true;
17423 if (!!l != !!r)
17424 return false;
17425
17426 return *l == *r;
17427 }
17428
17429 /// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
17430 /// equality; that is, make it compare the pointed to objects too.
17431 ///
17432 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
17433 /// of the equality.
17434 ///
17435 /// @param r the shared_ptr of @ref pointer_type_def on
17436 /// right-hand-side of the equality.
17437 ///
17438 /// @return true iff the @ref pointer_type_def pointed to by the
17439 /// shared_ptrs are different.
17440 bool
operator !=(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)17441 operator!=(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
17442 {return !operator==(l, r);}
17443
17444 // </pointer_type_def definitions>
17445
17446 // <reference_type_def definitions>
17447
17448 /// Private data structure of the @ref reference_type_def type.
17449 struct reference_type_def::priv
17450 {
17451
17452 type_base_wptr pointed_to_type_;
17453 bool is_lvalue_;
17454 interned_string internal_qualified_name_;
17455 interned_string temp_internal_qualified_name_;
17456
privabigail::ir::reference_type_def::priv17457 priv(const type_base_sptr& t, bool is_lvalue)
17458 : pointed_to_type_(type_or_void(t, t->get_environment())),
17459 is_lvalue_(is_lvalue)
17460 {}
17461
privabigail::ir::reference_type_def::priv17462 priv(bool is_lvalue)
17463 : is_lvalue_(is_lvalue)
17464 {}
17465
17466 priv() = delete;
17467 };
17468
17469 /// This function is automatically invoked whenever an instance of
17470 /// this type is canonicalized.
17471 ///
17472 /// It's an overload of the virtual type_base::on_canonical_type_set.
17473 ///
17474 /// We put here what is thus meant to be executed only at the point of
17475 /// type canonicalization.
17476 void
on_canonical_type_set()17477 reference_type_def::on_canonical_type_set()
17478 {clear_qualified_name();}
17479
17480 /// Constructor of the reference_type_def type.
17481 ///
17482 /// @param pointed_to the pointed to type.
17483 ///
17484 /// @param lvalue wether the reference is an lvalue reference. If
17485 /// false, the reference is an rvalue one.
17486 ///
17487 /// @param size_in_bits the size of the type, in bits.
17488 ///
17489 /// @param align_in_bits the alignment of the type, in bits.
17490 ///
17491 /// @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)17492 reference_type_def::reference_type_def(const type_base_sptr pointed_to,
17493 bool lvalue,
17494 size_t size_in_bits,
17495 size_t align_in_bits,
17496 const location& locus)
17497 : type_or_decl_base(pointed_to->get_environment(),
17498 REFERENCE_TYPE
17499 | ABSTRACT_TYPE_BASE
17500 | ABSTRACT_DECL_BASE),
17501 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
17502 decl_base(pointed_to->get_environment(), "", locus, ""),
17503 priv_(new priv(pointed_to, lvalue))
17504 {
17505 runtime_type_instance(this);
17506
17507 try
17508 {
17509 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
17510 string name;
17511 if (pto)
17512 {
17513 set_visibility(pto->get_visibility());
17514 name = string(pto->get_name()) + "&";
17515 }
17516 else
17517 name = string(get_type_name(is_function_type(pointed_to),
17518 /*qualified_name=*/true)) + "&";
17519
17520 if (!is_lvalue())
17521 name += "&";
17522 const environment& env = pointed_to->get_environment();
17523 set_name(env.intern(name));
17524 }
17525 catch (...)
17526 {}
17527 }
17528
17529 /// Constructor of the reference_type_def type.
17530 ///
17531 /// This one creates a type that has no pointed-to type, temporarily.
17532 /// This is useful for cases where the underlying type is not yet
17533 /// available. It can be set later using
17534 /// reference_type_def::set_pointed_to_type().
17535 ///
17536 /// @param env the environment of the type.
17537 ///
17538 /// @param lvalue wether the reference is an lvalue reference. If
17539 /// false, the reference is an rvalue one.
17540 ///
17541 /// @param size_in_bits the size of the type, in bits.
17542 ///
17543 /// @param align_in_bits the alignment of the type, in bits.
17544 ///
17545 /// @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)17546 reference_type_def::reference_type_def(const environment& env, bool lvalue,
17547 size_t size_in_bits,
17548 size_t alignment_in_bits,
17549 const location& locus)
17550 : type_or_decl_base(env,
17551 REFERENCE_TYPE
17552 | ABSTRACT_TYPE_BASE
17553 | ABSTRACT_DECL_BASE),
17554 type_base(env, size_in_bits, alignment_in_bits),
17555 decl_base(env, "", locus, ""),
17556 priv_(new priv(lvalue))
17557 {
17558 runtime_type_instance(this);
17559 string name = "void&";
17560 if (!is_lvalue())
17561 name += "&";
17562
17563 set_name(env.intern(name));
17564 priv_->pointed_to_type_ = type_base_wptr(env.get_void_type());
17565 }
17566
17567 /// Setter of the pointed_to type of the current reference type.
17568 ///
17569 /// @param pointed_to the new pointed to type.
17570 void
set_pointed_to_type(type_base_sptr & pointed_to_type)17571 reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
17572 {
17573 ABG_ASSERT(pointed_to_type);
17574 priv_->pointed_to_type_ = pointed_to_type;
17575
17576 decl_base_sptr pto;
17577 try
17578 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
17579 catch (...)
17580 {}
17581
17582 if (pto)
17583 {
17584 set_visibility(pto->get_visibility());
17585 string name = string(pto->get_name()) + "&";
17586 if (!is_lvalue())
17587 name += "&";
17588 const environment& env = pto->get_environment();
17589 set_name(env.intern(name));
17590 }
17591 }
17592
17593 /// Compares two instances of @ref reference_type_def.
17594 ///
17595 /// If the two intances are different, set a bitfield to give some
17596 /// insight about the kind of differences there are.
17597 ///
17598 /// @param l the first artifact of the comparison.
17599 ///
17600 /// @param r the second artifact of the comparison.
17601 ///
17602 /// @param k a pointer to a bitfield that gives information about the
17603 /// kind of changes there are between @p l and @p r. This one is set
17604 /// iff @p k is non-null and the function returns false.
17605 ///
17606 /// Please note that setting k to a non-null value does have a
17607 /// negative performance impact because even if @p l and @p r are not
17608 /// equal, the function keeps up the comparison in order to determine
17609 /// the different kinds of ways in which they are different.
17610 ///
17611 /// @return true if @p l equals @p r, false otherwise.
17612 bool
equals(const reference_type_def & l,const reference_type_def & r,change_kind * k)17613 equals(const reference_type_def& l, const reference_type_def& r, change_kind* k)
17614 {
17615 if (l.is_lvalue() != r.is_lvalue())
17616 {
17617 if (k)
17618 *k |= LOCAL_TYPE_CHANGE_KIND;
17619 ABG_RETURN_FALSE;
17620 }
17621
17622 // Compare the pointed-to-types modulo the typedefs they might have
17623 bool result = (l.get_pointed_to_type() == r.get_pointed_to_type());
17624 if (!result)
17625 if (k)
17626 {
17627 if (!types_have_similar_structure(&l, &r))
17628 *k |= LOCAL_TYPE_CHANGE_KIND;
17629 *k |= SUBTYPE_CHANGE_KIND;
17630 }
17631 ABG_RETURN(result);
17632 }
17633
17634 /// Equality operator of the @ref reference_type_def type.
17635 ///
17636 /// @param o the other instance of @ref reference_type_def to compare
17637 /// against.
17638 ///
17639 /// @return true iff the two instances are equal.
17640 bool
operator ==(const decl_base & o) const17641 reference_type_def::operator==(const decl_base& o) const
17642 {
17643 const reference_type_def* other =
17644 dynamic_cast<const reference_type_def*>(&o);
17645 if (!other)
17646 return false;
17647 return try_canonical_compare(this, other);
17648 }
17649
17650 /// Equality operator of the @ref reference_type_def type.
17651 ///
17652 /// @param o the other instance of @ref reference_type_def to compare
17653 /// against.
17654 ///
17655 /// @return true iff the two instances are equal.
17656 bool
operator ==(const type_base & o) const17657 reference_type_def::operator==(const type_base& o) const
17658 {
17659 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17660 if (!other)
17661 return false;
17662 return *this == *other;
17663 }
17664
17665 /// Equality operator of the @ref reference_type_def type.
17666 ///
17667 /// @param o the other instance of @ref reference_type_def to compare
17668 /// against.
17669 ///
17670 /// @return true iff the two instances are equal.
17671 bool
operator ==(const reference_type_def & o) const17672 reference_type_def::operator==(const reference_type_def& o) const
17673 {
17674 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17675 if (!other)
17676 return false;
17677 return *this == *other;
17678 }
17679
17680 type_base_sptr
get_pointed_to_type() const17681 reference_type_def::get_pointed_to_type() const
17682 {return priv_->pointed_to_type_.lock();}
17683
17684 bool
is_lvalue() const17685 reference_type_def::is_lvalue() const
17686 {return priv_->is_lvalue_;}
17687
17688 /// Build and return the qualified name of the current instance of the
17689 /// @ref reference_type_def.
17690 ///
17691 /// @param qn output parameter. Is set to the newly-built qualified
17692 /// name of the current instance of @ref reference_type_def.
17693 ///
17694 /// @param internal set to true if the call is intended for an
17695 /// internal use (for technical use inside the library itself), false
17696 /// otherwise. If you don't know what this is for, then set it to
17697 /// false.
17698 void
get_qualified_name(interned_string & qn,bool internal) const17699 reference_type_def::get_qualified_name(interned_string& qn, bool internal) const
17700 {qn = get_qualified_name(internal);}
17701
17702 /// Build, cache and return the qualified name of the current instance
17703 /// of the @ref reference_type_def. Subsequent invocations of this
17704 /// function return the cached value.
17705 ///
17706 /// @param internal set to true if the call is intended for an
17707 /// internal use (for technical use inside the library itself), false
17708 /// otherwise. If you don't know what this is for, then set it to
17709 /// false.
17710 ///
17711 /// @return the newly-built qualified name of the current instance of
17712 /// @ref reference_type_def.
17713 const interned_string&
get_qualified_name(bool internal) const17714 reference_type_def::get_qualified_name(bool internal) const
17715 {
17716 type_base_sptr pointed_to_type = get_pointed_to_type();
17717 pointed_to_type = look_through_decl_only(pointed_to_type);
17718
17719 if (internal)
17720 {
17721 if (get_canonical_type())
17722 {
17723 if (priv_->internal_qualified_name_.empty())
17724 if (pointed_to_type)
17725 priv_->internal_qualified_name_ =
17726 get_name_of_reference_to_type(*pointed_to_type,
17727 is_lvalue(),
17728 /*qualified_name=*/
17729 is_typedef(pointed_to_type)
17730 ? false
17731 : true,
17732 /*internal=*/true);
17733 return priv_->internal_qualified_name_;
17734 }
17735 else
17736 {
17737 // As the type hasn't yet been canonicalized, its structure
17738 // (and so its name) can change. So let's invalidate the
17739 // cache where we store its name at each invocation of this
17740 // function.
17741 if (pointed_to_type)
17742 priv_->temp_internal_qualified_name_ =
17743 get_name_of_reference_to_type(*pointed_to_type,
17744 is_lvalue(),
17745 /*qualified_name=*/
17746 is_typedef(pointed_to_type)
17747 ? false
17748 : true,
17749 /*internal=*/true);
17750 return priv_->temp_internal_qualified_name_;
17751 }
17752 }
17753 else
17754 {
17755 if (get_naked_canonical_type())
17756 {
17757 set_qualified_name
17758 (get_name_of_reference_to_type(*pointed_to_type,
17759 is_lvalue(),
17760 /*qualified_name=*/true,
17761 /*internal=*/false));
17762 return decl_base::peek_qualified_name();
17763 }
17764 else
17765 {
17766 // As the type hasn't yet been canonicalized, its structure
17767 // (and so its name) can change. So let's invalidate the
17768 // cache where we store its name at each invocation of this
17769 // function.
17770 if (pointed_to_type)
17771 set_qualified_name
17772 (get_name_of_reference_to_type(*pointed_to_type,
17773 is_lvalue(),
17774 /*qualified_name=*/true,
17775 /*internal=*/false));
17776 return decl_base::peek_qualified_name();
17777 }
17778 }
17779 }
17780
17781 /// Get the pretty representation of the current instance of @ref
17782 /// reference_type_def.
17783 ///
17784 /// @param internal set to true if the call is intended to get a
17785 /// representation of the decl (or type) for the purpose of canonical
17786 /// type comparison. This is mainly used in the function
17787 /// type_base::get_canonical_type_for().
17788 ///
17789 /// In other words if the argument for this parameter is true then the
17790 /// call is meant for internal use (for technical use inside the
17791 /// library itself), false otherwise. If you don't know what this is
17792 /// for, then set it to false.
17793 ///
17794 /// @param qualified_name if true, names emitted in the pretty
17795 /// representation are fully qualified.
17796 ///
17797 /// @return the pretty representatin of the @ref reference_type_def.
17798 string
get_pretty_representation(bool internal,bool qualified_name) const17799 reference_type_def::get_pretty_representation(bool internal,
17800 bool qualified_name) const
17801 {
17802 string result =
17803 get_name_of_reference_to_type(*look_through_decl_only
17804 (get_pointed_to_type()),
17805 is_lvalue(),
17806 qualified_name,
17807 internal);
17808
17809 return result;
17810 }
17811
17812 /// This implements the ir_traversable_base::traverse pure virtual
17813 /// function.
17814 ///
17815 /// @param v the visitor used on the current instance.
17816 ///
17817 /// @return true if the entire IR node tree got traversed, false
17818 /// otherwise.
17819 bool
traverse(ir_node_visitor & v)17820 reference_type_def::traverse(ir_node_visitor& v)
17821 {
17822 if (v.type_node_has_been_visited(this))
17823 return true;
17824
17825 if (visiting())
17826 return true;
17827
17828 if (v.visit_begin(this))
17829 {
17830 visiting(true);
17831 if (type_base_sptr t = get_pointed_to_type())
17832 t->traverse(v);
17833 visiting(false);
17834 }
17835
17836 bool result = v.visit_end(this);
17837 v.mark_type_node_as_visited(this);
17838 return result;
17839 }
17840
~reference_type_def()17841 reference_type_def::~reference_type_def()
17842 {}
17843
17844 /// Turn equality of shared_ptr of @ref reference_type_def into a deep
17845 /// equality; that is, make it compare the pointed to objects too.
17846 ///
17847 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
17848 /// of the equality.
17849 ///
17850 /// @param r the shared_ptr of @ref reference_type_def on
17851 /// right-hand-side of the equality.
17852 ///
17853 /// @return true if the @ref reference_type_def pointed to by the
17854 /// shared_ptrs are equal, false otherwise.
17855 bool
operator ==(const reference_type_def_sptr & l,const reference_type_def_sptr & r)17856 operator==(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
17857 {
17858 if (l.get() == r.get())
17859 return true;
17860 if (!!l != !!r)
17861 return false;
17862
17863 return *l == *r;
17864 }
17865
17866 /// Turn inequality of shared_ptr of @ref reference_type_def into a deep
17867 /// equality; that is, make it compare the pointed to objects too.
17868 ///
17869 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
17870 /// of the equality.
17871 ///
17872 /// @param r the shared_ptr of @ref reference_type_def on
17873 /// right-hand-side of the equality.
17874 ///
17875 /// @return true iff the @ref reference_type_def pointed to by the
17876 /// shared_ptrs are different.
17877 bool
operator !=(const reference_type_def_sptr & l,const reference_type_def_sptr & r)17878 operator!=(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
17879 {return !operator==(l, r);}
17880
17881 // </reference_type_def definitions>
17882
17883 // <array_type_def definitions>
17884
17885 // <array_type_def::subrange_type>
17886 array_type_def::subrange_type::~subrange_type() = default;
17887
17888 // <array_type_def::subrante_type::bound_value>
17889
17890 /// Default constructor of the @ref
17891 /// array_type_def::subrange_type::bound_value class.
17892 ///
17893 /// Constructs an unsigned bound_value of value zero.
bound_value()17894 array_type_def::subrange_type::bound_value::bound_value()
17895 : s_(UNSIGNED_SIGNEDNESS)
17896 {
17897 v_.unsigned_ = 0;
17898 }
17899
17900 /// Initialize an unsigned bound_value with a given value.
17901 ///
17902 /// @param v the initial bound value.
bound_value(uint64_t v)17903 array_type_def::subrange_type::bound_value::bound_value(uint64_t v)
17904 : s_(UNSIGNED_SIGNEDNESS)
17905 {
17906 v_.unsigned_ = v;
17907 }
17908
17909 /// Initialize a signed bound_value with a given value.
17910 ///
17911 /// @param v the initial bound value.
bound_value(int64_t v)17912 array_type_def::subrange_type::bound_value::bound_value(int64_t v)
17913 : s_(SIGNED_SIGNEDNESS)
17914 {
17915 v_.signed_ = v;
17916 }
17917
17918 /// Getter of the signedness (unsigned VS signed) of the bound value.
17919 ///
17920 /// @return the signedness of the bound value.
17921 enum array_type_def::subrange_type::bound_value::signedness
get_signedness() const17922 array_type_def::subrange_type::bound_value::get_signedness() const
17923 {return s_;}
17924
17925 /// Setter of the signedness (unsigned VS signed) of the bound value.
17926 ///
17927 /// @param s the new signedness of the bound value.
17928 void
set_signedness(enum signedness s)17929 array_type_def::subrange_type::bound_value::set_signedness(enum signedness s)
17930 { s_ = s;}
17931
17932 /// Getter of the bound value as a signed value.
17933 ///
17934 /// @return the bound value as signed.
17935 int64_t
get_signed_value() const17936 array_type_def::subrange_type::bound_value::get_signed_value() const
17937 {return v_.signed_;
17938 }
17939
17940 /// Getter of the bound value as an unsigned value.
17941 ///
17942 /// @return the bound value as unsigned.
17943 uint64_t
get_unsigned_value()17944 array_type_def::subrange_type::bound_value::get_unsigned_value()
17945 {return v_.unsigned_;}
17946
17947 /// Setter of the bound value as unsigned.
17948 ///
17949 /// @param v the new unsigned value.
17950 void
set_unsigned(uint64_t v)17951 array_type_def::subrange_type::bound_value::set_unsigned(uint64_t v)
17952 {
17953 s_ = UNSIGNED_SIGNEDNESS;
17954 v_.unsigned_ = v;
17955 }
17956
17957 /// Setter of the bound value as signed.
17958 ///
17959 /// @param v the new signed value.
17960 void
set_signed(int64_t v)17961 array_type_def::subrange_type::bound_value::set_signed(int64_t v)
17962 {
17963 s_ = SIGNED_SIGNEDNESS;
17964 v_.signed_ = v;
17965 }
17966
17967 /// Equality operator of the bound value.
17968 ///
17969 /// @param v the other bound value to compare with.
17970 ///
17971 /// @return true iff the current bound value equals @p v.
17972 bool
operator ==(const bound_value & v) const17973 array_type_def::subrange_type::bound_value::operator==(const bound_value& v) const
17974 {
17975 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
17976 }
17977
17978 // </array_type_def::subrante_type::bound_value>
17979
17980 struct array_type_def::subrange_type::priv
17981 {
17982 bound_value lower_bound_;
17983 bound_value upper_bound_;
17984 type_base_wptr underlying_type_;
17985 translation_unit::language language_;
17986 bool infinite_;
17987
privabigail::ir::array_type_def::subrange_type::priv17988 priv(bound_value ub,
17989 translation_unit::language l = translation_unit::LANG_C11)
17990 : upper_bound_(ub), language_(l), infinite_(false)
17991 {}
17992
privabigail::ir::array_type_def::subrange_type::priv17993 priv(bound_value lb, bound_value ub,
17994 translation_unit::language l = translation_unit::LANG_C11)
17995 : lower_bound_(lb), upper_bound_(ub),
17996 language_(l), infinite_(false)
17997 {}
17998
privabigail::ir::array_type_def::subrange_type::priv17999 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
18000 translation_unit::language l = translation_unit::LANG_C11)
18001 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
18002 language_(l), infinite_(false)
18003 {}
18004 };
18005
18006 /// Constructor of an array_type_def::subrange_type type.
18007 ///
18008 /// @param env the environment this type was created from.
18009 ///
18010 /// @param name the name of the subrange type.
18011 ///
18012 /// @param lower_bound the lower bound of the array. This is
18013 /// generally zero (at least for C and C++).
18014 ///
18015 /// @param upper_bound the upper bound of the array.
18016 ///
18017 /// @param underlying_type the underlying type of the subrange type.
18018 ///
18019 /// @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)18020 array_type_def::subrange_type::subrange_type(const environment& env,
18021 const string& name,
18022 bound_value lower_bound,
18023 bound_value upper_bound,
18024 const type_base_sptr& utype,
18025 const location& loc,
18026 translation_unit::language l)
18027 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18028 type_base(env,
18029 upper_bound.get_unsigned_value()
18030 - lower_bound.get_unsigned_value(),
18031 0),
18032 decl_base(env, name, loc, ""),
18033 priv_(new priv(lower_bound, upper_bound, utype, l))
18034 {
18035 runtime_type_instance(this);
18036 }
18037
18038 /// Constructor of the array_type_def::subrange_type type.
18039 ///
18040 /// @param env the environment this type is being created in.
18041 ///
18042 /// @param name the name of the subrange type.
18043 ///
18044 /// @param lower_bound the lower bound of the array. This is
18045 /// generally zero (at least for C and C++).
18046 ///
18047 /// @param upper_bound the upper bound of the array.
18048 ///
18049 /// @param loc the source location where the type is defined.
18050 ///
18051 /// @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)18052 array_type_def::subrange_type::subrange_type(const environment& env,
18053 const string& name,
18054 bound_value lower_bound,
18055 bound_value upper_bound,
18056 const location& loc,
18057 translation_unit::language l)
18058 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18059 type_base(env,
18060 upper_bound.get_unsigned_value()
18061 - lower_bound.get_unsigned_value(), 0),
18062 decl_base(env, name, loc, ""),
18063 priv_(new priv(lower_bound, upper_bound, l))
18064 {
18065 runtime_type_instance(this);
18066 }
18067
18068 /// Constructor of the array_type_def::subrange_type type.
18069 ///
18070 /// @param env the environment this type is being created from.
18071 ///
18072 /// @param name of the name of type.
18073 ///
18074 /// @param upper_bound the upper bound of the array. The lower bound
18075 /// is considered to be zero.
18076 ///
18077 /// @param loc the source location of the type.
18078 ///
18079 /// @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)18080 array_type_def::subrange_type::subrange_type(const environment& env,
18081 const string& name,
18082 bound_value upper_bound,
18083 const location& loc,
18084 translation_unit::language l)
18085 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
18086 type_base(env, upper_bound.get_unsigned_value(), 0),
18087 decl_base(env, name, loc, ""),
18088 priv_(new priv(upper_bound, l))
18089 {
18090 runtime_type_instance(this);
18091 }
18092
18093 /// Getter of the underlying type of the subrange, that is, the type
18094 /// that defines the range.
18095 ///
18096 /// @return the underlying type.
18097 type_base_sptr
get_underlying_type() const18098 array_type_def::subrange_type::get_underlying_type() const
18099 {return priv_->underlying_type_.lock();}
18100
18101 /// Setter of the underlying type of the subrange, that is, the type
18102 /// that defines the range.
18103 ///
18104 /// @param u the new underlying type.
18105 void
set_underlying_type(const type_base_sptr & u)18106 array_type_def::subrange_type::set_underlying_type(const type_base_sptr &u)
18107 {
18108 ABG_ASSERT(priv_->underlying_type_.expired());
18109 priv_->underlying_type_ = u;
18110 }
18111
18112 /// Getter of the upper bound of the subrange type.
18113 ///
18114 /// @return the upper bound of the subrange type.
18115 int64_t
get_upper_bound() const18116 array_type_def::subrange_type::get_upper_bound() const
18117 {return priv_->upper_bound_.get_signed_value();}
18118
18119 /// Getter of the lower bound of the subrange type.
18120 ///
18121 /// @return the lower bound of the subrange type.
18122 int64_t
get_lower_bound() const18123 array_type_def::subrange_type::get_lower_bound() const
18124 {return priv_->lower_bound_.get_signed_value();}
18125
18126 /// Setter of the upper bound of the subrange type.
18127 ///
18128 /// @param ub the new value of the upper bound.
18129 void
set_upper_bound(int64_t ub)18130 array_type_def::subrange_type::set_upper_bound(int64_t ub)
18131 {priv_->upper_bound_ = ub;}
18132
18133 /// Setter of the lower bound.
18134 ///
18135 /// @param lb the new value of the lower bound.
18136 void
set_lower_bound(int64_t lb)18137 array_type_def::subrange_type::set_lower_bound(int64_t lb)
18138 {priv_->lower_bound_ = lb;}
18139
18140 /// Getter of the length of the subrange type.
18141 ///
18142 /// Note that a length of zero means the array has an infinite (or
18143 /// rather a non-known) size.
18144 ///
18145 /// @return the length of the subrange type.
18146 uint64_t
get_length() const18147 array_type_def::subrange_type::get_length() const
18148 {
18149 if (is_infinite())
18150 return 0;
18151
18152 // A subrange can have an upper bound that is lower than its lower
18153 // bound. This is possible in Ada for instance. In that case, the
18154 // length of the subrange is considered to be zero.
18155 if (get_upper_bound() >= get_lower_bound())
18156 return get_upper_bound() - get_lower_bound() + 1;
18157 return 0;
18158 }
18159
18160 /// Test if the length of the subrange type is infinite.
18161 ///
18162 /// @return true iff the length of the subrange type is infinite.
18163 bool
is_infinite() const18164 array_type_def::subrange_type::is_infinite() const
18165 {return priv_->infinite_;}
18166
18167 /// Set the infinite-ness status of the subrange type.
18168 ///
18169 /// @param f true iff the length of the subrange type should be set to
18170 /// being infinite.
18171 void
is_infinite(bool f)18172 array_type_def::subrange_type::is_infinite(bool f)
18173 {priv_->infinite_ = f;}
18174
18175 /// Getter of the language that generated this type.
18176 ///
18177 /// @return the language of this type.
18178 translation_unit::language
get_language() const18179 array_type_def::subrange_type::get_language() const
18180 {return priv_->language_;}
18181
18182 /// Return a string representation of the sub range.
18183 ///
18184 /// @return the string representation of the sub range.
18185 string
as_string() const18186 array_type_def::subrange_type::as_string() const
18187 {
18188 std::ostringstream o;
18189
18190 if (is_ada_language(get_language()))
18191 {
18192 type_base_sptr underlying_type = get_underlying_type();
18193 if (underlying_type)
18194 o << ir::get_pretty_representation(underlying_type, false) << " ";
18195 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
18196 }
18197 else if (is_infinite())
18198 o << "[]";
18199 else
18200 o << "[" << get_length() << "]";
18201
18202 return o.str();
18203 }
18204
18205 /// Return a string representation of a vector of subranges
18206 ///
18207 /// @return the string representation of a vector of sub ranges.
18208 string
vector_as_string(const vector<subrange_sptr> & v)18209 array_type_def::subrange_type::vector_as_string(const vector<subrange_sptr>& v)
18210 {
18211 if (v.empty())
18212 return "[]";
18213
18214 string r;
18215 for (vector<subrange_sptr>::const_iterator i = v.begin();
18216 i != v.end();
18217 ++i)
18218 r += (*i)->as_string();
18219
18220 return r;
18221 }
18222
18223 /// Compares two isntances of @ref array_type_def::subrange_type.
18224 ///
18225 /// If the two intances are different, set a bitfield to give some
18226 /// insight about the kind of differences there are.
18227 ///
18228 /// @param l the first artifact of the comparison.
18229 ///
18230 /// @param r the second artifact of the comparison.
18231 ///
18232 /// @param k a pointer to a bitfield that gives information about the
18233 /// kind of changes there are between @p l and @p r. This one is set
18234 /// iff @p k is non-null and the function returns false.
18235 ///
18236 /// Please note that setting k to a non-null value does have a
18237 /// negative performance impact because even if @p l and @p r are not
18238 /// equal, the function keeps up the comparison in order to determine
18239 /// the different kinds of ways in which they are different.
18240 ///
18241 /// @return true if @p l equals @p r, false otherwise.
18242 bool
equals(const array_type_def::subrange_type & l,const array_type_def::subrange_type & r,change_kind * k)18243 equals(const array_type_def::subrange_type& l,
18244 const array_type_def::subrange_type& r,
18245 change_kind* k)
18246 {
18247 bool result = true;
18248
18249 if (l.get_lower_bound() != r.get_lower_bound()
18250 || l.get_upper_bound() != r.get_upper_bound()
18251 || l.get_name() != r.get_name())
18252 {
18253 result = false;
18254 if (k)
18255 *k |= LOCAL_TYPE_CHANGE_KIND;
18256 else
18257 ABG_RETURN(result);
18258 }
18259
18260 ABG_RETURN(result);
18261 }
18262
18263 /// Equality operator.
18264 ///
18265 /// @param o the other subrange to test against.
18266 ///
18267 /// @return true iff @p o equals the current instance of
18268 /// array_type_def::subrange_type.
18269 bool
operator ==(const decl_base & o) const18270 array_type_def::subrange_type::operator==(const decl_base& o) const
18271 {
18272 const subrange_type* other =
18273 dynamic_cast<const subrange_type*>(&o);
18274 if (!other)
18275 return false;
18276 return try_canonical_compare(this, other);
18277 }
18278
18279 /// Equality operator.
18280 ///
18281 /// @param o the other subrange to test against.
18282 ///
18283 /// @return true iff @p o equals the current instance of
18284 /// array_type_def::subrange_type.
18285 bool
operator ==(const type_base & o) const18286 array_type_def::subrange_type::operator==(const type_base& o) const
18287 {
18288 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18289 if (!other)
18290 return false;
18291 return *this == *other;
18292 }
18293
18294 /// Equality operator.
18295 ///
18296 /// @param o the other subrange to test against.
18297 ///
18298 /// @return true iff @p o equals the current instance of
18299 /// array_type_def::subrange_type.
18300 bool
operator ==(const subrange_type & o) const18301 array_type_def::subrange_type::operator==(const subrange_type& o) const
18302 {
18303 const type_base &t = o;
18304 return operator==(t);
18305 }
18306
18307 /// Equality operator.
18308 ///
18309 /// @param o the other subrange to test against.
18310 ///
18311 /// @return true iff @p o equals the current instance of
18312 /// array_type_def::subrange_type.
18313 bool
operator !=(const decl_base & o) const18314 array_type_def::subrange_type::operator!=(const decl_base& o) const
18315 {return !operator==(o);}
18316
18317 /// Equality operator.
18318 ///
18319 /// @param o the other subrange to test against.
18320 ///
18321 /// @return true iff @p o equals the current instance of
18322 /// array_type_def::subrange_type.
18323 bool
operator !=(const type_base & o) const18324 array_type_def::subrange_type::operator!=(const type_base& o) const
18325 {return !operator==(o);}
18326
18327 /// Inequality operator.
18328 ///
18329 /// @param o the other subrange to test against.
18330 ///
18331 /// @return true iff @p o is different from the current instance of
18332 /// array_type_def::subrange_type.
18333 bool
operator !=(const subrange_type & o) const18334 array_type_def::subrange_type::operator!=(const subrange_type& o) const
18335 {return !operator==(o);}
18336
18337 /// Build a pretty representation for an
18338 /// array_type_def::subrange_type.
18339 ///
18340 /// @param internal set to true if the call is intended to get a
18341 /// representation of the decl (or type) for the purpose of canonical
18342 /// type comparison. This is mainly used in the function
18343 /// type_base::get_canonical_type_for().
18344 ///
18345 /// In other words if the argument for this parameter is true then the
18346 /// call is meant for internal use (for technical use inside the
18347 /// library itself), false otherwise. If you don't know what this is
18348 /// for, then set it to false.
18349 ///
18350 /// @return a copy of the pretty representation of the current
18351 /// instance of typedef_decl.
18352 string
get_pretty_representation(bool,bool) const18353 array_type_def::subrange_type::get_pretty_representation(bool, bool) const
18354 {
18355 string name = get_name();
18356 string repr;
18357
18358 if (name.empty())
18359 repr += "<anonymous range>";
18360 else
18361 repr += "<range " + get_name() + ">";
18362 repr += as_string();
18363
18364 return repr;
18365 }
18366
18367 /// This implements the ir_traversable_base::traverse pure virtual
18368 /// function.
18369 ///
18370 /// @param v the visitor used on the current instance.
18371 ///
18372 /// @return true if the entire IR node tree got traversed, false
18373 /// otherwise.
18374 bool
traverse(ir_node_visitor & v)18375 array_type_def::subrange_type::traverse(ir_node_visitor& v)
18376 {
18377 if (v.type_node_has_been_visited(this))
18378 return true;
18379
18380 if (v.visit_begin(this))
18381 {
18382 visiting(true);
18383 if (type_base_sptr u = get_underlying_type())
18384 u->traverse(v);
18385 visiting(false);
18386 }
18387
18388 bool result = v.visit_end(this);
18389 v.mark_type_node_as_visited(this);
18390 return result;
18391 }
18392
18393 // </array_type_def::subrange_type>
18394
18395 struct array_type_def::priv
18396 {
18397 type_base_wptr element_type_;
18398 subranges_type subranges_;
18399 interned_string temp_internal_qualified_name_;
18400 interned_string internal_qualified_name_;
18401
privabigail::ir::array_type_def::priv18402 priv(type_base_sptr t)
18403 : element_type_(t)
18404 {}
18405
privabigail::ir::array_type_def::priv18406 priv(type_base_sptr t, subranges_type subs)
18407 : element_type_(t), subranges_(subs)
18408 {}
18409
privabigail::ir::array_type_def::priv18410 priv()
18411 {}
18412 };
18413
18414 /// Constructor for the type array_type_def
18415 ///
18416 /// Note how the constructor expects a vector of subrange
18417 /// objects. Parsing of the array information always entails
18418 /// parsing the subrange info as well, thus the class subrange_type
18419 /// is defined inside class array_type_def and also parsed
18420 /// simultaneously.
18421 ///
18422 /// @param e_type the type of the elements contained in the array
18423 ///
18424 /// @param subs a vector of the array's subranges(dimensions)
18425 ///
18426 /// @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)18427 array_type_def::array_type_def(const type_base_sptr e_type,
18428 const std::vector<subrange_sptr>& subs,
18429 const location& locus)
18430 : type_or_decl_base(e_type->get_environment(),
18431 ARRAY_TYPE
18432 | ABSTRACT_TYPE_BASE
18433 | ABSTRACT_DECL_BASE),
18434 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
18435 decl_base(e_type->get_environment(), locus),
18436 priv_(new priv(e_type))
18437 {
18438 runtime_type_instance(this);
18439 append_subranges(subs);
18440 }
18441
18442 /// Constructor for the type array_type_def
18443 ///
18444 /// This constructor builds a temporary array that has no element type
18445 /// associated. Later when the element type is available, it be set
18446 /// with the array_type_def::set_element_type() member function.
18447 ///
18448 /// Note how the constructor expects a vector of subrange
18449 /// objects. Parsing of the array information always entails
18450 /// parsing the subrange info as well, thus the class subrange_type
18451 /// is defined inside class array_type_def and also parsed
18452 /// simultaneously.
18453 ///
18454 /// @param env the environment of the array type.
18455 ///
18456 /// @param subs a vector of the array's subranges(dimensions)
18457 ///
18458 /// @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)18459 array_type_def::array_type_def(const environment& env,
18460 const std::vector<subrange_sptr>& subs,
18461 const location& locus)
18462 : type_or_decl_base(env,
18463 ARRAY_TYPE
18464 | ABSTRACT_TYPE_BASE
18465 | ABSTRACT_DECL_BASE),
18466 type_base(env, 0, 0),
18467 decl_base(env, locus),
18468 priv_(new priv)
18469 {
18470 runtime_type_instance(this);
18471 append_subranges(subs);
18472 }
18473
18474 /// Update the size of the array.
18475 ///
18476 /// This function computes the size of the array and sets it using
18477 /// type_base::set_size_in_bits().
18478 void
update_size()18479 array_type_def::update_size()
18480 {
18481 type_base_sptr e = priv_->element_type_.lock();
18482 if (e)
18483 {
18484 size_t s = e->get_size_in_bits();
18485 if (s)
18486 {
18487 for (const auto &sub : get_subranges())
18488 s *= sub->get_length();
18489 set_size_in_bits(s);
18490 }
18491 set_alignment_in_bits(e->get_alignment_in_bits());
18492 }
18493 }
18494
18495 string
get_subrange_representation() const18496 array_type_def::get_subrange_representation() const
18497 {
18498 string r = subrange_type::vector_as_string(get_subranges());
18499 return r;
18500 }
18501
18502 /// Get the string representation of an @ref array_type_def.
18503 ///
18504 /// @param a the array type to consider.
18505 ///
18506 /// @param internal set to true if the call is intended for an
18507 /// internal use (for technical use inside the library itself), false
18508 /// otherwise. If you don't know what this is for, then set it to
18509 /// false.
18510 static string
get_type_representation(const array_type_def & a,bool internal)18511 get_type_representation(const array_type_def& a, bool internal)
18512 {
18513 type_base_sptr e_type = a.get_element_type();
18514 decl_base_sptr d = get_type_declaration(e_type);
18515 string r;
18516
18517 if (is_ada_language(a.get_language()))
18518 {
18519 std::ostringstream o;
18520 o << "array ("
18521 << a.get_subrange_representation()
18522 << ") of "
18523 << e_type ? e_type->get_pretty_representation(internal):string("void");
18524 }
18525 else
18526 {
18527 if (internal)
18528 r = (e_type
18529 ? get_type_name(e_type,
18530 /*qualified=*/true,
18531 /*internal=*/true)
18532 : string("void"))
18533 + a.get_subrange_representation();
18534 else
18535 r = (e_type
18536 ? get_type_name(e_type, /*qualified=*/true, /*internal=*/false)
18537 : string("void"))
18538 + a.get_subrange_representation();
18539 }
18540
18541 return r;
18542 }
18543
18544 /// Get the pretty representation of the current instance of @ref
18545 /// array_type_def.
18546 ///
18547 /// @param internal set to true if the call is intended to get a
18548 /// representation of the decl (or type) for the purpose of canonical
18549 /// type comparison. This is mainly used in the function
18550 /// type_base::get_canonical_type_for().
18551 ///
18552 /// In other words if the argument for this parameter is true then the
18553 /// call is meant for internal use (for technical use inside the
18554 /// library itself), false otherwise. If you don't know what this is
18555 /// for, then set it to false.
18556 /// @param internal set to true if the call is intended for an
18557 /// internal use (for technical use inside the library itself), false
18558 /// otherwise. If you don't know what this is for, then set it to
18559 /// false.
18560 ///
18561 /// @return the pretty representation of the ABI artifact.
18562 string
get_pretty_representation(bool internal,bool) const18563 array_type_def::get_pretty_representation(bool internal,
18564 bool /*qualified_name*/) const
18565 {return get_type_representation(*this, internal);}
18566
18567 /// Compares two instances of @ref array_type_def.
18568 ///
18569 /// If the two intances are different, set a bitfield to give some
18570 /// insight about the kind of differences there are.
18571 ///
18572 /// @param l the first artifact of the comparison.
18573 ///
18574 /// @param r the second artifact of the comparison.
18575 ///
18576 /// @param k a pointer to a bitfield that gives information about the
18577 /// kind of changes there are between @p l and @p r. This one is set
18578 /// iff @p k is non-null and the function returns false.
18579 ///
18580 /// Please note that setting k to a non-null value does have a
18581 /// negative performance impact because even if @p l and @p r are not
18582 /// equal, the function keeps up the comparison in order to determine
18583 /// the different kinds of ways in which they are different.
18584 ///
18585 /// @return true if @p l equals @p r, false otherwise.
18586 bool
equals(const array_type_def & l,const array_type_def & r,change_kind * k)18587 equals(const array_type_def& l, const array_type_def& r, change_kind* k)
18588 {
18589 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
18590 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
18591
18592 bool result = true;
18593 if (this_subs.size() != other_subs.size())
18594 {
18595 result = false;
18596 if (k)
18597 *k |= LOCAL_TYPE_CHANGE_KIND;
18598 else
18599 ABG_RETURN_FALSE;
18600 }
18601
18602 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
18603 for (i = this_subs.begin(), j = other_subs.begin();
18604 i != this_subs.end() && j != other_subs.end();
18605 ++i, ++j)
18606 if (**i != **j)
18607 {
18608 result = false;
18609 if (k)
18610 {
18611 *k |= LOCAL_TYPE_CHANGE_KIND;
18612 break;
18613 }
18614 else
18615 ABG_RETURN_FALSE;
18616 }
18617
18618 // Compare the element types modulo the typedefs they might have
18619 if (l.get_element_type() != r.get_element_type())
18620 {
18621 result = false;
18622 if (k)
18623 *k |= SUBTYPE_CHANGE_KIND;
18624 else
18625 ABG_RETURN_FALSE;
18626 }
18627
18628 ABG_RETURN(result);
18629 }
18630
18631 /// Test if two variables are equals modulo CV qualifiers.
18632 ///
18633 /// @param l the first array of the comparison.
18634 ///
18635 /// @param r the second array of the comparison.
18636 ///
18637 /// @return true iff @p l equals @p r or, if they are different, the
18638 /// difference between the too is just a matter of CV qualifiers.
18639 bool
equals_modulo_cv_qualifier(const array_type_def * l,const array_type_def * r)18640 equals_modulo_cv_qualifier(const array_type_def* l, const array_type_def* r)
18641 {
18642 if (l == r)
18643 return true;
18644
18645 if (!l || !r)
18646 ABG_RETURN_FALSE;
18647
18648 l = is_array_type(peel_qualified_or_typedef_type(l));
18649 r = is_array_type(peel_qualified_or_typedef_type(r));
18650
18651 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
18652 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
18653
18654 if (this_subs.size() != other_subs.size())
18655 ABG_RETURN_FALSE;
18656
18657 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
18658 for (i = this_subs.begin(), j = other_subs.begin();
18659 i != this_subs.end() && j != other_subs.end();
18660 ++i, ++j)
18661 if (**i != **j)
18662 ABG_RETURN_FALSE;
18663
18664 type_base *first_element_type =
18665 peel_qualified_or_typedef_type(l->get_element_type().get());
18666 type_base *second_element_type =
18667 peel_qualified_or_typedef_type(r->get_element_type().get());
18668
18669 if (*first_element_type != *second_element_type)
18670 ABG_RETURN_FALSE;
18671
18672 return true;
18673 }
18674
18675 /// Get the language of the array.
18676 ///
18677 /// @return the language of the array.
18678 translation_unit::language
get_language() const18679 array_type_def::get_language() const
18680 {
18681 const std::vector<subrange_sptr>& subranges =
18682 get_subranges();
18683
18684 if (subranges.empty())
18685 return translation_unit::LANG_C11;
18686 return subranges.front()->get_language();
18687 }
18688
18689 bool
operator ==(const decl_base & o) const18690 array_type_def::operator==(const decl_base& o) const
18691 {
18692 const array_type_def* other =
18693 dynamic_cast<const array_type_def*>(&o);
18694 if (!other)
18695 return false;
18696 return try_canonical_compare(this, other);
18697 }
18698
18699 bool
operator ==(const type_base & o) const18700 array_type_def::operator==(const type_base& o) const
18701 {
18702 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18703 if (!other)
18704 return false;
18705 return *this == *other;
18706 }
18707
18708 /// Getter of the type of an array element.
18709 ///
18710 /// @return the type of an array element.
18711 const type_base_sptr
get_element_type() const18712 array_type_def::get_element_type() const
18713 {return priv_->element_type_.lock();}
18714
18715 /// Setter of the type of array element.
18716 ///
18717 /// Beware that after using this function, one might want to
18718 /// re-compute the canonical type of the array, if one has already
18719 /// been computed.
18720 ///
18721 /// The intended use of this method is to permit in-place adjustment
18722 /// of the element type's qualifiers. In particular, the size of the
18723 /// element type should not be changed.
18724 ///
18725 /// @param element_type the new element type to set.
18726 void
set_element_type(const type_base_sptr & element_type)18727 array_type_def::set_element_type(const type_base_sptr& element_type)
18728 {
18729 priv_->element_type_ = element_type;
18730 update_size();
18731 set_name(get_environment().intern(get_pretty_representation()));
18732 }
18733
18734 /// Append subranges from the vector @param subs to the current
18735 /// vector of subranges.
18736 void
append_subranges(const std::vector<subrange_sptr> & subs)18737 array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
18738 {
18739
18740 for (const auto &sub : subs)
18741 priv_->subranges_.push_back(sub);
18742
18743 update_size();
18744 set_name(get_environment().intern(get_pretty_representation()));
18745 }
18746
18747 /// @return true if one of the sub-ranges of the array is infinite, or
18748 /// if the array has no sub-range at all, also meaning that the size
18749 /// of the array is infinite.
18750 bool
is_infinite() const18751 array_type_def::is_infinite() const
18752 {
18753 if (priv_->subranges_.empty())
18754 return true;
18755
18756 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
18757 priv_->subranges_.begin();
18758 i != priv_->subranges_.end();
18759 ++i)
18760 if ((*i)->is_infinite())
18761 return true;
18762
18763 return false;
18764 }
18765
18766 int
get_dimension_count() const18767 array_type_def::get_dimension_count() const
18768 {return priv_->subranges_.size();}
18769
18770 /// Build and return the qualified name of the current instance of the
18771 /// @ref array_type_def.
18772 ///
18773 /// @param qn output parameter. Is set to the newly-built qualified
18774 /// name of the current instance of @ref array_type_def.
18775 ///
18776 /// @param internal set to true if the call is intended for an
18777 /// internal use (for technical use inside the library itself), false
18778 /// otherwise. If you don't know what this is for, then set it to
18779 /// false.
18780 void
get_qualified_name(interned_string & qn,bool internal) const18781 array_type_def::get_qualified_name(interned_string& qn, bool internal) const
18782 {qn = get_qualified_name(internal);}
18783
18784 /// Compute the qualified name of the array.
18785 ///
18786 /// @param internal set to true if the call is intended for an
18787 /// internal use (for technical use inside the library itself), false
18788 /// otherwise. If you don't know what this is for, then set it to
18789 /// false.
18790 ///
18791 /// @return the resulting qualified name.
18792 const interned_string&
get_qualified_name(bool internal) const18793 array_type_def::get_qualified_name(bool internal) const
18794 {
18795 const environment& env = get_environment();
18796
18797
18798 if (internal)
18799 {
18800 if (get_canonical_type())
18801 {
18802 if (priv_->internal_qualified_name_.empty())
18803 priv_->internal_qualified_name_ =
18804 env.intern(get_type_representation(*this, /*internal=*/true));
18805 return priv_->internal_qualified_name_;
18806 }
18807 else
18808 {
18809 priv_->temp_internal_qualified_name_ =
18810 env.intern(get_type_representation(*this, /*internal=*/true));
18811 return priv_->temp_internal_qualified_name_;
18812 }
18813 }
18814 else
18815 {
18816 if (get_canonical_type())
18817 {
18818 if (decl_base::peek_qualified_name().empty())
18819 set_qualified_name(env.intern(get_type_representation
18820 (*this, /*internal=*/false)));
18821 return decl_base::peek_qualified_name();
18822 }
18823 else
18824 {
18825 set_temporary_qualified_name(env.intern(get_type_representation
18826 (*this,
18827 /*internal=*/false)));
18828 return decl_base::peek_temporary_qualified_name();
18829 }
18830 }
18831 }
18832
18833 /// This implements the ir_traversable_base::traverse pure virtual
18834 /// function.
18835 ///
18836 /// @param v the visitor used on the current instance.
18837 ///
18838 /// @return true if the entire IR node tree got traversed, false
18839 /// otherwise.
18840 bool
traverse(ir_node_visitor & v)18841 array_type_def::traverse(ir_node_visitor& v)
18842 {
18843 if (v.type_node_has_been_visited(this))
18844 return true;
18845
18846 if (visiting())
18847 return true;
18848
18849 if (v.visit_begin(this))
18850 {
18851 visiting(true);
18852 if (type_base_sptr t = get_element_type())
18853 t->traverse(v);
18854 visiting(false);
18855 }
18856
18857 bool result = v.visit_end(this);
18858 v.mark_type_node_as_visited(this);
18859 return result;
18860 }
18861
18862 const location&
get_location() const18863 array_type_def::get_location() const
18864 {return decl_base::get_location();}
18865
18866 /// Get the array's subranges
18867 const std::vector<array_type_def::subrange_sptr>&
get_subranges() const18868 array_type_def::get_subranges() const
18869 {return priv_->subranges_;}
18870
~array_type_def()18871 array_type_def::~array_type_def()
18872 {}
18873
18874 // </array_type_def definitions>
18875
18876 // <enum_type_decl definitions>
18877
18878 class enum_type_decl::priv
18879 {
18880 type_base_sptr underlying_type_;
18881 enumerators enumerators_;
18882 mutable enumerators sorted_enumerators_;
18883
18884 friend class enum_type_decl;
18885
18886 priv();
18887
18888 public:
priv(type_base_sptr underlying_type,enumerators & enumerators)18889 priv(type_base_sptr underlying_type,
18890 enumerators& enumerators)
18891 : underlying_type_(underlying_type),
18892 enumerators_(enumerators)
18893 {}
18894 }; // end class enum_type_decl::priv
18895
18896 /// Constructor.
18897 ///
18898 /// @param name the name of the type declaration.
18899 ///
18900 /// @param locus the source location where the type was defined.
18901 ///
18902 /// @param underlying_type the underlying type of the enum.
18903 ///
18904 /// @param enums the enumerators of this enum type.
18905 ///
18906 /// @param linkage_name the linkage name of the enum.
18907 ///
18908 /// @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)18909 enum_type_decl::enum_type_decl(const string& name,
18910 const location& locus,
18911 type_base_sptr underlying_type,
18912 enumerators& enums,
18913 const string& linkage_name,
18914 visibility vis)
18915 : type_or_decl_base(underlying_type->get_environment(),
18916 ENUM_TYPE
18917 | ABSTRACT_TYPE_BASE
18918 | ABSTRACT_DECL_BASE),
18919 type_base(underlying_type->get_environment(),
18920 underlying_type->get_size_in_bits(),
18921 underlying_type->get_alignment_in_bits()),
18922 decl_base(underlying_type->get_environment(),
18923 name, locus, linkage_name, vis),
18924 priv_(new priv(underlying_type, enums))
18925 {
18926 runtime_type_instance(this);
18927 for (enumerators::iterator e = get_enumerators().begin();
18928 e != get_enumerators().end();
18929 ++e)
18930 e->set_enum_type(this);
18931 }
18932
18933 /// Return the underlying type of the enum.
18934 type_base_sptr
get_underlying_type() const18935 enum_type_decl::get_underlying_type() const
18936 {return priv_->underlying_type_;}
18937
18938 /// @return the list of enumerators of the enum.
18939 const enum_type_decl::enumerators&
get_enumerators() const18940 enum_type_decl::get_enumerators() const
18941 {return priv_->enumerators_;}
18942
18943 /// @return the list of enumerators of the enum.
18944 enum_type_decl::enumerators&
get_enumerators()18945 enum_type_decl::get_enumerators()
18946 {return priv_->enumerators_;}
18947
18948 /// Get the lexicographically sorted vector of enumerators.
18949 ///
18950 /// @return the lexicographically sorted vector of enumerators.
18951 const enum_type_decl::enumerators&
get_sorted_enumerators() const18952 enum_type_decl::get_sorted_enumerators() const
18953 {
18954 if (priv_->sorted_enumerators_.empty())
18955 {
18956 for (auto e = get_enumerators().rbegin();
18957 e != get_enumerators().rend();
18958 ++e)
18959 priv_->sorted_enumerators_.push_back(*e);
18960
18961 std::sort(priv_->sorted_enumerators_.begin(),
18962 priv_->sorted_enumerators_.end(),
18963 [](const enum_type_decl::enumerator& l,
18964 const enum_type_decl::enumerator& r)
18965 {
18966 if (l.get_name() == r.get_name())
18967 return l.get_value() < r.get_value();
18968 return (l.get_name() < r.get_name());
18969 });
18970 }
18971
18972 return priv_->sorted_enumerators_;
18973 }
18974
18975 /// Get the pretty representation of the current instance of @ref
18976 /// enum_type_decl.
18977 ///
18978 /// @param internal set to true if the call is intended to get a
18979 /// representation of the decl (or type) for the purpose of canonical
18980 /// type comparison. This is mainly used in the function
18981 /// type_base::get_canonical_type_for().
18982 ///
18983 /// In other words if the argument for this parameter is true then the
18984 /// call is meant for internal use (for technical use inside the
18985 /// library itself), false otherwise. If you don't know what this is
18986 /// for, then set it to false.
18987 ///
18988 /// @param qualified_name if true, names emitted in the pretty
18989 /// representation are fully qualified.
18990 ///
18991 /// @return the pretty representation of the enum type.
18992 string
get_pretty_representation(bool internal,bool qualified_name) const18993 enum_type_decl::get_pretty_representation(bool internal,
18994 bool qualified_name) const
18995 {
18996 string r = "enum ";
18997
18998 if (internal && get_is_anonymous())
18999 r += get_type_name(this, qualified_name, /*internal=*/true);
19000 else if (get_is_anonymous())
19001 r += get_enum_flat_representation(*this, "",
19002 /*one_line=*/true,
19003 qualified_name);
19004 else
19005 r += decl_base::get_pretty_representation(internal,
19006 qualified_name);
19007 return r;
19008 }
19009
19010 /// This implements the ir_traversable_base::traverse pure virtual
19011 /// function.
19012 ///
19013 /// @param v the visitor used on the current instance.
19014 ///
19015 /// @return true if the entire IR node tree got traversed, false
19016 /// otherwise.
19017 bool
traverse(ir_node_visitor & v)19018 enum_type_decl::traverse(ir_node_visitor &v)
19019 {
19020 if (v.type_node_has_been_visited(this))
19021 return true;
19022
19023 if (visiting())
19024 return true;
19025
19026 if (v.visit_begin(this))
19027 {
19028 visiting(true);
19029 if (type_base_sptr t = get_underlying_type())
19030 t->traverse(v);
19031 visiting(false);
19032 }
19033
19034 bool result = v.visit_end(this);
19035 v.mark_type_node_as_visited(this);
19036 return result;
19037 }
19038
19039 /// Destructor for the enum type declaration.
~enum_type_decl()19040 enum_type_decl::~enum_type_decl()
19041 {}
19042
19043 /// Test if two enums differ, but not by a name change.
19044 ///
19045 /// @param l the first enum to consider.
19046 ///
19047 /// @param r the second enum to consider.
19048 ///
19049 /// @return true iff @p l differs from @p r by anything but a name
19050 /// change.
19051 bool
enum_has_non_name_change(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)19052 enum_has_non_name_change(const enum_type_decl& l,
19053 const enum_type_decl& r,
19054 change_kind* k)
19055 {
19056 bool result = false;
19057 if (*l.get_underlying_type() != *r.get_underlying_type())
19058 {
19059 result = true;
19060 if (k)
19061 *k |= SUBTYPE_CHANGE_KIND;
19062 else
19063 return true;
19064 }
19065
19066 enum_type_decl::enumerators::const_iterator i, j;
19067 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
19068 i != l.get_enumerators().end() && j != r.get_enumerators().end();
19069 ++i, ++j)
19070 if (*i != *j)
19071 {
19072 result = true;
19073 if (k)
19074 {
19075 *k |= LOCAL_TYPE_CHANGE_KIND;
19076 break;
19077 }
19078 else
19079 return true;
19080 }
19081
19082 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
19083 {
19084 result = true;
19085 if (k)
19086 *k |= LOCAL_TYPE_CHANGE_KIND;
19087 else
19088 return true;
19089 }
19090
19091 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
19092 interned_string qn_r = l.get_environment().intern(r.get_qualified_name());
19093 interned_string qn_l = l.get_environment().intern(l.get_qualified_name());
19094 string n_l = l.get_name();
19095 string n_r = r.get_name();
19096 local_r.set_qualified_name(qn_l);
19097 local_r.set_name(n_l);
19098
19099 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
19100 {
19101 result = true;
19102 if (k)
19103 {
19104 if (!l.decl_base::operator==(r))
19105 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19106 if (!l.type_base::operator==(r))
19107 *k |= LOCAL_TYPE_CHANGE_KIND;
19108 }
19109 else
19110 {
19111 local_r.set_name(n_r);
19112 local_r.set_qualified_name(qn_r);
19113 return true;
19114 }
19115 }
19116 local_r.set_qualified_name(qn_r);
19117 local_r.set_name(n_r);
19118
19119 return result;
19120 }
19121
19122 /// Test if a given enumerator is found present in an enum.
19123 ///
19124 /// This is a subroutine of the equals function for enums.
19125 ///
19126 /// @param enr the enumerator to consider.
19127 ///
19128 /// @param enom the enum to consider.
19129 ///
19130 /// @return true iff the enumerator @p enr is present in the enum @p
19131 /// enom.
19132 bool
is_enumerator_present_in_enum(const enum_type_decl::enumerator & enr,const enum_type_decl & enom)19133 is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr,
19134 const enum_type_decl &enom)
19135 {
19136 for (const auto &e : enom.get_enumerators())
19137 if (e == enr)
19138 return true;
19139 return false;
19140 }
19141
19142 /// Check if two enumerators values are equal.
19143 ///
19144 /// This function doesn't check if the names of the enumerators are
19145 /// equal or not.
19146 ///
19147 /// @param enr the first enumerator to consider.
19148 ///
19149 /// @param enl the second enumerator to consider.
19150 ///
19151 /// @return true iff @p enr has the same value as @p enl.
19152 static bool
enumerators_values_are_equal(const enum_type_decl::enumerator & enr,const enum_type_decl::enumerator & enl)19153 enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
19154 const enum_type_decl::enumerator &enl)
19155 {return enr.get_value() == enl.get_value();}
19156
19157 /// Detect if a given enumerator value is present in an enum.
19158 ///
19159 /// This function looks inside the enumerators of a given enum and
19160 /// detect if the enum contains at least one enumerator or a given
19161 /// value. The function also detects if the enumerator value we are
19162 /// looking at is present in the enum with a different name. An
19163 /// enumerator with the same value but with a different name is named
19164 /// a "redundant enumerator". The function returns the set of
19165 /// enumerators that are redundant with the value we are looking at.
19166 ///
19167 /// @param enr the enumerator to consider.
19168 ///
19169 /// @param enom the enum to consider.
19170 ///
19171 /// @param redundant_enrs if the function returns true, then this
19172 /// vector is filled with enumerators that are redundant with the
19173 /// value of @p enr.
19174 ///
19175 /// @return true iff the function detects that @p enom contains
19176 /// enumerators with the same value as @p enr.
19177 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)19178 is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
19179 const enum_type_decl &enom,
19180 vector<enum_type_decl::enumerator>& redundant_enrs)
19181 {
19182 bool found = false;
19183 for (const auto &e : enom.get_enumerators())
19184 if (enumerators_values_are_equal(e, enr))
19185 {
19186 found = true;
19187 if (e != enr)
19188 redundant_enrs.push_back(e);
19189 }
19190
19191 return found;
19192 }
19193
19194 /// Check if an enumerator value is redundant in a given enum.
19195 ///
19196 /// Given an enumerator value, this function detects if an enum
19197 /// contains at least one enumerator with the the same value but with
19198 /// a different name.
19199 ///
19200 /// @param enr the enumerator to consider.
19201 ///
19202 /// @param enom the enum to consider.
19203 ///
19204 /// @return true iff @p enr is a redundant enumerator in enom.
19205 static bool
is_enumerator_value_redundant(const enum_type_decl::enumerator & enr,const enum_type_decl & enom)19206 is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
19207 const enum_type_decl &enom)
19208 {
19209 vector<enum_type_decl::enumerator> redundant_enrs;
19210 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
19211 {
19212 if (!redundant_enrs.empty())
19213 return true;
19214 }
19215 return false;
19216 }
19217
19218 /// Compares two instances of @ref enum_type_decl.
19219 ///
19220 /// If the two intances are different, set a bitfield to give some
19221 /// insight about the kind of differences there are.
19222 ///
19223 /// @param l the first artifact of the comparison.
19224 ///
19225 /// @param r the second artifact of the comparison.
19226 ///
19227 /// @param k a pointer to a bitfield that gives information about the
19228 /// kind of changes there are between @p l and @p r. This one is set
19229 /// iff @p k is non-null and the function returns false.
19230 ///
19231 /// Please note that setting k to a non-null value does have a
19232 /// negative performance impact because even if @p l and @p r are not
19233 /// equal, the function keeps up the comparison in order to determine
19234 /// the different kinds of ways in which they are different.
19235 ///
19236 /// @return true if @p l equals @p r, false otherwise.
19237 bool
equals(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)19238 equals(const enum_type_decl& l, const enum_type_decl& r, change_kind* k)
19239 {
19240 bool result = true;
19241
19242 //
19243 // Look through decl-only-enum.
19244 //
19245
19246 const enum_type_decl *def1 =
19247 l.get_is_declaration_only()
19248 ? is_enum_type(l.get_naked_definition_of_declaration())
19249 : &l;
19250
19251 const enum_type_decl *def2 =
19252 r.get_is_declaration_only()
19253 ? is_enum_type(r.get_naked_definition_of_declaration())
19254 : &r;
19255
19256 if (!!def1 != !!def2)
19257 {
19258 // One enum is decl-only while the other is not.
19259 // So the two enums are different.
19260 result = false;
19261 if (k)
19262 *k |= SUBTYPE_CHANGE_KIND;
19263 else
19264 ABG_RETURN_FALSE;
19265 }
19266
19267 //
19268 // At this point, both enums have the same state of decl-only-ness.
19269 // So we can compare oranges to oranges.
19270 //
19271
19272 if (!def1)
19273 def1 = &l;
19274 if (!def2)
19275 def2 = &r;
19276
19277 if (def1->get_underlying_type() != def2->get_underlying_type())
19278 {
19279 result = false;
19280 if (k)
19281 *k |= SUBTYPE_CHANGE_KIND;
19282 else
19283 ABG_RETURN_FALSE;
19284 }
19285
19286 if (!(def1->decl_base::operator==(*def2)
19287 && def1->type_base::operator==(*def2)))
19288 {
19289 result = false;
19290 if (k)
19291 {
19292 if (!def1->decl_base::operator==(*def2))
19293 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19294 if (!def1->type_base::operator==(*def2))
19295 *k |= LOCAL_TYPE_CHANGE_KIND;
19296 }
19297 else
19298 ABG_RETURN_FALSE;
19299 }
19300
19301 // Now compare the enumerators. Note that the order of declaration
19302 // of enumerators should not matter in the comparison.
19303 //
19304 // Also if an enumerator value is redundant, that shouldn't impact
19305 // the comparison.
19306 //
19307 // In that case, note that the two enums below are considered equal:
19308 //
19309 // enum foo
19310 // {
19311 // e0 = 0;
19312 // e1 = 1;
19313 // e2 = 2;
19314 // };
19315 //
19316 // enum foo
19317 // {
19318 // e0 = 0;
19319 // e1 = 1;
19320 // e2 = 2;
19321 // e_added = 1; // <-- this value is redundant with the value
19322 // // of the enumerator e1.
19323 // };
19324 //
19325 // Note however that in the case below, the enums are different.
19326 //
19327 // enum foo
19328 // {
19329 // e0 = 0;
19330 // e1 = 1;
19331 // };
19332 //
19333 // enum foo
19334 // {
19335 // e0 = 0;
19336 // e2 = 1; // <-- this enum value is present in the first version
19337 // // of foo, but is not redundant with any enumerator
19338 // // in the second version of of enum foo.
19339 // };
19340 //
19341 // These two enums are considered equal.
19342
19343 for(const auto &e : def1->get_enumerators())
19344 if (!is_enumerator_present_in_enum(e, *def2)
19345 && (!is_enumerator_value_redundant(e, *def2)
19346 || !is_enumerator_value_redundant(e, *def1)))
19347 {
19348 result = false;
19349 if (k)
19350 {
19351 *k |= LOCAL_TYPE_CHANGE_KIND;
19352 break;
19353 }
19354 else
19355 ABG_RETURN_FALSE;
19356 }
19357
19358 for(const auto &e : def2->get_enumerators())
19359 if (!is_enumerator_present_in_enum(e, *def1)
19360 && (!is_enumerator_value_redundant(e, *def1)
19361 || !is_enumerator_value_redundant(e, *def2)))
19362 {
19363 result = false;
19364 if (k)
19365 {
19366 *k |= LOCAL_TYPE_CHANGE_KIND;
19367 break;
19368 }
19369 else
19370 ABG_RETURN_FALSE;
19371 }
19372
19373 ABG_RETURN(result);
19374 }
19375
19376 /// Equality operator.
19377 ///
19378 /// @param o the other enum to test against.
19379 ///
19380 /// @return true iff @p o equals the current instance of enum type
19381 /// decl.
19382 bool
operator ==(const decl_base & o) const19383 enum_type_decl::operator==(const decl_base& o) const
19384 {
19385 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
19386 if (!op)
19387 return false;
19388 return try_canonical_compare(this, op);
19389 }
19390
19391 /// Equality operator.
19392 ///
19393 /// @param o the other enum to test against.
19394 ///
19395 /// @return true iff @p o is equals the current instance of enum type
19396 /// decl.
19397 bool
operator ==(const type_base & o) const19398 enum_type_decl::operator==(const type_base& o) const
19399 {
19400 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19401 if (!other)
19402 return false;
19403 return *this == *other;
19404 }
19405
19406 /// Equality operator for @ref enum_type_decl_sptr.
19407 ///
19408 /// @param l the first operand to compare.
19409 ///
19410 /// @param r the second operand to compare.
19411 ///
19412 /// @return true iff @p l equals @p r.
19413 bool
operator ==(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)19414 operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
19415 {
19416 if (!!l != !!r)
19417 return false;
19418 if (l.get() == r.get())
19419 return true;
19420 decl_base_sptr o = r;
19421 return *l == *o;
19422 }
19423
19424 /// Inequality operator for @ref enum_type_decl_sptr.
19425 ///
19426 /// @param l the first operand to compare.
19427 ///
19428 /// @param r the second operand to compare.
19429 ///
19430 /// @return true iff @p l equals @p r.
19431 bool
operator !=(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)19432 operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
19433 {return !operator==(l, r);}
19434
19435 /// The type of the private data of an @ref
19436 /// enum_type_decl::enumerator.
19437 class enum_type_decl::enumerator::priv
19438 {
19439 string name_;
19440 int64_t value_;
19441 string qualified_name_;
19442 enum_type_decl* enum_type_;
19443
19444 friend class enum_type_decl::enumerator;
19445
19446 public:
19447
priv()19448 priv()
19449 : enum_type_()
19450 {}
19451
priv(const string & name,int64_t value,enum_type_decl * e=0)19452 priv(const string& name,
19453 int64_t value,
19454 enum_type_decl* e = 0)
19455 : name_(name),
19456 value_(value),
19457 enum_type_(e)
19458 {}
19459 }; // end class enum_type_def::enumerator::priv
19460
19461 /// Default constructor of the @ref enum_type_decl::enumerator type.
enumerator()19462 enum_type_decl::enumerator::enumerator()
19463 : priv_(new priv)
19464 {}
19465
19466 enum_type_decl::enumerator::~enumerator() = default;
19467
19468 /// Constructor of the @ref enum_type_decl::enumerator type.
19469 ///
19470 /// @param env the environment we are operating from.
19471 ///
19472 /// @param name the name of the enumerator.
19473 ///
19474 /// @param value the value of the enumerator.
enumerator(const string & name,int64_t value)19475 enum_type_decl::enumerator::enumerator(const string& name,
19476 int64_t value)
19477 : priv_(new priv(name, value))
19478 {}
19479
19480 /// Copy constructor of the @ref enum_type_decl::enumerator type.
19481 ///
19482 /// @param other enumerator to copy.
enumerator(const enumerator & other)19483 enum_type_decl::enumerator::enumerator(const enumerator& other)
19484 : priv_(new priv(other.get_name(),
19485 other.get_value(),
19486 other.get_enum_type()))
19487 {}
19488
19489 /// Assignment operator of the @ref enum_type_decl::enumerator type.
19490 ///
19491 /// @param o
19492 enum_type_decl::enumerator&
operator =(const enumerator & o)19493 enum_type_decl::enumerator::operator=(const enumerator& o)
19494 {
19495 priv_->name_ = o.get_name();
19496 priv_->value_ = o.get_value();
19497 priv_->enum_type_ = o.get_enum_type();
19498 return *this;
19499 }
19500
19501 /// Equality operator
19502 ///
19503 /// @param other the enumerator to compare to the current
19504 /// instance of enum_type_decl::enumerator.
19505 ///
19506 /// @return true if @p other equals the current instance of
19507 /// enum_type_decl::enumerator.
19508 bool
operator ==(const enumerator & other) const19509 enum_type_decl::enumerator::operator==(const enumerator& other) const
19510 {
19511 bool names_equal = true;
19512 names_equal = (get_name() == other.get_name());
19513 return names_equal && (get_value() == other.get_value());
19514 }
19515
19516 /// Inequality operator.
19517 ///
19518 /// @param other the other instance to compare against.
19519 ///
19520 /// @return true iff @p other is different from the current instance.
19521 bool
operator !=(const enumerator & other) const19522 enum_type_decl::enumerator::operator!=(const enumerator& other) const
19523 {return !operator==(other);}
19524
19525 /// Getter for the name of the current instance of
19526 /// enum_type_decl::enumerator.
19527 ///
19528 /// @return a reference to the name of the current instance of
19529 /// enum_type_decl::enumerator.
19530 const string&
get_name() const19531 enum_type_decl::enumerator::get_name() const
19532 {return priv_->name_;}
19533
19534 /// Getter for the qualified name of the current instance of
19535 /// enum_type_decl::enumerator. The first invocation of the method
19536 /// builds the qualified name, caches it and return a reference to the
19537 /// cached qualified name. Subsequent invocations just return the
19538 /// cached value.
19539 ///
19540 /// @param internal set to true if the call is intended for an
19541 /// internal use (for technical use inside the library itself), false
19542 /// otherwise. If you don't know what this is for, then set it to
19543 /// false.
19544 ///
19545 /// @return the qualified name of the current instance of
19546 /// enum_type_decl::enumerator.
19547 const string&
get_qualified_name(bool internal) const19548 enum_type_decl::enumerator::get_qualified_name(bool internal) const
19549 {
19550 if (priv_->qualified_name_.empty())
19551 {
19552 priv_->qualified_name_ =
19553 get_enum_type()->get_qualified_name(internal)
19554 + "::"
19555 + get_name();
19556 }
19557 return priv_->qualified_name_;
19558 }
19559
19560 /// Setter for the name of @ref enum_type_decl::enumerator.
19561 ///
19562 /// @param n the new name.
19563 void
set_name(const string & n)19564 enum_type_decl::enumerator::set_name(const string& n)
19565 {priv_->name_ = n;}
19566
19567 /// Getter for the value of @ref enum_type_decl::enumerator.
19568 ///
19569 /// @return the value of the current instance of
19570 /// enum_type_decl::enumerator.
19571 int64_t
get_value() const19572 enum_type_decl::enumerator::get_value() const
19573 {return priv_->value_;}
19574
19575 /// Setter for the value of @ref enum_type_decl::enumerator.
19576 ///
19577 /// @param v the new value of the enum_type_decl::enumerator.
19578 void
set_value(int64_t v)19579 enum_type_decl::enumerator::set_value(int64_t v)
19580 {priv_->value_= v;}
19581
19582 /// Getter for the enum type that this enumerator is for.
19583 ///
19584 /// @return the enum type that this enumerator is for.
19585 enum_type_decl*
get_enum_type() const19586 enum_type_decl::enumerator::get_enum_type() const
19587 {return priv_->enum_type_;}
19588
19589 /// Setter for the enum type that this enumerator is for.
19590 ///
19591 /// @param e the new enum type.
19592 void
set_enum_type(enum_type_decl * e)19593 enum_type_decl::enumerator::set_enum_type(enum_type_decl* e)
19594 {priv_->enum_type_ = e;}
19595 // </enum_type_decl definitions>
19596
19597 // <typedef_decl definitions>
19598
19599 /// Private data structure of the @ref typedef_decl.
19600 struct typedef_decl::priv
19601 {
19602 type_base_wptr underlying_type_;
19603
privabigail::ir::typedef_decl::priv19604 priv(const type_base_sptr& t)
19605 : underlying_type_(t)
19606 {}
19607 }; // end struct typedef_decl::priv
19608
19609 /// Constructor of the typedef_decl type.
19610 ///
19611 /// @param name the name of the typedef.
19612 ///
19613 /// @param underlying_type the underlying type of the typedef.
19614 ///
19615 /// @param locus the source location of the typedef declaration.
19616 ///
19617 /// @param linkage_name the mangled name of the typedef.
19618 ///
19619 /// @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)19620 typedef_decl::typedef_decl(const string& name,
19621 const type_base_sptr underlying_type,
19622 const location& locus,
19623 const string& linkage_name,
19624 visibility vis)
19625 : type_or_decl_base(underlying_type->get_environment(),
19626 TYPEDEF_TYPE
19627 | ABSTRACT_TYPE_BASE
19628 | ABSTRACT_DECL_BASE),
19629 type_base(underlying_type->get_environment(),
19630 underlying_type->get_size_in_bits(),
19631 underlying_type->get_alignment_in_bits()),
19632 decl_base(underlying_type->get_environment(),
19633 name, locus, linkage_name, vis),
19634 priv_(new priv(underlying_type))
19635 {
19636 runtime_type_instance(this);
19637 }
19638
19639 /// Constructor of the typedef_decl type.
19640 ///
19641 /// @param name the name of the typedef.
19642 ///
19643 /// @param env the environment of the current typedef.
19644 ///
19645 /// @param locus the source location of the typedef declaration.
19646 ///
19647 /// @param mangled_name the mangled name of the typedef.
19648 ///
19649 /// @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)19650 typedef_decl::typedef_decl(const string& name,
19651 const environment& env,
19652 const location& locus,
19653 const string& mangled_name,
19654 visibility vis)
19655 : type_or_decl_base(env,
19656 TYPEDEF_TYPE
19657 | ABSTRACT_TYPE_BASE
19658 | ABSTRACT_DECL_BASE),
19659 type_base(env, /*size_in_bits=*/0,
19660 /*alignment_in_bits=*/0),
19661 decl_base(env, name, locus, mangled_name, vis),
19662 priv_(new priv(nullptr))
19663 {
19664 runtime_type_instance(this);
19665 }
19666
19667 /// Return the size of the typedef.
19668 ///
19669 /// This function looks at the size of the underlying type and ensures
19670 /// that it's the same as the size of the typedef.
19671 ///
19672 /// @return the size of the typedef.
19673 size_t
get_size_in_bits() const19674 typedef_decl::get_size_in_bits() const
19675 {
19676 if (!get_underlying_type())
19677 return 0;
19678 size_t s = get_underlying_type()->get_size_in_bits();
19679 if (s != type_base::get_size_in_bits())
19680 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
19681 return type_base::get_size_in_bits();
19682 }
19683
19684 /// Return the alignment of the typedef.
19685 ///
19686 /// This function looks at the alignment of the underlying type and
19687 /// ensures that it's the same as the alignment of the typedef.
19688 ///
19689 /// @return the size of the typedef.
19690 size_t
get_alignment_in_bits() const19691 typedef_decl::get_alignment_in_bits() const
19692 {
19693 if (!get_underlying_type())
19694 return 0;
19695 size_t s = get_underlying_type()->get_alignment_in_bits();
19696 if (s != type_base::get_alignment_in_bits())
19697 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
19698 return type_base::get_alignment_in_bits();
19699 }
19700
19701 /// Compares two instances of @ref typedef_decl.
19702 ///
19703 /// If the two intances are different, set a bitfield to give some
19704 /// insight about the kind of differences there are.
19705 ///
19706 /// @param l the first artifact of the comparison.
19707 ///
19708 /// @param r the second artifact of the comparison.
19709 ///
19710 /// @param k a pointer to a bitfield that gives information about the
19711 /// kind of changes there are between @p l and @p r. This one is set
19712 /// iff @p k is non-null and the function returns false.
19713 ///
19714 /// Please note that setting k to a non-null value does have a
19715 /// negative performance impact because even if @p l and @p r are not
19716 /// equal, the function keeps up the comparison in order to determine
19717 /// the different kinds of ways in which they are different.
19718 ///
19719 /// @return true if @p l equals @p r, false otherwise.
19720 bool
equals(const typedef_decl & l,const typedef_decl & r,change_kind * k)19721 equals(const typedef_decl& l, const typedef_decl& r, change_kind* k)
19722 {
19723 bool result = true;
19724
19725 // No need to go further if the types have different names or
19726 // different size / alignment.
19727 if (!(l.decl_base::operator==(r)))
19728 {
19729 result = false;
19730 if (k)
19731 *k |= LOCAL_TYPE_CHANGE_KIND;
19732 else
19733 ABG_RETURN_FALSE;
19734 }
19735
19736 if (*l.get_underlying_type() != *r.get_underlying_type())
19737 {
19738 // Changes to the underlying type of a typedef are considered
19739 // local, a bit like for pointers.
19740 result = false;
19741 if (k)
19742 *k |= LOCAL_TYPE_CHANGE_KIND;
19743 else
19744 ABG_RETURN_FALSE;
19745 }
19746
19747 ABG_RETURN(result);
19748 }
19749
19750 /// Equality operator
19751 ///
19752 /// @param o the other typedef_decl to test against.
19753 bool
operator ==(const decl_base & o) const19754 typedef_decl::operator==(const decl_base& o) const
19755 {
19756 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
19757 if (!other)
19758 return false;
19759 return try_canonical_compare(this, other);
19760 }
19761
19762 /// Equality operator
19763 ///
19764 /// @param o the other typedef_decl to test against.
19765 ///
19766 /// @return true if the current instance of @ref typedef_decl equals
19767 /// @p o.
19768 bool
operator ==(const type_base & o) const19769 typedef_decl::operator==(const type_base& o) const
19770 {
19771 const decl_base* other = dynamic_cast<const decl_base*>(&o);
19772 if (!other)
19773 return false;
19774 return *this == *other;
19775 }
19776
19777 /// Build a pretty representation for a typedef_decl.
19778 ///
19779 /// @param internal set to true if the call is intended to get a
19780 /// representation of the decl (or type) for the purpose of canonical
19781 /// type comparison. This is mainly used in the function
19782 /// type_base::get_canonical_type_for().
19783 ///
19784 /// In other words if the argument for this parameter is true then the
19785 /// call is meant for internal use (for technical use inside the
19786 /// library itself), false otherwise. If you don't know what this is
19787 /// for, then set it to false.
19788
19789 /// @param qualified_name if true, names emitted in the pretty
19790 /// representation are fully qualified.
19791 ///
19792 /// @return a copy of the pretty representation of the current
19793 /// instance of typedef_decl.
19794 string
get_pretty_representation(bool internal,bool qualified_name) const19795 typedef_decl::get_pretty_representation(bool internal,
19796 bool qualified_name) const
19797 {
19798
19799 string result = "typedef ";
19800 if (internal)
19801 result += get_name();
19802 else
19803 {
19804 if (qualified_name)
19805 result += get_qualified_name(internal);
19806 else
19807 result += get_name();
19808 }
19809
19810 return result;
19811 }
19812
19813 /// Getter of the underlying type of the typedef.
19814 ///
19815 /// @return the underlying_type.
19816 type_base_sptr
get_underlying_type() const19817 typedef_decl::get_underlying_type() const
19818 {return priv_->underlying_type_.lock();}
19819
19820 /// Setter ofthe underlying type of the typedef.
19821 ///
19822 /// @param t the new underlying type of the typedef.
19823 void
set_underlying_type(const type_base_sptr & t)19824 typedef_decl::set_underlying_type(const type_base_sptr& t)
19825 {
19826 priv_->underlying_type_ = t;
19827 set_size_in_bits(t->get_size_in_bits());
19828 set_alignment_in_bits(t->get_alignment_in_bits());
19829 }
19830
19831 /// Implementation of the virtual "get_qualified_name" method.
19832 ///
19833 /// @param qualified_name the resuling qualified name of the typedef type.
19834 ///
19835 /// @param internal if true, then it means the qualified name is for
19836 /// "internal" purposes, meaning mainly for type canonicalization
19837 /// purposes.
19838 void
get_qualified_name(interned_string & qualified_name,bool internal) const19839 typedef_decl::get_qualified_name(interned_string& qualified_name,
19840 bool internal) const
19841 {qualified_name = get_qualified_name(internal);}
19842
19843 /// Implementation of the virtual "get_qualified_name" method.
19844 ///
19845 /// @param internal if true, then it means the qualified name is for
19846 /// "internal" purposes, meaning mainly for type canonicalization
19847 /// purposes.
19848 ///
19849 /// @return the qualified name.
19850 const interned_string&
get_qualified_name(bool internal) const19851 typedef_decl::get_qualified_name(bool internal) const
19852 {
19853 // Note that the qualified name has been already set by
19854 // qualified_name_setter::do_update, which is invoked by
19855 // update_qualified_name. The latter is itself invoked whenever the
19856 // typedef is added to its scope, in scope_decl::add_member_decl.
19857 if (internal)
19858 return decl_base::priv_->internal_qualified_name_;
19859 else
19860 return decl_base::priv_->qualified_name_;
19861 }
19862
19863 /// This implements the ir_traversable_base::traverse pure virtual
19864 /// function.
19865 ///
19866 /// @param v the visitor used on the current instance.
19867 ///
19868 /// @return true if the entire IR node tree got traversed, false
19869 /// otherwise.
19870 bool
traverse(ir_node_visitor & v)19871 typedef_decl::traverse(ir_node_visitor& v)
19872 {
19873 if (v.type_node_has_been_visited(this))
19874 return true;
19875
19876 if (visiting())
19877 return true;
19878
19879 if (v.visit_begin(this))
19880 {
19881 visiting(true);
19882 if (type_base_sptr t = get_underlying_type())
19883 t->traverse(v);
19884 visiting(false);
19885 }
19886
19887 bool result = v.visit_end(this);
19888 v.mark_type_node_as_visited(this);
19889 return result;
19890 }
19891
~typedef_decl()19892 typedef_decl::~typedef_decl()
19893 {}
19894 // </typedef_decl definitions>
19895
19896 // <var_decl definitions>
19897
19898 struct var_decl::priv
19899 {
19900 type_base_wptr type_;
19901 type_base* naked_type_;
19902 decl_base::binding binding_;
19903 elf_symbol_sptr symbol_;
19904 interned_string id_;
19905
privabigail::ir::var_decl::priv19906 priv()
19907 : naked_type_(),
19908 binding_(decl_base::BINDING_GLOBAL)
19909 {}
19910
privabigail::ir::var_decl::priv19911 priv(type_base_sptr t,
19912 decl_base::binding b)
19913 : type_(t),
19914 naked_type_(t.get()),
19915 binding_(b)
19916 {}
19917
19918 /// Setter of the type of the variable.
19919 ///
19920 /// @param t the new variable type.
19921 void
set_typeabigail::ir::var_decl::priv19922 set_type(type_base_sptr t)
19923 {
19924 type_ = t;
19925 naked_type_ = t.get();
19926 }
19927 }; // end struct var_decl::priv
19928
19929 /// Constructor of the @ref var_decl type.
19930 ///
19931 /// @param name the name of the variable declaration
19932 ///
19933 /// @param type the type of the variable declaration
19934 ///
19935 /// @param locus the source location where the variable was defined.
19936 ///
19937 /// @param linkage_name the linkage name of the variable.
19938 ///
19939 /// @param vis the visibility of of the variable.
19940 ///
19941 /// @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)19942 var_decl::var_decl(const string& name,
19943 type_base_sptr type,
19944 const location& locus,
19945 const string& linkage_name,
19946 visibility vis,
19947 binding bind)
19948 : type_or_decl_base(type->get_environment(),
19949 VAR_DECL | ABSTRACT_DECL_BASE),
19950 decl_base(type->get_environment(), name, locus, linkage_name, vis),
19951 priv_(new priv(type, bind))
19952 {
19953 runtime_type_instance(this);
19954 }
19955
19956 /// Getter of the type of the variable.
19957 ///
19958 /// @return the type of the variable.
19959 const type_base_sptr
get_type() const19960 var_decl::get_type() const
19961 {return priv_->type_.lock();}
19962
19963 /// Setter of the type of the variable.
19964 ///
19965 /// @param the new type of the variable.
19966 void
set_type(type_base_sptr & t)19967 var_decl::set_type(type_base_sptr& t)
19968 {priv_->set_type(t);}
19969
19970 /// Getter of the type of the variable.
19971 ///
19972 /// This getter returns a bare pointer, as opposed to a smart pointer.
19973 /// It's to be used on performance sensitive code paths identified by
19974 /// careful profiling.
19975 ///
19976 /// @return the type of the variable, as a bare pointer.
19977 const type_base*
get_naked_type() const19978 var_decl::get_naked_type() const
19979 {return priv_->naked_type_;}
19980
19981 /// Getter of the binding of the variable.
19982 ///
19983 /// @return the biding of the variable.
19984 decl_base::binding
get_binding() const19985 var_decl::get_binding() const
19986 {return priv_->binding_;}
19987
19988 /// Setter of the binding of the variable.
19989 ///
19990 /// @param b the new binding value.
19991 void
set_binding(decl_base::binding b)19992 var_decl::set_binding(decl_base::binding b)
19993 {priv_->binding_ = b;}
19994
19995 /// Sets the underlying ELF symbol for the current variable.
19996 ///
19997 /// And underlyin$g ELF symbol for the current variable might exist
19998 /// only if the corpus that this variable originates from was
19999 /// constructed from an ELF binary file.
20000 ///
20001 /// Note that comparing two variables that have underlying ELF symbols
20002 /// involves comparing their underlying elf symbols. The decl name
20003 /// for the variable thus becomes irrelevant in the comparison.
20004 ///
20005 /// @param sym the new ELF symbol for this variable decl.
20006 void
set_symbol(const elf_symbol_sptr & sym)20007 var_decl::set_symbol(const elf_symbol_sptr& sym)
20008 {
20009 priv_->symbol_ = sym;
20010 // The variable id cache that depends on the symbol must be
20011 // invalidated because the symbol changed.
20012 priv_->id_ = get_environment().intern("");
20013 }
20014
20015 /// Gets the the underlying ELF symbol for the current variable,
20016 /// that was set using var_decl::set_symbol(). Please read the
20017 /// documentation for that member function for more information about
20018 /// "underlying ELF symbols".
20019 ///
20020 /// @return sym the underlying ELF symbol for this variable decl, if
20021 /// one exists.
20022 const elf_symbol_sptr&
get_symbol() const20023 var_decl::get_symbol() const
20024 {return priv_->symbol_;}
20025
20026 /// Create a new var_decl that is a clone of the current one.
20027 ///
20028 /// @return the cloned var_decl.
20029 var_decl_sptr
clone() const20030 var_decl::clone() const
20031 {
20032 var_decl_sptr v(new var_decl(get_name(),
20033 get_type(),
20034 get_location(),
20035 get_linkage_name(),
20036 get_visibility(),
20037 get_binding()));
20038
20039 v->set_symbol(get_symbol());
20040
20041 if (is_member_decl(*this))
20042 {
20043 class_or_union* scope = is_class_or_union_type(get_scope());
20044 scope->add_data_member(v, get_member_access_specifier(*this),
20045 get_data_member_is_laid_out(*this),
20046 get_member_is_static(*this),
20047 get_data_member_offset(*this));
20048 }
20049 else
20050 add_decl_to_scope(v, get_scope());
20051
20052 return v;
20053 }
20054 /// Setter of the scope of the current var_decl.
20055 ///
20056 /// Note that the decl won't hold a reference on the scope. It's
20057 /// rather the scope that holds a reference on its members.
20058 ///
20059 /// @param scope the new scope.
20060 void
set_scope(scope_decl * scope)20061 var_decl::set_scope(scope_decl* scope)
20062 {
20063 if (!get_context_rel())
20064 set_context_rel(new dm_context_rel(scope));
20065 else
20066 get_context_rel()->set_scope(scope);
20067 }
20068
20069 /// Compares two instances of @ref var_decl without taking their type
20070 /// into account.
20071 ///
20072 /// If the two intances are different modulo their type, set a
20073 /// bitfield to give some insight about the kind of differences there
20074 /// are.
20075 ///
20076 /// @param l the first artifact of the comparison.
20077 ///
20078 /// @param r the second artifact of the comparison.
20079 ///
20080 /// @param k a pointer to a bitfield that gives information about the
20081 /// kind of changes there are between @p l and @p r. This one is set
20082 /// iff @p k is non-null and the function returns false.
20083 ///
20084 /// Please note that setting k to a non-null value does have a
20085 /// negative performance impact because even if @p l and @p r are not
20086 /// equal, the function keeps up the comparison in order to determine
20087 /// the different kinds of ways in which they are different.
20088 ///
20089 /// @return true if @p l equals @p r, false otherwise.
20090 bool
var_equals_modulo_types(const var_decl & l,const var_decl & r,change_kind * k)20091 var_equals_modulo_types(const var_decl& l, const var_decl& r, change_kind* k)
20092 {
20093 bool result = true;
20094
20095 // If there are underlying elf symbols for these variables,
20096 // compare them. And then compare the other parts.
20097 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
20098 if (!!s0 != !!s1)
20099 {
20100 result = false;
20101 if (k)
20102 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20103 else
20104 ABG_RETURN_FALSE;
20105 }
20106 else if (s0 && s0 != s1)
20107 {
20108 result = false;
20109 if (k)
20110 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20111 else
20112 ABG_RETURN_FALSE;
20113 }
20114 bool symbols_are_equal = (s0 && s1 && result);
20115
20116 if (symbols_are_equal)
20117 {
20118 // The variables have underlying elf symbols that are equal, so
20119 // now, let's compare the decl_base part of the variables w/o
20120 // considering their decl names.
20121 const environment& env = l.get_environment();
20122 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
20123 const_cast<var_decl&>(l).set_qualified_name(env.intern(""));
20124 const_cast<var_decl&>(r).set_qualified_name(env.intern(""));
20125 bool decl_bases_different = !l.decl_base::operator==(r);
20126 const_cast<var_decl&>(l).set_qualified_name(n1);
20127 const_cast<var_decl&>(r).set_qualified_name(n2);
20128
20129 if (decl_bases_different)
20130 {
20131 result = false;
20132 if (k)
20133 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20134 else
20135 ABG_RETURN_FALSE;
20136 }
20137 }
20138 else
20139 if (!l.decl_base::operator==(r))
20140 {
20141 result = false;
20142 if (k)
20143 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20144 else
20145 ABG_RETURN_FALSE;
20146 }
20147
20148 const dm_context_rel* c0 =
20149 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
20150 const dm_context_rel* c1 =
20151 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
20152 ABG_ASSERT(c0 && c1);
20153
20154 if (*c0 != *c1)
20155 {
20156 result = false;
20157 if (k)
20158 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20159 else
20160 ABG_RETURN_FALSE;
20161 }
20162
20163 ABG_RETURN(result);
20164 }
20165
20166 /// Compares two instances of @ref var_decl.
20167 ///
20168 /// If the two intances are different, set a bitfield to give some
20169 /// insight about the kind of differences there are.
20170 ///
20171 /// @param l the first artifact of the comparison.
20172 ///
20173 /// @param r the second artifact of the comparison.
20174 ///
20175 /// @param k a pointer to a bitfield that gives information about the
20176 /// kind of changes there are between @p l and @p r. This one is set
20177 /// iff @p k is non-null and the function returns false.
20178 ///
20179 /// Please note that setting k to a non-null value does have a
20180 /// negative performance impact because even if @p l and @p r are not
20181 /// equal, the function keeps up the comparison in order to determine
20182 /// the different kinds of ways in which they are different.
20183 ///
20184 /// @return true if @p l equals @p r, false otherwise.
20185 bool
equals(const var_decl & l,const var_decl & r,change_kind * k)20186 equals(const var_decl& l, const var_decl& r, change_kind* k)
20187 {
20188 bool result = true;
20189
20190 // First test types of variables. This should be fast because in
20191 // the general case, most types should be canonicalized.
20192 if (*l.get_naked_type() != *r.get_naked_type())
20193 {
20194 result = false;
20195 if (k)
20196 {
20197 if (!types_have_similar_structure(l.get_naked_type(),
20198 r.get_naked_type()))
20199 *k |= (LOCAL_TYPE_CHANGE_KIND);
20200 else
20201 *k |= SUBTYPE_CHANGE_KIND;
20202 }
20203 else
20204 ABG_RETURN_FALSE;
20205 }
20206
20207 result &= var_equals_modulo_types(l, r, k);
20208
20209 ABG_RETURN(result);
20210 }
20211
20212 /// Comparison operator of @ref var_decl.
20213 ///
20214 /// @param o the instance of @ref var_decl to compare against.
20215 ///
20216 /// @return true iff the current instance of @ref var_decl equals @p o.
20217 bool
operator ==(const decl_base & o) const20218 var_decl::operator==(const decl_base& o) const
20219 {
20220 const var_decl* other = dynamic_cast<const var_decl*>(&o);
20221 if (!other)
20222 return false;
20223
20224 return equals(*this, *other, 0);
20225 }
20226
20227 /// Return an ID that tries to uniquely identify the variable inside a
20228 /// program or a library.
20229 ///
20230 /// So if the variable has an underlying elf symbol, the ID is the
20231 /// concatenation of the symbol name and its version. Otherwise, the
20232 /// ID is the linkage name if its non-null. Otherwise, it's the
20233 /// pretty representation of the variable.
20234 ///
20235 /// @return the ID.
20236 interned_string
get_id() const20237 var_decl::get_id() const
20238 {
20239 if (priv_->id_.empty())
20240 {
20241 string repr = get_name();
20242 string sym_str;
20243 if (elf_symbol_sptr s = get_symbol())
20244 sym_str = s->get_id_string();
20245 else if (!get_linkage_name().empty())
20246 sym_str = get_linkage_name();
20247
20248 const environment& env = get_type()->get_environment();
20249 priv_->id_ = env.intern(repr);
20250 if (!sym_str.empty())
20251 priv_->id_ = env.intern(priv_->id_ + "{" + sym_str + "}");
20252 }
20253 return priv_->id_;
20254 }
20255
20256 /// Return the hash value for the current instance.
20257 ///
20258 /// @return the hash value.
20259 size_t
get_hash() const20260 var_decl::get_hash() const
20261 {
20262 var_decl::hash hash_var;
20263 return hash_var(this);
20264 }
20265
20266 /// Get the qualified name of a given variable or data member.
20267 ///
20268 ///
20269 /// Note that if the current instance of @ref var_decl is an anonymous
20270 /// data member, then the qualified name is actually the flat
20271 /// representation (the definition) of the type of the anonymous data
20272 /// member. We chose the flat representation because otherwise, the
20273 /// name of an *anonymous* data member is empty, by construction, e.g:
20274 ///
20275 /// struct foo {
20276 /// int a;
20277 /// union {
20278 /// char b;
20279 /// char c;
20280 /// }; // <---- this data member is anonymous.
20281 /// int d;
20282 /// }
20283 ///
20284 /// The string returned for the anonymous member here is going to be:
20285 ///
20286 /// "union {char b; char c}"
20287 ///
20288 /// @param internal if true then this is for a purpose to the library,
20289 /// otherwise, it's for being displayed to users.
20290 ///
20291 /// @return the resulting qualified name.
20292 const interned_string&
get_qualified_name(bool internal) const20293 var_decl::get_qualified_name(bool internal) const
20294 {
20295 if (is_anonymous_data_member(this)
20296 && decl_base::get_qualified_name().empty())
20297 {
20298 // Display the anonymous data member in a way that makes sense.
20299 string r = get_pretty_representation(internal);
20300 set_qualified_name(get_environment().intern(r));
20301 }
20302
20303 return decl_base::get_qualified_name(internal);
20304 }
20305
20306 /// Build and return the pretty representation of this variable.
20307 ///
20308 /// @param internal set to true if the call is intended to get a
20309 /// representation of the decl (or type) for the purpose of canonical
20310 /// type comparison. This is mainly used in the function
20311 /// type_base::get_canonical_type_for().
20312 ///
20313 /// In other words if the argument for this parameter is true then the
20314 /// call is meant for internal use (for technical use inside the
20315 /// library itself), false otherwise. If you don't know what this is
20316 /// for, then set it to false.
20317 ///
20318 /// @param qualified_name if true, names emitted in the pretty
20319 /// representation are fully qualified.
20320 ///
20321 /// @return a copy of the pretty representation of this variable.
20322 string
get_pretty_representation(bool internal,bool qualified_name) const20323 var_decl::get_pretty_representation(bool internal, bool qualified_name) const
20324 {
20325 string result;
20326
20327 if (is_member_decl(this) && get_member_is_static(this))
20328 result = "static ";
20329
20330 // Detect if the current instance of var_decl is a member of
20331 // an anonymous class or union.
20332 bool member_of_anonymous_class = false;
20333 if (class_or_union* scope = is_at_class_scope(this))
20334 if (scope->get_is_anonymous())
20335 member_of_anonymous_class = true;
20336
20337 if (array_type_def_sptr t = is_array_type(get_type()))
20338 {
20339 string name;
20340 if (member_of_anonymous_class || !qualified_name)
20341 name = get_name();
20342 else
20343 name = get_qualified_name(internal);
20344
20345 type_base_sptr et = t->get_element_type();
20346 ABG_ASSERT(et);
20347 decl_base_sptr decl = get_type_declaration(et);
20348 ABG_ASSERT(decl);
20349 result += decl->get_qualified_name(internal)
20350 + " " + name + t->get_subrange_representation();
20351 }
20352 else
20353 {
20354 if (/*The current var_decl is to be used as an anonymous data
20355 member. */
20356 get_name().empty())
20357 {
20358 // Display the anonymous data member in a way that
20359 // makes sense.
20360 result +=
20361 get_class_or_union_flat_representation
20362 (is_class_or_union_type(get_type()),
20363 "", /*one_line=*/true, internal);
20364 }
20365 else if (data_member_has_anonymous_type(this))
20366 {
20367 result += get_class_or_union_flat_representation
20368 (is_class_or_union_type(get_type()),
20369 "", /*one_line=*/true, internal);
20370 result += " ";
20371 if (!internal
20372 && (member_of_anonymous_class || !qualified_name))
20373 // It doesn't make sense to name the member of an
20374 // anonymous class or union like:
20375 // "__anonymous__::data_member_name". So let's just use
20376 // its non-qualified name.
20377 result += get_name();
20378 else
20379 result += get_qualified_name(internal);
20380 }
20381 else
20382 {
20383 result +=
20384 get_type_declaration(get_type())->get_qualified_name(internal)
20385 + " ";
20386
20387 if (!internal
20388 && (member_of_anonymous_class || !qualified_name))
20389 // It doesn't make sense to name the member of an
20390 // anonymous class or union like:
20391 // "__anonymous__::data_member_name". So let's just use
20392 // its non-qualified name.
20393 result += get_name();
20394 else
20395 result += get_qualified_name(internal);
20396 }
20397 }
20398 return result;
20399 }
20400
20401 /// Get a name that is valid even for an anonymous data member.
20402 ///
20403 /// If the current @ref var_decl is an anonymous data member, then
20404 /// return its pretty representation. As of now, that pretty
20405 /// representation is actually its flat representation as returned by
20406 /// get_class_or_union_flat_representation().
20407 ///
20408 /// Otherwise, just return the name of the current @ref var_decl.
20409 ///
20410 /// @param qualified if true, return the qualified name. This doesn't
20411 /// have an effet if the current @ref var_decl represents an anonymous
20412 /// data member.
20413 string
get_anon_dm_reliable_name(bool qualified) const20414 var_decl::get_anon_dm_reliable_name(bool qualified) const
20415 {
20416 string name;
20417 if (is_anonymous_data_member(this))
20418 // This function is used in the comparison engine to determine
20419 // which anonymous data member was deleted. So it's not involved
20420 // in type comparison or canonicalization. We don't want to use
20421 // the 'internal' version of the pretty presentation.
20422 name = get_pretty_representation(/*internal=*/false, qualified);
20423 else
20424 name = get_name();
20425
20426 return name;
20427 }
20428
20429 /// This implements the ir_traversable_base::traverse pure virtual
20430 /// function.
20431 ///
20432 /// @param v the visitor used on the current instance.
20433 ///
20434 /// @return true if the entire IR node tree got traversed, false
20435 /// otherwise.
20436 bool
traverse(ir_node_visitor & v)20437 var_decl::traverse(ir_node_visitor& v)
20438 {
20439 if (visiting())
20440 return true;
20441
20442 if (v.visit_begin(this))
20443 {
20444 visiting(true);
20445 if (type_base_sptr t = get_type())
20446 t->traverse(v);
20447 visiting(false);
20448 }
20449 return v.visit_end(this);
20450 }
20451
~var_decl()20452 var_decl::~var_decl()
20453 {}
20454
20455 // </var_decl definitions>
20456
20457 /// This function is automatically invoked whenever an instance of
20458 /// this type is canonicalized.
20459 ///
20460 /// It's an overload of the virtual type_base::on_canonical_type_set.
20461 ///
20462 /// We put here what is thus meant to be executed only at the point of
20463 /// type canonicalization.
20464 void
on_canonical_type_set()20465 function_type::on_canonical_type_set()
20466 {
20467 priv_->cached_name_.clear();
20468 priv_->internal_cached_name_.clear();
20469 }
20470
20471 /// The most straightforward constructor for the function_type class.
20472 ///
20473 /// @param return_type the return type of the function type.
20474 ///
20475 /// @param parms the list of parameters of the function type.
20476 /// Stricto sensu, we just need a list of types; we are using a list
20477 /// of parameters (where each parameter also carries the name of the
20478 /// parameter and its source location) to try and provide better
20479 /// diagnostics whenever it makes sense. If it appears that this
20480 /// wasts too many resources, we can fall back to taking just a
20481 /// vector of types here.
20482 ///
20483 /// @param size_in_bits the size of this type, in bits.
20484 ///
20485 /// @param alignment_in_bits the alignment of this type, in bits.
20486 ///
20487 /// @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)20488 function_type::function_type(type_base_sptr return_type,
20489 const parameters& parms,
20490 size_t size_in_bits,
20491 size_t alignment_in_bits)
20492 : type_or_decl_base(return_type->get_environment(),
20493 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
20494 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
20495 priv_(new priv(parms, return_type))
20496 {
20497 runtime_type_instance(this);
20498
20499 for (parameters::size_type i = 0, j = 1;
20500 i < priv_->parms_.size();
20501 ++i, ++j)
20502 {
20503 if (i == 0 && priv_->parms_[i]->get_is_artificial())
20504 // If the first parameter is artificial, then it certainly
20505 // means that this is a member function, and the first
20506 // parameter is the implicit this pointer. In that case, set
20507 // the index of that implicit parameter to zero. Otherwise,
20508 // the index of the first parameter starts at one.
20509 j = 0;
20510 priv_->parms_[i]->set_index(j);
20511 }
20512 }
20513
20514 /// A constructor for a function_type that takes no parameters.
20515 ///
20516 /// @param return_type the return type of this function_type.
20517 ///
20518 /// @param size_in_bits the size of this type, in bits.
20519 ///
20520 /// @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)20521 function_type::function_type(type_base_sptr return_type,
20522 size_t size_in_bits, size_t alignment_in_bits)
20523 : type_or_decl_base(return_type->get_environment(),
20524 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
20525 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
20526 priv_(new priv(return_type))
20527 {
20528 runtime_type_instance(this);
20529 }
20530
20531 /// A constructor for a function_type that takes no parameter and
20532 /// that has no return_type yet. These missing parts can (and must)
20533 /// be added later.
20534 ///
20535 /// @param env the environment we are operating from.
20536 ///
20537 /// @param size_in_bits the size of this type, in bits.
20538 ///
20539 /// @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)20540 function_type::function_type(const environment& env,
20541 size_t size_in_bits,
20542 size_t alignment_in_bits)
20543 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
20544 type_base(env, size_in_bits, alignment_in_bits),
20545 priv_(new priv)
20546 {
20547 runtime_type_instance(this);
20548 }
20549
20550 /// Getter for the return type of the current instance of @ref
20551 /// function_type.
20552 ///
20553 /// @return the return type.
20554 type_base_sptr
get_return_type() const20555 function_type::get_return_type() const
20556 {return priv_->return_type_.lock();}
20557
20558 /// Setter of the return type of the current instance of @ref
20559 /// function_type.
20560 ///
20561 /// @param t the new return type to set.
20562 void
set_return_type(type_base_sptr t)20563 function_type::set_return_type(type_base_sptr t)
20564 {priv_->return_type_ = t;}
20565
20566 /// Getter for the set of parameters of the current intance of @ref
20567 /// function_type.
20568 ///
20569 /// @return the parameters of the current instance of @ref
20570 /// function_type.
20571 const function_decl::parameters&
get_parameters() const20572 function_type::get_parameters() const
20573 {return priv_->parms_;}
20574
20575 /// Get the Ith parameter of the vector of parameters of the current
20576 /// instance of @ref function_type.
20577 ///
20578 /// Note that the first parameter is at index 0. That parameter is
20579 /// the first parameter that comes after the possible implicit "this"
20580 /// parameter, when the current instance @ref function_type is for a
20581 /// member function. Otherwise, if the current instance of @ref
20582 /// function_type is for a non-member function, the parameter at index
20583 /// 0 is the first parameter of the function.
20584 ///
20585 ///
20586 /// @param i the index of the parameter to return. If i is greater
20587 /// than the index of the last parameter, then this function returns
20588 /// an empty parameter (smart) pointer.
20589 ///
20590 /// @return the @p i th parameter that is not implicit.
20591 const function_decl::parameter_sptr
get_parm_at_index_from_first_non_implicit_parm(size_t i) const20592 function_type::get_parm_at_index_from_first_non_implicit_parm(size_t i) const
20593 {
20594 parameter_sptr result;
20595 if (dynamic_cast<const method_type*>(this))
20596 {
20597 if (i + 1 < get_parameters().size())
20598 result = get_parameters()[i + 1];
20599 }
20600 else
20601 {
20602 if (i < get_parameters().size())
20603 result = get_parameters()[i];
20604 }
20605 return result;
20606 }
20607
20608 /// Setter for the parameters of the current instance of @ref
20609 /// function_type.
20610 ///
20611 /// @param p the new vector of parameters to set.
20612 void
set_parameters(const parameters & p)20613 function_type::set_parameters(const parameters &p)
20614 {
20615 priv_->parms_ = p;
20616 for (parameters::size_type i = 0, j = 1;
20617 i < priv_->parms_.size();
20618 ++i, ++j)
20619 {
20620 if (i == 0 && priv_->parms_[i]->get_is_artificial())
20621 // If the first parameter is artificial, then it certainly
20622 // means that this is a member function, and the first
20623 // parameter is the implicit this pointer. In that case, set
20624 // the index of that implicit parameter to zero. Otherwise,
20625 // the index of the first parameter starts at one.
20626 j = 0;
20627 priv_->parms_[i]->set_index(j);
20628 }
20629 }
20630
20631 /// Append a new parameter to the vector of parameters of the current
20632 /// instance of @ref function_type.
20633 ///
20634 /// @param parm the parameter to append.
20635 void
append_parameter(parameter_sptr parm)20636 function_type::append_parameter(parameter_sptr parm)
20637 {
20638 parm->set_index(priv_->parms_.size());
20639 priv_->parms_.push_back(parm);
20640 }
20641
20642 /// Test if the current instance of @ref function_type is for a
20643 /// variadic function.
20644 ///
20645 /// A variadic function is a function that takes a variable number of
20646 /// arguments.
20647 ///
20648 /// @return true iff the current instance of @ref function_type is for
20649 /// a variadic function.
20650 bool
is_variadic() const20651 function_type::is_variadic() const
20652 {
20653 return (!priv_->parms_.empty()
20654 && priv_->parms_.back()->get_variadic_marker());
20655 }
20656
20657 /// Compare two function types.
20658 ///
20659 /// In case these function types are actually method types, this
20660 /// function avoids comparing two parameters (of the function types)
20661 /// if the types of the parameters are actually the types of the
20662 /// classes of the method types. This prevents infinite recursion
20663 /// during the comparison of two classes that are structurally
20664 /// identical.
20665 ///
20666 /// This is a subroutine of the equality operator of function_type.
20667 ///
20668 /// @param lhs the first function type to consider
20669 ///
20670 /// @param rhs the second function type to consider
20671 ///
20672 /// @param k a pointer to a bitfield set by the function to give
20673 /// information about the kind of changes carried by @p lhs and @p
20674 /// rhs. It is set iff @p k is non-null and the function returns
20675 /// false.
20676 ///
20677 /// Please note that setting k to a non-null value does have a
20678 /// negative performance impact because even if @p l and @p r are not
20679 /// equal, the function keeps up the comparison in order to determine
20680 /// the different kinds of ways in which they are different.
20681 ///
20682 ///@return true if lhs == rhs, false otherwise.
20683 bool
equals(const function_type & l,const function_type & r,change_kind * k)20684 equals(const function_type& l, const function_type& r, change_kind* k)
20685 {
20686 #define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
20687
20688 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
20689
20690 {
20691 // First of all, let's see if these two function types haven't
20692 // already been compared. If so, and if the result of the
20693 // comparison has been cached, let's just re-use it, rather than
20694 // comparing them all over again.
20695 bool cached_result = false;
20696 if (l.get_environment().priv_->is_type_comparison_cached(l, r,
20697 cached_result))
20698 ABG_RETURN(cached_result);
20699 }
20700
20701 mark_types_as_being_compared(l, r);
20702
20703 bool result = true;
20704
20705 if (!l.type_base::operator==(r))
20706 {
20707 result = false;
20708 if (k)
20709 *k |= LOCAL_TYPE_CHANGE_KIND;
20710 else
20711 RETURN(result);
20712 }
20713
20714 class_or_union* l_class = 0, *r_class = 0;
20715 if (const method_type* m = dynamic_cast<const method_type*>(&l))
20716 l_class = m->get_class_type().get();
20717
20718 if (const method_type* m = dynamic_cast<const method_type*>(&r))
20719 r_class = m->get_class_type().get();
20720
20721 // Compare the names of the class of the method
20722
20723 if (!!l_class != !!r_class)
20724 {
20725 result = false;
20726 if (k)
20727 *k |= LOCAL_TYPE_CHANGE_KIND;
20728 else
20729 RETURN(result);
20730 }
20731 else if (l_class
20732 && (l_class->get_qualified_name()
20733 != r_class->get_qualified_name()))
20734 {
20735 result = false;
20736 if (k)
20737 *k |= LOCAL_TYPE_CHANGE_KIND;
20738 else
20739 RETURN(result);
20740 }
20741
20742 // Then compare the return type; Beware if it's t's a class type
20743 // that is the same as the method class name; we can recurse for
20744 // ever in that case.
20745
20746 decl_base* l_return_type_decl =
20747 get_type_declaration(l.get_return_type()).get();
20748 decl_base* r_return_type_decl =
20749 get_type_declaration(r.get_return_type()).get();
20750 bool compare_result_types = true;
20751 string l_rt_name = l_return_type_decl
20752 ? l_return_type_decl->get_qualified_name()
20753 : string();
20754 string r_rt_name = r_return_type_decl
20755 ? r_return_type_decl->get_qualified_name()
20756 : string();
20757
20758 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
20759 ||
20760 (r_class && (r_class->get_qualified_name() == r_rt_name)))
20761 compare_result_types = false;
20762
20763 if (compare_result_types)
20764 {
20765 // Let's not consider typedefs when comparing return types to
20766 // avoid spurious changes.
20767 //
20768 // TODO: We should also do this for parameter types, or rather,
20769 // we should teach the equality operators in the IR, at some
20770 // point, to peel typedefs off.
20771 if (peel_typedef_type(l.get_return_type())
20772 !=
20773 peel_typedef_type(r.get_return_type()))
20774 {
20775 result = false;
20776 if (k)
20777 {
20778 if (!types_have_similar_structure(l.get_return_type(),
20779 r.get_return_type()))
20780 *k |= LOCAL_TYPE_CHANGE_KIND;
20781 else
20782 *k |= SUBTYPE_CHANGE_KIND;
20783 }
20784 else
20785 RETURN(result);
20786 }
20787 }
20788 else
20789 if (l_rt_name != r_rt_name)
20790 {
20791 result = false;
20792 if (k)
20793 *k |= SUBTYPE_CHANGE_KIND;
20794 else
20795 RETURN(result);
20796 }
20797
20798 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
20799 for (i = l.get_first_parm(), j = r.get_first_parm();
20800 i != l.get_parameters().end() && j != r.get_parameters().end();
20801 ++i, ++j)
20802 {
20803 if (**i != **j)
20804 {
20805 result = false;
20806 if (k)
20807 {
20808 if (!types_have_similar_structure((*i)->get_type(),
20809 (*j)->get_type()))
20810 *k |= LOCAL_TYPE_CHANGE_KIND;
20811 else
20812 *k |= SUBTYPE_CHANGE_KIND;
20813 }
20814 else
20815 RETURN(result);
20816 }
20817 }
20818
20819 if ((i != l.get_parameters().end()
20820 || j != r.get_parameters().end()))
20821 {
20822 result = false;
20823 if (k)
20824 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20825 else
20826 RETURN(result);
20827 }
20828
20829 RETURN(result);
20830 #undef RETURN
20831 }
20832
20833 /// Get the first parameter of the function.
20834 ///
20835 /// If the function is a non-static member function, the parameter
20836 /// returned is the first one following the implicit 'this' parameter.
20837 ///
20838 /// @return the first non implicit parameter of the function.
20839 function_type::parameters::const_iterator
get_first_non_implicit_parm() const20840 function_type::get_first_non_implicit_parm() const
20841 {
20842 if (get_parameters().empty())
20843 return get_parameters().end();
20844
20845 bool is_method = dynamic_cast<const method_type*>(this);
20846
20847 parameters::const_iterator i = get_parameters().begin();
20848
20849 if (is_method)
20850 ++i;
20851
20852 return i;
20853 }
20854
20855 /// Get the first parameter of the function.
20856 ///
20857 /// Note that if the function is a non-static member function, the
20858 /// parameter returned is the implicit 'this' parameter.
20859 ///
20860 /// @return the first parameter of the function.
20861 function_type::parameters::const_iterator
get_first_parm() const20862 function_type::get_first_parm() const
20863 {return get_parameters().begin();}
20864
20865 /// Get the name of the current @ref function_type.
20866 ///
20867 /// The name is retrieved from a cache. If the cache is empty, this
20868 /// function computes the name of the type, stores it in the cache and
20869 /// returns it. Subsequent invocation of the function are going to
20870 /// just hit the cache.
20871 ///
20872 /// Note that if the type is *NOT* canonicalized then function type
20873 /// name is never cached.
20874 ///
20875 /// @param internal if true then it means the function type name is
20876 /// going to be used for purposes that are internal to libabigail
20877 /// itself. If you don't know what this is then you probably should
20878 /// set this parameter to 'false'.
20879 ///
20880 /// @return the name of the function type.
20881 const interned_string&
get_cached_name(bool internal) const20882 function_type::get_cached_name(bool internal) const
20883 {
20884 if (internal)
20885 {
20886 if (get_naked_canonical_type())
20887 {
20888 if (priv_->internal_cached_name_.empty())
20889 priv_->internal_cached_name_ =
20890 get_function_type_name(this, /*internal=*/true);
20891 return priv_->internal_cached_name_;
20892 }
20893 else
20894 {
20895 priv_->temp_internal_cached_name_ =
20896 get_function_type_name(this,
20897 /*internal=*/true);
20898 return priv_->temp_internal_cached_name_;
20899 }
20900 }
20901 else
20902 {
20903 if (get_naked_canonical_type())
20904 {
20905 if (priv_->cached_name_.empty())
20906 priv_->cached_name_ =
20907 get_function_type_name(this, /*internal=*/false);
20908 return priv_->cached_name_;
20909 }
20910 else
20911 {
20912 priv_->cached_name_ =
20913 get_function_type_name(this, /*internal=*/false);
20914 return priv_->cached_name_;
20915 }
20916 }
20917 }
20918
20919 /// Equality operator for function_type.
20920 ///
20921 /// @param o the other function_type to compare against.
20922 ///
20923 /// @return true iff the two function_type are equal.
20924 bool
operator ==(const type_base & other) const20925 function_type::operator==(const type_base& other) const
20926 {
20927 const function_type* o = dynamic_cast<const function_type*>(&other);
20928 if (!o)
20929 return false;
20930 return try_canonical_compare(this, o);
20931 }
20932
20933 /// Return a copy of the pretty representation of the current @ref
20934 /// function_type.
20935 ///
20936 /// @param internal set to true if the call is intended to get a
20937 /// representation of the decl (or type) for the purpose of canonical
20938 /// type comparison. This is mainly used in the function
20939 /// type_base::get_canonical_type_for().
20940 ///
20941 /// In other words if the argument for this parameter is true then the
20942 /// call is meant for internal use (for technical use inside the
20943 /// library itself), false otherwise. If you don't know what this is
20944 /// for, then set it to false.
20945 ///
20946 /// @return a copy of the pretty representation of the current @ref
20947 /// function_type.
20948 string
get_pretty_representation(bool internal,bool) const20949 function_type::get_pretty_representation(bool internal,
20950 bool /*qualified_name*/) const
20951 {return ir::get_pretty_representation(this, internal);}
20952
20953 /// Traverses an instance of @ref function_type, visiting all the
20954 /// sub-types and decls that it might contain.
20955 ///
20956 /// @param v the visitor that is used to visit every IR sub-node of
20957 /// the current node.
20958 ///
20959 /// @return true if either
20960 /// - all the children nodes of the current IR node were traversed
20961 /// and the calling code should keep going with the traversing.
20962 /// - or the current IR node is already being traversed.
20963 /// Otherwise, returning false means that the calling code should not
20964 /// keep traversing the tree.
20965 bool
traverse(ir_node_visitor & v)20966 function_type::traverse(ir_node_visitor& v)
20967 {
20968 // TODO: should we allow the walker to avoid visiting function type
20969 // twice? I think that if we do, then ir_node_visitor needs an
20970 // option to specifically disallow this feature for function types.
20971
20972 if (visiting())
20973 return true;
20974
20975 if (v.visit_begin(this))
20976 {
20977 visiting(true);
20978 bool keep_going = true;
20979
20980 if (type_base_sptr t = get_return_type())
20981 {
20982 if (!t->traverse(v))
20983 keep_going = false;
20984 }
20985
20986 if (keep_going)
20987 for (parameters::const_iterator i = get_parameters().begin();
20988 i != get_parameters().end();
20989 ++i)
20990 if (type_base_sptr parm_type = (*i)->get_type())
20991 if (!parm_type->traverse(v))
20992 break;
20993
20994 visiting(false);
20995 }
20996 return v.visit_end(this);
20997 }
20998
~function_type()20999 function_type::~function_type()
21000 {}
21001 // </function_type>
21002
21003 // <method_type>
21004
21005 struct method_type::priv
21006 {
21007 class_or_union_wptr class_type_;
21008 bool is_const;
21009
privabigail::ir::method_type::priv21010 priv()
21011 : is_const()
21012 {}
21013 }; // end struct method_type::priv
21014
21015 /// Constructor for instances of method_type.
21016 ///
21017 /// Instances of method_decl must be of type method_type.
21018 ///
21019 /// @param return_type the type of the return value of the method.
21020 ///
21021 /// @param class_type the base type of the method type. That is, the
21022 /// type of the class the method belongs to.
21023 ///
21024 /// @param p the vector of the parameters of the method.
21025 ///
21026 /// @param is_const whether this method type is for a const method.
21027 /// Note that const-ness is a property of the method *type* and of the
21028 /// relationship between a method *declaration* and its scope.
21029 ///
21030 /// @param size_in_bits the size of an instance of method_type,
21031 /// expressed in bits.
21032 ///
21033 /// @param alignment_in_bits the alignment of an instance of
21034 /// 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)21035 method_type::method_type (type_base_sptr return_type,
21036 class_or_union_sptr class_type,
21037 const std::vector<function_decl::parameter_sptr>& p,
21038 bool is_const,
21039 size_t size_in_bits,
21040 size_t alignment_in_bits)
21041 : type_or_decl_base(class_type->get_environment(),
21042 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21043 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21044 function_type(return_type, p, size_in_bits, alignment_in_bits),
21045 priv_(new priv)
21046 {
21047 runtime_type_instance(this);
21048 set_class_type(class_type);
21049 set_is_const(is_const);
21050 }
21051
21052 /// Constructor of instances of method_type.
21053 ///
21054 ///Instances of method_decl must be of type method_type.
21055 ///
21056 /// @param return_type the type of the return value of the method.
21057 ///
21058 /// @param class_type the type of the class the method belongs to.
21059 /// The actual (dynamic) type of class_type must be a pointer
21060 /// class_type. We are setting it to pointer to type_base here to
21061 /// help client code that is compiled without rtti and thus cannot
21062 /// perform dynamic casts.
21063 ///
21064 /// @param p the vector of the parameters of the method type.
21065 ///
21066 /// @param is_const whether this method type is for a const method.
21067 /// Note that const-ness is a property of the method *type* and of the
21068 /// relationship between a method *declaration* and its scope.
21069 ///
21070 /// @param size_in_bits the size of an instance of method_type,
21071 /// expressed in bits.
21072 ///
21073 /// @param alignment_in_bits the alignment of an instance of
21074 /// 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)21075 method_type::method_type(type_base_sptr return_type,
21076 type_base_sptr class_type,
21077 const std::vector<function_decl::parameter_sptr>& p,
21078 bool is_const,
21079 size_t size_in_bits,
21080 size_t alignment_in_bits)
21081 : type_or_decl_base(class_type->get_environment(),
21082 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21083 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21084 function_type(return_type, p, size_in_bits, alignment_in_bits),
21085 priv_(new priv)
21086 {
21087 runtime_type_instance(this);
21088 set_class_type(is_class_type(class_type));
21089 set_is_const(is_const);
21090 }
21091
21092 /// Constructor of the qualified_type_def
21093 ///
21094 /// @param env the environment we are operating from.
21095 ///
21096 /// @param size_in_bits the size of the type, expressed in bits.
21097 ///
21098 /// @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)21099 method_type::method_type(const environment& env,
21100 size_t size_in_bits,
21101 size_t alignment_in_bits)
21102 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21103 type_base(env, size_in_bits, alignment_in_bits),
21104 function_type(env, size_in_bits, alignment_in_bits),
21105 priv_(new priv)
21106 {
21107 runtime_type_instance(this);
21108 }
21109
21110 /// Constructor of instances of method_type.
21111 ///
21112 /// When constructed with this constructor, and instane of method_type
21113 /// must set a return type using method_type::set_return_type
21114 ///
21115 /// @param class_typ the base type of the method type. That is, the
21116 /// type of the class (or union) the method belongs to.
21117 ///
21118 /// @param size_in_bits the size of an instance of method_type,
21119 /// expressed in bits.
21120 ///
21121 /// @param alignment_in_bits the alignment of an instance of
21122 /// 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)21123 method_type::method_type(class_or_union_sptr class_type,
21124 bool is_const,
21125 size_t size_in_bits,
21126 size_t alignment_in_bits)
21127 : type_or_decl_base(class_type->get_environment(),
21128 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
21129 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
21130 function_type(class_type->get_environment(),
21131 size_in_bits,
21132 alignment_in_bits),
21133 priv_(new priv)
21134 {
21135 runtime_type_instance(this);
21136 set_class_type(class_type);
21137 set_is_const(is_const);
21138 }
21139
21140 /// Get the class type this method belongs to.
21141 ///
21142 /// @return the class type.
21143 class_or_union_sptr
get_class_type() const21144 method_type::get_class_type() const
21145 {return class_or_union_sptr(priv_->class_type_);}
21146
21147 /// Sets the class type of the current instance of method_type.
21148 ///
21149 /// The class type is the type of the class the method belongs to.
21150 ///
21151 /// @param t the new class type to set.
21152 void
set_class_type(const class_or_union_sptr & t)21153 method_type::set_class_type(const class_or_union_sptr& t)
21154 {
21155 if (!t)
21156 return;
21157
21158 priv_->class_type_ = t;
21159 }
21160
21161 /// Return a copy of the pretty representation of the current @ref
21162 /// method_type.
21163 ///
21164 /// @param internal set to true if the call is intended to get a
21165 /// representation of the decl (or type) for the purpose of canonical
21166 /// type comparison. This is mainly used in the function
21167 /// type_base::get_canonical_type_for().
21168 ///
21169 /// In other words if the argument for this parameter is true then the
21170 /// call is meant for internal use (for technical use inside the
21171 /// library itself), false otherwise. If you don't know what this is
21172 /// for, then set it to false.
21173 ///
21174 /// @return a copy of the pretty representation of the current @ref
21175 /// method_type.
21176 string
get_pretty_representation(bool internal,bool) const21177 method_type::get_pretty_representation(bool internal,
21178 bool /*qualified_name*/) const
21179 {return ir::get_pretty_representation(*this, internal);}
21180
21181 /// Setter of the "is-const" property of @ref method_type.
21182 ///
21183 /// @param the new value of the "is-const" property.
21184 void
set_is_const(bool f)21185 method_type::set_is_const(bool f)
21186 {priv_->is_const = f;}
21187
21188 /// Getter of the "is-const" property of @ref method_type.
21189 ///
21190 /// @return true iff the "is-const" property was set.
21191 bool
get_is_const() const21192 method_type::get_is_const() const
21193 {return priv_->is_const;}
21194
21195 /// The destructor of method_type
~method_type()21196 method_type::~method_type()
21197 {}
21198
21199 // </method_type>
21200
21201 // <function_decl definitions>
21202
21203 struct function_decl::priv
21204 {
21205 bool declared_inline_;
21206 decl_base::binding binding_;
21207 function_type_wptr type_;
21208 function_type* naked_type_;
21209 elf_symbol_sptr symbol_;
21210 interned_string id_;
21211
privabigail::ir::function_decl::priv21212 priv()
21213 : declared_inline_(false),
21214 binding_(decl_base::BINDING_GLOBAL),
21215 naked_type_()
21216 {}
21217
privabigail::ir::function_decl::priv21218 priv(function_type_sptr t,
21219 bool declared_inline,
21220 decl_base::binding binding)
21221 : declared_inline_(declared_inline),
21222 binding_(binding),
21223 type_(t),
21224 naked_type_(t.get())
21225 {}
21226
privabigail::ir::function_decl::priv21227 priv(function_type_sptr t,
21228 bool declared_inline,
21229 decl_base::binding binding,
21230 elf_symbol_sptr s)
21231 : declared_inline_(declared_inline),
21232 binding_(binding),
21233 type_(t),
21234 naked_type_(t.get()),
21235 symbol_(s)
21236 {}
21237 }; // end sruct function_decl::priv
21238
21239 /// Constructor of the @ref function_decl.
21240 ///
21241 /// @param name the name of the function.
21242 ///
21243 /// @param function_type the type of the function.
21244 ///
21245 /// @param declared_inline wether the function is declared inline.
21246 ///
21247 /// @param locus the source location of the function.
21248 ///
21249 /// @param mangled_name the linkage name of the function.
21250 ///
21251 /// @param vis the visibility of the function.
21252 ///
21253 /// @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)21254 function_decl::function_decl(const string& name,
21255 function_type_sptr function_type,
21256 bool declared_inline,
21257 const location& locus,
21258 const string& mangled_name,
21259 visibility vis,
21260 binding bind)
21261 : type_or_decl_base(function_type->get_environment(),
21262 FUNCTION_DECL | ABSTRACT_DECL_BASE),
21263 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
21264 priv_(new priv(function_type, declared_inline, bind))
21265 {
21266 runtime_type_instance(this);
21267 }
21268
21269 /// Constructor of the function_decl type.
21270 ///
21271 /// This flavour of constructor is for when the pointer to the
21272 /// instance of function_type that the client code has is presented as
21273 /// a pointer to type_base. In that case, this constructor saves the
21274 /// client code from doing a dynamic_cast to get the function_type
21275 /// pointer.
21276 ///
21277 /// @param name the name of the function declaration.
21278 ///
21279 /// @param fn_type the type of the function declaration. The dynamic
21280 /// type of this parameter should be 'pointer to function_type'
21281 ///
21282 /// @param declared_inline whether this function was declared inline
21283 ///
21284 /// @param locus the source location of the function declaration.
21285 ///
21286 /// @param linkage_name the mangled name of the function declaration.
21287 ///
21288 /// @param vis the visibility of the function declaration.
21289 ///
21290 /// @param bind the kind of the binding of the function
21291 /// 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)21292 function_decl::function_decl(const string& name,
21293 type_base_sptr fn_type,
21294 bool declared_inline,
21295 const location& locus,
21296 const string& linkage_name,
21297 visibility vis,
21298 binding bind)
21299 : type_or_decl_base(fn_type->get_environment(),
21300 FUNCTION_DECL | ABSTRACT_DECL_BASE),
21301 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
21302 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
21303 declared_inline,
21304 bind))
21305 {
21306 runtime_type_instance(this);
21307 }
21308
21309 /// Get the pretty representation of the current instance of @ref function_decl.
21310 ///
21311 /// @param internal set to true if the call is intended to get a
21312 /// representation of the decl (or type) for the purpose of canonical
21313 /// type comparison. This is mainly used in the function
21314 /// type_base::get_canonical_type_for().
21315 ///
21316 /// In other words if the argument for this parameter is true then the
21317 /// call is meant for internal use (for technical use inside the
21318 /// library itself), false otherwise. If you don't know what this is
21319 /// for, then set it to false.
21320 ///
21321 /// @return the pretty representation for a function.
21322 string
get_pretty_representation(bool internal,bool qualified_name) const21323 function_decl::get_pretty_representation(bool internal,
21324 bool qualified_name) const
21325 {
21326 const method_decl* mem_fn =
21327 dynamic_cast<const method_decl*>(this);
21328
21329 string result = mem_fn ? "method ": "function ";
21330
21331 if (mem_fn
21332 && is_member_function(mem_fn)
21333 && get_member_function_is_virtual(mem_fn))
21334 result += "virtual ";
21335
21336 decl_base_sptr type;
21337 if ((mem_fn
21338 && is_member_function(mem_fn)
21339 && (get_member_function_is_dtor(*mem_fn)
21340 || get_member_function_is_ctor(*mem_fn))))
21341 /*cdtors do not have return types. */;
21342 else
21343 type = mem_fn
21344 ? get_type_declaration(mem_fn->get_type()->get_return_type())
21345 : get_type_declaration(get_type()->get_return_type());
21346
21347 if (type)
21348 result += get_type_name(is_type(type).get(),
21349 qualified_name,
21350 internal) + " ";
21351
21352 result += get_pretty_representation_of_declarator(internal);
21353
21354 return result;
21355 }
21356
21357 /// Compute and return the pretty representation for the part of the
21358 /// function declaration that starts at the declarator. That is, the
21359 /// return type and the other specifiers of the beginning of the
21360 /// function's declaration ar omitted.
21361 ///
21362 /// @param internal set to true if the call is intended to get a
21363 /// representation of the decl (or type) for the purpose of canonical
21364 /// type comparison. This is mainly used in the function
21365 /// type_base::get_canonical_type_for().
21366 ///
21367 /// In other words if the argument for this parameter is true then the
21368 /// call is meant for internal use (for technical use inside the
21369 /// library itself), false otherwise. If you don't know what this is
21370 /// for, then set it to false.
21371 ///
21372 /// @return the pretty representation for the part of the function
21373 /// declaration that starts at the declarator.
21374 string
get_pretty_representation_of_declarator(bool internal) const21375 function_decl::get_pretty_representation_of_declarator (bool internal) const
21376 {
21377 const method_decl* mem_fn =
21378 dynamic_cast<const method_decl*>(this);
21379
21380 string result;
21381
21382 if (mem_fn)
21383 {
21384 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
21385 + "::" + mem_fn->get_name();
21386 }
21387 else
21388 result += get_qualified_name();
21389
21390 result += "(";
21391
21392 parameters::const_iterator i = get_parameters().begin(),
21393 end = get_parameters().end();
21394
21395 // Skip the first parameter if this is a method.
21396 if (mem_fn && i != end)
21397 ++i;
21398 parameter_sptr parm;
21399 parameter_sptr first_parm;
21400 if (i != end)
21401 first_parm = *i;
21402 for (; i != end; ++i)
21403 {
21404 parm = *i;
21405 if (parm.get() != first_parm.get())
21406 result += ", ";
21407 if (parm->get_variadic_marker()
21408 || get_environment().is_variadic_parameter_type(parm->get_type()))
21409 result += "...";
21410 else
21411 {
21412 type_base_sptr type = parm->get_type();
21413 if (internal)
21414 type = peel_typedef_type(type);
21415 result += get_type_name(type, /*qualified=*/true, internal);
21416 }
21417 }
21418 result += ")";
21419
21420 if (mem_fn
21421 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
21422 || is_method_type(mem_fn->get_type())->get_is_const()))
21423 result += " const";
21424
21425 return result;
21426 }
21427
21428 /// Getter for the first non-implicit parameter of a function decl.
21429 ///
21430 /// If the function is a non-static member function, the parameter
21431 /// returned is the first one following the implicit 'this' parameter.
21432 ///
21433 /// @return the first non implicit parm.
21434 function_decl::parameters::const_iterator
get_first_non_implicit_parm() const21435 function_decl::get_first_non_implicit_parm() const
21436 {
21437 if (get_parameters().empty())
21438 return get_parameters().end();
21439
21440 bool is_method = dynamic_cast<const method_decl*>(this);
21441
21442 parameters::const_iterator i = get_parameters().begin();
21443 if (is_method)
21444 ++i;
21445
21446 return i;
21447 }
21448
21449 /// Return the type of the current instance of @ref function_decl.
21450 ///
21451 /// It's either a function_type or method_type.
21452 /// @return the type of the current instance of @ref function_decl.
21453 const shared_ptr<function_type>
get_type() const21454 function_decl::get_type() const
21455 {return priv_->type_.lock();}
21456
21457 /// Fast getter of the type of the current instance of @ref function_decl.
21458 ///
21459 /// Note that this function returns the underlying pointer managed by
21460 /// the smart pointer returned by function_decl::get_type(). It's
21461 /// faster than function_decl::get_type(). This getter is to be used
21462 /// in code paths that are proven to be performance hot spots;
21463 /// especially (for instance) when comparing function types. Those
21464 /// are compared extremely frequently when libabigail is used to
21465 /// handle huge binaries with a lot of functions.
21466 ///
21467 /// @return the type of the current instance of @ref function_decl.
21468 const function_type*
get_naked_type() const21469 function_decl::get_naked_type() const
21470 {return priv_->naked_type_;}
21471
21472 void
set_type(const function_type_sptr & fn_type)21473 function_decl::set_type(const function_type_sptr& fn_type)
21474 {
21475 priv_->type_ = fn_type;
21476 priv_->naked_type_ = fn_type.get();
21477 }
21478
21479 /// This sets the underlying ELF symbol for the current function decl.
21480 ///
21481 /// And underlyin$g ELF symbol for the current function decl might
21482 /// exist only if the corpus that this function decl originates from
21483 /// was constructed from an ELF binary file.
21484 ///
21485 /// Note that comparing two function decls that have underlying ELF
21486 /// symbols involves comparing their underlying elf symbols. The decl
21487 /// name for the function thus becomes irrelevant in the comparison.
21488 ///
21489 /// @param sym the new ELF symbol for this function decl.
21490 void
set_symbol(const elf_symbol_sptr & sym)21491 function_decl::set_symbol(const elf_symbol_sptr& sym)
21492 {
21493 priv_->symbol_ = sym;
21494 // The function id cache that depends on the symbol must be
21495 // invalidated because the symbol changed.
21496 priv_->id_ = get_environment().intern("");
21497 }
21498
21499 /// Gets the the underlying ELF symbol for the current variable,
21500 /// that was set using function_decl::set_symbol(). Please read the
21501 /// documentation for that member function for more information about
21502 /// "underlying ELF symbols".
21503 ///
21504 /// @return sym the underlying ELF symbol for this function decl, if
21505 /// one exists.
21506 const elf_symbol_sptr&
get_symbol() const21507 function_decl::get_symbol() const
21508 {return priv_->symbol_;}
21509
21510 bool
is_declared_inline() const21511 function_decl::is_declared_inline() const
21512 {return priv_->declared_inline_;}
21513
21514 decl_base::binding
get_binding() const21515 function_decl::get_binding() const
21516 {return priv_->binding_;}
21517
21518 /// @return the return type of the current instance of function_decl.
21519 const shared_ptr<type_base>
get_return_type() const21520 function_decl::get_return_type() const
21521 {return get_type()->get_return_type();}
21522
21523 /// @return the parameters of the function.
21524 const std::vector<shared_ptr<function_decl::parameter> >&
get_parameters() const21525 function_decl::get_parameters() const
21526 {return get_type()->get_parameters();}
21527
21528 /// Append a parameter to the type of this function.
21529 ///
21530 /// @param parm the parameter to append.
21531 void
append_parameter(shared_ptr<parameter> parm)21532 function_decl::append_parameter(shared_ptr<parameter> parm)
21533 {get_type()->append_parameter(parm);}
21534
21535 /// Append a vector of parameters to the type of this function.
21536 ///
21537 /// @param parms the vector of parameters to append.
21538 void
append_parameters(std::vector<shared_ptr<parameter>> & parms)21539 function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
21540 {
21541 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
21542 i != parms.end();
21543 ++i)
21544 get_type()->append_parameter(*i);
21545 }
21546
21547 /// Create a new instance of function_decl that is a clone of the
21548 /// current one.
21549 ///
21550 /// @return the new clone.
21551 function_decl_sptr
clone() const21552 function_decl::clone() const
21553 {
21554 function_decl_sptr f;
21555 if (is_member_function(*this))
21556 {
21557 method_decl_sptr
21558 m(new method_decl(get_name(),
21559 get_type(),
21560 is_declared_inline(),
21561 get_location(),
21562 get_linkage_name(),
21563 get_visibility(),
21564 get_binding()));
21565 class_or_union* scope = is_class_or_union_type(get_scope());
21566 ABG_ASSERT(scope);
21567 scope->add_member_function(m, get_member_access_specifier(*this),
21568 get_member_function_is_virtual(*this),
21569 get_member_function_vtable_offset(*this),
21570 get_member_is_static(*this),
21571 get_member_function_is_ctor(*this),
21572 get_member_function_is_dtor(*this),
21573 get_member_function_is_const(*this));
21574 f = m;
21575 }
21576 else
21577 {
21578 f.reset(new function_decl(get_name(),
21579 get_type(),
21580 is_declared_inline(),
21581 get_location(),
21582 get_linkage_name(),
21583 get_visibility(),
21584 get_binding()));
21585 add_decl_to_scope(f, get_scope());
21586 }
21587 f->set_symbol(get_symbol());
21588
21589 return f;
21590 }
21591
21592 /// Compares two instances of @ref function_decl.
21593 ///
21594 /// If the two intances are different, set a bitfield to give some
21595 /// insight about the kind of differences there are.
21596 ///
21597 /// @param l the first artifact of the comparison.
21598 ///
21599 /// @param r the second artifact of the comparison.
21600 ///
21601 /// @param k a pointer to a bitfield that gives information about the
21602 /// kind of changes there are between @p l and @p r. This one is set
21603 /// iff @p k is non-null and the function returns false.
21604 ///
21605 /// Please note that setting k to a non-null value does have a
21606 /// negative performance impact because even if @p l and @p r are not
21607 /// equal, the function keeps up the comparison in order to determine
21608 /// the different kinds of ways in which they are different.
21609 ///
21610 /// @return true if @p l equals @p r, false otherwise.
21611 bool
equals(const function_decl & l,const function_decl & r,change_kind * k)21612 equals(const function_decl& l, const function_decl& r, change_kind* k)
21613 {
21614 bool result = true;
21615
21616 // Compare function types
21617 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
21618 if (t0 == t1 || *t0 == *t1)
21619 ; // the types are equal, let's move on to compare the other
21620 // properties of the functions.
21621 else
21622 {
21623 result = false;
21624 if (k)
21625 {
21626 if (!types_have_similar_structure(t0, t1))
21627 *k |= LOCAL_TYPE_CHANGE_KIND;
21628 else
21629 *k |= SUBTYPE_CHANGE_KIND;
21630 }
21631 else
21632 ABG_RETURN_FALSE;
21633 }
21634
21635 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
21636 if (!!s0 != !!s1)
21637 {
21638 result = false;
21639 if (k)
21640 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21641 else
21642 ABG_RETURN_FALSE;
21643 }
21644 else if (s0 && s0 != s1)
21645 {
21646 if (!elf_symbols_alias(s0, s1))
21647 {
21648 result = false;
21649 if (k)
21650 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21651 else
21652 ABG_RETURN_FALSE;
21653 }
21654 }
21655 bool symbols_are_equal = (s0 && s1 && result);
21656
21657 if (symbols_are_equal)
21658 {
21659 // The functions have underlying elf symbols that are equal,
21660 // so now, let's compare the decl_base part of the functions
21661 // w/o considering their decl names.
21662 interned_string n1 = l.get_name(), n2 = r.get_name();
21663 interned_string ln1 = l.get_linkage_name(), ln2 = r.get_linkage_name();
21664 const_cast<function_decl&>(l).set_name("");
21665 const_cast<function_decl&>(l).set_linkage_name("");
21666 const_cast<function_decl&>(r).set_name("");
21667 const_cast<function_decl&>(r).set_linkage_name("");
21668
21669 bool decl_bases_different = !l.decl_base::operator==(r);
21670
21671 const_cast<function_decl&>(l).set_name(n1);
21672 const_cast<function_decl&>(l).set_linkage_name(ln1);
21673 const_cast<function_decl&>(r).set_name(n2);
21674 const_cast<function_decl&>(r).set_linkage_name(ln2);
21675
21676 if (decl_bases_different)
21677 {
21678 result = false;
21679 if (k)
21680 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21681 else
21682 ABG_RETURN_FALSE;
21683 }
21684 }
21685 else
21686 if (!l.decl_base::operator==(r))
21687 {
21688 result = false;
21689 if (k)
21690 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21691 else
21692 ABG_RETURN_FALSE;
21693 }
21694
21695 // Compare the remaining properties
21696 if (l.is_declared_inline() != r.is_declared_inline()
21697 || l.get_binding() != r.get_binding())
21698 {
21699 result = false;
21700 if (k)
21701 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21702 else
21703 ABG_RETURN_FALSE;
21704 }
21705
21706 if (is_member_function(l) != is_member_function(r))
21707 {
21708 result = false;
21709 if (k)
21710 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21711 else
21712 ABG_RETURN_FALSE;
21713 }
21714
21715 if (is_member_function(l) && is_member_function(r))
21716 {
21717 if (!((get_member_function_is_ctor(l)
21718 == get_member_function_is_ctor(r))
21719 && (get_member_function_is_dtor(l)
21720 == get_member_function_is_dtor(r))
21721 && (get_member_is_static(l)
21722 == get_member_is_static(r))
21723 && (get_member_function_is_const(l)
21724 == get_member_function_is_const(r))
21725 && (get_member_function_is_virtual(l)
21726 == get_member_function_is_virtual(r))
21727 && (get_member_function_vtable_offset(l)
21728 == get_member_function_vtable_offset(r))))
21729 {
21730 result = false;
21731 if (k)
21732 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21733 else
21734 ABG_RETURN_FALSE;
21735 }
21736 }
21737
21738 ABG_RETURN(result);
21739 }
21740
21741 /// Comparison operator for @ref function_decl.
21742 ///
21743 /// @param other the other instance of @ref function_decl to compare
21744 /// against.
21745 ///
21746 /// @return true iff the current instance of @ref function_decl equals
21747 /// @p other.
21748 bool
operator ==(const decl_base & other) const21749 function_decl::operator==(const decl_base& other) const
21750 {
21751 const function_decl* o = dynamic_cast<const function_decl*>(&other);
21752 if (!o)
21753 return false;
21754 return equals(*this, *o, 0);
21755 }
21756
21757 /// Return true iff the function takes a variable number of
21758 /// parameters.
21759 ///
21760 /// @return true if the function taks a variable number
21761 /// of parameters.
21762 bool
is_variadic() const21763 function_decl::is_variadic() const
21764 {
21765 return (!get_parameters().empty()
21766 && get_parameters().back()->get_variadic_marker());
21767 }
21768
21769 /// The virtual implementation of 'get_hash' for a function_decl.
21770 ///
21771 /// This allows decl_base::get_hash to work for function_decls.
21772 ///
21773 /// @return the hash value for function decl.
21774 size_t
get_hash() const21775 function_decl::get_hash() const
21776 {
21777 function_decl::hash hash_fn;
21778 return hash_fn(*this);
21779 }
21780
21781 /// Return an ID that tries to uniquely identify the function inside a
21782 /// program or a library.
21783 ///
21784 /// So if the function has an underlying elf symbol, the ID is the
21785 /// concatenation of the symbol name and its version. Otherwise, the
21786 /// ID is the linkage name if its non-null. Otherwise, it's the
21787 /// pretty representation of the function.
21788 ///
21789 /// @return the ID.
21790 interned_string
get_id() const21791 function_decl::get_id() const
21792 {
21793 if (priv_->id_.empty())
21794 {
21795 const environment& env = get_type()->get_environment();
21796 if (elf_symbol_sptr s = get_symbol())
21797 {
21798 string virtual_member_suffix;
21799 if (is_member_function(this))
21800 {
21801 method_decl* m = is_method_decl(this);
21802 ABG_ASSERT(m);
21803 if (get_member_function_is_virtual(m))
21804 {
21805 if (is_declaration_only_class_or_union_type
21806 (m->get_type()->get_class_type(),
21807 /*look_through_decl_only=*/true))
21808 virtual_member_suffix += "/o";
21809 }
21810 }
21811 if (s->has_aliases())
21812 // The symbol has several aliases, so let's use a scheme
21813 // that allows all aliased functions to have different
21814 // IDs.
21815 priv_->id_ = env.intern(get_name() + "/" + s->get_id_string());
21816 else
21817 // Let's use the full symbol name with its version as ID.
21818 priv_->id_ = env.intern(s->get_id_string());
21819
21820 if (!virtual_member_suffix.empty())
21821 priv_->id_ = env.intern(priv_->id_ + virtual_member_suffix);
21822 }
21823 else if (!get_linkage_name().empty())
21824 priv_->id_= env.intern(get_linkage_name());
21825 else
21826 priv_->id_ = env.intern(get_pretty_representation());
21827 }
21828 return priv_->id_;
21829 }
21830
21831 /// Test if two function declarations are aliases.
21832 ///
21833 /// Two functions declarations are aliases if their symbols are
21834 /// aliases, in the ELF sense.
21835 ///
21836 /// @param f1 the first function to consider.
21837 ///
21838 /// @param f2 the second function to consider.
21839 ///
21840 /// @return true iff @p f1 is an alias of @p f2
21841 bool
function_decls_alias(const function_decl & f1,const function_decl & f2)21842 function_decls_alias(const function_decl& f1, const function_decl& f2)
21843 {
21844 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
21845
21846 if (!s1 || !s2)
21847 return false;
21848
21849 return elf_symbols_alias(s1, s2);
21850 }
21851
21852 /// This implements the ir_traversable_base::traverse pure virtual
21853 /// function.
21854 ///
21855 /// @param v the visitor used on the current instance.
21856 ///
21857 /// @return true if the entire IR node tree got traversed, false
21858 /// otherwise.
21859 bool
traverse(ir_node_visitor & v)21860 function_decl::traverse(ir_node_visitor& v)
21861 {
21862 if (visiting())
21863 return true;
21864
21865 if (v.visit_begin(this))
21866 {
21867 visiting(true);
21868 if (type_base_sptr t = get_type())
21869 t->traverse(v);
21870 visiting(false);
21871 }
21872 return v.visit_end(this);
21873 }
21874
21875 /// Destructor of the @ref function_decl type.
~function_decl()21876 function_decl::~function_decl()
21877 {delete priv_;}
21878
21879 /// A deep comparison operator for a shared pointer to @ref function_decl
21880 ///
21881 /// This function compares to shared pointers to @ref function_decl by
21882 /// looking at the pointed-to instances of @ref function_dec
21883 /// comparing them too. If the two pointed-to objects are equal then
21884 /// this function returns true.
21885 ///
21886 /// @param l the left-hand side argument of the equality operator.
21887 ///
21888 /// @param r the right-hand side argument of the equality operator.
21889 ///
21890 /// @return true iff @p l equals @p r.
21891 bool
operator ==(const function_decl_sptr & l,const function_decl_sptr & r)21892 operator==(const function_decl_sptr& l, const function_decl_sptr& r)
21893 {
21894 if (l.get() == r.get())
21895 return true;
21896 if (!!l != !!r)
21897 return false;
21898
21899 return *l == *r;
21900 }
21901
21902 /// A deep inequality operator for smart pointers to functions.
21903 ///
21904 /// @param l the left-hand side argument of the inequality operator.
21905 ///
21906 /// @pram r the right-hand side argument of the inequality operator.
21907 ///
21908 /// @return true iff @p is not equal to @p r.
21909 bool
operator !=(const function_decl_sptr & l,const function_decl_sptr & r)21910 operator!=(const function_decl_sptr& l, const function_decl_sptr& r)
21911 {return !operator==(l, r);}
21912
21913 // <function_decl definitions>
21914
21915 // <function_decl::parameter definitions>
21916
21917 struct function_decl::parameter::priv
21918 {
21919 type_base_wptr type_;
21920 unsigned index_;
21921 bool variadic_marker_;
21922
privabigail::ir::function_decl::parameter::priv21923 priv()
21924 : index_(),
21925 variadic_marker_()
21926 {}
21927
privabigail::ir::function_decl::parameter::priv21928 priv(type_base_sptr type,
21929 unsigned index,
21930 bool variadic_marker)
21931 : type_(type),
21932 index_(index),
21933 variadic_marker_(variadic_marker)
21934 {}
21935 };// end struct function_decl::parameter::priv
21936
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic)21937 function_decl::parameter::parameter(const type_base_sptr type,
21938 unsigned index,
21939 const string& name,
21940 const location& loc,
21941 bool is_variadic)
21942 : type_or_decl_base(type->get_environment(),
21943 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21944 decl_base(type->get_environment(), name, loc),
21945 priv_(new priv(type, index, is_variadic))
21946 {
21947 runtime_type_instance(this);
21948 }
21949
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic,bool is_artificial)21950 function_decl::parameter::parameter(const type_base_sptr type,
21951 unsigned index,
21952 const string& name,
21953 const location& loc,
21954 bool is_variadic,
21955 bool is_artificial)
21956 : type_or_decl_base(type->get_environment(),
21957 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21958 decl_base(type->get_environment(), name, loc),
21959 priv_(new priv(type, index, is_variadic))
21960 {
21961 runtime_type_instance(this);
21962 set_is_artificial(is_artificial);
21963 }
21964
parameter(const type_base_sptr type,const string & name,const location & loc,bool is_variadic,bool is_artificial)21965 function_decl::parameter::parameter(const type_base_sptr type,
21966 const string& name,
21967 const location& loc,
21968 bool is_variadic,
21969 bool is_artificial)
21970 : type_or_decl_base(type->get_environment(),
21971 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21972 decl_base(type->get_environment(), name, loc),
21973 priv_(new priv(type, 0, is_variadic))
21974 {
21975 runtime_type_instance(this);
21976 set_is_artificial(is_artificial);
21977 }
21978
parameter(const type_base_sptr type,unsigned index,bool variad)21979 function_decl::parameter::parameter(const type_base_sptr type,
21980 unsigned index,
21981 bool variad)
21982 : type_or_decl_base(type->get_environment(),
21983 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
21984 decl_base(type->get_environment(), "", location()),
21985 priv_(new priv(type, index, variad))
21986 {
21987 runtime_type_instance(this);
21988 }
21989
21990 function_decl::parameter::~parameter() = default;
21991
21992 const type_base_sptr
get_type() const21993 function_decl::parameter::get_type()const
21994 {return priv_->type_.lock();}
21995
21996 /// @return a copy of the type name of the parameter.
21997 interned_string
get_type_name() const21998 function_decl::parameter::get_type_name() const
21999 {
22000 const environment& env = get_environment();
22001
22002 type_base_sptr t = get_type();
22003 string str;
22004 if (get_variadic_marker() || env.is_variadic_parameter_type(t))
22005 str = "...";
22006 else
22007 {
22008 ABG_ASSERT(t);
22009 str = abigail::ir::get_type_name(t);
22010 }
22011 return env.intern(str);
22012 }
22013
22014 /// @return a copy of the pretty representation of the type of the
22015 /// parameter.
22016 const string
get_type_pretty_representation() const22017 function_decl::parameter::get_type_pretty_representation() const
22018 {
22019 type_base_sptr t = get_type();
22020 string str;
22021 if (get_variadic_marker()
22022 || get_environment().is_variadic_parameter_type(t))
22023 str = "...";
22024 else
22025 {
22026 ABG_ASSERT(t);
22027 str += get_type_declaration(t)->get_pretty_representation();
22028 }
22029 return str;
22030 }
22031
22032 /// Get a name uniquely identifying the parameter in the function.
22033 ///
22034 ///@return the unique parm name id.
22035 interned_string
get_name_id() const22036 function_decl::parameter::get_name_id() const
22037 {
22038 const environment& env = get_environment();
22039
22040
22041 std::ostringstream o;
22042 o << "parameter-" << get_index();
22043
22044 return env.intern(o.str());
22045 }
22046
22047 unsigned
get_index() const22048 function_decl::parameter::get_index() const
22049 {return priv_->index_;}
22050
22051 void
set_index(unsigned i)22052 function_decl::parameter::set_index(unsigned i)
22053 {priv_->index_ = i;}
22054
22055
22056 bool
get_variadic_marker() const22057 function_decl::parameter::get_variadic_marker() const
22058 {return priv_->variadic_marker_;}
22059
22060 /// Compares two instances of @ref function_decl::parameter.
22061 ///
22062 /// If the two intances are different, set a bitfield to give some
22063 /// insight about the kind of differences there are.
22064 ///
22065 /// @param l the first artifact of the comparison.
22066 ///
22067 /// @param r the second artifact of the comparison.
22068 ///
22069 /// @param k a pointer to a bitfield that gives information about the
22070 /// kind of changes there are between @p l and @p r. This one is set
22071 /// iff @p k is non-null and the function returns false.
22072 ///
22073 /// Please note that setting k to a non-null value does have a
22074 /// negative performance impact because even if @p l and @p r are not
22075 /// equal, the function keeps up the comparison in order to determine
22076 /// the different kinds of ways in which they are different.
22077 ///
22078 /// @return true if @p l equals @p r, false otherwise.
22079 bool
equals(const function_decl::parameter & l,const function_decl::parameter & r,change_kind * k)22080 equals(const function_decl::parameter& l,
22081 const function_decl::parameter& r,
22082 change_kind* k)
22083 {
22084 bool result = true;
22085
22086 if ((l.get_variadic_marker() != r.get_variadic_marker())
22087 || (l.get_index() != r.get_index())
22088 || (!!l.get_type() != !!r.get_type()))
22089 {
22090 result = false;
22091 if (k)
22092 {
22093 if (l.get_index() != r.get_index())
22094 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
22095 if (l.get_variadic_marker() != r.get_variadic_marker()
22096 || !!l.get_type() != !!r.get_type())
22097 *k |= LOCAL_TYPE_CHANGE_KIND;
22098 }
22099 else
22100 ABG_RETURN_FALSE;
22101 }
22102
22103 type_base_sptr l_type = peel_typedef_type(l.get_type());
22104 type_base_sptr r_type = peel_typedef_type(r.get_type());
22105 if (l_type != r_type)
22106 {
22107 result = false;
22108 if (k)
22109 {
22110 if (!types_have_similar_structure(l_type, r_type))
22111 *k |= LOCAL_TYPE_CHANGE_KIND;
22112 else
22113 *k |= SUBTYPE_CHANGE_KIND;
22114 }
22115 else
22116 ABG_RETURN_FALSE;
22117 }
22118
22119 ABG_RETURN(result);
22120 }
22121
22122 bool
operator ==(const parameter & o) const22123 function_decl::parameter::operator==(const parameter& o) const
22124 {return equals(*this, o, 0);}
22125
22126 bool
operator ==(const decl_base & o) const22127 function_decl::parameter::operator==(const decl_base& o) const
22128 {
22129 const function_decl::parameter* p =
22130 dynamic_cast<const function_decl::parameter*>(&o);
22131 if (!p)
22132 return false;
22133 return function_decl::parameter::operator==(*p);
22134 }
22135
22136 /// Non-member equality operator for @ref function_decl::parameter.
22137 ///
22138 /// @param l the left-hand side of the equality operator
22139 ///
22140 /// @param r the right-hand side of the equality operator
22141 ///
22142 /// @return true iff @p l and @p r equals.
22143 bool
operator ==(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)22144 operator==(const function_decl::parameter_sptr& l,
22145 const function_decl::parameter_sptr& r)
22146 {
22147 if (!!l != !!r)
22148 return false;
22149 if (!l)
22150 return true;
22151 return *l == *r;
22152 }
22153
22154 /// Non-member inequality operator for @ref function_decl::parameter.
22155 ///
22156 /// @param l the left-hand side of the equality operator
22157 ///
22158 /// @param r the right-hand side of the equality operator
22159 ///
22160 /// @return true iff @p l and @p r different.
22161 bool
operator !=(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)22162 operator!=(const function_decl::parameter_sptr& l,
22163 const function_decl::parameter_sptr& r)
22164 {return !operator==(l, r);}
22165
22166 /// Traverse the diff sub-tree under the current instance
22167 /// function_decl.
22168 ///
22169 /// @param v the visitor to invoke on each diff node of the sub-tree.
22170 ///
22171 /// @return true if the traversing has to keep going on, false
22172 /// otherwise.
22173 bool
traverse(ir_node_visitor & v)22174 function_decl::parameter::traverse(ir_node_visitor& v)
22175 {
22176 if (visiting())
22177 return true;
22178
22179 if (v.visit_begin(this))
22180 {
22181 visiting(true);
22182 if (type_base_sptr t = get_type())
22183 t->traverse(v);
22184 visiting(false);
22185 }
22186 return v.visit_end(this);
22187 }
22188
22189 /// Get the hash of a decl. If the hash hasn't been computed yet,
22190 /// compute it ans store its value; otherwise, just return the hash.
22191 ///
22192 /// @return the hash of the decl.
22193 size_t
get_hash() const22194 function_decl::parameter::get_hash() const
22195 {
22196 function_decl::parameter::hash hash_fn_parm;
22197 return hash_fn_parm(this);
22198 }
22199
22200 /// Compute the qualified name of the parameter.
22201 ///
22202 /// @param internal set to true if the call is intended for an
22203 /// internal use (for technical use inside the library itself), false
22204 /// otherwise. If you don't know what this is for, then set it to
22205 /// false.
22206 ///
22207 /// @param qn the resulting qualified name.
22208 void
get_qualified_name(interned_string & qualified_name,bool) const22209 function_decl::parameter::get_qualified_name(interned_string& qualified_name,
22210 bool /*internal*/) const
22211 {qualified_name = get_name();}
22212
22213 /// Compute and return a copy of the pretty representation of the
22214 /// current function parameter.
22215 ///
22216 /// @param internal set to true if the call is intended to get a
22217 /// representation of the decl (or type) for the purpose of canonical
22218 /// type comparison. This is mainly used in the function
22219 /// type_base::get_canonical_type_for().
22220 ///
22221 /// In other words if the argument for this parameter is true then the
22222 /// call is meant for internal use (for technical use inside the
22223 /// library itself), false otherwise. If you don't know what this is
22224 /// for, then set it to false.
22225 ///
22226 /// @return a copy of the textual representation of the current
22227 /// function parameter.
22228 string
get_pretty_representation(bool internal,bool) const22229 function_decl::parameter::get_pretty_representation(bool internal,
22230 bool /*qualified_name*/) const
22231 {
22232 const environment& env = get_environment();
22233
22234 string type_repr;
22235 type_base_sptr t = get_type();
22236 if (!t)
22237 type_repr = "void";
22238 else if (env.is_variadic_parameter_type(t))
22239 type_repr = "...";
22240 else
22241 type_repr = ir::get_pretty_representation(t, internal);
22242
22243 string result = type_repr;
22244 string parm_name = get_name_id();
22245
22246 if (!parm_name.empty())
22247 result += " " + parm_name;
22248
22249 return result;
22250 }
22251
22252 // </function_decl::parameter definitions>
22253
22254 // <class_or_union definitions>
22255
22256 /// A Constructor for instances of @ref class_or_union
22257 ///
22258 /// @param env the environment we are operating from.
22259 ///
22260 /// @param name the identifier of the class.
22261 ///
22262 /// @param size_in_bits the size of an instance of @ref
22263 /// class_or_union, expressed in bits
22264 ///
22265 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
22266 /// expressed in bits.
22267 ///
22268 /// @param locus the source location of declaration point this class.
22269 ///
22270 /// @param vis the visibility of instances of @ref class_or_union.
22271 ///
22272 /// @param mem_types the vector of member types of this instance of
22273 /// @ref class_or_union.
22274 ///
22275 /// @param data_members the vector of data members of this instance of
22276 /// @ref class_or_union.
22277 ///
22278 /// @param member_fns the vector of member functions of this instance
22279 /// 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)22280 class_or_union::class_or_union(const environment& env, const string& name,
22281 size_t size_in_bits, size_t align_in_bits,
22282 const location& locus, visibility vis,
22283 member_types& mem_types,
22284 data_members& data_members,
22285 member_functions& member_fns)
22286 : type_or_decl_base(env,
22287 ABSTRACT_TYPE_BASE
22288 | ABSTRACT_DECL_BASE
22289 | ABSTRACT_SCOPE_TYPE_DECL
22290 | ABSTRACT_SCOPE_DECL),
22291 decl_base(env, name, locus, name, vis),
22292 type_base(env, size_in_bits, align_in_bits),
22293 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
22294 priv_(new priv(data_members, member_fns))
22295 {
22296 for (member_types::iterator i = mem_types.begin();
22297 i != mem_types.end();
22298 ++i)
22299 if (!has_scope(get_type_declaration(*i)))
22300 add_decl_to_scope(get_type_declaration(*i), this);
22301
22302 for (data_members::iterator i = data_members.begin();
22303 i != data_members.end();
22304 ++i)
22305 if (!has_scope(*i))
22306 add_decl_to_scope(*i, this);
22307
22308 for (member_functions::iterator i = member_fns.begin();
22309 i != member_fns.end();
22310 ++i)
22311 if (!has_scope(static_pointer_cast<decl_base>(*i)))
22312 add_decl_to_scope(*i, this);
22313 }
22314
22315 /// A constructor for instances of @ref class_or_union.
22316 ///
22317 /// @param env the environment we are operating from.
22318 ///
22319 /// @param name the name of the class.
22320 ///
22321 /// @param size_in_bits the size of an instance of @ref
22322 /// class_or_union, expressed in bits
22323 ///
22324 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
22325 /// expressed in bits.
22326 ///
22327 /// @param locus the source location of declaration point this class.
22328 ///
22329 /// @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)22330 class_or_union::class_or_union(const environment& env, const string& name,
22331 size_t size_in_bits, size_t align_in_bits,
22332 const location& locus, visibility vis)
22333 : type_or_decl_base(env,
22334 ABSTRACT_TYPE_BASE
22335 | ABSTRACT_DECL_BASE
22336 | ABSTRACT_SCOPE_TYPE_DECL
22337 | ABSTRACT_SCOPE_DECL),
22338 decl_base(env, name, locus, name, vis),
22339 type_base(env, size_in_bits, align_in_bits),
22340 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
22341 priv_(new priv)
22342 {}
22343
22344 /// Constructor of the @ref class_or_union type.
22345 ///
22346 /// @param env the @ref environment we are operating from.
22347 ///
22348 /// @param name the name of the @ref class_or_union.
22349 ///
22350 /// @param is_declaration_only a boolean saying whether the instance
22351 /// represents a declaration only, or not.
class_or_union(const environment & env,const string & name,bool is_declaration_only)22352 class_or_union::class_or_union(const environment& env, const string& name,
22353 bool is_declaration_only)
22354 : type_or_decl_base(env,
22355 ABSTRACT_TYPE_BASE
22356 | ABSTRACT_DECL_BASE
22357 | ABSTRACT_SCOPE_TYPE_DECL
22358 | ABSTRACT_SCOPE_DECL),
22359 decl_base(env, name, location(), name),
22360 type_base(env, 0, 0),
22361 scope_type_decl(env, name, 0, 0, location()),
22362 priv_(new priv)
22363 {
22364 set_is_declaration_only(is_declaration_only);
22365 }
22366
22367 /// This implements the ir_traversable_base::traverse pure virtual
22368 /// function.
22369 ///
22370 /// @param v the visitor used on the member nodes of the translation
22371 /// unit during the traversal.
22372 ///
22373 /// @return true if the entire IR node tree got traversed, false
22374 /// otherwise.
22375 bool
traverse(ir_node_visitor & v)22376 class_or_union::traverse(ir_node_visitor& v)
22377 {
22378 if (v.type_node_has_been_visited(this))
22379 return true;
22380
22381 if (visiting())
22382 return true;
22383
22384 if (v.visit_begin(this))
22385 {
22386 visiting(true);
22387 bool stop = false;
22388
22389 if (!stop)
22390 for (data_members::const_iterator i = get_data_members().begin();
22391 i != get_data_members().end();
22392 ++i)
22393 if (!(*i)->traverse(v))
22394 {
22395 stop = true;
22396 break;
22397 }
22398
22399 if (!stop)
22400 for (member_functions::const_iterator i= get_member_functions().begin();
22401 i != get_member_functions().end();
22402 ++i)
22403 if (!(*i)->traverse(v))
22404 {
22405 stop = true;
22406 break;
22407 }
22408
22409 if (!stop)
22410 for (member_types::const_iterator i = get_member_types().begin();
22411 i != get_member_types().end();
22412 ++i)
22413 if (!(*i)->traverse(v))
22414 {
22415 stop = true;
22416 break;
22417 }
22418
22419 if (!stop)
22420 for (member_function_templates::const_iterator i =
22421 get_member_function_templates().begin();
22422 i != get_member_function_templates().end();
22423 ++i)
22424 if (!(*i)->traverse(v))
22425 {
22426 stop = true;
22427 break;
22428 }
22429
22430 if (!stop)
22431 for (member_class_templates::const_iterator i =
22432 get_member_class_templates().begin();
22433 i != get_member_class_templates().end();
22434 ++i)
22435 if (!(*i)->traverse(v))
22436 {
22437 stop = true;
22438 break;
22439 }
22440 visiting(false);
22441 }
22442
22443 bool result = v.visit_end(this);
22444 v.mark_type_node_as_visited(this);
22445 return result;
22446 }
22447
22448 /// Destrcutor of the @ref class_or_union type.
~class_or_union()22449 class_or_union::~class_or_union()
22450 {delete priv_;}
22451
22452 /// Add a member declaration to the current instance of class_or_union.
22453 /// The member declaration can be either a member type, data member,
22454 /// member function, or member template.
22455 ///
22456 /// @param d the member declaration to add.
22457 decl_base_sptr
add_member_decl(const decl_base_sptr & d)22458 class_or_union::add_member_decl(const decl_base_sptr& d)
22459 {return insert_member_decl(d);}
22460
22461 /// Remove a given decl from the current @ref class_or_union scope.
22462 ///
22463 /// Note that only type declarations are supported by this method for
22464 /// now. Support for the other kinds of declaration is left as an
22465 /// exercise for the interested reader of the code.
22466 ///
22467 /// @param decl the declaration to remove from this @ref
22468 /// class_or_union scope.
22469 void
remove_member_decl(decl_base_sptr decl)22470 class_or_union::remove_member_decl(decl_base_sptr decl)
22471 {
22472 type_base_sptr t = is_type(decl);
22473
22474 // For now we want to support just removing types from classes. For
22475 // other kinds of IR node, we need more work.
22476 ABG_ASSERT(t);
22477
22478 remove_member_type(t);
22479 }
22480
22481 /// Fixup the members of the type of an anonymous data member.
22482 ///
22483 /// Walk all data members of (the type of) a given anonymous data
22484 /// member and set a particular property of the relationship between
22485 /// each data member and its containing type.
22486 ///
22487 /// That property records the fact that the data member belongs to the
22488 /// anonymous data member we consider.
22489 ///
22490 /// In the future, if there are other properties of this relationship
22491 /// to set in this manner, they ought to be added here.
22492 ///
22493 /// @param anon_dm the anonymous data member to consider.
22494 void
maybe_fixup_members_of_anon_data_member(var_decl_sptr & anon_dm)22495 class_or_union::maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm)
22496 {
22497 class_or_union * anon_dm_type =
22498 anonymous_data_member_to_class_or_union(anon_dm.get());
22499 if (!anon_dm_type)
22500 return;
22501
22502 for (class_or_union::data_members::const_iterator it =
22503 anon_dm_type->get_non_static_data_members().begin();
22504 it != anon_dm_type->get_non_static_data_members().end();
22505 ++it)
22506 {
22507 dm_context_rel *rel =
22508 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
22509 ABG_ASSERT(rel);
22510 rel->set_anonymous_data_member(anon_dm.get());
22511 }
22512 }
22513
22514 /// Getter of the alignment of the @ref class_or_union type.
22515 ///
22516 /// If this @ref class_or_union is a declaration of a definition that
22517 /// is elsewhere, then the size of the definition is returned.
22518 ///
22519 /// @return the alignment of the @ref class_or_union type.
22520 size_t
get_alignment_in_bits() const22521 class_or_union::get_alignment_in_bits() const
22522 {
22523 if (get_is_declaration_only() && get_definition_of_declaration())
22524 return is_class_or_union_type
22525 (get_definition_of_declaration())->get_alignment_in_bits();
22526
22527 return type_base::get_alignment_in_bits();
22528 }
22529
22530 /// Setter of the alignment of the class type.
22531 ///
22532 /// If this class is a declaration of a definition that is elsewhere,
22533 /// then the new alignment is set to the definition.
22534 ///
22535 /// @param s the new alignment.
22536 void
set_alignment_in_bits(size_t a)22537 class_or_union::set_alignment_in_bits(size_t a)
22538 {
22539 if (get_is_declaration_only() && get_definition_of_declaration())
22540 is_class_or_union_type
22541 (get_definition_of_declaration()) ->set_alignment_in_bits(a);
22542 else
22543 type_base::set_alignment_in_bits(a);
22544 }
22545
22546 /// Setter of the size of the @ref class_or_union type.
22547 ///
22548 /// If this @ref class_or_union is a declaration of a definition that
22549 /// is elsewhere, then the new size is set to the definition.
22550 ///
22551 /// @param s the new size.
22552 void
set_size_in_bits(size_t s)22553 class_or_union::set_size_in_bits(size_t s)
22554 {
22555 if (get_is_declaration_only() && get_definition_of_declaration())
22556 is_class_or_union_type
22557 (get_definition_of_declaration())->set_size_in_bits(s);
22558 else
22559 type_base::set_size_in_bits(s);
22560 }
22561
22562 /// Getter of the size of the @ref class_or_union type.
22563 ///
22564 /// If this @ref class_or_union is a declaration of a definition that
22565 /// is elsewhere, then the size of the definition is returned.
22566 ///
22567 /// @return the size of the @ref class_or_union type.
22568 size_t
get_size_in_bits() const22569 class_or_union::get_size_in_bits() const
22570 {
22571 if (get_is_declaration_only() && get_definition_of_declaration())
22572 return is_class_or_union_type
22573 (get_definition_of_declaration())->get_size_in_bits();
22574
22575 return type_base::get_size_in_bits();
22576 }
22577
22578 /// Get the number of anonymous member classes contained in this
22579 /// class.
22580 ///
22581 /// @return the number of anonymous member classes contained in this
22582 /// class.
22583 size_t
get_num_anonymous_member_classes() const22584 class_or_union::get_num_anonymous_member_classes() const
22585 {
22586 int result = 0;
22587 for (member_types::const_iterator it = get_member_types().begin();
22588 it != get_member_types().end();
22589 ++it)
22590 if (class_decl_sptr t = is_class_type(*it))
22591 if (t->get_is_anonymous())
22592 ++result;
22593
22594 return result;
22595 }
22596
22597 /// Get the number of anonymous member unions contained in this class.
22598 ///
22599 /// @return the number of anonymous member unions contained in this
22600 /// class.
22601 size_t
get_num_anonymous_member_unions() const22602 class_or_union::get_num_anonymous_member_unions() const
22603 {
22604 int result = 0;
22605 for (member_types::const_iterator it = get_member_types().begin();
22606 it != get_member_types().end();
22607 ++it)
22608 if (union_decl_sptr t = is_union_type(*it))
22609 if (t->get_is_anonymous())
22610 ++result;
22611
22612 return result;
22613 }
22614
22615 /// Get the number of anonymous member enums contained in this class.
22616 ///
22617 /// @return the number of anonymous member enums contained in this
22618 /// class.
22619 size_t
get_num_anonymous_member_enums() const22620 class_or_union::get_num_anonymous_member_enums() const
22621 {
22622 int result = 0;
22623 for (member_types::const_iterator it = get_member_types().begin();
22624 it != get_member_types().end();
22625 ++it)
22626 if (enum_type_decl_sptr t = is_enum_type(*it))
22627 if (t->get_is_anonymous())
22628 ++result;
22629
22630 return result;
22631 }
22632
22633 /// Add a data member to the current instance of class_or_union.
22634 ///
22635 /// @param v a var_decl to add as a data member. A proper
22636 /// class_or_union::data_member is created from @p v and added to the
22637 /// class_or_union. This var_decl should not have been already added
22638 /// to a scope.
22639 ///
22640 /// @param access the access specifier for the data member.
22641 ///
22642 /// @param is_laid_out whether the data member was laid out. That is,
22643 /// if its offset has been computed. In the pattern of a class
22644 /// template for instance, this would be set to false.
22645 ///
22646 /// @param is_static whether the data memer is static.
22647 ///
22648 /// @param offset_in_bits if @p is_laid_out is true, this is the
22649 /// offset of the data member, expressed (oh, surprise) in bits.
22650 void
add_data_member(var_decl_sptr v,access_specifier access,bool is_laid_out,bool is_static,size_t offset_in_bits)22651 class_or_union::add_data_member(var_decl_sptr v, access_specifier access,
22652 bool is_laid_out, bool is_static,
22653 size_t offset_in_bits)
22654 {
22655 ABG_ASSERT(!has_scope(v));
22656
22657 priv_->data_members_.push_back(v);
22658 scope_decl::add_member_decl(v);
22659 set_data_member_is_laid_out(v, is_laid_out);
22660 set_data_member_offset(v, offset_in_bits);
22661 set_member_access_specifier(v, access);
22662 set_member_is_static(v, is_static);
22663
22664 if (!is_static)
22665 {
22666 // If this is a non-static variable, add it to the set of
22667 // non-static variables, if it's not only in there.
22668 bool is_already_in = false;
22669 for (data_members::const_iterator i =
22670 priv_->non_static_data_members_.begin();
22671 i != priv_->non_static_data_members_.end();
22672 ++i)
22673 if (*i == v)
22674 {
22675 is_already_in = true;
22676 break;
22677 }
22678 if (!is_already_in)
22679 priv_->non_static_data_members_.push_back(v);
22680 }
22681
22682 // If v is an anonymous data member, then fixup its data members.
22683 // For now, the only thing the fixup does is to make the data
22684 // members of the anonymous data member be aware of their containing
22685 // anonymous data member. That is helpful to compute the absolute
22686 // bit offset of each of the members of the anonymous data member.
22687 maybe_fixup_members_of_anon_data_member(v);
22688 }
22689
22690 /// Get the data members of this @ref class_or_union.
22691 ///
22692 /// @return a vector of the data members of this @ref class_or_union.
22693 const class_or_union::data_members&
get_data_members() const22694 class_or_union::get_data_members() const
22695 {return priv_->data_members_;}
22696
22697 /// Find a data member of a given name in the current @ref class_or_union.
22698 ///
22699 /// @param name the name of the data member to find in the current
22700 /// @ref class_or_union.
22701 ///
22702 /// @return a pointer to the @ref var_decl that represents the data
22703 /// member to find inside the current @ref class_or_union.
22704 const var_decl_sptr
find_data_member(const string & name) const22705 class_or_union::find_data_member(const string& name) const
22706 {
22707 for (data_members::const_iterator i = get_data_members().begin();
22708 i != get_data_members().end();
22709 ++i)
22710 if ((*i)->get_name() == name)
22711 return *i;
22712
22713 // We haven't found a data member with the name 'name'. Let's look
22714 // closer again, this time in our anonymous data members.
22715 for (data_members::const_iterator i = get_data_members().begin();
22716 i != get_data_members().end();
22717 ++i)
22718 if (is_anonymous_data_member(*i))
22719 {
22720 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
22721 ABG_ASSERT(type);
22722 if (var_decl_sptr data_member = type->find_data_member(name))
22723 return data_member;
22724 }
22725
22726 return var_decl_sptr();
22727 }
22728
22729 /// Find an anonymous data member in the class.
22730 ///
22731 /// @param v the anonymous data member to find.
22732 ///
22733 /// @return the anonymous data member found, or nil if none was found.
22734 const var_decl_sptr
find_anonymous_data_member(const var_decl_sptr & v) const22735 class_or_union::find_anonymous_data_member(const var_decl_sptr& v) const
22736 {
22737 if (!v->get_name().empty())
22738 return var_decl_sptr();
22739
22740 for (data_members::const_iterator it = get_non_static_data_members().begin();
22741 it != get_non_static_data_members().end();
22742 ++it)
22743 {
22744 if (is_anonymous_data_member(*it))
22745 if ((*it)->get_pretty_representation(/*internal=*/false, true)
22746 == v->get_pretty_representation(/*internal=*/false, true))
22747 return *it;
22748 }
22749
22750 return var_decl_sptr();
22751 }
22752
22753 /// Find a given data member.
22754 ///
22755 /// This function takes a @ref var_decl as an argument. If it has a
22756 /// non-empty name, then it tries to find a data member which has the
22757 /// same name as the argument.
22758 ///
22759 /// If it has an empty name, then the @ref var_decl is considered as
22760 /// an anonymous data member. In that case, this function tries to
22761 /// find an anonymous data member which type equals that of the @ref
22762 /// var_decl argument.
22763 ///
22764 /// @param v this carries either the name of the data member we need
22765 /// to look for, or the type of the anonymous data member we are
22766 /// looking for.
22767 const var_decl_sptr
find_data_member(const var_decl_sptr & v) const22768 class_or_union::find_data_member(const var_decl_sptr& v) const
22769 {
22770 if (!v)
22771 return var_decl_sptr();
22772
22773 if (v->get_name().empty())
22774 return find_anonymous_data_member(v);
22775
22776 return find_data_member(v->get_name());
22777 }
22778
22779
22780 /// Get the non-static data memebers of this @ref class_or_union.
22781 ///
22782 /// @return a vector of the non-static data members of this @ref
22783 /// class_or_union.
22784 const class_or_union::data_members&
get_non_static_data_members() const22785 class_or_union::get_non_static_data_members() const
22786 {return priv_->non_static_data_members_;}
22787
22788 /// Add a member function.
22789 ///
22790 /// @param f the new member function to add.
22791 ///
22792 /// @param a the access specifier to use for the new member function.
22793 ///
22794 /// @param is_static whether the new member function is static.
22795 ///
22796 /// @param is_ctor whether the new member function is a constructor.
22797 ///
22798 /// @param is_dtor whether the new member function is a destructor.
22799 ///
22800 /// @param is_const whether the new member function is const.
22801 void
add_member_function(method_decl_sptr f,access_specifier a,bool is_static,bool is_ctor,bool is_dtor,bool is_const)22802 class_or_union::add_member_function(method_decl_sptr f,
22803 access_specifier a,
22804 bool is_static, bool is_ctor,
22805 bool is_dtor, bool is_const)
22806 {
22807 ABG_ASSERT(!has_scope(f));
22808
22809 scope_decl::add_member_decl(f);
22810
22811 set_member_function_is_ctor(f, is_ctor);
22812 set_member_function_is_dtor(f, is_dtor);
22813 set_member_access_specifier(f, a);
22814 set_member_is_static(f, is_static);
22815 set_member_function_is_const(f, is_const);
22816
22817 priv_->member_functions_.push_back(f);
22818
22819 // Update the map of linkage name -> member functions. It's useful,
22820 // so that class_or_union::find_member_function() can function.
22821 if (!f->get_linkage_name().empty())
22822 priv_->mem_fns_map_[f->get_linkage_name()] = f;
22823 }
22824
22825 /// Get the member functions of this @ref class_or_union.
22826 ///
22827 /// @return a vector of the member functions of this @ref
22828 /// class_or_union.
22829 const class_or_union::member_functions&
get_member_functions() const22830 class_or_union::get_member_functions() const
22831 {return priv_->member_functions_;}
22832
22833 /// Find a method, using its linkage name as a key.
22834 ///
22835 /// @param linkage_name the linkage name of the method to find.
22836 ///
22837 /// @return the method found, or nil if none was found.
22838 const method_decl*
find_member_function(const string & linkage_name) const22839 class_or_union::find_member_function(const string& linkage_name) const
22840 {
22841 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
22842 }
22843
22844 /// Find a method, using its linkage name as a key.
22845 ///
22846 /// @param linkage_name the linkage name of the method to find.
22847 ///
22848 /// @return the method found, or nil if none was found.
22849 method_decl*
find_member_function(const string & linkage_name)22850 class_or_union::find_member_function(const string& linkage_name)
22851 {
22852 string_mem_fn_sptr_map_type::const_iterator i =
22853 priv_->mem_fns_map_.find(linkage_name);
22854 if (i == priv_->mem_fns_map_.end())
22855 return 0;
22856 return i->second.get();
22857 }
22858
22859 /// Find a method, using its linkage name as a key.
22860 ///
22861 /// @param linkage_name the linkage name of the method to find.
22862 ///
22863 /// @return the method found, or nil if none was found.
22864 method_decl_sptr
find_member_function_sptr(const string & linkage_name)22865 class_or_union::find_member_function_sptr(const string& linkage_name)
22866 {
22867 string_mem_fn_sptr_map_type::const_iterator i =
22868 priv_->mem_fns_map_.find(linkage_name);
22869 if (i == priv_->mem_fns_map_.end())
22870 return 0;
22871 return i->second;
22872 }
22873
22874 /// Find a method (member function) using its signature (pretty
22875 /// representation) as a key.
22876 ///
22877 /// @param s the signature of the method.
22878 ///
22879 /// @return the method found, or nil if none was found.
22880 const method_decl*
find_member_function_from_signature(const string & s) const22881 class_or_union::find_member_function_from_signature(const string& s) const
22882 {
22883 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
22884 }
22885
22886 /// Find a method (member function) using its signature (pretty
22887 /// representation) as a key.
22888 ///
22889 /// @param s the signature of the method.
22890 ///
22891 /// @return the method found, or nil if none was found.
22892 method_decl*
find_member_function_from_signature(const string & s)22893 class_or_union::find_member_function_from_signature(const string& s)
22894 {
22895 string_mem_fn_ptr_map_type::const_iterator i =
22896 priv_->signature_2_mem_fn_map_.find(s);
22897 if (i == priv_->signature_2_mem_fn_map_.end())
22898 return 0;
22899 return i->second;
22900 }
22901
22902 /// Get the member function templates of this class.
22903 ///
22904 /// @return a vector of the member function templates of this class.
22905 const member_function_templates&
get_member_function_templates() const22906 class_or_union::get_member_function_templates() const
22907 {return priv_->member_function_templates_;}
22908
22909 /// Get the member class templates of this class.
22910 ///
22911 /// @return a vector of the member class templates of this class.
22912 const member_class_templates&
get_member_class_templates() const22913 class_or_union::get_member_class_templates() const
22914 {return priv_->member_class_templates_;}
22915
22916 /// Append a member function template to the @ref class_or_union.
22917 ///
22918 /// @param m the member function template to append.
22919 void
add_member_function_template(member_function_template_sptr m)22920 class_or_union::add_member_function_template(member_function_template_sptr m)
22921 {
22922 decl_base* c = m->as_function_tdecl()->get_scope();
22923 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
22924 /// error message or something like a structured error.
22925 priv_->member_function_templates_.push_back(m);
22926 if (!c)
22927 scope_decl::add_member_decl(m->as_function_tdecl());
22928 }
22929
22930 /// Append a member class template to the @ref class_or_union.
22931 ///
22932 /// @param m the member function template to append.
22933 void
add_member_class_template(member_class_template_sptr m)22934 class_or_union::add_member_class_template(member_class_template_sptr m)
22935 {
22936 decl_base* c = m->as_class_tdecl()->get_scope();
22937 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
22938 /// error message or something like a structured error.
22939 m->set_scope(this);
22940 priv_->member_class_templates_.push_back(m);
22941 if (!c)
22942 scope_decl::add_member_decl(m->as_class_tdecl());
22943 }
22944
22945 ///@return true iff the current instance has no member.
22946 bool
has_no_member() const22947 class_or_union::has_no_member() const
22948 {
22949 return (get_member_types().empty()
22950 && priv_->data_members_.empty()
22951 && priv_->member_functions_.empty()
22952 && priv_->member_function_templates_.empty()
22953 && priv_->member_class_templates_.empty());
22954 }
22955
22956 /// Insert a data member to this @ref class_or_union type.
22957 ///
22958 /// @param d the data member to insert.
22959 ///
22960 /// @return the decl @p that got inserted.
22961 decl_base_sptr
insert_member_decl(decl_base_sptr d)22962 class_or_union::insert_member_decl(decl_base_sptr d)
22963 {
22964 if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
22965 {
22966 add_data_member(v, public_access,
22967 /*is_laid_out=*/false,
22968 /*is_static=*/true,
22969 /*offset_in_bits=*/0);
22970 d = v;
22971 }
22972 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
22973 add_member_function(f, public_access,
22974 /*is_static=*/false,
22975 /*is_ctor=*/false,
22976 /*is_dtor=*/false,
22977 /*is_const=*/false);
22978 else if (member_function_template_sptr f =
22979 dynamic_pointer_cast<member_function_template>(d))
22980 add_member_function_template(f);
22981 else if (member_class_template_sptr c =
22982 dynamic_pointer_cast<member_class_template>(d))
22983 add_member_class_template(c);
22984 else
22985 scope_decl::add_member_decl(d);
22986
22987 return d;
22988 }
22989
22990 /// Equality operator.
22991 ///
22992 /// @param other the other @ref class_or_union to compare against.
22993 ///
22994 /// @return true iff @p other equals the current @ref class_or_union.
22995 bool
operator ==(const decl_base & other) const22996 class_or_union::operator==(const decl_base& other) const
22997 {
22998 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
22999 if (!op)
23000 return false;
23001
23002 // If this is a decl-only type (and thus with no canonical type),
23003 // use the canonical type of the definition, if any.
23004 const class_or_union *l = 0;
23005 if (get_is_declaration_only())
23006 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
23007 if (l == 0)
23008 l = this;
23009
23010 // Likewise for the other class.
23011 const class_or_union *r = 0;
23012 if (op->get_is_declaration_only())
23013 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
23014 if (r == 0)
23015 r = op;
23016
23017 return try_canonical_compare(l, r);
23018 }
23019
23020 /// Equality operator.
23021 ///
23022 /// @param other the other @ref class_or_union to compare against.
23023 ///
23024 /// @return true iff @p other equals the current @ref class_or_union.
23025 bool
operator ==(const type_base & other) const23026 class_or_union::operator==(const type_base& other) const
23027 {
23028 const decl_base* o = dynamic_cast<const decl_base*>(&other);
23029 if (!o)
23030 return false;
23031 return *this == *o;
23032 }
23033
23034 /// Equality operator.
23035 ///
23036 /// @param other the other @ref class_or_union to compare against.
23037 ///
23038 /// @return true iff @p other equals the current @ref class_or_union.
23039 bool
operator ==(const class_or_union & other) const23040 class_or_union::operator==(const class_or_union& other) const
23041 {
23042 const decl_base& o = other;
23043 return class_or_union::operator==(o);
23044 }
23045
23046 /// Compares two instances of @ref class_or_union.
23047 ///
23048 /// If the two intances are different, set a bitfield to give some
23049 /// insight about the kind of differences there are.
23050 ///
23051 /// @param l the first artifact of the comparison.
23052 ///
23053 /// @param r the second artifact of the comparison.
23054 ///
23055 /// @param k a pointer to a bitfield that gives information about the
23056 /// kind of changes there are between @p l and @p r. This one is set
23057 /// iff it's non-null and if the function returns false.
23058 ///
23059 /// Please note that setting k to a non-null value does have a
23060 /// negative performance impact because even if @p l and @p r are not
23061 /// equal, the function keeps up the comparison in order to determine
23062 /// the different kinds of ways in which they are different.
23063 ///
23064 /// @return true if @p l equals @p r, false otherwise.
23065 bool
equals(const class_or_union & l,const class_or_union & r,change_kind * k)23066 equals(const class_or_union& l, const class_or_union& r, change_kind* k)
23067 {
23068 // if one of the classes is declaration-only, look through it to
23069 // get its definition.
23070 bool l_is_decl_only = l.get_is_declaration_only();
23071 bool r_is_decl_only = r.get_is_declaration_only();
23072 if (l_is_decl_only || r_is_decl_only)
23073 {
23074 const class_or_union* def1 = l_is_decl_only
23075 ? is_class_or_union_type(l.get_naked_definition_of_declaration())
23076 : &l;
23077
23078 const class_or_union* def2 = r_is_decl_only
23079 ? is_class_or_union_type(r.get_naked_definition_of_declaration())
23080 : &r;
23081
23082 if (!def1 || !def2)
23083 {
23084 if (!l.get_is_anonymous()
23085 && !r.get_is_anonymous()
23086 && l_is_decl_only && r_is_decl_only
23087 && comparison::filtering::is_decl_only_class_with_size_change(l, r))
23088 // The two decl-only classes differ from their size. A
23089 // true decl-only class should not have a size property to
23090 // begin with. This comes from a DWARF oddity and can
23091 // results in a false positive, so let's not consider that
23092 // change.
23093 return true;
23094
23095 if ((l.get_environment().decl_only_class_equals_definition()
23096 || ((odr_is_relevant(l) && !def1)
23097 || (odr_is_relevant(r) && !def2)))
23098 && !is_anonymous_or_typedef_named(l)
23099 && !is_anonymous_or_typedef_named(r))
23100 {
23101 const interned_string& q1 = l.get_scoped_name();
23102 const interned_string& q2 = r.get_scoped_name();
23103 if (q1 == q2)
23104 // Not using RETURN(true) here, because that causes
23105 // performance issues. We don't need to do
23106 // l.priv_->unmark_as_being_compared({l,r}) here because
23107 // we haven't marked l or r as being compared yet, and
23108 // doing so has a peformance cost that shows up on
23109 // performance profiles for *big* libraries.
23110 return true;
23111 else
23112 {
23113 if (k)
23114 *k |= LOCAL_TYPE_CHANGE_KIND;
23115 // Not using RETURN(true) here, because that causes
23116 // performance issues. We don't need to do
23117 // l.priv_->unmark_as_being_compared({l,r}) here because
23118 // we haven't marked l or r as being compared yet, and
23119 // doing so has a peformance cost that shows up on
23120 // performance profiles for *big* libraries.
23121 ABG_RETURN_FALSE;
23122 }
23123 }
23124 else // A decl-only class is considered different from a
23125 // class definition of the same name.
23126 {
23127 if (!!def1 != !!def2)
23128 {
23129 if (k)
23130 *k |= LOCAL_TYPE_CHANGE_KIND;
23131 ABG_RETURN_FALSE;
23132 }
23133
23134 // both definitions are empty
23135 if (!(l.decl_base::operator==(r)
23136 && l.type_base::operator==(r)))
23137 {
23138 if (k)
23139 *k |= LOCAL_TYPE_CHANGE_KIND;
23140 ABG_RETURN_FALSE;
23141 }
23142
23143 return true;
23144 }
23145 }
23146
23147 bool val = *def1 == *def2;
23148 if (!val)
23149 if (k)
23150 *k |= LOCAL_TYPE_CHANGE_KIND;
23151 ABG_RETURN(val);
23152 }
23153
23154 // No need to go further if the classes have different names or
23155 // different size / alignment.
23156 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
23157 {
23158 if (k)
23159 *k |= LOCAL_TYPE_CHANGE_KIND;
23160 ABG_RETURN_FALSE;
23161 }
23162
23163 if (types_defined_same_linux_kernel_corpus_public(l, r))
23164 return true;
23165
23166 //TODO: Maybe remove this (cycle detection and canonical type
23167 //propagation handling) from here and have it only in the equal
23168 //overload for class_decl and union_decl because this one ( the
23169 //equal overload for class_or_union) is just a sub-routine of these
23170 //two above.
23171 #define RETURN(value) \
23172 return return_comparison_result(l, r, value, \
23173 /*propagate_canonical_type=*/false);
23174
23175 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
23176
23177 mark_types_as_being_compared(l, r);
23178
23179 bool result = true;
23180
23181 //compare data_members
23182 {
23183 if (l.get_non_static_data_members().size()
23184 != r.get_non_static_data_members().size())
23185 {
23186 result = false;
23187 if (k)
23188 *k |= LOCAL_TYPE_CHANGE_KIND;
23189 else
23190 RETURN(result);
23191 }
23192
23193 for (class_or_union::data_members::const_iterator
23194 d0 = l.get_non_static_data_members().begin(),
23195 d1 = r.get_non_static_data_members().begin();
23196 (d0 != l.get_non_static_data_members().end()
23197 && d1 != r.get_non_static_data_members().end());
23198 ++d0, ++d1)
23199 if (**d0 != **d1)
23200 {
23201 result = false;
23202 if (k)
23203 {
23204 // Report any representation change as being local.
23205 if (!types_have_similar_structure((*d0)->get_type(),
23206 (*d1)->get_type())
23207 || (*d0)->get_type() == (*d1)->get_type())
23208 *k |= LOCAL_TYPE_CHANGE_KIND;
23209 else
23210 *k |= SUBTYPE_CHANGE_KIND;
23211 }
23212 else
23213 RETURN(result);
23214 }
23215 }
23216
23217 // Do not compare member functions. DWARF does not necessarily
23218 // all the member functions, be they virtual or not, in all
23219 // translation units. So we cannot have a clear view of them, per
23220 // class
23221
23222 // compare member function templates
23223 {
23224 if (l.get_member_function_templates().size()
23225 != r.get_member_function_templates().size())
23226 {
23227 result = false;
23228 if (k)
23229 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23230 else
23231 RETURN(result);
23232 }
23233
23234 for (member_function_templates::const_iterator
23235 fn_tmpl_it0 = l.get_member_function_templates().begin(),
23236 fn_tmpl_it1 = r.get_member_function_templates().begin();
23237 fn_tmpl_it0 != l.get_member_function_templates().end()
23238 && fn_tmpl_it1 != r.get_member_function_templates().end();
23239 ++fn_tmpl_it0, ++fn_tmpl_it1)
23240 if (**fn_tmpl_it0 != **fn_tmpl_it1)
23241 {
23242 result = false;
23243 if (k)
23244 {
23245 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23246 break;
23247 }
23248 else
23249 RETURN(result);
23250 }
23251 }
23252
23253 // compare member class templates
23254 {
23255 if (l.get_member_class_templates().size()
23256 != r.get_member_class_templates().size())
23257 {
23258 result = false;
23259 if (k)
23260 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23261 else
23262 RETURN(result);
23263 }
23264
23265 for (member_class_templates::const_iterator
23266 cl_tmpl_it0 = l.get_member_class_templates().begin(),
23267 cl_tmpl_it1 = r.get_member_class_templates().begin();
23268 cl_tmpl_it0 != l.get_member_class_templates().end()
23269 && cl_tmpl_it1 != r.get_member_class_templates().end();
23270 ++cl_tmpl_it0, ++cl_tmpl_it1)
23271 if (**cl_tmpl_it0 != **cl_tmpl_it1)
23272 {
23273 result = false;
23274 if (k)
23275 {
23276 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23277 break;
23278 }
23279 else
23280 RETURN(result);
23281 }
23282 }
23283
23284 RETURN(result);
23285 #undef RETURN
23286 }
23287
23288
23289 /// Copy a method of a @ref class_or_union into a new @ref
23290 /// class_or_union.
23291 ///
23292 /// @param t the @ref class_or_union into which the method is to be copied.
23293 ///
23294 /// @param method the method to copy into @p t.
23295 ///
23296 /// @return the resulting newly copied method.
23297 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl_sptr & method)23298 copy_member_function(const class_or_union_sptr& t,
23299 const method_decl_sptr& method)
23300 {return copy_member_function(t, method.get());}
23301
23302
23303 /// Copy a method of a @ref class_or_union into a new @ref
23304 /// class_or_union.
23305 ///
23306 /// @param t the @ref class_or_union into which the method is to be copied.
23307 ///
23308 /// @param method the method to copy into @p t.
23309 ///
23310 /// @return the resulting newly copied method.
23311 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl * method)23312 copy_member_function(const class_or_union_sptr& t, const method_decl* method)
23313 {
23314 ABG_ASSERT(t);
23315 ABG_ASSERT(method);
23316
23317 method_type_sptr old_type = method->get_type();
23318 ABG_ASSERT(old_type);
23319 method_type_sptr new_type(new method_type(old_type->get_return_type(),
23320 t,
23321 old_type->get_parameters(),
23322 old_type->get_is_const(),
23323 old_type->get_size_in_bits(),
23324 old_type->get_alignment_in_bits()));
23325 t->get_translation_unit()->bind_function_type_life_time(new_type);
23326
23327 method_decl_sptr
23328 new_method(new method_decl(method->get_name(),
23329 new_type,
23330 method->is_declared_inline(),
23331 method->get_location(),
23332 method->get_linkage_name(),
23333 method->get_visibility(),
23334 method->get_binding()));
23335 new_method->set_symbol(method->get_symbol());
23336
23337 if (class_decl_sptr class_type = is_class_type(t))
23338 class_type->add_member_function(new_method,
23339 get_member_access_specifier(*method),
23340 get_member_function_is_virtual(*method),
23341 get_member_function_vtable_offset(*method),
23342 get_member_is_static(*method),
23343 get_member_function_is_ctor(*method),
23344 get_member_function_is_dtor(*method),
23345 get_member_function_is_const(*method));
23346 else
23347 t->add_member_function(new_method,
23348 get_member_access_specifier(*method),
23349 get_member_is_static(*method),
23350 get_member_function_is_ctor(*method),
23351 get_member_function_is_dtor(*method),
23352 get_member_function_is_const(*method));
23353 return new_method;
23354 }
23355
23356 // </class_or_union definitions>
23357
23358 /// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
23359 /// @{
23360 ///
23361 /// This optimization is also known as "canonical type propagation".
23362 ///
23363 /// During the canonicalization of a type T (which doesn't yet have a
23364 /// canonical type), T is compared structurally (member-wise) against
23365 /// a type C which already has a canonical type. The comparison
23366 /// expression is C == T.
23367 ///
23368 /// During that structural comparison, if a subtype of C (which also
23369 /// already has a canonical type) is structurally compared to a
23370 /// subtype of T (which doesn't yet have a canonical type) and if they
23371 /// are equal, then we can deduce that the canonical type of the
23372 /// subtype of C is the canonical type of the subtype of C.
23373 ///
23374 /// Thus, we can canonicalize the sub-type of the T, during the
23375 /// canonicalization of T itself. That canonicalization of the
23376 /// sub-type of T is what we call the "on-the-fly canonicalization".
23377 /// It's on the fly because it happens during a comparison -- which
23378 /// itself happens during the canonicalization of T.
23379 ///
23380 /// For now this on-the-fly canonicalization only happens when
23381 /// comparing @ref class_decl and @ref function_type.
23382 ///
23383 /// Note however that there is a case when a type is *NOT* eligible to
23384 /// this canonical type propagation optimization.
23385 ///
23386 /// The reason why a type is deemed NON-eligible to the canonical type
23387 /// propagation optimization is that it "depends" on recursively
23388 /// present type. Let me explain.
23389 ///
23390 /// Suppose we have a type T that has sub-types named ST0 and ST1.
23391 /// Suppose ST1 itself has a sub-type that is T itself. In this case,
23392 /// we say that T is a recursive type, because it has T (itself) as
23393 /// one of its sub-types:
23394 ///
23395 /// <PRE>
23396 /// T
23397 /// +-- ST0
23398 /// |
23399 /// +-- ST1
23400 /// | +
23401 /// | |
23402 /// | +-- T
23403 /// |
23404 /// +-- ST2
23405 /// </PRE>
23406 ///
23407 /// ST1 is said to "depend" on T because it has T as a sub-type. But
23408 /// because T is recursive, then ST1 is said to depend on a recursive
23409 /// type. Notice however that ST0 does not depend on any recursive
23410 /// type.
23411 ///
23412 /// Now suppose we are comparing T to a type T' that has the same
23413 /// structure with sub-types ST0', ST1' and ST2'. During the
23414 /// comparison of ST1 against ST1', their sub-type T is compared
23415 /// against T'. Because T (resp. T') is a recursive type that is
23416 /// already being compared, the comparison of T against T' (as a
23417 /// subtypes of ST1 and ST1') returns true, meaning they are
23418 /// considered equal. This is done so that we don't enter an infinite
23419 /// recursion.
23420 ///
23421 /// That means ST1 is also deemed equal to ST1'. If we are in the
23422 /// course of the canonicalization of T' and thus if T (as well as as
23423 /// all of its sub-types) is already canonicalized, then the canonical
23424 /// type propagation optimization will make us propagate the canonical
23425 /// type of ST1 onto ST1'. So the canonical type of ST1' will be
23426 /// equal to the canonical type of ST1 as a result of that
23427 /// optmization.
23428 ///
23429 /// But then, later down the road, when ST2 is compared against ST2',
23430 /// let's suppose that we find out that they are different. Meaning
23431 /// that ST2 != ST2'. This means that T != T', i.e, the
23432 /// canonicalization of T' failed for now. But most importantly, it
23433 /// means that the propagation of the canonical type of ST1 to ST1'
23434 /// must now be invalidated. Meaning, ST1' must now be considered as
23435 /// not having any canonical type.
23436 ///
23437 /// In other words, during type canonicalization, if ST1' depends on a
23438 /// recursive type T', its propagated canonical type must be
23439 /// invalidated (set to nullptr) if T' appears to be different from T,
23440 /// a.k.a, the canonicalization of T' temporarily failed.
23441 ///
23442 /// This means that any sub-type that depends on recursive types and
23443 /// that has been the target of the canonical type propagation
23444 /// optimization must be tracked. If the dependant recursive type
23445 /// fails its canonicalization, then the sub-type being compared must
23446 /// have its propagated canonical type cleared. In other words, its
23447 /// propagated canonical type must be cancelled.
23448 ///
23449 /// @}
23450
23451
23452 /// If on-the-fly canonicalization is turned on, then this function
23453 /// sets the canonical type of its second parameter to the canonical
23454 /// type of the first parameter.
23455 ///
23456 /// @param lhs_type the type which canonical type to propagate.
23457 ///
23458 /// @param rhs_type the type which canonical type to set.
23459 static bool
maybe_propagate_canonical_type(const type_base & lhs_type,const type_base & rhs_type)23460 maybe_propagate_canonical_type(const type_base& lhs_type,
23461 const type_base& rhs_type)
23462 {
23463 const environment& env = lhs_type.get_environment();
23464 #if WITH_DEBUG_TYPE_CANONICALIZATION
23465 if (!env.priv_->use_canonical_type_comparison_)
23466 return false;
23467 #endif
23468
23469 if (env.do_on_the_fly_canonicalization())
23470 if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
23471 if (!rhs_type.get_canonical_type())
23472 if (env.priv_->propagate_ct(lhs_type, rhs_type))
23473 return true;
23474 return false;
23475 }
23476
23477 // <class_decl definitions>
23478
23479 static void
23480 sort_virtual_member_functions(class_decl::member_functions& mem_fns);
23481
23482 /// The private data for the class_decl type.
23483 struct class_decl::priv
23484 {
23485 base_specs bases_;
23486 unordered_map<string, base_spec_sptr> bases_map_;
23487 member_functions virtual_mem_fns_;
23488 virtual_mem_fn_map_type virtual_mem_fns_map_;
23489 bool is_struct_;
23490
privabigail::ir::class_decl::priv23491 priv()
23492 : is_struct_(false)
23493 {}
23494
privabigail::ir::class_decl::priv23495 priv(bool is_struct, class_decl::base_specs& bases)
23496 : bases_(bases),
23497 is_struct_(is_struct)
23498 {
23499 }
23500
privabigail::ir::class_decl::priv23501 priv(bool is_struct)
23502 : is_struct_(is_struct)
23503 {}
23504 };// end struct class_decl::priv
23505
23506 /// A Constructor for instances of \ref class_decl
23507 ///
23508 /// @param env the environment we are operating from.
23509 ///
23510 /// @param name the identifier of the class.
23511 ///
23512 /// @param size_in_bits the size of an instance of class_decl, expressed
23513 /// in bits
23514 ///
23515 /// @param align_in_bits the alignment of an instance of class_decl,
23516 /// expressed in bits.
23517 ///
23518 /// @param locus the source location of declaration point this class.
23519 ///
23520 /// @param vis the visibility of instances of class_decl.
23521 ///
23522 /// @param bases the vector of base classes for this instance of class_decl.
23523 ///
23524 /// @param mbrs the vector of member types of this instance of
23525 /// class_decl.
23526 ///
23527 /// @param data_mbrs the vector of data members of this instance of
23528 /// class_decl.
23529 ///
23530 /// @param mbr_fns the vector of member functions of this instance of
23531 /// 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)23532 class_decl::class_decl(const environment& env, const string& name,
23533 size_t size_in_bits, size_t align_in_bits,
23534 bool is_struct, const location& locus,
23535 visibility vis, base_specs& bases,
23536 member_types& mbr_types,
23537 data_members& data_mbrs,
23538 member_functions& mbr_fns)
23539 : type_or_decl_base(env,
23540 CLASS_TYPE
23541 | ABSTRACT_TYPE_BASE
23542 | ABSTRACT_DECL_BASE
23543 | ABSTRACT_SCOPE_TYPE_DECL
23544 | ABSTRACT_SCOPE_DECL),
23545 decl_base(env, name, locus, name, vis),
23546 type_base(env, size_in_bits, align_in_bits),
23547 class_or_union(env, name, size_in_bits, align_in_bits,
23548 locus, vis, mbr_types, data_mbrs, mbr_fns),
23549 priv_(new priv(is_struct, bases))
23550 {
23551 runtime_type_instance(this);
23552 }
23553
23554 /// A Constructor for instances of @ref class_decl
23555 ///
23556 /// @param env the environment we are operating from.
23557 ///
23558 /// @param name the identifier of the class.
23559 ///
23560 /// @param size_in_bits the size of an instance of class_decl, expressed
23561 /// in bits
23562 ///
23563 /// @param align_in_bits the alignment of an instance of class_decl,
23564 /// expressed in bits.
23565 ///
23566 /// @param locus the source location of declaration point this class.
23567 ///
23568 /// @param vis the visibility of instances of class_decl.
23569 ///
23570 /// @param bases the vector of base classes for this instance of class_decl.
23571 ///
23572 /// @param mbrs the vector of member types of this instance of
23573 /// class_decl.
23574 ///
23575 /// @param data_mbrs the vector of data members of this instance of
23576 /// class_decl.
23577 ///
23578 /// @param mbr_fns the vector of member functions of this instance of
23579 /// class_decl.
23580 ///
23581 /// @param is_anonymous whether the newly created instance is
23582 /// 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)23583 class_decl::class_decl(const environment& env, const string& name,
23584 size_t size_in_bits, size_t align_in_bits,
23585 bool is_struct, const location& locus,
23586 visibility vis, base_specs& bases,
23587 member_types& mbr_types, data_members& data_mbrs,
23588 member_functions& mbr_fns, bool is_anonymous)
23589 : type_or_decl_base(env,
23590 CLASS_TYPE
23591 | ABSTRACT_TYPE_BASE
23592 | ABSTRACT_DECL_BASE
23593 | ABSTRACT_SCOPE_TYPE_DECL
23594 | ABSTRACT_SCOPE_DECL),
23595 decl_base(env, name, locus,
23596 // If the class is anonymous then by default it won't
23597 // have a linkage name. Also, the anonymous class does
23598 // have an internal-only unique name that is generally
23599 // not taken into account when comparing classes; such a
23600 // unique internal-only name, when used as a linkage
23601 // name might introduce spurious comparison false
23602 // negatives.
23603 /*linkage_name=*/is_anonymous ? string() : name,
23604 vis),
23605 type_base(env, size_in_bits, align_in_bits),
23606 class_or_union(env, name, size_in_bits, align_in_bits,
23607 locus, vis, mbr_types, data_mbrs, mbr_fns),
23608 priv_(new priv(is_struct, bases))
23609 {
23610 runtime_type_instance(this);
23611 set_is_anonymous(is_anonymous);
23612 }
23613
23614 /// A constructor for instances of class_decl.
23615 ///
23616 /// @param env the environment we are operating from.
23617 ///
23618 /// @param name the name of the class.
23619 ///
23620 /// @param size_in_bits the size of an instance of class_decl, expressed
23621 /// in bits
23622 ///
23623 /// @param align_in_bits the alignment of an instance of class_decl,
23624 /// expressed in bits.
23625 ///
23626 /// @param locus the source location of declaration point this class.
23627 ///
23628 /// @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)23629 class_decl::class_decl(const environment& env, const string& name,
23630 size_t size_in_bits, size_t align_in_bits,
23631 bool is_struct, const location& locus,
23632 visibility vis)
23633 : type_or_decl_base(env,
23634 CLASS_TYPE
23635 | ABSTRACT_TYPE_BASE
23636 | ABSTRACT_DECL_BASE
23637 | ABSTRACT_SCOPE_TYPE_DECL
23638 | ABSTRACT_SCOPE_DECL),
23639 decl_base(env, name, locus, name, vis),
23640 type_base(env, size_in_bits, align_in_bits),
23641 class_or_union(env, name, size_in_bits, align_in_bits,
23642 locus, vis),
23643 priv_(new priv(is_struct))
23644 {
23645 runtime_type_instance(this);
23646 }
23647
23648 /// A constructor for instances of @ref class_decl.
23649 ///
23650 /// @param env the environment we are operating from.
23651 ///
23652 /// @param name the name of the class.
23653 ///
23654 /// @param size_in_bits the size of an instance of class_decl, expressed
23655 /// in bits
23656 ///
23657 /// @param align_in_bits the alignment of an instance of class_decl,
23658 /// expressed in bits.
23659 ///
23660 /// @param locus the source location of declaration point this class.
23661 ///
23662 /// @param vis the visibility of instances of class_decl.
23663 ///
23664 /// @param is_anonymous whether the newly created instance is
23665 /// 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)23666 class_decl:: class_decl(const environment& env, const string& name,
23667 size_t size_in_bits, size_t align_in_bits,
23668 bool is_struct, const location& locus,
23669 visibility vis, bool is_anonymous)
23670 : type_or_decl_base(env,
23671 CLASS_TYPE
23672 | ABSTRACT_TYPE_BASE
23673 | ABSTRACT_DECL_BASE
23674 | ABSTRACT_SCOPE_TYPE_DECL
23675 | ABSTRACT_SCOPE_DECL),
23676 decl_base(env, name, locus,
23677 // If the class is anonymous then by default it won't
23678 // have a linkage name. Also, the anonymous class does
23679 // have an internal-only unique name that is generally
23680 // not taken into account when comparing classes; such a
23681 // unique internal-only name, when used as a linkage
23682 // name might introduce spurious comparison false
23683 // negatives.
23684 /*linkage_name=*/ is_anonymous ? string() : name,
23685 vis),
23686 type_base(env, size_in_bits, align_in_bits),
23687 class_or_union(env, name, size_in_bits, align_in_bits,
23688 locus, vis),
23689 priv_(new priv(is_struct))
23690 {
23691 runtime_type_instance(this);
23692 set_is_anonymous(is_anonymous);
23693 }
23694
23695 /// A constuctor for instances of class_decl that represent a
23696 /// declaration without definition.
23697 ///
23698 /// @param env the environment we are operating from.
23699 ///
23700 /// @param name the name of the class.
23701 ///
23702 /// @param is_declaration_only a boolean saying whether the instance
23703 /// represents a declaration only, or not.
class_decl(const environment & env,const string & name,bool is_struct,bool is_declaration_only)23704 class_decl::class_decl(const environment& env, const string& name,
23705 bool is_struct, bool is_declaration_only)
23706 : type_or_decl_base(env,
23707 CLASS_TYPE
23708 | ABSTRACT_TYPE_BASE
23709 | ABSTRACT_DECL_BASE
23710 | ABSTRACT_SCOPE_TYPE_DECL
23711 | ABSTRACT_SCOPE_DECL),
23712 decl_base(env, name, location(), name),
23713 type_base(env, 0, 0),
23714 class_or_union(env, name, is_declaration_only),
23715 priv_(new priv(is_struct))
23716 {
23717 runtime_type_instance(this);
23718 }
23719
23720 /// This method is invoked automatically right after the current
23721 /// instance of @ref class_decl has been canonicalized.
23722 ///
23723 /// Currently, the only thing it does is to sort the virtual member
23724 /// functions vector.
23725 void
on_canonical_type_set()23726 class_decl::on_canonical_type_set()
23727 {
23728 sort_virtual_mem_fns();
23729
23730 for (class_decl::virtual_mem_fn_map_type::iterator i =
23731 priv_->virtual_mem_fns_map_.begin();
23732 i != priv_->virtual_mem_fns_map_.end();
23733 ++i)
23734 sort_virtual_member_functions(i->second);
23735 }
23736
23737 /// Set the "is-struct" flag of the class.
23738 ///
23739 /// @param f the new value of the flag.
23740 void
is_struct(bool f)23741 class_decl::is_struct(bool f)
23742 {priv_->is_struct_ = f;}
23743
23744 /// Test if the class is a struct.
23745 ///
23746 /// @return true iff the class is a struct.
23747 bool
is_struct() const23748 class_decl::is_struct() const
23749 {return priv_->is_struct_;}
23750
23751 /// Add a base specifier to this class.
23752 ///
23753 /// @param b the new base specifier.
23754 void
add_base_specifier(base_spec_sptr b)23755 class_decl::add_base_specifier(base_spec_sptr b)
23756 {
23757 priv_->bases_.push_back(b);
23758 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
23759 }
23760
23761 /// Get the base specifiers for this class.
23762 ///
23763 /// @return a vector of the base specifiers.
23764 const class_decl::base_specs&
get_base_specifiers() const23765 class_decl::get_base_specifiers() const
23766 {return priv_->bases_;}
23767
23768 /// Find a base class of a given qualified name for the current class.
23769 ///
23770 /// @param qualified_name the qualified name of the base class to look for.
23771 ///
23772 /// @return a pointer to the @ref class_decl that represents the base
23773 /// class of name @p qualified_name, if found.
23774 class_decl_sptr
find_base_class(const string & qualified_name) const23775 class_decl::find_base_class(const string& qualified_name) const
23776 {
23777 unordered_map<string, base_spec_sptr>::iterator i =
23778 priv_->bases_map_.find(qualified_name);
23779
23780 if (i != priv_->bases_map_.end())
23781 return i->second->get_base_class();
23782
23783 return class_decl_sptr();
23784 }
23785
23786 /// Get the virtual member functions of this class.
23787 ///
23788 /// @param return a vector of the virtual member functions of this
23789 /// class.
23790 const class_decl::member_functions&
get_virtual_mem_fns() const23791 class_decl::get_virtual_mem_fns() const
23792 {return priv_->virtual_mem_fns_;}
23793
23794 /// Get the map that associates a virtual table offset to the virtual
23795 /// member functions with that virtual table offset.
23796 ///
23797 /// Usually, there should be a 1:1 mapping between a given vtable
23798 /// offset and virtual member functions of that vtable offset. But
23799 /// because of some implementation details, there can be several C++
23800 /// destructor functions that are *generated* by compilers, for a
23801 /// given destructor that is defined in the source code. If the
23802 /// destructor is virtual then those generated functions have some
23803 /// DWARF attributes in common with the constructor that the user
23804 /// actually defined in its source code. Among those attributes are
23805 /// the vtable offset of the destructor.
23806 ///
23807 /// @return the map that associates a virtual table offset to the
23808 /// virtual member functions with that virtual table offset.
23809 const class_decl::virtual_mem_fn_map_type&
get_virtual_mem_fns_map() const23810 class_decl::get_virtual_mem_fns_map() const
23811 {return priv_->virtual_mem_fns_map_;}
23812
23813 /// Sort the virtual member functions by their virtual index.
23814 void
sort_virtual_mem_fns()23815 class_decl::sort_virtual_mem_fns()
23816 {sort_virtual_member_functions(priv_->virtual_mem_fns_);}
23817
23818 /// Getter of the pretty representation of the current instance of
23819 /// @ref class_decl.
23820 ///
23821 /// @param internal set to true if the call is intended to get a
23822 /// representation of the decl (or type) for the purpose of canonical
23823 /// type comparison. This is mainly used in the function
23824 /// type_base::get_canonical_type_for().
23825 ///
23826 /// In other words if the argument for this parameter is true then the
23827 /// call is meant for internal use (for technical use inside the
23828 /// library itself), false otherwise. If you don't know what this is
23829 /// for, then set it to false.
23830 ///
23831 /// @param qualified_name if true, names emitted in the pretty
23832 /// representation are fully qualified.
23833 ///
23834 /// @return the pretty representaion for a class_decl.
23835 string
get_pretty_representation(bool internal,bool qualified_name) const23836 class_decl::get_pretty_representation(bool internal,
23837 bool qualified_name) const
23838 {
23839 string cl = "class ";
23840 if (!internal && is_struct())
23841 cl = "struct ";
23842
23843 // When computing the pretty representation for internal purposes,
23844 // if an anonymous class is named by a typedef, then consider that
23845 // it has a name, which is the typedef name.
23846 if (get_is_anonymous())
23847 {
23848 if (internal && !get_name().empty())
23849 return cl + get_type_name(this, qualified_name, /*internal=*/true);
23850 return get_class_or_union_flat_representation(this, "",
23851 /*one_line=*/true,
23852 internal);
23853
23854 }
23855
23856 string result = cl;
23857 if (qualified_name)
23858 result += get_qualified_name(internal);
23859 else
23860 result += get_name();
23861
23862 return result;
23863 }
23864
23865 decl_base_sptr
insert_member_decl(decl_base_sptr d)23866 class_decl::insert_member_decl(decl_base_sptr d)
23867 {
23868 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
23869 add_member_function(f, public_access,
23870 /*is_virtual=*/false,
23871 /*vtable_offset=*/0,
23872 /*is_static=*/false,
23873 /*is_ctor=*/false,
23874 /*is_dtor=*/false,
23875 /*is_const=*/false);
23876 else
23877 d = class_or_union::insert_member_decl(d);
23878
23879 return d;
23880 }
23881
23882 /// The private data structure of class_decl::base_spec.
23883 struct class_decl::base_spec::priv
23884 {
23885 class_decl_wptr base_class_;
23886 long offset_in_bits_;
23887 bool is_virtual_;
23888
privabigail::ir::class_decl::base_spec::priv23889 priv(const class_decl_sptr& cl,
23890 long offset_in_bits,
23891 bool is_virtual)
23892 : base_class_(cl),
23893 offset_in_bits_(offset_in_bits),
23894 is_virtual_(is_virtual)
23895 {}
23896 };
23897
23898 /// Constructor for base_spec instances.
23899 ///
23900 /// @param base the base class to consider
23901 ///
23902 /// @param a the access specifier of the base class.
23903 ///
23904 /// @param offset_in_bits if positive or null, represents the offset
23905 /// of the base in the layout of its containing type.. If negative,
23906 /// means that the current base is not laid out in its containing type.
23907 ///
23908 /// @param is_virtual if true, means that the current base class is
23909 /// virtual in it's containing type.
base_spec(const class_decl_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)23910 class_decl::base_spec::base_spec(const class_decl_sptr& base,
23911 access_specifier a,
23912 long offset_in_bits,
23913 bool is_virtual)
23914 : type_or_decl_base(base->get_environment(),
23915 ABSTRACT_DECL_BASE),
23916 decl_base(base->get_environment(), base->get_name(), base->get_location(),
23917 base->get_linkage_name(), base->get_visibility()),
23918 member_base(a),
23919 priv_(new priv(base, offset_in_bits, is_virtual))
23920 {
23921 runtime_type_instance(this);
23922 set_qualified_name(base->get_qualified_name());
23923 }
23924
23925 /// Get the base class referred to by the current base class
23926 /// specifier.
23927 ///
23928 /// @return the base class.
23929 class_decl_sptr
get_base_class() const23930 class_decl::base_spec::get_base_class() const
23931 {return priv_->base_class_.lock();}
23932
23933 /// Getter of the "is-virtual" proprerty of the base class specifier.
23934 ///
23935 /// @return true iff this specifies a virtual base class.
23936 bool
get_is_virtual() const23937 class_decl::base_spec::get_is_virtual() const
23938 {return priv_->is_virtual_;}
23939
23940 /// Getter of the offset of the base.
23941 ///
23942 /// @return the offset of the base.
23943 long
get_offset_in_bits() const23944 class_decl::base_spec::get_offset_in_bits() const
23945 {return priv_->offset_in_bits_;}
23946
23947 /// Calculate the hash value for a class_decl::base_spec.
23948 ///
23949 /// @return the hash value.
23950 size_t
get_hash() const23951 class_decl::base_spec::get_hash() const
23952 {
23953 base_spec::hash h;
23954 return h(*this);
23955 }
23956
23957 /// Traverses an instance of @ref class_decl::base_spec, visiting all
23958 /// the sub-types and decls that it might contain.
23959 ///
23960 /// @param v the visitor that is used to visit every IR sub-node of
23961 /// the current node.
23962 ///
23963 /// @return true if either
23964 /// - all the children nodes of the current IR node were traversed
23965 /// and the calling code should keep going with the traversing.
23966 /// - or the current IR node is already being traversed.
23967 /// Otherwise, returning false means that the calling code should not
23968 /// keep traversing the tree.
23969 bool
traverse(ir_node_visitor & v)23970 class_decl::base_spec::traverse(ir_node_visitor& v)
23971 {
23972 if (visiting())
23973 return true;
23974
23975 if (v.visit_begin(this))
23976 {
23977 visiting(true);
23978 get_base_class()->traverse(v);
23979 visiting(false);
23980 }
23981
23982 return v.visit_end(this);
23983 }
23984
23985 /// Constructor for base_spec instances.
23986 ///
23987 /// Note that this constructor is for clients that don't support RTTI
23988 /// and that have a base class of type_base, but of dynamic type
23989 /// class_decl.
23990 ///
23991 /// @param base the base class to consider. Must be a pointer to an
23992 /// instance of class_decl
23993 ///
23994 /// @param a the access specifier of the base class.
23995 ///
23996 /// @param offset_in_bits if positive or null, represents the offset
23997 /// of the base in the layout of its containing type.. If negative,
23998 /// means that the current base is not laid out in its containing type.
23999 ///
24000 /// @param is_virtual if true, means that the current base class is
24001 /// virtual in it's containing type.
base_spec(const type_base_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)24002 class_decl::base_spec::base_spec(const type_base_sptr& base,
24003 access_specifier a,
24004 long offset_in_bits,
24005 bool is_virtual)
24006 : type_or_decl_base(base->get_environment(),
24007 ABSTRACT_DECL_BASE),
24008 decl_base(base->get_environment(), get_type_declaration(base)->get_name(),
24009 get_type_declaration(base)->get_location(),
24010 get_type_declaration(base)->get_linkage_name(),
24011 get_type_declaration(base)->get_visibility()),
24012 member_base(a),
24013 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
24014 offset_in_bits,
24015 is_virtual))
24016 {
24017 runtime_type_instance(this);
24018 }
24019
24020 class_decl::base_spec::~base_spec() = default;
24021
24022 /// Compares two instances of @ref class_decl::base_spec.
24023 ///
24024 /// If the two intances are different, set a bitfield to give some
24025 /// insight about the kind of differences there are.
24026 ///
24027 /// @param l the first artifact of the comparison.
24028 ///
24029 /// @param r the second artifact of the comparison.
24030 ///
24031 /// @param k a pointer to a bitfield that gives information about the
24032 /// kind of changes there are between @p l and @p r. This one is set
24033 /// iff @p k is non-null and the function returns false.
24034 ///
24035 /// Please note that setting k to a non-null value does have a
24036 /// negative performance impact because even if @p l and @p r are not
24037 /// equal, the function keeps up the comparison in order to determine
24038 /// the different kinds of ways in which they are different.
24039 ///
24040 /// @return true if @p l equals @p r, false otherwise.
24041 bool
equals(const class_decl::base_spec & l,const class_decl::base_spec & r,change_kind * k)24042 equals(const class_decl::base_spec& l,
24043 const class_decl::base_spec& r,
24044 change_kind* k)
24045 {
24046 if (!l.member_base::operator==(r))
24047 {
24048 if (k)
24049 *k |= LOCAL_TYPE_CHANGE_KIND;
24050 ABG_RETURN_FALSE;
24051 }
24052
24053 ABG_RETURN((*l.get_base_class() == *r.get_base_class()));
24054 }
24055
24056 /// Comparison operator for @ref class_decl::base_spec.
24057 ///
24058 /// @param other the instance of @ref class_decl::base_spec to compare
24059 /// against.
24060 ///
24061 /// @return true if the current instance of @ref class_decl::base_spec
24062 /// equals @p other.
24063 bool
operator ==(const decl_base & other) const24064 class_decl::base_spec::operator==(const decl_base& other) const
24065 {
24066 const class_decl::base_spec* o =
24067 dynamic_cast<const class_decl::base_spec*>(&other);
24068
24069 if (!o)
24070 return false;
24071
24072 return equals(*this, *o, 0);
24073 }
24074
24075 /// Comparison operator for @ref class_decl::base_spec.
24076 ///
24077 /// @param other the instance of @ref class_decl::base_spec to compare
24078 /// against.
24079 ///
24080 /// @return true if the current instance of @ref class_decl::base_spec
24081 /// equals @p other.
24082 bool
operator ==(const member_base & other) const24083 class_decl::base_spec::operator==(const member_base& other) const
24084 {
24085 const class_decl::base_spec* o =
24086 dynamic_cast<const class_decl::base_spec*>(&other);
24087 if (!o)
24088 return false;
24089
24090 return operator==(static_cast<const decl_base&>(*o));
24091 }
24092
~mem_fn_context_rel()24093 mem_fn_context_rel::~mem_fn_context_rel()
24094 {
24095 }
24096
24097 /// A constructor for instances of method_decl.
24098 ///
24099 /// @param name the name of the method.
24100 ///
24101 /// @param type the type of the method.
24102 ///
24103 /// @param declared_inline whether the method was
24104 /// declared inline or not.
24105 ///
24106 /// @param locus the source location of the method.
24107 ///
24108 /// @param linkage_name the mangled name of the method.
24109 ///
24110 /// @param vis the visibility of the method.
24111 ///
24112 /// @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)24113 method_decl::method_decl(const string& name,
24114 method_type_sptr type,
24115 bool declared_inline,
24116 const location& locus,
24117 const string& linkage_name,
24118 visibility vis,
24119 binding bind)
24120 : type_or_decl_base(type->get_environment(),
24121 METHOD_DECL
24122 | ABSTRACT_DECL_BASE
24123 |FUNCTION_DECL),
24124 decl_base(type->get_environment(), name, locus, linkage_name, vis),
24125 function_decl(name, static_pointer_cast<function_type>(type),
24126 declared_inline, locus, linkage_name, vis, bind)
24127 {
24128 runtime_type_instance(this);
24129 set_context_rel(new mem_fn_context_rel(0));
24130 set_member_function_is_const(*this, type->get_is_const());
24131 }
24132
24133 /// A constructor for instances of method_decl.
24134 ///
24135 /// @param name the name of the method.
24136 ///
24137 /// @param type the type of the method. Must be an instance of
24138 /// method_type.
24139 ///
24140 /// @param declared_inline whether the method was
24141 /// declared inline or not.
24142 ///
24143 /// @param locus the source location of the method.
24144 ///
24145 /// @param linkage_name the mangled name of the method.
24146 ///
24147 /// @param vis the visibility of the method.
24148 ///
24149 /// @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)24150 method_decl::method_decl(const string& name,
24151 function_type_sptr type,
24152 bool declared_inline,
24153 const location& locus,
24154 const string& linkage_name,
24155 visibility vis,
24156 binding bind)
24157 : type_or_decl_base(type->get_environment(),
24158 METHOD_DECL
24159 | ABSTRACT_DECL_BASE
24160 | FUNCTION_DECL),
24161 decl_base(type->get_environment(), name, locus, linkage_name, vis),
24162 function_decl(name, static_pointer_cast<function_type>
24163 (dynamic_pointer_cast<method_type>(type)),
24164 declared_inline, locus, linkage_name, vis, bind)
24165 {
24166 runtime_type_instance(this);
24167 set_context_rel(new mem_fn_context_rel(0));
24168 }
24169
24170 /// A constructor for instances of method_decl.
24171 ///
24172 /// @param name the name of the method.
24173 ///
24174 /// @param type the type of the method. Must be an instance of
24175 /// method_type.
24176 ///
24177 /// @param declared_inline whether the method was
24178 /// declared inline or not.
24179 ///
24180 /// @param locus the source location of the method.
24181 ///
24182 /// @param linkage_name the mangled name of the method.
24183 ///
24184 /// @param vis the visibility of the method.
24185 ///
24186 /// @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)24187 method_decl::method_decl(const string& name,
24188 type_base_sptr type,
24189 bool declared_inline,
24190 const location& locus,
24191 const string& linkage_name,
24192 visibility vis,
24193 binding bind)
24194 : type_or_decl_base(type->get_environment(),
24195 METHOD_DECL
24196 | ABSTRACT_DECL_BASE
24197 | FUNCTION_DECL),
24198 decl_base(type->get_environment(), name, locus, linkage_name, vis),
24199 function_decl(name, static_pointer_cast<function_type>
24200 (dynamic_pointer_cast<method_type>(type)),
24201 declared_inline, locus, linkage_name, vis, bind)
24202 {
24203 runtime_type_instance(this);
24204 set_context_rel(new mem_fn_context_rel(0));
24205 }
24206
24207 /// Set the linkage name of the method.
24208 ///
24209 /// @param l the new linkage name of the method.
24210 void
set_linkage_name(const string & l)24211 method_decl::set_linkage_name(const string& l)
24212 {
24213 string old_lname = get_linkage_name();
24214 decl_base::set_linkage_name(l);
24215 // Update the linkage_name -> member function map of the containing
24216 // class declaration.
24217 if (!l.empty())
24218 {
24219 method_type_sptr t = get_type();
24220 class_or_union_sptr cl = t->get_class_type();
24221 method_decl_sptr m(this, sptr_utils::noop_deleter());
24222 cl->priv_->mem_fns_map_[l] = m;
24223 if (!old_lname.empty() && l != old_lname)
24224 {
24225 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
24226 {
24227 ABG_ASSERT(m.get() == this);
24228 cl->priv_->mem_fns_map_.erase(old_lname);
24229 }
24230 }
24231 }
24232 }
24233
~method_decl()24234 method_decl::~method_decl()
24235 {}
24236
24237 const method_type_sptr
get_type() const24238 method_decl::get_type() const
24239 {
24240 method_type_sptr result;
24241 if (function_decl::get_type())
24242 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
24243 return result;
24244 }
24245
24246 /// Set the containing class of a method_decl.
24247 ///
24248 /// @param scope the new containing class_decl.
24249 void
set_scope(scope_decl * scope)24250 method_decl::set_scope(scope_decl* scope)
24251 {
24252 if (!get_context_rel())
24253 set_context_rel(new mem_fn_context_rel(scope));
24254 else
24255 get_context_rel()->set_scope(scope);
24256 }
24257
24258 /// Equality operator for @ref method_decl_sptr.
24259 ///
24260 /// This is a deep equality operator, as it compares the @ref
24261 /// method_decl that is pointed-to by the smart pointer.
24262 ///
24263 /// @param l the left-hand side argument of the equality operator.
24264 ///
24265 /// @param r the righ-hand side argument of the equality operator.
24266 ///
24267 /// @return true iff @p l equals @p r.
24268 bool
operator ==(const method_decl_sptr & l,const method_decl_sptr & r)24269 operator==(const method_decl_sptr& l, const method_decl_sptr& r)
24270 {
24271 if (l.get() == r.get())
24272 return true;
24273 if (!!l != !!r)
24274 return false;
24275
24276 return *l == *r;
24277 }
24278
24279 /// Inequality operator for @ref method_decl_sptr.
24280 ///
24281 /// This is a deep equality operator, as it compares the @ref
24282 /// method_decl that is pointed-to by the smart pointer.
24283 ///
24284 /// @param l the left-hand side argument of the equality operator.
24285 ///
24286 /// @param r the righ-hand side argument of the equality operator.
24287 ///
24288 /// @return true iff @p l differs from @p r.
24289 bool
operator !=(const method_decl_sptr & l,const method_decl_sptr & r)24290 operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
24291 {return !operator==(l, r);}
24292
24293 /// Test if a function_decl is actually a method_decl.
24294 ///
24295 ///@param d the @ref function_decl to consider.
24296 ///
24297 /// @return the method_decl sub-object of @p d if inherits
24298 /// a method_decl type.
24299 method_decl*
is_method_decl(const type_or_decl_base * d)24300 is_method_decl(const type_or_decl_base *d)
24301 {
24302 return dynamic_cast<method_decl*>
24303 (const_cast<type_or_decl_base*>(d));
24304 }
24305
24306 /// Test if a function_decl is actually a method_decl.
24307 ///
24308 ///@param d the @ref function_decl to consider.
24309 ///
24310 /// @return the method_decl sub-object of @p d if inherits
24311 /// a method_decl type.
24312 method_decl*
is_method_decl(const type_or_decl_base & d)24313 is_method_decl(const type_or_decl_base&d)
24314 {return is_method_decl(&d);}
24315
24316 /// Test if a function_decl is actually a method_decl.
24317 ///
24318 ///@param d the @ref function_decl to consider.
24319 ///
24320 /// @return the method_decl sub-object of @p d if inherits
24321 /// a method_decl type.
24322 method_decl_sptr
is_method_decl(const type_or_decl_base_sptr & d)24323 is_method_decl(const type_or_decl_base_sptr& d)
24324 {return dynamic_pointer_cast<method_decl>(d);}
24325
24326 /// A "less than" functor to sort a vector of instances of
24327 /// method_decl that are virtual.
24328 struct virtual_member_function_less_than
24329 {
24330 /// The less than operator. First, it sorts the methods by their
24331 /// vtable index. If they have the same vtable index, it sorts them
24332 /// by the name of their ELF symbol. If they don't have elf
24333 /// symbols, it sorts them by considering their pretty
24334 /// representation.
24335 ///
24336 /// Note that this method expects virtual methods.
24337 ///
24338 /// @param f the first method to consider.
24339 ///
24340 /// @param s the second method to consider.
24341 ///
24342 /// @return true if method @p is less than method @s.
24343 bool
operator ()abigail::ir::virtual_member_function_less_than24344 operator()(const method_decl& f,
24345 const method_decl& s)
24346 {
24347 ABG_ASSERT(get_member_function_is_virtual(f));
24348 ABG_ASSERT(get_member_function_is_virtual(s));
24349
24350 ssize_t f_offset = get_member_function_vtable_offset(f);
24351 ssize_t s_offset = get_member_function_vtable_offset(s);
24352 if (f_offset != s_offset) return f_offset < s_offset;
24353
24354 string fn, sn;
24355
24356 // If the functions have symbols, then compare their symbol-id
24357 // string.
24358 elf_symbol_sptr f_sym = f.get_symbol();
24359 elf_symbol_sptr s_sym = s.get_symbol();
24360 if ((!f_sym) != (!s_sym)) return !f_sym;
24361 if (f_sym && s_sym)
24362 {
24363 fn = f_sym->get_id_string();
24364 sn = s_sym->get_id_string();
24365 if (fn != sn) return fn < sn;
24366 }
24367
24368 // Try the linkage names (important for destructors).
24369 fn = f.get_linkage_name();
24370 sn = s.get_linkage_name();
24371 if (fn != sn) return fn < sn;
24372
24373 // None of the functions have symbols or linkage names that
24374 // distinguish them, so compare their pretty representation.
24375 fn = f.get_pretty_representation();
24376 sn = s.get_pretty_representation();
24377 if (fn != sn) return fn < sn;
24378
24379 /// If it's just the file paths that are different then sort them
24380 /// too.
24381 string fn_filepath, sn_filepath;
24382 unsigned line = 0, column = 0;
24383 location fn_loc = f.get_location(), sn_loc = s.get_location();
24384 if (fn_loc)
24385 fn_loc.expand(fn_filepath, line, column);
24386 if (sn_loc)
24387 sn_loc.expand(sn_filepath, line, column);
24388 return fn_filepath < sn_filepath;
24389 }
24390
24391 /// The less than operator. First, it sorts the methods by their
24392 /// vtable index. If they have the same vtable index, it sorts them
24393 /// by the name of their ELF symbol. If they don't have elf
24394 /// symbols, it sorts them by considering their pretty
24395 /// representation.
24396 ///
24397 /// Note that this method expects to take virtual methods.
24398 ///
24399 /// @param f the first method to consider.
24400 ///
24401 /// @param s the second method to consider.
24402 bool
operator ()abigail::ir::virtual_member_function_less_than24403 operator()(const method_decl_sptr f,
24404 const method_decl_sptr s)
24405 {return operator()(*f, *s);}
24406 }; // end struct virtual_member_function_less_than
24407
24408 /// Sort a vector of instances of virtual member functions.
24409 ///
24410 /// @param mem_fns the vector of member functions to sort.
24411 static void
sort_virtual_member_functions(class_decl::member_functions & mem_fns)24412 sort_virtual_member_functions(class_decl::member_functions& mem_fns)
24413 {
24414 virtual_member_function_less_than lt;
24415 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
24416 }
24417
24418 /// Add a member function to the current instance of @ref class_or_union.
24419 ///
24420 /// @param f a method_decl to add to the current class. This function
24421 /// should not have been already added to a scope.
24422 ///
24423 /// @param access the access specifier for the member function to add.
24424 ///
24425 /// @param is_virtual if this is true then it means the function @p f
24426 /// is a virtual function. That also means that the current instance
24427 /// of @ref class_or_union is actually an instance of @ref class_decl.
24428 ///
24429 /// @param vtable_offset the offset of the member function in the
24430 /// virtual table. This parameter is taken into account only if @p
24431 /// is_virtual is true.
24432 ///
24433 /// @param is_static whether the member function is static.
24434 ///
24435 /// @param is_ctor whether the member function is a constructor.
24436 ///
24437 /// @param is_dtor whether the member function is a destructor.
24438 ///
24439 /// @param is_const whether the member function is const.
24440 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)24441 class_or_union::add_member_function(method_decl_sptr f,
24442 access_specifier a,
24443 bool is_virtual,
24444 size_t vtable_offset,
24445 bool is_static, bool is_ctor,
24446 bool is_dtor, bool is_const)
24447 {
24448 add_member_function(f, a, is_static, is_ctor,
24449 is_dtor, is_const);
24450
24451 if (class_decl* klass = is_class_type(this))
24452 {
24453 set_member_function_is_virtual(f, is_virtual);
24454 if (is_virtual)
24455 {
24456 set_member_function_vtable_offset(f, vtable_offset);
24457 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
24458 }
24459 }
24460 }
24461
24462 /// When a virtual member function has seen its virtualness set by
24463 /// set_member_function_is_virtual(), this function ensures that the
24464 /// member function is added to the specific vectors and maps of
24465 /// virtual member function of its class.
24466 ///
24467 /// @param method the method to fixup.
24468 void
fixup_virtual_member_function(method_decl_sptr method)24469 fixup_virtual_member_function(method_decl_sptr method)
24470 {
24471 if (!method || !get_member_function_is_virtual(method))
24472 return;
24473
24474 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
24475
24476 class_decl::member_functions::const_iterator m;
24477 for (m = klass->priv_->virtual_mem_fns_.begin();
24478 m != klass->priv_->virtual_mem_fns_.end();
24479 ++m)
24480 if (m->get() == method.get())
24481 break;
24482 if (m == klass->priv_->virtual_mem_fns_.end())
24483 klass->priv_->virtual_mem_fns_.push_back(method);
24484
24485 // Build or udpate the map that associates a vtable offset to the
24486 // number of virtual member functions that "point" to it.
24487 ssize_t voffset = get_member_function_vtable_offset(method);
24488 if (voffset == -1)
24489 return;
24490
24491 class_decl::virtual_mem_fn_map_type::iterator i =
24492 klass->priv_->virtual_mem_fns_map_.find(voffset);
24493 if (i == klass->priv_->virtual_mem_fns_map_.end())
24494 {
24495 class_decl::member_functions virtual_mem_fns_at_voffset;
24496 virtual_mem_fns_at_voffset.push_back(method);
24497 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
24498 }
24499 else
24500 {
24501 for (m = i->second.begin() ; m != i->second.end(); ++m)
24502 if (m->get() == method.get())
24503 break;
24504 if (m == i->second.end())
24505 i->second.push_back(method);
24506 }
24507 }
24508
24509 /// Return true iff the class has no entity in its scope.
24510 bool
has_no_base_nor_member() const24511 class_decl::has_no_base_nor_member() const
24512 {return priv_->bases_.empty() && has_no_member();}
24513
24514 /// Test if the current instance of @ref class_decl has virtual member
24515 /// functions.
24516 ///
24517 /// @return true iff the current instance of @ref class_decl has
24518 /// virtual member functions.
24519 bool
has_virtual_member_functions() const24520 class_decl::has_virtual_member_functions() const
24521 {return !get_virtual_mem_fns().empty();}
24522
24523 /// Test if the current instance of @ref class_decl has at least one
24524 /// virtual base.
24525 ///
24526 /// @return true iff the current instance of @ref class_decl has a
24527 /// virtual member function.
24528 bool
has_virtual_bases() const24529 class_decl::has_virtual_bases() const
24530 {
24531 for (base_specs::const_iterator b = get_base_specifiers().begin();
24532 b != get_base_specifiers().end();
24533 ++b)
24534 if ((*b)->get_is_virtual()
24535 || (*b)->get_base_class()->has_virtual_bases())
24536 return true;
24537
24538 return false;
24539 }
24540
24541 /// Test if the current instance has a vtable.
24542 ///
24543 /// This is only valid for a C++ program.
24544 ///
24545 /// Basically this function checks if the class has either virtual
24546 /// functions, or virtual bases.
24547 bool
has_vtable() const24548 class_decl::has_vtable() const
24549 {
24550 if (has_virtual_member_functions()
24551 || has_virtual_bases())
24552 return true;
24553 return false;
24554 }
24555
24556 /// Get the highest vtable offset of all the virtual methods of the
24557 /// class.
24558 ///
24559 /// @return the highest vtable offset of all the virtual methods of
24560 /// the class.
24561 ssize_t
get_biggest_vtable_offset() const24562 class_decl::get_biggest_vtable_offset() const
24563 {
24564 ssize_t offset = -1;
24565 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
24566 get_virtual_mem_fns_map().begin();
24567 e != get_virtual_mem_fns_map().end();
24568 ++e)
24569 if (e->first > offset)
24570 offset = e->first;
24571
24572 return offset;
24573 }
24574
24575 /// Return the hash value for the current instance.
24576 ///
24577 /// @return the hash value.
24578 size_t
get_hash() const24579 class_decl::get_hash() const
24580 {
24581 class_decl::hash hash_class;
24582 return hash_class(this);
24583 }
24584
24585 /// Test if two methods are equal without taking their symbol or
24586 /// linkage name into account.
24587 ///
24588 /// @param f the first method.
24589 ///
24590 /// @param s the second method.
24591 ///
24592 /// @return true iff @p f equals @p s without taking their linkage
24593 /// name or symbol into account.
24594 static bool
methods_equal_modulo_elf_symbol(const method_decl_sptr & f,const method_decl_sptr & s)24595 methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
24596 const method_decl_sptr& s)
24597 {
24598 method_decl_sptr first = f, second = s;
24599 elf_symbol_sptr saved_first_elf_symbol =
24600 first->get_symbol();
24601 elf_symbol_sptr saved_second_elf_symbol =
24602 second->get_symbol();
24603 interned_string saved_first_linkage_name =
24604 first->get_linkage_name();
24605 interned_string saved_second_linkage_name =
24606 second->get_linkage_name();
24607
24608 first->set_symbol(elf_symbol_sptr());
24609 first->set_linkage_name("");
24610 second->set_symbol(elf_symbol_sptr());
24611 second->set_linkage_name("");
24612
24613 bool equal = *first == *second;
24614
24615 first->set_symbol(saved_first_elf_symbol);
24616 first->set_linkage_name(saved_first_linkage_name);
24617 second->set_symbol(saved_second_elf_symbol);
24618 second->set_linkage_name(saved_second_linkage_name);
24619
24620 return equal;
24621 }
24622
24623 /// Test if a given method is equivalent to at least of other method
24624 /// that is in a vector of methods.
24625 ///
24626 /// Note that "equivalent" here means being equal without taking the
24627 /// linkage name or the symbol of the methods into account.
24628 ///
24629 /// This is a sub-routine of the 'equals' function that compares @ref
24630 /// class_decl.
24631 ///
24632 /// @param method the method to compare.
24633 ///
24634 /// @param fns the vector of functions to compare @p method against.
24635 ///
24636 /// @return true iff @p is equivalent to at least one method in @p
24637 /// fns.
24638 static bool
method_matches_at_least_one_in_vector(const method_decl_sptr & method,const class_decl::member_functions & fns)24639 method_matches_at_least_one_in_vector(const method_decl_sptr& method,
24640 const class_decl::member_functions& fns)
24641 {
24642 for (class_decl::member_functions::const_iterator i = fns.begin();
24643 i != fns.end();
24644 ++i)
24645 // Note that the comparison must be done in this order: method ==
24646 // *i This is to keep the consistency of the comparison. It's
24647 // important especially when doing type canonicalization. The
24648 // already canonicalize type is the left operand, and the type
24649 // being canonicalized is the right operand. This comes from the
24650 // code in type_base::get_canonical_type_for().
24651 if (methods_equal_modulo_elf_symbol(method, *i))
24652 return true;
24653
24654 return false;
24655 }
24656
24657 /// Cancel the canonical type that was propagated.
24658 ///
24659 /// If we are in the process of comparing a type for the purpose of
24660 /// canonicalization, and if that type has been the target of the
24661 /// canonical type propagation optimization, then clear the propagated
24662 /// canonical type. See @ref OnTheFlyCanonicalization for more about
24663 /// the canonical type optimization
24664 ///
24665 /// @param t the type to consider.
24666 static bool
maybe_cancel_propagated_canonical_type(const class_or_union & t)24667 maybe_cancel_propagated_canonical_type(const class_or_union& t)
24668 {
24669 const environment& env = t.get_environment();
24670 if (env.do_on_the_fly_canonicalization())
24671 if (is_type(&t)->priv_->canonical_type_propagated())
24672 {
24673 is_type(&t)->priv_->clear_propagated_canonical_type();
24674 env.priv_->remove_from_types_with_non_confirmed_propagated_ct(&t);
24675 return true;
24676 }
24677 return false;
24678 }
24679
24680 /// Compares two instances of @ref class_decl.
24681 ///
24682 /// If the two intances are different, set a bitfield to give some
24683 /// insight about the kind of differences there are.
24684 ///
24685 /// @param l the first artifact of the comparison.
24686 ///
24687 /// @param r the second artifact of the comparison.
24688 ///
24689 /// @param k a pointer to a bitfield that gives information about the
24690 /// kind of changes there are between @p l and @p r. This one is set
24691 /// iff @p k is non-null and the function returns false.
24692 ///
24693 /// Please note that setting k to a non-null value does have a
24694 /// negative performance impact because even if @p l and @p r are not
24695 /// equal, the function keeps up the comparison in order to determine
24696 /// the different kinds of ways in which they are different.
24697 ///
24698 /// @return true if @p l equals @p r, false otherwise.
24699 bool
equals(const class_decl & l,const class_decl & r,change_kind * k)24700 equals(const class_decl& l, const class_decl& r, change_kind* k)
24701 {
24702 {
24703 // First of all, let's see if these two types haven't already been
24704 // compared. If so, and if the result of the comparison has been
24705 // cached, let's just re-use it, rather than comparing them all
24706 // over again.
24707 bool result = false;
24708 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
24709 ABG_RETURN(result);
24710 }
24711
24712 // if one of the classes is declaration-only then we take a fast
24713 // path here.
24714 if (l.get_is_declaration_only() || r.get_is_declaration_only())
24715 ABG_RETURN(equals(static_cast<const class_or_union&>(l),
24716 static_cast<const class_or_union&>(r),
24717 k));
24718
24719 bool had_canonical_type = !!r.get_naked_canonical_type();
24720 bool result = true;
24721 if (!equals(static_cast<const class_or_union&>(l),
24722 static_cast<const class_or_union&>(r),
24723 k))
24724 {
24725 result = false;
24726 if (!k)
24727 ABG_RETURN(result);
24728 }
24729
24730 // If comparing the class_or_union 'part' of the type led to
24731 // canonical type propagation, then cancel that because it's too
24732 // early to do that at this point. We still need to compare bases
24733 // virtual members.
24734 if (!had_canonical_type)
24735 maybe_cancel_propagated_canonical_type(r);
24736
24737 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
24738
24739 mark_types_as_being_compared(l, r);
24740
24741 #define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
24742
24743 // Compare bases.
24744 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
24745 {
24746 result = false;
24747 if (k)
24748 *k |= LOCAL_TYPE_CHANGE_KIND;
24749 else
24750 RETURN(result);
24751 }
24752
24753 for (class_decl::base_specs::const_iterator
24754 b0 = l.get_base_specifiers().begin(),
24755 b1 = r.get_base_specifiers().begin();
24756 (b0 != l.get_base_specifiers().end()
24757 && b1 != r.get_base_specifiers().end());
24758 ++b0, ++b1)
24759 if (*b0 != *b1)
24760 {
24761 result = false;
24762 if (k)
24763 {
24764 if (!types_have_similar_structure((*b0)->get_base_class().get(),
24765 (*b1)->get_base_class().get()))
24766 *k |= LOCAL_TYPE_CHANGE_KIND;
24767 else
24768 *k |= SUBTYPE_CHANGE_KIND;
24769 break;
24770 }
24771 RETURN(result);
24772 }
24773
24774 // Compare virtual member functions
24775
24776 // We look at the map that associates a given vtable offset to a
24777 // vector of virtual member functions that point to that offset.
24778 //
24779 // This is because there are cases where several functions can
24780 // point to the same virtual table offset.
24781 //
24782 // This is usually the case for virtual destructors. Even though
24783 // there can be only one virtual destructor declared in source
24784 // code, there are actually potentially up to three generated
24785 // functions for that destructor. Some of these generated
24786 // functions can be clones of other functions that are among those
24787 // generated ones. In any cases, they all have the same
24788 // properties, including the vtable offset property.
24789
24790 // So, there should be the same number of different vtable
24791 // offsets, the size of two maps must be equals.
24792 if (l.get_virtual_mem_fns_map().size()
24793 != r.get_virtual_mem_fns_map().size())
24794 {
24795 result = false;
24796 if (k)
24797 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
24798 else
24799 RETURN(result);
24800 }
24801
24802 // Then, each virtual member function of a given vtable offset in
24803 // the first class type, must match an equivalent virtual member
24804 // function of a the same vtable offset in the second class type.
24805 //
24806 // By "match", I mean that the two virtual member function should
24807 // be equal if we don't take into account their symbol name or
24808 // their linkage name. This is because two destructor functions
24809 // clones (for instance) might have different linkage name, but
24810 // are still equivalent if their other properties are the same.
24811 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
24812 l.get_virtual_mem_fns_map().begin();
24813 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
24814 ++first_v_fn_entry)
24815 {
24816 unsigned voffset = first_v_fn_entry->first;
24817 const class_decl::member_functions& first_vfns =
24818 first_v_fn_entry->second;
24819
24820 const class_decl::virtual_mem_fn_map_type::const_iterator
24821 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
24822
24823 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
24824 {
24825 result = false;
24826 if (k)
24827 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
24828 RETURN(result);
24829 }
24830
24831 const class_decl::member_functions& second_vfns =
24832 second_v_fn_entry->second;
24833
24834 bool matches = false;
24835 for (class_decl::member_functions::const_iterator i =
24836 first_vfns.begin();
24837 i != first_vfns.end();
24838 ++i)
24839 if (method_matches_at_least_one_in_vector(*i, second_vfns))
24840 {
24841 matches = true;
24842 break;
24843 }
24844
24845 if (!matches)
24846 {
24847 result = false;
24848 if (k)
24849 *k |= SUBTYPE_CHANGE_KIND;
24850 else
24851 RETURN(result);
24852 }
24853 }
24854
24855 RETURN(result);
24856 #undef RETURN
24857 }
24858
24859 /// Copy a method of a class into a new class.
24860 ///
24861 /// @param klass the class into which the method is to be copied.
24862 ///
24863 /// @param method the method to copy into @p klass.
24864 ///
24865 /// @return the resulting newly copied method.
24866 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl_sptr & f)24867 copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
24868 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
24869
24870 /// Copy a method of a class into a new class.
24871 ///
24872 /// @param klass the class into which the method is to be copied.
24873 ///
24874 /// @param method the method to copy into @p klass.
24875 ///
24876 /// @return the resulting newly copied method.
24877 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl * f)24878 copy_member_function(const class_decl_sptr& clazz, const method_decl* f)
24879 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
24880
24881 /// Comparison operator for @ref class_decl.
24882 ///
24883 /// @param other the instance of @ref class_decl to compare against.
24884 ///
24885 /// @return true iff the current instance of @ref class_decl equals @p
24886 /// other.
24887 bool
operator ==(const decl_base & other) const24888 class_decl::operator==(const decl_base& other) const
24889 {
24890 const class_decl* op = is_class_type(&other);
24891 if (!op)
24892 return false;
24893
24894 // If this is a decl-only type (and thus with no canonical type),
24895 // use the canonical type of the definition, if any.
24896 const class_decl *l = 0;
24897 if (get_is_declaration_only())
24898 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
24899 if (l == 0)
24900 l = this;
24901
24902 ABG_ASSERT(l);
24903
24904 // Likewise for the other type.
24905 const class_decl *r = 0;
24906 if (op->get_is_declaration_only())
24907 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
24908 if (r == 0)
24909 r = op;
24910
24911 ABG_ASSERT(r);
24912
24913 return try_canonical_compare(l, r);
24914 }
24915
24916 /// Equality operator for class_decl.
24917 ///
24918 /// Re-uses the equality operator that takes a decl_base.
24919 ///
24920 /// @param other the other class_decl to compare against.
24921 ///
24922 /// @return true iff the current instance equals the other one.
24923 bool
operator ==(const type_base & other) const24924 class_decl::operator==(const type_base& other) const
24925 {
24926 const decl_base* o = is_decl(&other);
24927 if (!o)
24928 return false;
24929 return *this == *o;
24930 }
24931
24932 /// Equality operator for class_decl.
24933 ///
24934 /// Re-uses the equality operator that takes a decl_base.
24935 ///
24936 /// @param other the other class_decl to compare against.
24937 ///
24938 /// @return true iff the current instance equals the other one.
24939 bool
operator ==(const class_or_union & other) const24940 class_decl::operator==(const class_or_union& other) const
24941 {
24942 const decl_base& o = other;
24943 return *this == o;
24944 }
24945
24946 /// Comparison operator for @ref class_decl.
24947 ///
24948 /// @param other the instance of @ref class_decl to compare against.
24949 ///
24950 /// @return true iff the current instance of @ref class_decl equals @p
24951 /// other.
24952 bool
operator ==(const class_decl & other) const24953 class_decl::operator==(const class_decl& other) const
24954 {
24955 const decl_base& o = other;
24956 return *this == o;
24957 }
24958
24959 /// Turn equality of shared_ptr of class_decl into a deep equality;
24960 /// that is, make it compare the pointed to objects too.
24961 ///
24962 /// @param l the shared_ptr of class_decl on left-hand-side of the
24963 /// equality.
24964 ///
24965 /// @param r the shared_ptr of class_decl on right-hand-side of the
24966 /// equality.
24967 ///
24968 /// @return true if the class_decl pointed to by the shared_ptrs are
24969 /// equal, false otherwise.
24970 bool
operator ==(const class_decl_sptr & l,const class_decl_sptr & r)24971 operator==(const class_decl_sptr& l, const class_decl_sptr& r)
24972 {
24973 if (l.get() == r.get())
24974 return true;
24975 if (!!l != !!r)
24976 return false;
24977
24978 return *l == *r;
24979 }
24980
24981 /// Turn inequality of shared_ptr of class_decl into a deep equality;
24982 /// that is, make it compare the pointed to objects too.
24983 ///
24984 /// @param l the shared_ptr of class_decl on left-hand-side of the
24985 /// equality.
24986 ///
24987 /// @param r the shared_ptr of class_decl on right-hand-side of the
24988 /// equality.
24989 ///
24990 /// @return true if the class_decl pointed to by the shared_ptrs are
24991 /// different, false otherwise.
24992 bool
operator !=(const class_decl_sptr & l,const class_decl_sptr & r)24993 operator!=(const class_decl_sptr& l, const class_decl_sptr& r)
24994 {return !operator==(l, r);}
24995
24996 /// Turn equality of shared_ptr of class_or_union into a deep
24997 /// equality; that is, make it compare the pointed to objects too.
24998 ///
24999 /// @param l the left-hand-side operand of the operator
25000 ///
25001 /// @param r the right-hand-side operand of the operator.
25002 ///
25003 /// @return true iff @p l equals @p r.
25004 bool
operator ==(const class_or_union_sptr & l,const class_or_union_sptr & r)25005 operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
25006 {
25007 if (l.get() == r.get())
25008 return true;
25009 if (!!l != !!r)
25010 return false;
25011
25012 return *l == *r;
25013 }
25014
25015 /// Turn inequality of shared_ptr of class_or_union into a deep
25016 /// equality; that is, make it compare the pointed to objects too.
25017 ///
25018 /// @param l the left-hand-side operand of the operator
25019 ///
25020 /// @param r the right-hand-side operand of the operator.
25021 ///
25022 /// @return true iff @p l is different from @p r.
25023 bool
operator !=(const class_or_union_sptr & l,const class_or_union_sptr & r)25024 operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
25025 {return !operator==(l, r);}
25026
25027 /// This implements the ir_traversable_base::traverse pure virtual
25028 /// function.
25029 ///
25030 /// @param v the visitor used on the current instance and on its
25031 /// members.
25032 ///
25033 /// @return true if the entire IR node tree got traversed, false
25034 /// otherwise.
25035 bool
traverse(ir_node_visitor & v)25036 class_decl::traverse(ir_node_visitor& v)
25037 {
25038 if (v.type_node_has_been_visited(this))
25039 return true;
25040
25041 if (visiting())
25042 return true;
25043
25044 if (v.visit_begin(this))
25045 {
25046 visiting(true);
25047 bool stop = false;
25048
25049 for (base_specs::const_iterator i = get_base_specifiers().begin();
25050 i != get_base_specifiers().end();
25051 ++i)
25052 {
25053 if (!(*i)->traverse(v))
25054 {
25055 stop = true;
25056 break;
25057 }
25058 }
25059
25060 if (!stop)
25061 for (data_members::const_iterator i = get_data_members().begin();
25062 i != get_data_members().end();
25063 ++i)
25064 if (!(*i)->traverse(v))
25065 {
25066 stop = true;
25067 break;
25068 }
25069
25070 if (!stop)
25071 for (member_functions::const_iterator i= get_member_functions().begin();
25072 i != get_member_functions().end();
25073 ++i)
25074 if (!(*i)->traverse(v))
25075 {
25076 stop = true;
25077 break;
25078 }
25079
25080 if (!stop)
25081 for (member_types::const_iterator i = get_member_types().begin();
25082 i != get_member_types().end();
25083 ++i)
25084 if (!(*i)->traverse(v))
25085 {
25086 stop = true;
25087 break;
25088 }
25089
25090 if (!stop)
25091 for (member_function_templates::const_iterator i =
25092 get_member_function_templates().begin();
25093 i != get_member_function_templates().end();
25094 ++i)
25095 if (!(*i)->traverse(v))
25096 {
25097 stop = true;
25098 break;
25099 }
25100
25101 if (!stop)
25102 for (member_class_templates::const_iterator i =
25103 get_member_class_templates().begin();
25104 i != get_member_class_templates().end();
25105 ++i)
25106 if (!(*i)->traverse(v))
25107 {
25108 stop = true;
25109 break;
25110 }
25111 visiting(false);
25112 }
25113
25114 bool result = v.visit_end(this);
25115 v.mark_type_node_as_visited(this);
25116 return result;
25117 }
25118
25119 /// Destructor of the @ref class_decl type.
~class_decl()25120 class_decl::~class_decl()
25121 {delete priv_;}
25122
~context_rel()25123 context_rel::~context_rel()
25124 {}
25125
25126 bool
operator ==(const member_base & o) const25127 member_base::operator==(const member_base& o) const
25128 {
25129 return (get_access_specifier() == o.get_access_specifier()
25130 && get_is_static() == o.get_is_static());
25131 }
25132
25133 /// Equality operator for smart pointers to @ref
25134 /// class_decl::base_specs.
25135 ///
25136 /// This compares the pointed-to objects.
25137 ///
25138 /// @param l the first instance to consider.
25139 ///
25140 /// @param r the second instance to consider.
25141 ///
25142 /// @return true iff @p l equals @p r.
25143 bool
operator ==(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)25144 operator==(const class_decl::base_spec_sptr& l,
25145 const class_decl::base_spec_sptr& r)
25146 {
25147 if (l.get() == r.get())
25148 return true;
25149 if (!!l != !!r)
25150 return false;
25151
25152 return *l == static_cast<const decl_base&>(*r);
25153 }
25154
25155 /// Inequality operator for smart pointers to @ref
25156 /// class_decl::base_specs.
25157 ///
25158 /// This compares the pointed-to objects.
25159 ///
25160 /// @param l the first instance to consider.
25161 ///
25162 /// @param r the second instance to consider.
25163 ///
25164 /// @return true iff @p l is different from @p r.
25165 bool
operator !=(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)25166 operator!=(const class_decl::base_spec_sptr& l,
25167 const class_decl::base_spec_sptr& r)
25168 {return !operator==(l, r);}
25169
25170 /// Test if an ABI artifact is a class base specifier.
25171 ///
25172 /// @param tod the ABI artifact to consider.
25173 ///
25174 /// @return a pointer to the @ref class_decl::base_spec sub-object of
25175 /// @p tod iff it's a class base specifier.
25176 class_decl::base_spec*
is_class_base_spec(const type_or_decl_base * tod)25177 is_class_base_spec(const type_or_decl_base* tod)
25178 {
25179 return dynamic_cast<class_decl::base_spec*>
25180 (const_cast<type_or_decl_base*>(tod));
25181 }
25182
25183 /// Test if an ABI artifact is a class base specifier.
25184 ///
25185 /// @param tod the ABI artifact to consider.
25186 ///
25187 /// @return a pointer to the @ref class_decl::base_spec sub-object of
25188 /// @p tod iff it's a class base specifier.
25189 class_decl::base_spec_sptr
is_class_base_spec(type_or_decl_base_sptr tod)25190 is_class_base_spec(type_or_decl_base_sptr tod)
25191 {return dynamic_pointer_cast<class_decl::base_spec>(tod);}
25192
25193 bool
operator ==(const member_base & other) const25194 member_function_template::operator==(const member_base& other) const
25195 {
25196 try
25197 {
25198 const member_function_template& o =
25199 dynamic_cast<const member_function_template&>(other);
25200
25201 if (!(is_constructor() == o.is_constructor()
25202 && is_const() == o.is_const()
25203 && member_base::operator==(o)))
25204 return false;
25205
25206 if (function_tdecl_sptr ftdecl = as_function_tdecl())
25207 {
25208 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
25209 if (other_ftdecl)
25210 return ftdecl->function_tdecl::operator==(*other_ftdecl);
25211 }
25212 }
25213 catch(...)
25214 {}
25215 return false;
25216 }
25217
25218 /// Equality operator for smart pointers to @ref
25219 /// member_function_template. This is compares the
25220 /// pointed-to instances.
25221 ///
25222 /// @param l the first instance to consider.
25223 ///
25224 /// @param r the second instance to consider.
25225 ///
25226 /// @return true iff @p l equals @p r.
25227 bool
operator ==(const member_function_template_sptr & l,const member_function_template_sptr & r)25228 operator==(const member_function_template_sptr& l,
25229 const member_function_template_sptr& r)
25230 {
25231 if (l.get() == r.get())
25232 return true;
25233 if (!!l != !!r)
25234 return false;
25235
25236 return *l == *r;
25237 }
25238
25239 /// Inequality operator for smart pointers to @ref
25240 /// member_function_template. This is compares the pointed-to
25241 /// instances.
25242 ///
25243 /// @param l the first instance to consider.
25244 ///
25245 /// @param r the second instance to consider.
25246 ///
25247 /// @return true iff @p l equals @p r.
25248 bool
operator !=(const member_function_template_sptr & l,const member_function_template_sptr & r)25249 operator!=(const member_function_template_sptr& l,
25250 const member_function_template_sptr& r)
25251 {return !operator==(l, r);}
25252
25253 /// This implements the ir_traversable_base::traverse pure virtual
25254 /// function.
25255 ///
25256 /// @param v the visitor used on the current instance and on its
25257 /// underlying function template.
25258 ///
25259 /// @return true if the entire IR node tree got traversed, false
25260 /// otherwise.
25261 bool
traverse(ir_node_visitor & v)25262 member_function_template::traverse(ir_node_visitor& v)
25263 {
25264 if (visiting())
25265 return true;
25266
25267 if (v.visit_begin(this))
25268 {
25269 visiting(true);
25270 if (function_tdecl_sptr f = as_function_tdecl())
25271 f->traverse(v);
25272 visiting(false);
25273 }
25274 return v.visit_end(this);
25275 }
25276
25277 /// Equality operator of the the @ref member_class_template class.
25278 ///
25279 /// @param other the other @ref member_class_template to compare against.
25280 ///
25281 /// @return true iff the current instance equals @p other.
25282 bool
operator ==(const member_base & other) const25283 member_class_template::operator==(const member_base& other) const
25284 {
25285 try
25286 {
25287 const member_class_template& o =
25288 dynamic_cast<const member_class_template&>(other);
25289
25290 if (!member_base::operator==(o))
25291 return false;
25292
25293 return as_class_tdecl()->class_tdecl::operator==(o);
25294 }
25295 catch(...)
25296 {return false;}
25297 }
25298
25299 /// Equality operator of the the @ref member_class_template class.
25300 ///
25301 /// @param other the other @ref member_class_template to compare against.
25302 ///
25303 /// @return true iff the current instance equals @p other.
25304 bool
operator ==(const decl_base & other) const25305 member_class_template::operator==(const decl_base& other) const
25306 {
25307 if (!decl_base::operator==(other))
25308 return false;
25309 return as_class_tdecl()->class_tdecl::operator==(other);
25310 }
25311
25312 /// Comparison operator for the @ref member_class_template
25313 /// type.
25314 ///
25315 /// @param other the other instance of @ref
25316 /// member_class_template to compare against.
25317 ///
25318 /// @return true iff the two instances are equal.
25319 bool
operator ==(const member_class_template & other) const25320 member_class_template::operator==(const member_class_template& other) const
25321 {
25322 const decl_base* o = dynamic_cast<const decl_base*>(&other);
25323 return *this == *o;
25324 }
25325
25326 /// Comparison operator for the @ref member_class_template
25327 /// type.
25328 ///
25329 /// @param l the first argument of the operator.
25330 ///
25331 /// @param r the second argument of the operator.
25332 ///
25333 /// @return true iff the two instances are equal.
25334 bool
operator ==(const member_class_template_sptr & l,const member_class_template_sptr & r)25335 operator==(const member_class_template_sptr& l,
25336 const member_class_template_sptr& r)
25337 {
25338 if (l.get() == r.get())
25339 return true;
25340 if (!!l != !!r)
25341 return false;
25342
25343 return *l == *r;
25344 }
25345
25346 /// Inequality operator for the @ref member_class_template
25347 /// type.
25348 ///
25349 /// @param l the first argument of the operator.
25350 ///
25351 /// @param r the second argument of the operator.
25352 ///
25353 /// @return true iff the two instances are equal.
25354 bool
operator !=(const member_class_template_sptr & l,const member_class_template_sptr & r)25355 operator!=(const member_class_template_sptr& l,
25356 const member_class_template_sptr& r)
25357 {return !operator==(l, r);}
25358
25359 /// This implements the ir_traversable_base::traverse pure virtual
25360 /// function.
25361 ///
25362 /// @param v the visitor used on the current instance and on the class
25363 /// pattern of the template.
25364 ///
25365 /// @return true if the entire IR node tree got traversed, false
25366 /// otherwise.
25367 bool
traverse(ir_node_visitor & v)25368 member_class_template::traverse(ir_node_visitor& v)
25369 {
25370 if (visiting())
25371 return true;
25372
25373 if (v.visit_begin(this))
25374 {
25375 visiting(true);
25376 if (class_tdecl_sptr t = as_class_tdecl())
25377 t->traverse(v);
25378 visiting(false);
25379 }
25380 return v.visit_end(this);
25381 }
25382
25383 /// Streaming operator for class_decl::access_specifier.
25384 ///
25385 /// @param o the output stream to serialize the access specifier to.
25386 ///
25387 /// @param a the access specifier to serialize.
25388 ///
25389 /// @return the output stream.
25390 std::ostream&
operator <<(std::ostream & o,access_specifier a)25391 operator<<(std::ostream& o, access_specifier a)
25392 {
25393 string r;
25394
25395 switch (a)
25396 {
25397 case no_access:
25398 r = "none";
25399 break;
25400 case private_access:
25401 r = "private";
25402 break;
25403 case protected_access:
25404 r = "protected";
25405 break;
25406 case public_access:
25407 r= "public";
25408 break;
25409 };
25410 o << r;
25411 return o;
25412 }
25413
25414 /// Sets the static-ness property of a class member.
25415 ///
25416 /// @param d the class member to set the static-ness property for.
25417 /// Note that this must be a class member otherwise the function
25418 /// aborts the current process.
25419 ///
25420 /// @param s this must be true if the member is to be static, false
25421 /// otherwise.
25422 void
set_member_is_static(decl_base & d,bool s)25423 set_member_is_static(decl_base& d, bool s)
25424 {
25425 ABG_ASSERT(is_member_decl(d));
25426
25427 context_rel* c = d.get_context_rel();
25428 ABG_ASSERT(c);
25429
25430 c->set_is_static(s);
25431
25432 scope_decl* scope = d.get_scope();
25433
25434 if (class_or_union* cl = is_class_or_union_type(scope))
25435 {
25436 if (var_decl* v = is_var_decl(&d))
25437 {
25438 if (s)
25439 // remove from the non-static data members
25440 for (class_decl::data_members::iterator i =
25441 cl->priv_->non_static_data_members_.begin();
25442 i != cl->priv_->non_static_data_members_.end();
25443 ++i)
25444 {
25445 if ((*i)->get_name() == v->get_name())
25446 {
25447 cl->priv_->non_static_data_members_.erase(i);
25448 break;
25449 }
25450 }
25451 else
25452 {
25453 bool is_already_in_non_static_data_members = false;
25454 for (class_or_union::data_members::iterator i =
25455 cl->priv_->non_static_data_members_.begin();
25456 i != cl->priv_->non_static_data_members_.end();
25457 ++i)
25458 {
25459 if ((*i)->get_name() == v->get_name())
25460 {
25461 is_already_in_non_static_data_members = true;
25462 break;
25463 }
25464 }
25465 if (!is_already_in_non_static_data_members)
25466 {
25467 var_decl_sptr var;
25468 // add to non-static data members.
25469 for (class_or_union::data_members::const_iterator i =
25470 cl->priv_->data_members_.begin();
25471 i != cl->priv_->data_members_.end();
25472 ++i)
25473 {
25474 if ((*i)->get_name() == v->get_name())
25475 {
25476 var = *i;
25477 break;
25478 }
25479 }
25480 ABG_ASSERT(var);
25481 cl->priv_->non_static_data_members_.push_back(var);
25482 }
25483 }
25484 }
25485 }
25486 }
25487
25488 /// Sets the static-ness property of a class member.
25489 ///
25490 /// @param d the class member to set the static-ness property for.
25491 /// Note that this must be a class member otherwise the function
25492 /// aborts the current process.
25493 ///
25494 /// @param s this must be true if the member is to be static, false
25495 /// otherwise.
25496 void
set_member_is_static(const decl_base_sptr & d,bool s)25497 set_member_is_static(const decl_base_sptr& d, bool s)
25498 {set_member_is_static(*d, s);}
25499
25500 // </class_decl>
25501
25502 // <union_decl>
25503
25504 /// Constructor for the @ref union_decl type.
25505 ///
25506 /// @param env the @ref environment we are operating from.
25507 ///
25508 /// @param name the name of the union type.
25509 ///
25510 /// @param size_in_bits the size of the union, in bits.
25511 ///
25512 /// @param locus the location of the type.
25513 ///
25514 /// @param vis the visibility of instances of @ref union_decl.
25515 ///
25516 /// @param mbr_types the member types of the union.
25517 ///
25518 /// @param data_mbrs the data members of the union.
25519 ///
25520 /// @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)25521 union_decl::union_decl(const environment& env, const string& name,
25522 size_t size_in_bits, const location& locus,
25523 visibility vis, member_types& mbr_types,
25524 data_members& data_mbrs, member_functions& member_fns)
25525 : type_or_decl_base(env,
25526 UNION_TYPE
25527 | ABSTRACT_TYPE_BASE
25528 | ABSTRACT_DECL_BASE),
25529 decl_base(env, name, locus, name, vis),
25530 type_base(env, size_in_bits, 0),
25531 class_or_union(env, name, size_in_bits, 0,
25532 locus, vis, mbr_types, data_mbrs, member_fns)
25533 {
25534 runtime_type_instance(this);
25535 }
25536
25537 /// Constructor for the @ref union_decl type.
25538 ///
25539 /// @param env the @ref environment we are operating from.
25540 ///
25541 /// @param name the name of the union type.
25542 ///
25543 /// @param size_in_bits the size of the union, in bits.
25544 ///
25545 /// @param locus the location of the type.
25546 ///
25547 /// @param vis the visibility of instances of @ref union_decl.
25548 ///
25549 /// @param mbr_types the member types of the union.
25550 ///
25551 /// @param data_mbrs the data members of the union.
25552 ///
25553 /// @param member_fns the member functions of the union.
25554 ///
25555 /// @param is_anonymous whether the newly created instance is
25556 /// 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)25557 union_decl::union_decl(const environment& env, const string& name,
25558 size_t size_in_bits, const location& locus,
25559 visibility vis, member_types& mbr_types,
25560 data_members& data_mbrs, member_functions& member_fns,
25561 bool is_anonymous)
25562 : type_or_decl_base(env,
25563 UNION_TYPE
25564 | ABSTRACT_TYPE_BASE
25565 | ABSTRACT_DECL_BASE),
25566 decl_base(env, name, locus,
25567 // If the class is anonymous then by default it won't
25568 // have a linkage name. Also, the anonymous class does
25569 // have an internal-only unique name that is generally
25570 // not taken into account when comparing classes; such a
25571 // unique internal-only name, when used as a linkage
25572 // name might introduce spurious comparison false
25573 // negatives.
25574 /*linkage_name=*/is_anonymous ? string() : name,
25575 vis),
25576 type_base(env, size_in_bits, 0),
25577 class_or_union(env, name, size_in_bits, 0,
25578 locus, vis, mbr_types, data_mbrs, member_fns)
25579 {
25580 runtime_type_instance(this);
25581 set_is_anonymous(is_anonymous);
25582 }
25583
25584 /// Constructor for the @ref union_decl type.
25585 ///
25586 /// @param env the @ref environment we are operating from.
25587 ///
25588 /// @param name the name of the union type.
25589 ///
25590 /// @param size_in_bits the size of the union, in bits.
25591 ///
25592 /// @param locus the location of the type.
25593 ///
25594 /// @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)25595 union_decl::union_decl(const environment& env, const string& name,
25596 size_t size_in_bits, const location& locus,
25597 visibility vis)
25598 : type_or_decl_base(env,
25599 UNION_TYPE
25600 | ABSTRACT_TYPE_BASE
25601 | ABSTRACT_DECL_BASE
25602 | ABSTRACT_SCOPE_TYPE_DECL
25603 | ABSTRACT_SCOPE_DECL),
25604 decl_base(env, name, locus, name, vis),
25605 type_base(env, size_in_bits, 0),
25606 class_or_union(env, name, size_in_bits,
25607 0, locus, vis)
25608 {
25609 runtime_type_instance(this);
25610 }
25611
25612 /// Constructor for the @ref union_decl type.
25613 ///
25614 /// @param env the @ref environment we are operating from.
25615 ///
25616 /// @param name the name of the union type.
25617 ///
25618 /// @param size_in_bits the size of the union, in bits.
25619 ///
25620 /// @param locus the location of the type.
25621 ///
25622 /// @param vis the visibility of instances of @ref union_decl.
25623 ///
25624 /// @param is_anonymous whether the newly created instance is
25625 /// anonymous.
union_decl(const environment & env,const string & name,size_t size_in_bits,const location & locus,visibility vis,bool is_anonymous)25626 union_decl::union_decl(const environment& env, const string& name,
25627 size_t size_in_bits, const location& locus,
25628 visibility vis, bool is_anonymous)
25629 : type_or_decl_base(env,
25630 UNION_TYPE
25631 | ABSTRACT_TYPE_BASE
25632 | ABSTRACT_DECL_BASE
25633 | ABSTRACT_SCOPE_TYPE_DECL
25634 | ABSTRACT_SCOPE_DECL),
25635 decl_base(env, name, locus,
25636 // If the class is anonymous then by default it won't
25637 // have a linkage name. Also, the anonymous class does
25638 // have an internal-only unique name that is generally
25639 // not taken into account when comparing classes; such a
25640 // unique internal-only name, when used as a linkage
25641 // name might introduce spurious comparison false
25642 // negatives.
25643 /*linkage_name=*/is_anonymous ? string() : name,
25644 vis),
25645 type_base(env, size_in_bits, 0),
25646 class_or_union(env, name, size_in_bits,
25647 0, locus, vis)
25648 {
25649 runtime_type_instance(this);
25650 set_is_anonymous(is_anonymous);
25651 }
25652
25653 /// Constructor for the @ref union_decl type.
25654 ///
25655 /// @param env the @ref environment we are operating from.
25656 ///
25657 /// @param name the name of the union type.
25658 ///
25659 /// @param is_declaration_only a boolean saying whether the instance
25660 /// represents a declaration only, or not.
union_decl(const environment & env,const string & name,bool is_declaration_only)25661 union_decl::union_decl(const environment& env,
25662 const string& name,
25663 bool is_declaration_only)
25664 : type_or_decl_base(env,
25665 UNION_TYPE
25666 | ABSTRACT_TYPE_BASE
25667 | ABSTRACT_DECL_BASE
25668 | ABSTRACT_SCOPE_TYPE_DECL
25669 | ABSTRACT_SCOPE_DECL),
25670 decl_base(env, name, location(), name),
25671 type_base(env, 0, 0),
25672 class_or_union(env, name, is_declaration_only)
25673 {
25674 runtime_type_instance(this);
25675 }
25676
25677 /// Getter of the pretty representation of the current instance of
25678 /// @ref union_decl.
25679 ///
25680 /// @param internal set to true if the call is intended to get a
25681 /// representation of the decl (or type) for the purpose of canonical
25682 /// type comparison. This is mainly used in the function
25683 /// type_base::get_canonical_type_for().
25684 ///
25685 /// In other words if the argument for this parameter is true then the
25686 /// call is meant for internal use (for technical use inside the
25687 /// library itself), false otherwise. If you don't know what this is
25688 /// for, then set it to false.
25689 ///
25690 /// @param qualified_name if true, names emitted in the pretty
25691 /// representation are fully qualified.
25692 ///
25693 /// @return the pretty representaion for a union_decl.
25694 string
get_pretty_representation(bool internal,bool qualified_name) const25695 union_decl::get_pretty_representation(bool internal,
25696 bool qualified_name) const
25697 {
25698 string repr;
25699 if (get_is_anonymous())
25700 {
25701 if (internal && !get_name().empty())
25702 repr = string("union ") +
25703 get_type_name(this, qualified_name, /*internal=*/true);
25704 else
25705 repr = get_class_or_union_flat_representation(this, "",
25706 /*one_line=*/true,
25707 internal);
25708 }
25709 else
25710 {
25711 repr = "union ";
25712 if (qualified_name)
25713 repr += get_qualified_name(internal);
25714 else
25715 repr += get_name();
25716 }
25717
25718 return repr;
25719 }
25720
25721 /// Comparison operator for @ref union_decl.
25722 ///
25723 /// @param other the instance of @ref union_decl to compare against.
25724 ///
25725 /// @return true iff the current instance of @ref union_decl equals @p
25726 /// other.
25727 bool
operator ==(const decl_base & other) const25728 union_decl::operator==(const decl_base& other) const
25729 {
25730 const union_decl* op = dynamic_cast<const union_decl*>(&other);
25731 if (!op)
25732 return false;
25733 return try_canonical_compare(this, op);
25734 }
25735
25736 /// Equality operator for union_decl.
25737 ///
25738 /// Re-uses the equality operator that takes a decl_base.
25739 ///
25740 /// @param other the other union_decl to compare against.
25741 ///
25742 /// @return true iff the current instance equals the other one.
25743 bool
operator ==(const type_base & other) const25744 union_decl::operator==(const type_base& other) const
25745 {
25746 const decl_base *o = dynamic_cast<const decl_base*>(&other);
25747 if (!o)
25748 return false;
25749 return *this == *o;
25750 }
25751
25752 /// Equality operator for union_decl.
25753 ///
25754 /// Re-uses the equality operator that takes a decl_base.
25755 ///
25756 /// @param other the other union_decl to compare against.
25757 ///
25758 /// @return true iff the current instance equals the other one.
25759 bool
operator ==(const class_or_union & other) const25760 union_decl::operator==(const class_or_union&other) const
25761 {
25762 const decl_base *o = dynamic_cast<const decl_base*>(&other);
25763 return *this == *o;
25764 }
25765
25766 /// Comparison operator for @ref union_decl.
25767 ///
25768 /// @param other the instance of @ref union_decl to compare against.
25769 ///
25770 /// @return true iff the current instance of @ref union_decl equals @p
25771 /// other.
25772 bool
operator ==(const union_decl & other) const25773 union_decl::operator==(const union_decl& other) const
25774 {
25775 const decl_base& o = other;
25776 return *this == o;
25777 }
25778
25779 /// This implements the ir_traversable_base::traverse pure virtual
25780 /// function.
25781 ///
25782 /// @param v the visitor used on the current instance and on its
25783 /// members.
25784 ///
25785 /// @return true if the entire IR node tree got traversed, false
25786 /// otherwise.
25787 bool
traverse(ir_node_visitor & v)25788 union_decl::traverse(ir_node_visitor& v)
25789 {
25790 if (v.type_node_has_been_visited(this))
25791 return true;
25792
25793 if (visiting())
25794 return true;
25795
25796 if (v.visit_begin(this))
25797 {
25798 visiting(true);
25799 bool stop = false;
25800
25801 if (!stop)
25802 for (data_members::const_iterator i = get_data_members().begin();
25803 i != get_data_members().end();
25804 ++i)
25805 if (!(*i)->traverse(v))
25806 {
25807 stop = true;
25808 break;
25809 }
25810
25811 if (!stop)
25812 for (member_functions::const_iterator i= get_member_functions().begin();
25813 i != get_member_functions().end();
25814 ++i)
25815 if (!(*i)->traverse(v))
25816 {
25817 stop = true;
25818 break;
25819 }
25820
25821 if (!stop)
25822 for (member_types::const_iterator i = get_member_types().begin();
25823 i != get_member_types().end();
25824 ++i)
25825 if (!(*i)->traverse(v))
25826 {
25827 stop = true;
25828 break;
25829 }
25830
25831 if (!stop)
25832 for (member_function_templates::const_iterator i =
25833 get_member_function_templates().begin();
25834 i != get_member_function_templates().end();
25835 ++i)
25836 if (!(*i)->traverse(v))
25837 {
25838 stop = true;
25839 break;
25840 }
25841
25842 if (!stop)
25843 for (member_class_templates::const_iterator i =
25844 get_member_class_templates().begin();
25845 i != get_member_class_templates().end();
25846 ++i)
25847 if (!(*i)->traverse(v))
25848 {
25849 stop = true;
25850 break;
25851 }
25852 visiting(false);
25853 }
25854
25855 bool result = v.visit_end(this);
25856 v.mark_type_node_as_visited(this);
25857 return result;
25858 }
25859
25860 /// Destructor of the @ref union_decl type.
~union_decl()25861 union_decl::~union_decl()
25862 {}
25863
25864 /// Compares two instances of @ref union_decl.
25865 ///
25866 /// If the two intances are different, set a bitfield to give some
25867 /// insight about the kind of differences there are.
25868 ///
25869 /// @param l the first artifact of the comparison.
25870 ///
25871 /// @param r the second artifact of the comparison.
25872 ///
25873 /// @param k a pointer to a bitfield that gives information about the
25874 /// kind of changes there are between @p l and @p r. This one is set
25875 /// iff @p k is non-null and the function returns false.
25876 ///
25877 /// Please note that setting k to a non-null value does have a
25878 /// negative performance impact because even if @p l and @p r are not
25879 /// equal, the function keeps up the comparison in order to determine
25880 /// the different kinds of ways in which they are different.
25881 ///
25882 /// @return true if @p l equals @p r, false otherwise.
25883 bool
equals(const union_decl & l,const union_decl & r,change_kind * k)25884 equals(const union_decl& l, const union_decl& r, change_kind* k)
25885 {
25886
25887 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
25888
25889 {
25890 // First of all, let's see if these two types haven't already been
25891 // compared. If so, and if the result of the comparison has been
25892 // cached, let's just re-use it, rather than comparing them all
25893 // over again.
25894 bool result = false;
25895 if (l.get_environment().priv_->is_type_comparison_cached(l, r, result))
25896 ABG_RETURN(result);
25897 }
25898
25899 bool result = equals(static_cast<const class_or_union&>(l),
25900 static_cast<const class_or_union&>(r),
25901 k);
25902
25903 CACHE_COMPARISON_RESULT_AND_RETURN(result);
25904 }
25905
25906 /// Copy a method of a @ref union_decl into a new @ref
25907 /// union_decl.
25908 ///
25909 /// @param t the @ref union_decl into which the method is to be copied.
25910 ///
25911 /// @param method the method to copy into @p t.
25912 ///
25913 /// @return the resulting newly copied method.
25914 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl_sptr & f)25915 copy_member_function(const union_decl_sptr& union_type,
25916 const method_decl_sptr& f)
25917 {return copy_member_function(union_type, f.get());}
25918
25919 /// Copy a method of a @ref union_decl into a new @ref
25920 /// union_decl.
25921 ///
25922 /// @param t the @ref union_decl into which the method is to be copied.
25923 ///
25924 /// @param method the method to copy into @p t.
25925 ///
25926 /// @return the resulting newly copied method.
25927 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl * f)25928 copy_member_function(const union_decl_sptr& union_type,
25929 const method_decl* f)
25930 {
25931 const class_or_union_sptr t = union_type;
25932 return copy_member_function(t, f);
25933 }
25934
25935 /// Turn equality of shared_ptr of union_decl into a deep equality;
25936 /// that is, make it compare the pointed to objects too.
25937 ///
25938 /// @param l the left-hand-side operand of the operator
25939 ///
25940 /// @param r the right-hand-side operand of the operator.
25941 ///
25942 /// @return true iff @p l equals @p r.
25943 bool
operator ==(const union_decl_sptr & l,const union_decl_sptr & r)25944 operator==(const union_decl_sptr& l, const union_decl_sptr& r)
25945 {
25946 if (l.get() == r.get())
25947 return true;
25948 if (!!l != !!r)
25949 return false;
25950
25951 return *l == *r;
25952 }
25953
25954 /// Turn inequality of shared_ptr of union_decl into a deep equality;
25955 /// that is, make it compare the pointed to objects too.
25956 ///
25957 /// @param l the left-hand-side operand of the operator
25958 ///
25959 /// @param r the right-hand-side operand of the operator.
25960 ///
25961 /// @return true iff @p l is different from @p r.
25962 bool
operator !=(const union_decl_sptr & l,const union_decl_sptr & r)25963 operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
25964 {return !operator==(l, r);}
25965 // </union_decl>
25966
25967 // <template_decl stuff>
25968
25969 /// Data type of the private data of the @template_decl type.
25970 class template_decl::priv
25971 {
25972 friend class template_decl;
25973
25974 std::list<template_parameter_sptr> parms_;
25975 public:
25976
priv()25977 priv()
25978 {}
25979 }; // end class template_decl::priv
25980
25981 /// Add a new template parameter to the current instance of @ref
25982 /// template_decl.
25983 ///
25984 /// @param p the new template parameter to add.
25985 void
add_template_parameter(const template_parameter_sptr p)25986 template_decl::add_template_parameter(const template_parameter_sptr p)
25987 {priv_->parms_.push_back(p);}
25988
25989 /// Get the list of template parameters of the current instance of
25990 /// @ref template_decl.
25991 ///
25992 /// @return the list of template parameters.
25993 const std::list<template_parameter_sptr>&
get_template_parameters() const25994 template_decl::get_template_parameters() const
25995 {return priv_->parms_;}
25996
25997 /// Constructor.
25998 ///
25999 /// @param env the environment we are operating from.
26000 ///
26001 /// @param name the name of the template decl.
26002 ///
26003 /// @param locus the source location where the template declaration is
26004 /// defined.
26005 ///
26006 /// @param vis the visibility of the template declaration.
template_decl(const environment & env,const string & name,const location & locus,visibility vis)26007 template_decl::template_decl(const environment& env,
26008 const string& name,
26009 const location& locus,
26010 visibility vis)
26011 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
26012 decl_base(env, name, locus, /*mangled_name=*/"", vis),
26013 priv_(new priv)
26014 {
26015 runtime_type_instance(this);
26016 }
26017
26018 /// Destructor.
~template_decl()26019 template_decl::~template_decl()
26020 {}
26021
26022 /// Equality operator.
26023 ///
26024 /// @param o the other instance to compare against.
26025 ///
26026 /// @return true iff @p equals the current instance.
26027 bool
operator ==(const decl_base & o) const26028 template_decl::operator==(const decl_base& o) const
26029 {
26030 const template_decl* other = dynamic_cast<const template_decl*>(&o);
26031 if (!other)
26032 return false;
26033 return *this == *other;
26034 }
26035
26036 /// Equality operator.
26037 ///
26038 /// @param o the other instance to compare against.
26039 ///
26040 /// @return true iff @p equals the current instance.
26041 bool
operator ==(const template_decl & o) const26042 template_decl::operator==(const template_decl& o) const
26043 {
26044 try
26045 {
26046 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
26047 for (t0 = get_template_parameters().begin(),
26048 t1 = o.get_template_parameters().begin();
26049 (t0 != get_template_parameters().end()
26050 && t1 != o.get_template_parameters().end());
26051 ++t0, ++t1)
26052 {
26053 if (**t0 != **t1)
26054 return false;
26055 }
26056
26057 if (t0 != get_template_parameters().end()
26058 || t1 != o.get_template_parameters().end())
26059 return false;
26060
26061 return true;
26062 }
26063 catch(...)
26064 {return false;}
26065 }
26066
26067 // </template_decl stuff>
26068
26069 //<template_parameter>
26070
26071 /// The type of the private data of the @ref template_parameter type.
26072 class template_parameter::priv
26073 {
26074 friend class template_parameter;
26075
26076 unsigned index_;
26077 template_decl_wptr template_decl_;
26078 mutable bool hashing_started_;
26079 mutable bool comparison_started_;
26080
26081 priv();
26082
26083 public:
26084
priv(unsigned index,template_decl_sptr enclosing_template_decl)26085 priv(unsigned index, template_decl_sptr enclosing_template_decl)
26086 : index_(index),
26087 template_decl_(enclosing_template_decl),
26088 hashing_started_(),
26089 comparison_started_()
26090 {}
26091 }; // end class template_parameter::priv
26092
template_parameter(unsigned index,template_decl_sptr enclosing_template)26093 template_parameter::template_parameter(unsigned index,
26094 template_decl_sptr enclosing_template)
26095 : priv_(new priv(index, enclosing_template))
26096 {}
26097
26098 unsigned
get_index() const26099 template_parameter::get_index() const
26100 {return priv_->index_;}
26101
26102 const template_decl_sptr
get_enclosing_template_decl() const26103 template_parameter::get_enclosing_template_decl() const
26104 {return priv_->template_decl_.lock();}
26105
26106 bool
get_hashing_has_started() const26107 template_parameter::get_hashing_has_started() const
26108 {return priv_->hashing_started_;}
26109
26110 void
set_hashing_has_started(bool f) const26111 template_parameter::set_hashing_has_started(bool f) const
26112 {priv_->hashing_started_ = f;}
26113
26114 bool
operator ==(const template_parameter & o) const26115 template_parameter::operator==(const template_parameter& o) const
26116 {
26117 if (get_index() != o.get_index())
26118 return false;
26119
26120 if (priv_->comparison_started_)
26121 return true;
26122
26123 bool result = false;
26124
26125 // Avoid inifite loops due to the fact that comparison the enclosing
26126 // template decl might lead to comparing this very same template
26127 // parameter with another one ...
26128 priv_->comparison_started_ = true;
26129
26130 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
26131 ;
26132 else if (get_enclosing_template_decl()
26133 && (*get_enclosing_template_decl()
26134 != *o.get_enclosing_template_decl()))
26135 ;
26136 else
26137 result = true;
26138
26139 priv_->comparison_started_ = false;
26140
26141 return result;
26142 }
26143
26144 /// Inequality operator.
26145 ///
26146 /// @param other the other instance to compare against.
26147 ///
26148 /// @return true iff the other instance is different from the current
26149 /// one.
26150 bool
operator !=(const template_parameter & other) const26151 template_parameter::operator!=(const template_parameter& other) const
26152 {return !operator==(other);}
26153
26154 /// Destructor.
~template_parameter()26155 template_parameter::~template_parameter()
26156 {}
26157
26158 /// The type of the private data of the @ref type_tparameter type.
26159 class type_tparameter::priv
26160 {
26161 friend class type_tparameter;
26162 }; // end class type_tparameter::priv
26163
26164 /// Constructor of the @ref type_tparameter type.
26165 ///
26166 /// @param index the index the type template parameter.
26167 ///
26168 /// @param enclosing_tdecl the enclosing template declaration.
26169 ///
26170 /// @param name the name of the template parameter.
26171 ///
26172 /// @param locus the location of the declaration of this type template
26173 /// parameter.
type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)26174 type_tparameter::type_tparameter(unsigned index,
26175 template_decl_sptr enclosing_tdecl,
26176 const string& name,
26177 const location& locus)
26178 : type_or_decl_base(enclosing_tdecl->get_environment(),
26179 ABSTRACT_DECL_BASE
26180 | ABSTRACT_TYPE_BASE
26181 | BASIC_TYPE),
26182 decl_base(enclosing_tdecl->get_environment(), name, locus),
26183 type_base(enclosing_tdecl->get_environment(), 0, 0),
26184 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
26185 template_parameter(index, enclosing_tdecl),
26186 priv_(new priv)
26187 {
26188 runtime_type_instance(this);
26189 }
26190
26191 /// Equality operator.
26192 ///
26193 /// @param other the other template type parameter to compare against.
26194 ///
26195 /// @return true iff @p other equals the current instance.
26196 bool
operator ==(const type_base & other) const26197 type_tparameter::operator==(const type_base& other) const
26198 {
26199 if (!type_decl::operator==(other))
26200 return false;
26201
26202 try
26203 {
26204 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26205 return template_parameter::operator==(o);
26206 }
26207 catch (...)
26208 {return false;}
26209 }
26210
26211 /// Equality operator.
26212 ///
26213 /// @param other the other template type parameter to compare against.
26214 ///
26215 /// @return true iff @p other equals the current instance.
26216 bool
operator ==(const type_decl & other) const26217 type_tparameter::operator==(const type_decl& other) const
26218 {
26219 if (!type_decl::operator==(other))
26220 return false;
26221
26222 try
26223 {
26224 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26225 return template_parameter::operator==(o);
26226 }
26227 catch (...)
26228 {return false;}
26229 }
26230
26231 /// Equality operator.
26232 ///
26233 /// @param other the other template type parameter to compare against.
26234 ///
26235 /// @return true iff @p other equals the current instance.
26236 bool
operator ==(const decl_base & other) const26237 type_tparameter::operator==(const decl_base& other) const
26238 {
26239 if (!decl_base::operator==(other))
26240 return false;
26241
26242 try
26243 {
26244 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
26245 return template_parameter::operator==(o);
26246 }
26247 catch (...)
26248 {return false;}
26249 }
26250
26251 /// Equality operator.
26252 ///
26253 /// @param other the other template type parameter to compare against.
26254 ///
26255 /// @return true iff @p other equals the current instance.
26256 bool
operator ==(const template_parameter & other) const26257 type_tparameter::operator==(const template_parameter& other) const
26258 {
26259 try
26260 {
26261 const type_base& o = dynamic_cast<const type_base&>(other);
26262 return *this == o;
26263 }
26264 catch(...)
26265 {return false;}
26266 }
26267
26268 /// Equality operator.
26269 ///
26270 /// @param other the other template type parameter to compare against.
26271 ///
26272 /// @return true iff @p other equals the current instance.
26273 bool
operator ==(const type_tparameter & other) const26274 type_tparameter::operator==(const type_tparameter& other) const
26275 {return *this == static_cast<const type_base&>(other);}
26276
~type_tparameter()26277 type_tparameter::~type_tparameter()
26278 {}
26279
26280 /// The type of the private data of the @ref non_type_tparameter type.
26281 class non_type_tparameter::priv
26282 {
26283 friend class non_type_tparameter;
26284
26285 type_base_wptr type_;
26286
26287 priv();
26288
26289 public:
26290
priv(type_base_sptr type)26291 priv(type_base_sptr type)
26292 : type_(type)
26293 {}
26294 }; // end class non_type_tparameter::priv
26295
26296 /// The constructor for the @ref non_type_tparameter type.
26297 ///
26298 /// @param index the index of the template parameter.
26299 ///
26300 /// @param enclosing_tdecl the enclosing template declaration that
26301 /// holds this parameter parameter.
26302 ///
26303 /// @param name the name of the template parameter.
26304 ///
26305 /// @param type the type of the template parameter.
26306 ///
26307 /// @param locus the location of the declaration of this template
26308 /// parameter.
non_type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,type_base_sptr type,const location & locus)26309 non_type_tparameter::non_type_tparameter(unsigned index,
26310 template_decl_sptr enclosing_tdecl,
26311 const string& name,
26312 type_base_sptr type,
26313 const location& locus)
26314 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
26315 decl_base(type->get_environment(), name, locus, ""),
26316 template_parameter(index, enclosing_tdecl),
26317 priv_(new priv(type))
26318 {
26319 runtime_type_instance(this);
26320 }
26321
26322 /// Getter for the type of the template parameter.
26323 ///
26324 /// @return the type of the template parameter.
26325 const type_base_sptr
get_type() const26326 non_type_tparameter::get_type() const
26327 {return priv_->type_.lock();}
26328
26329 /// Get the hash value of the current instance.
26330 ///
26331 /// @return the hash value.
26332 size_t
get_hash() const26333 non_type_tparameter::get_hash() const
26334 {
26335 non_type_tparameter::hash hash_tparm;
26336 return hash_tparm(this);
26337 }
26338
26339 bool
operator ==(const decl_base & other) const26340 non_type_tparameter::operator==(const decl_base& other) const
26341 {
26342 if (!decl_base::operator==(other))
26343 return false;
26344
26345 try
26346 {
26347 const non_type_tparameter& o =
26348 dynamic_cast<const non_type_tparameter&>(other);
26349 return (template_parameter::operator==(o)
26350 && get_type() == o.get_type());
26351 }
26352 catch(...)
26353 {return false;}
26354 }
26355
26356 bool
operator ==(const template_parameter & other) const26357 non_type_tparameter::operator==(const template_parameter& other) const
26358 {
26359 try
26360 {
26361 const decl_base& o = dynamic_cast<const decl_base&>(other);
26362 return *this == o;
26363 }
26364 catch(...)
26365 {return false;}
26366 }
26367
~non_type_tparameter()26368 non_type_tparameter::~non_type_tparameter()
26369 {}
26370
26371 // <template_tparameter stuff>
26372
26373 /// Type of the private data of the @ref template_tparameter type.
26374 class template_tparameter::priv
26375 {
26376 }; //end class template_tparameter::priv
26377
26378 /// Constructor for the @ref template_tparameter.
26379 ///
26380 /// @param index the index of the template parameter.
26381 ///
26382 /// @param enclosing_tdecl the enclosing template declaration.
26383 ///
26384 /// @param name the name of the template parameter.
26385 ///
26386 /// @param locus the location of the declaration of the template
26387 /// parameter.
template_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)26388 template_tparameter::template_tparameter(unsigned index,
26389 template_decl_sptr enclosing_tdecl,
26390 const string& name,
26391 const location& locus)
26392 : type_or_decl_base(enclosing_tdecl->get_environment(),
26393 ABSTRACT_DECL_BASE
26394 | ABSTRACT_TYPE_BASE
26395 | BASIC_TYPE),
26396 decl_base(enclosing_tdecl->get_environment(), name, locus),
26397 type_base(enclosing_tdecl->get_environment(), 0, 0),
26398 type_decl(enclosing_tdecl->get_environment(), name,
26399 0, 0, locus, name, VISIBILITY_DEFAULT),
26400 type_tparameter(index, enclosing_tdecl, name, locus),
26401 template_decl(enclosing_tdecl->get_environment(), name, locus),
26402 priv_(new priv)
26403 {
26404 runtime_type_instance(this);
26405 }
26406
26407 /// Equality operator.
26408 ///
26409 /// @param other the other template parameter to compare against.
26410 ///
26411 /// @return true iff @p other equals the current instance.
26412 bool
operator ==(const type_base & other) const26413 template_tparameter::operator==(const type_base& other) const
26414 {
26415 try
26416 {
26417 const template_tparameter& o =
26418 dynamic_cast<const template_tparameter&>(other);
26419 return (type_tparameter::operator==(o)
26420 && template_decl::operator==(o));
26421 }
26422 catch(...)
26423 {return false;}
26424 }
26425
26426 /// Equality operator.
26427 ///
26428 /// @param other the other template parameter to compare against.
26429 ///
26430 /// @return true iff @p other equals the current instance.
26431 bool
operator ==(const decl_base & other) const26432 template_tparameter::operator==(const decl_base& other) const
26433 {
26434 try
26435 {
26436 const template_tparameter& o =
26437 dynamic_cast<const template_tparameter&>(other);
26438 return (type_tparameter::operator==(o)
26439 && template_decl::operator==(o));
26440 }
26441 catch(...)
26442 {return false;}
26443 }
26444
26445 bool
operator ==(const template_parameter & o) const26446 template_tparameter::operator==(const template_parameter& o) const
26447 {
26448 try
26449 {
26450 const template_tparameter& other =
26451 dynamic_cast<const template_tparameter&>(o);
26452 return *this == static_cast<const type_base&>(other);
26453 }
26454 catch(...)
26455 {return false;}
26456 }
26457
26458 bool
operator ==(const template_decl & o) const26459 template_tparameter::operator==(const template_decl& o) const
26460 {
26461 try
26462 {
26463 const template_tparameter& other =
26464 dynamic_cast<const template_tparameter&>(o);
26465 return type_base::operator==(other);
26466 }
26467 catch(...)
26468 {return false;}
26469 }
26470
~template_tparameter()26471 template_tparameter::~template_tparameter()
26472 {}
26473
26474 // </template_tparameter stuff>
26475
26476 // <type_composition stuff>
26477
26478 /// The type of the private data of the @ref type_composition type.
26479 class type_composition::priv
26480 {
26481 friend class type_composition;
26482
26483 type_base_wptr type_;
26484
26485 // Forbid this.
26486 priv();
26487
26488 public:
26489
priv(type_base_wptr type)26490 priv(type_base_wptr type)
26491 : type_(type)
26492 {}
26493 }; //end class type_composition::priv
26494
26495 /// Constructor for the @ref type_composition type.
26496 ///
26497 /// @param index the index of the template type composition.
26498 ///
26499 /// @param tdecl the enclosing template parameter that owns the
26500 /// composition.
26501 ///
26502 /// @param t the resulting type.
type_composition(unsigned index,template_decl_sptr tdecl,type_base_sptr t)26503 type_composition::type_composition(unsigned index,
26504 template_decl_sptr tdecl,
26505 type_base_sptr t)
26506 : type_or_decl_base(tdecl->get_environment(),
26507 ABSTRACT_DECL_BASE),
26508 decl_base(tdecl->get_environment(), "", location()),
26509 template_parameter(index, tdecl),
26510 priv_(new priv(t))
26511 {
26512 runtime_type_instance(this);
26513 }
26514
26515 /// Getter for the resulting composed type.
26516 ///
26517 /// @return the composed type.
26518 const type_base_sptr
get_composed_type() const26519 type_composition::get_composed_type() const
26520 {return priv_->type_.lock();}
26521
26522 /// Setter for the resulting composed type.
26523 ///
26524 /// @param t the composed type.
26525 void
set_composed_type(type_base_sptr t)26526 type_composition::set_composed_type(type_base_sptr t)
26527 {priv_->type_ = t;}
26528
26529 /// Get the hash value for the current instance.
26530 ///
26531 /// @return the hash value.
26532 size_t
get_hash() const26533 type_composition::get_hash() const
26534 {
26535 type_composition::hash hash_type_composition;
26536 return hash_type_composition(this);
26537 }
26538
~type_composition()26539 type_composition::~type_composition()
26540 {}
26541
26542 // </type_composition stuff>
26543
26544 //</template_parameter stuff>
26545
26546 // <function_template>
26547
26548 class function_tdecl::priv
26549 {
26550 friend class function_tdecl;
26551
26552 function_decl_sptr pattern_;
26553 binding binding_;
26554
26555 priv();
26556
26557 public:
26558
priv(function_decl_sptr pattern,binding bind)26559 priv(function_decl_sptr pattern, binding bind)
26560 : pattern_(pattern), binding_(bind)
26561 {}
26562
priv(binding bind)26563 priv(binding bind)
26564 : binding_(bind)
26565 {}
26566 }; // end class function_tdecl::priv
26567
26568 /// Constructor for a function template declaration.
26569 ///
26570 /// @param env the environment we are operating from.
26571 ///
26572 /// @param locus the location of the declaration.
26573 ///
26574 /// @param vis the visibility of the declaration. This is the
26575 /// visibility the functions instantiated from this template are going
26576 /// to have.
26577 ///
26578 /// @param bind the binding of the declaration. This is the binding
26579 /// the functions instantiated from this template are going to have.
function_tdecl(const environment & env,const location & locus,visibility vis,binding bind)26580 function_tdecl::function_tdecl(const environment& env,
26581 const location& locus,
26582 visibility vis,
26583 binding bind)
26584 : type_or_decl_base(env,
26585 ABSTRACT_DECL_BASE
26586 | TEMPLATE_DECL
26587 | ABSTRACT_SCOPE_DECL),
26588 decl_base(env, "", locus, "", vis),
26589 template_decl(env, "", locus, vis),
26590 scope_decl(env, "", locus),
26591 priv_(new priv(bind))
26592 {
26593 runtime_type_instance(this);
26594 }
26595
26596 /// Constructor for a function template declaration.
26597 ///
26598 /// @param pattern the pattern of the template.
26599 ///
26600 /// @param locus the location of the declaration.
26601 ///
26602 /// @param vis the visibility of the declaration. This is the
26603 /// visibility the functions instantiated from this template are going
26604 /// to have.
26605 ///
26606 /// @param bind the binding of the declaration. This is the binding
26607 /// the functions instantiated from this template are going to have.
function_tdecl(function_decl_sptr pattern,const location & locus,visibility vis,binding bind)26608 function_tdecl::function_tdecl(function_decl_sptr pattern,
26609 const location& locus,
26610 visibility vis,
26611 binding bind)
26612 : type_or_decl_base(pattern->get_environment(),
26613 ABSTRACT_DECL_BASE
26614 | TEMPLATE_DECL
26615 | ABSTRACT_SCOPE_DECL),
26616 decl_base(pattern->get_environment(), pattern->get_name(), locus,
26617 pattern->get_name(), vis),
26618 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
26619 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
26620 priv_(new priv(pattern, bind))
26621 {
26622 runtime_type_instance(this);
26623 }
26624
26625 /// Set a new pattern to the function template.
26626 ///
26627 /// @param p the new pattern.
26628 void
set_pattern(function_decl_sptr p)26629 function_tdecl::set_pattern(function_decl_sptr p)
26630 {
26631 priv_->pattern_ = p;
26632 add_decl_to_scope(p, this);
26633 set_name(p->get_name());
26634 }
26635
26636 /// Get the pattern of the function template.
26637 ///
26638 /// @return the pattern.
26639 function_decl_sptr
get_pattern() const26640 function_tdecl::get_pattern() const
26641 {return priv_->pattern_;}
26642
26643 /// Get the binding of the function template.
26644 ///
26645 /// @return the binding
26646 decl_base::binding
get_binding() const26647 function_tdecl::get_binding() const
26648 {return priv_->binding_;}
26649
26650 /// Comparison operator for the @ref function_tdecl type.
26651 ///
26652 /// @param other the other instance of @ref function_tdecl to compare against.
26653 ///
26654 /// @return true iff the two instance are equal.
26655 bool
operator ==(const decl_base & other) const26656 function_tdecl::operator==(const decl_base& other) const
26657 {
26658 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
26659 if (o)
26660 return *this == *o;
26661 return false;
26662 }
26663
26664 /// Comparison operator for the @ref function_tdecl type.
26665 ///
26666 /// @param other the other instance of @ref function_tdecl to compare against.
26667 ///
26668 /// @return true iff the two instance are equal.
26669 bool
operator ==(const template_decl & other) const26670 function_tdecl::operator==(const template_decl& other) const
26671 {
26672 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
26673 if (o)
26674 return *this == *o;
26675 return false;
26676 }
26677
26678 /// Comparison operator for the @ref function_tdecl type.
26679 ///
26680 /// @param o the other instance of @ref function_tdecl to compare against.
26681 ///
26682 /// @return true iff the two instance are equal.
26683 bool
operator ==(const function_tdecl & o) const26684 function_tdecl::operator==(const function_tdecl& o) const
26685 {
26686 if (!(get_binding() == o.get_binding()
26687 && template_decl::operator==(o)
26688 && scope_decl::operator==(o)
26689 && !!get_pattern() == !!o.get_pattern()))
26690 return false;
26691
26692 if (get_pattern())
26693 return (*get_pattern() == *o.get_pattern());
26694
26695 return true;
26696 }
26697
26698 /// This implements the ir_traversable_base::traverse pure virtual
26699 /// function.
26700 ///
26701 /// @param v the visitor used on the current instance and on the
26702 /// function pattern of the template.
26703 ///
26704 /// @return true if the entire IR node tree got traversed, false
26705 /// otherwise.
26706 bool
traverse(ir_node_visitor & v)26707 function_tdecl::traverse(ir_node_visitor&v)
26708 {
26709 if (visiting())
26710 return true;
26711
26712 if (!v.visit_begin(this))
26713 {
26714 visiting(true);
26715 if (get_pattern())
26716 get_pattern()->traverse(v);
26717 visiting(false);
26718 }
26719 return v.visit_end(this);
26720 }
26721
~function_tdecl()26722 function_tdecl::~function_tdecl()
26723 {}
26724
26725 // </function_template>
26726
26727 // <class template>
26728
26729 /// Type of the private data of the the @ref class_tdecl type.
26730 class class_tdecl::priv
26731 {
26732 friend class class_tdecl;
26733 class_decl_sptr pattern_;
26734
26735 public:
26736
priv()26737 priv()
26738 {}
26739
priv(class_decl_sptr pattern)26740 priv(class_decl_sptr pattern)
26741 : pattern_(pattern)
26742 {}
26743 }; // end class class_tdecl::priv
26744
26745 /// Constructor for the @ref class_tdecl type.
26746 ///
26747 /// @param env the environment we are operating from.
26748 ///
26749 /// @param locus the location of the declaration of the class_tdecl
26750 /// type.
26751 ///
26752 /// @param vis the visibility of the instance of class instantiated
26753 /// from this template.
class_tdecl(const environment & env,const location & locus,visibility vis)26754 class_tdecl::class_tdecl(const environment& env,
26755 const location& locus,
26756 visibility vis)
26757 : type_or_decl_base(env,
26758 ABSTRACT_DECL_BASE
26759 | TEMPLATE_DECL
26760 | ABSTRACT_SCOPE_DECL),
26761 decl_base(env, "", locus, "", vis),
26762 template_decl(env, "", locus, vis),
26763 scope_decl(env, "", locus),
26764 priv_(new priv)
26765 {
26766 runtime_type_instance(this);
26767 }
26768
26769 /// Constructor for the @ref class_tdecl type.
26770 ///
26771 /// @param pattern The details of the class template. This must NOT be a
26772 /// null pointer. If you really this to be null, please use the
26773 /// constructor above instead.
26774 ///
26775 /// @param locus the source location of the declaration of the type.
26776 ///
26777 /// @param vis the visibility of the instances of class instantiated
26778 /// from this template.
class_tdecl(class_decl_sptr pattern,const location & locus,visibility vis)26779 class_tdecl::class_tdecl(class_decl_sptr pattern,
26780 const location& locus,
26781 visibility vis)
26782 : type_or_decl_base(pattern->get_environment(),
26783 ABSTRACT_DECL_BASE
26784 | TEMPLATE_DECL
26785 | ABSTRACT_SCOPE_DECL),
26786 decl_base(pattern->get_environment(), pattern->get_name(),
26787 locus, pattern->get_name(), vis),
26788 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
26789 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
26790 priv_(new priv(pattern))
26791 {
26792 runtime_type_instance(this);
26793 }
26794
26795 /// Setter of the pattern of the template.
26796 ///
26797 /// @param p the new template.
26798 void
set_pattern(class_decl_sptr p)26799 class_tdecl::set_pattern(class_decl_sptr p)
26800 {
26801 priv_->pattern_ = p;
26802 add_decl_to_scope(p, this);
26803 set_name(p->get_name());
26804 }
26805
26806 /// Getter of the pattern of the template.
26807 ///
26808 /// @return p the new template.
26809 class_decl_sptr
get_pattern() const26810 class_tdecl::get_pattern() const
26811 {return priv_->pattern_;}
26812
26813 bool
operator ==(const decl_base & other) const26814 class_tdecl::operator==(const decl_base& other) const
26815 {
26816 try
26817 {
26818 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
26819
26820 if (!(template_decl::operator==(o)
26821 && scope_decl::operator==(o)
26822 && !!get_pattern() == !!o.get_pattern()))
26823 return false;
26824
26825 if (!get_pattern() || !o.get_pattern())
26826 return true;
26827
26828 return get_pattern()->decl_base::operator==(*o.get_pattern());
26829 }
26830 catch(...) {}
26831 return false;
26832 }
26833
26834 bool
operator ==(const template_decl & other) const26835 class_tdecl::operator==(const template_decl& other) const
26836 {
26837 try
26838 {
26839 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
26840 return *this == static_cast<const decl_base&>(o);
26841 }
26842 catch(...)
26843 {return false;}
26844 }
26845
26846 bool
operator ==(const class_tdecl & o) const26847 class_tdecl::operator==(const class_tdecl& o) const
26848 {return *this == static_cast<const decl_base&>(o);}
26849
26850 /// This implements the ir_traversable_base::traverse pure virtual
26851 /// function.
26852 ///
26853 /// @param v the visitor used on the current instance and on the class
26854 /// pattern of the template.
26855 ///
26856 /// @return true if the entire IR node tree got traversed, false
26857 /// otherwise.
26858 bool
traverse(ir_node_visitor & v)26859 class_tdecl::traverse(ir_node_visitor&v)
26860 {
26861 if (visiting())
26862 return true;
26863
26864 if (v.visit_begin(this))
26865 {
26866 visiting(true);
26867 if (class_decl_sptr pattern = get_pattern())
26868 pattern->traverse(v);
26869 visiting(false);
26870 }
26871 return v.visit_end(this);
26872 }
26873
~class_tdecl()26874 class_tdecl::~class_tdecl()
26875 {}
26876
26877 /// This visitor checks if a given type as non-canonicalized sub
26878 /// types.
26879 class non_canonicalized_subtype_detector : public ir::ir_node_visitor
26880 {
26881 type_base* type_;
26882 type_base* has_non_canonical_type_;
26883
26884 private:
26885 non_canonicalized_subtype_detector();
26886
26887 public:
non_canonicalized_subtype_detector(type_base * type)26888 non_canonicalized_subtype_detector(type_base* type)
26889 : type_(type),
26890 has_non_canonical_type_()
26891 {}
26892
26893 /// Return true if the visitor detected that there is a
26894 /// non-canonicalized sub-type.
26895 ///
26896 /// @return true if the visitor detected that there is a
26897 /// non-canonicalized sub-type.
26898 type_base*
has_non_canonical_type() const26899 has_non_canonical_type() const
26900 {return has_non_canonical_type_;}
26901
26902 /// The intent of this visitor handler is to avoid looking into
26903 /// sub-types of member functions of the type we are traversing.
26904 bool
visit_begin(function_decl * f)26905 visit_begin(function_decl* f)
26906 {
26907 // Do not look at sub-types of non-virtual member functions.
26908 if (is_member_function(f)
26909 && get_member_function_is_virtual(*f))
26910 return false;
26911 return true;
26912 }
26913
26914 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
26915 /// the 'has_non_canonical_type' flag. And in any case, when
26916 /// visiting a sub-type, do not visit its children nodes. So this
26917 /// function only goes to the level below the level of the top-most
26918 /// type.
26919 ///
26920 /// @return true if we are at the same level as the top-most type,
26921 /// otherwise return false.
26922 bool
visit_begin(type_base * t)26923 visit_begin(type_base* t)
26924 {
26925 if (t != type_)
26926 {
26927 if (!t->get_canonical_type())
26928 // We are looking a sub-type of 'type_' which has no
26929 // canonical type. So tada! we found one! Get out right
26930 // now with the trophy.
26931 has_non_canonical_type_ = t;
26932
26933 return false;
26934 }
26935 return true;
26936 }
26937
26938 /// When we are done visiting a sub-type, if it's been flagged as
26939 /// been non-canonicalized, then stop the traversing.
26940 ///
26941 /// Otherwise, keep going.
26942 ///
26943 /// @return false iff the sub-type that has been visited is
26944 /// non-canonicalized.
26945 bool
visit_end(type_base *)26946 visit_end(type_base* )
26947 {
26948 if (has_non_canonical_type_)
26949 return false;
26950 return true;
26951 }
26952 }; //end class non_canonicalized_subtype_detector
26953
26954 /// Test if a type has sub-types that are non-canonicalized.
26955 ///
26956 /// @param t the type which sub-types to consider.
26957 ///
26958 /// @return true if a type has sub-types that are non-canonicalized.
26959 type_base*
type_has_non_canonicalized_subtype(type_base_sptr t)26960 type_has_non_canonicalized_subtype(type_base_sptr t)
26961 {
26962 if (!t)
26963 return 0;
26964
26965 non_canonicalized_subtype_detector v(t.get());
26966 t->traverse(v);
26967 return v.has_non_canonical_type();
26968 }
26969
26970 /// Tests if the change of a given type effectively comes from just
26971 /// its sub-types. That is, if the type has changed but its type name
26972 /// hasn't changed, then the change of the type mostly likely is a
26973 /// sub-type change.
26974 ///
26975 /// @param t_v1 the first version of the type.
26976 ///
26977 /// @param t_v2 the second version of the type.
26978 ///
26979 /// @return true iff the type changed and the change is about its
26980 /// sub-types.
26981 bool
type_has_sub_type_changes(const type_base_sptr t_v1,const type_base_sptr t_v2)26982 type_has_sub_type_changes(const type_base_sptr t_v1,
26983 const type_base_sptr t_v2)
26984 {
26985 type_base_sptr t1 = strip_typedef(t_v1);
26986 type_base_sptr t2 = strip_typedef(t_v2);
26987
26988 string repr1 = get_pretty_representation(t1, /*internal=*/false),
26989 repr2 = get_pretty_representation(t2, /*internal=*/false);
26990 return (t1 != t2 && repr1 == repr2);
26991 }
26992
26993 /// Make sure that the life time of a given (smart pointer to a) type
26994 /// is the same as the life time of the libabigail library.
26995 ///
26996 /// @param t the type to consider.
26997 void
keep_type_alive(type_base_sptr t)26998 keep_type_alive(type_base_sptr t)
26999 {
27000 const environment& env = t->get_environment();
27001 env.priv_->extra_live_types_.push_back(t);
27002 }
27003
27004 /// Hash an ABI artifact that is either a type or a decl.
27005 ///
27006 /// This function intends to provides the fastest possible hashing for
27007 /// types and decls, while being completely correct.
27008 ///
27009 /// Note that if the artifact is a type and if it has a canonical
27010 /// type, the hash value is going to be the pointer value of the
27011 /// canonical type. Otherwise, this function computes a hash value
27012 /// for the type by recursively walking the type members. This last
27013 /// code path is possibly *very* slow and should only be used when
27014 /// only handful of types are going to be hashed.
27015 ///
27016 /// If the artifact is a decl, then a combination of the hash of its
27017 /// type and the hash of the other properties of the decl is computed.
27018 ///
27019 /// @param tod the type or decl to hash.
27020 ///
27021 /// @return the resulting hash value.
27022 size_t
hash_type_or_decl(const type_or_decl_base * tod)27023 hash_type_or_decl(const type_or_decl_base *tod)
27024 {
27025 size_t result = 0;
27026
27027 if (tod == 0)
27028 ;
27029 else if (const type_base* t = is_type(tod))
27030 result = hash_type(t);
27031 else if (const decl_base* d = is_decl(tod))
27032 {
27033 if (var_decl* v = is_var_decl(d))
27034 {
27035 ABG_ASSERT(v->get_type());
27036 size_t h = hash_type_or_decl(v->get_type());
27037 string repr = v->get_pretty_representation(/*internal=*/true);
27038 std::hash<string> hash_string;
27039 h = hashing::combine_hashes(h, hash_string(repr));
27040 result = h;
27041 }
27042 else if (function_decl* f = is_function_decl(d))
27043 {
27044 ABG_ASSERT(f->get_type());
27045 size_t h = hash_type_or_decl(f->get_type());
27046 string repr = f->get_pretty_representation(/*internal=*/true);
27047 std::hash<string> hash_string;
27048 h = hashing::combine_hashes(h, hash_string(repr));
27049 result = h;
27050 }
27051 else if (function_decl::parameter* p = is_function_parameter(d))
27052 {
27053 type_base_sptr parm_type = p->get_type();
27054 ABG_ASSERT(parm_type);
27055 std::hash<bool> hash_bool;
27056 std::hash<unsigned> hash_unsigned;
27057 size_t h = hash_type_or_decl(parm_type);
27058 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
27059 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
27060 result = h;
27061 }
27062 else if (class_decl::base_spec *bs = is_class_base_spec(d))
27063 {
27064 member_base::hash hash_member;
27065 std::hash<size_t> hash_size;
27066 std::hash<bool> hash_bool;
27067 type_base_sptr type = bs->get_base_class();
27068 size_t h = hash_type_or_decl(type);
27069 h = hashing::combine_hashes(h, hash_member(*bs));
27070 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
27071 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
27072 result = h;
27073 }
27074 else
27075 // This is a *really* *SLOW* path. If it shows up in a
27076 // performance profile, I bet it'd be a good idea to try to
27077 // avoid it altogether.
27078 result = d->get_hash();
27079 }
27080 else
27081 // We should never get here.
27082 abort();
27083 return result;
27084 }
27085
27086 /// Hash an ABI artifact that is either a type.
27087 ///
27088 /// This function intends to provides the fastest possible hashing for
27089 /// types while being completely correct.
27090 ///
27091 /// Note that if the type artifact has a canonical type, the hash
27092 /// value is going to be the pointer value of the canonical type.
27093 /// Otherwise, this function computes a hash value for the type by
27094 /// recursively walking the type members. This last code path is
27095 /// possibly *very* slow and should only be used when only handful of
27096 /// types are going to be hashed.
27097 ///
27098 /// @param t the type or decl to hash.
27099 ///
27100 /// @return the resulting hash value.
27101 size_t
hash_type(const type_base * t)27102 hash_type(const type_base *t)
27103 {return hash_as_canonical_type_or_constant(t);}
27104
27105 /// Hash an ABI artifact that is either a type of a decl.
27106 ///
27107 /// @param tod the ABI artifact to hash.
27108 ///
27109 /// @return the hash value of the ABI artifact.
27110 size_t
hash_type_or_decl(const type_or_decl_base_sptr & tod)27111 hash_type_or_decl(const type_or_decl_base_sptr& tod)
27112 {return hash_type_or_decl(tod.get());}
27113
27114 /// Test if a given type is allowed to be non canonicalized
27115 ///
27116 /// This is a subroutine of hash_as_canonical_type_or_constant.
27117 ///
27118 /// For now, the only types allowed to be non canonicalized in the
27119 /// system are (typedefs & pointers to) decl-only class/union, the
27120 /// void type and variadic parameter types.
27121 ///
27122 /// @return true iff @p t is a one of the only types allowed to be
27123 /// non-canonicalized in the system.
27124 bool
is_non_canonicalized_type(const type_base * t)27125 is_non_canonicalized_type(const type_base *t)
27126 {
27127 if (!t)
27128 return true;
27129
27130 return (// The IR nodes for the types below are unique across the
27131 // entire ABI corpus. Thus, no need to canonicalize them.
27132 // Maybe we could say otherwise and canonicalize them once
27133 // for all so that they can be removed from here.
27134 is_unique_type(t)
27135
27136 // An IR node for the types below can be equal to several
27137 // other types (i.e, a decl-only type t equals a fully
27138 // defined type of the same name in ODR-supported
27139 // languages). Hence, they can't be given a canonical type.
27140 //
27141 // TODO: Maybe add a mode that would detect ODR violations
27142 // that would make a decl-only type co-exists with several
27143 // different definitions of the type in the ABI corpus.
27144 || is_void_pointer_type_equivalent(t)
27145 || is_declaration_only_class_or_union_type(t,
27146 /*look_through_decl_only=*/true)
27147 || is_typedef_ptr_or_ref_to_decl_only_class_or_union_type(t));
27148
27149 }
27150
27151 /// Test if a type is unique in the entire environment.
27152 ///
27153 /// Examples of unique types are void, void* and variadic parameter
27154 /// types.
27155 ///
27156 /// @param t the type to test for.
27157 ///
27158 /// @return true iff the type @p t is unique in the entire
27159 /// environment.
27160 bool
is_unique_type(const type_base_sptr & t)27161 is_unique_type(const type_base_sptr& t)
27162 {return is_unique_type(t.get());}
27163
27164 /// Test if a type is unique in the entire environment.
27165 ///
27166 /// Examples of unique types are void, void* and variadic parameter
27167 /// types.
27168 ///
27169 /// @param t the type to test for.
27170 ///
27171 /// @return true iff the type @p t is unique in the entire
27172 /// environment.
27173 bool
is_unique_type(const type_base * t)27174 is_unique_type(const type_base* t)
27175 {
27176 if (!t)
27177 return false;
27178
27179 const environment& env = t->get_environment();
27180 return (env.is_void_type(t)
27181 || env.is_void_pointer_type(t)
27182 || env.is_variadic_parameter_type(t));
27183 }
27184
27185 /// For a given type, return its exemplar type.
27186 ///
27187 /// For a given type, its exemplar type is either its canonical type
27188 /// or the canonical type of the definition type of a given
27189 /// declaration-only type. If the neither of those two types exist,
27190 /// then the exemplar type is the given type itself.
27191 ///
27192 /// @param type the input to consider.
27193 ///
27194 /// @return the exemplar type.
27195 type_base*
get_exemplar_type(const type_base * type)27196 get_exemplar_type(const type_base* type)
27197 {
27198 if (decl_base * decl = is_decl(type))
27199 {
27200 // Make sure we get the real definition of a decl-only type.
27201 decl = look_through_decl_only(decl);
27202 type = is_type(decl);
27203 ABG_ASSERT(type);
27204 }
27205 type_base *exemplar = type->get_naked_canonical_type();
27206 if (!exemplar)
27207 {
27208 // The type has no canonical type. Let's be sure that it's one
27209 // of those rare types that are allowed to be non canonicalized
27210 // in the system.
27211 exemplar = const_cast<type_base*>(type);
27212 ABG_ASSERT(is_non_canonicalized_type(exemplar));
27213 }
27214 return exemplar;
27215 }
27216
27217 /// Test if a given type is allowed to be non canonicalized
27218 ///
27219 /// This is a subroutine of hash_as_canonical_type_or_constant.
27220 ///
27221 /// For now, the only types allowed to be non canonicalized in the
27222 /// system are decl-only class/union and the void type.
27223 ///
27224 /// @return true iff @p t is a one of the only types allowed to be
27225 /// non-canonicalized in the system.
27226 bool
is_non_canonicalized_type(const type_base_sptr & t)27227 is_non_canonicalized_type(const type_base_sptr& t)
27228 {return is_non_canonicalized_type(t.get());}
27229
27230 /// Hash a type by either returning the pointer value of its canonical
27231 /// type or by returning a constant if the type doesn't have a
27232 /// canonical type.
27233 ///
27234 /// This is a subroutine of hash_type.
27235 ///
27236 /// @param t the type to consider.
27237 ///
27238 /// @return the hash value.
27239 static size_t
hash_as_canonical_type_or_constant(const type_base * t)27240 hash_as_canonical_type_or_constant(const type_base *t)
27241 {
27242 type_base *canonical_type = 0;
27243
27244 if (t)
27245 canonical_type = t->get_naked_canonical_type();
27246
27247 if (!canonical_type)
27248 {
27249 // If the type doesn't have a canonical type, maybe it's because
27250 // it's a declaration-only type? If that's the case, let's try
27251 // to get the canonical type of the definition of this
27252 // declaration.
27253 decl_base *decl = is_decl(t);
27254 if (decl
27255 && decl->get_is_declaration_only()
27256 && decl->get_naked_definition_of_declaration())
27257 {
27258 type_base *definition =
27259 is_type(decl->get_naked_definition_of_declaration());
27260 ABG_ASSERT(definition);
27261 canonical_type = definition->get_naked_canonical_type();
27262 }
27263 }
27264
27265 if (canonical_type)
27266 return reinterpret_cast<size_t>(canonical_type);
27267
27268 // If we reached this point, it means we are seeing a
27269 // non-canonicalized type. It must be a decl-only class or a void
27270 // type, otherwise it means that for some weird reason, the type
27271 // hasn't been canonicalized. It should be!
27272 ABG_ASSERT(is_non_canonicalized_type(t));
27273
27274 return 0xDEADBABE;
27275 }
27276
27277 /// Test if the pretty representation of a given @ref function_decl is
27278 /// lexicographically less then the pretty representation of another
27279 /// @ref function_decl.
27280 ///
27281 /// @param f the first @ref function_decl to consider for comparison.
27282 ///
27283 /// @param s the second @ref function_decl to consider for comparison.
27284 ///
27285 /// @return true iff the pretty representation of @p f is
27286 /// lexicographically less than the pretty representation of @p s.
27287 bool
function_decl_is_less_than(const function_decl & f,const function_decl & s)27288 function_decl_is_less_than(const function_decl &f, const function_decl &s)
27289 {
27290 string fr = f.get_pretty_representation_of_declarator(),
27291 sr = s.get_pretty_representation_of_declarator();
27292
27293 if (fr != sr)
27294 return fr < sr;
27295
27296 fr = f.get_pretty_representation(/*internal=*/true),
27297 sr = s.get_pretty_representation(/*internal=*/true);
27298
27299 if (fr != sr)
27300 return fr < sr;
27301
27302 if (f.get_symbol())
27303 fr = f.get_symbol()->get_id_string();
27304 else if (!f.get_linkage_name().empty())
27305 fr = f.get_linkage_name();
27306
27307 if (s.get_symbol())
27308 sr = s.get_symbol()->get_id_string();
27309 else if (!s.get_linkage_name().empty())
27310 sr = s.get_linkage_name();
27311
27312 return fr < sr;
27313 }
27314
27315 /// Test if two types have similar structures, even though they are
27316 /// (or can be) different.
27317 ///
27318 /// const and volatile qualifiers are completely ignored.
27319 ///
27320 /// typedef are resolved to their definitions; their names are ignored.
27321 ///
27322 /// Two indirect types (pointers or references) have similar structure
27323 /// if their underlying types are of the same kind and have the same
27324 /// name. In the indirect types case, the size of the underlying type
27325 /// does not matter.
27326 ///
27327 /// Two direct types (i.e, non indirect) have a similar structure if
27328 /// they have the same kind, name and size. Two class types have
27329 /// similar structure if they have the same name, size, and if the
27330 /// types of their data members have similar types.
27331 ///
27332 /// @param first the first type to consider.
27333 ///
27334 /// @param second the second type to consider.
27335 ///
27336 /// @param indirect_type whether to do an indirect comparison
27337 ///
27338 /// @return true iff @p first and @p second have similar structures.
27339 bool
types_have_similar_structure(const type_base_sptr & first,const type_base_sptr & second,bool indirect_type)27340 types_have_similar_structure(const type_base_sptr& first,
27341 const type_base_sptr& second,
27342 bool indirect_type)
27343 {return types_have_similar_structure(first.get(), second.get(), indirect_type);}
27344
27345 /// Test if two types have similar structures, even though they are
27346 /// (or can be) different.
27347 ///
27348 /// const and volatile qualifiers are completely ignored.
27349 ///
27350 /// typedef are resolved to their definitions; their names are ignored.
27351 ///
27352 /// Two indirect types (pointers, references or arrays) have similar
27353 /// structure if their underlying types are of the same kind and have
27354 /// the same name. In the indirect types case, the size of the
27355 /// underlying type does not matter.
27356 ///
27357 /// Two direct types (i.e, non indirect) have a similar structure if
27358 /// they have the same kind, name and size. Two class types have
27359 /// similar structure if they have the same name, size, and if the
27360 /// types of their data members have similar types.
27361 ///
27362 /// @param first the first type to consider.
27363 ///
27364 /// @param second the second type to consider.
27365 ///
27366 /// @param indirect_type if true, then consider @p first and @p
27367 /// second as being underlying types of indirect types. Meaning that
27368 /// their size does not matter.
27369 ///
27370 /// @return true iff @p first and @p second have similar structures.
27371 bool
types_have_similar_structure(const type_base * first,const type_base * second,bool indirect_type)27372 types_have_similar_structure(const type_base* first,
27373 const type_base* second,
27374 bool indirect_type)
27375 {
27376 if (!!first != !!second)
27377 return false;
27378
27379 if (!first)
27380 return false;
27381
27382 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
27383 first = peel_qualified_or_typedef_type(first);
27384 second = peel_qualified_or_typedef_type(second);
27385
27386 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
27387 // various ty2 below cannot be null.
27388 if (typeid(*first) != typeid(*second))
27389 return false;
27390
27391 // Peel off matching pointers.
27392 if (const pointer_type_def* ty1 = is_pointer_type(first))
27393 {
27394 const pointer_type_def* ty2 = is_pointer_type(second);
27395 return types_have_similar_structure(ty1->get_pointed_to_type(),
27396 ty2->get_pointed_to_type(),
27397 /*indirect_type=*/true);
27398 }
27399
27400 // Peel off matching references.
27401 if (const reference_type_def* ty1 = is_reference_type(first))
27402 {
27403 const reference_type_def* ty2 = is_reference_type(second);
27404 if (ty1->is_lvalue() != ty2->is_lvalue())
27405 return false;
27406 return types_have_similar_structure(ty1->get_pointed_to_type(),
27407 ty2->get_pointed_to_type(),
27408 /*indirect_type=*/true);
27409 }
27410
27411 if (const type_decl* ty1 = is_type_decl(first))
27412 {
27413 const type_decl* ty2 = is_type_decl(second);
27414 if (!indirect_type)
27415 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
27416 return false;
27417
27418 return ty1->get_name() == ty2->get_name();
27419 }
27420
27421 if (const enum_type_decl* ty1 = is_enum_type(first))
27422 {
27423 const enum_type_decl* ty2 = is_enum_type(second);
27424 if (!indirect_type)
27425 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
27426 return false;
27427
27428 return (get_name(ty1->get_underlying_type())
27429 == get_name(ty2->get_underlying_type()));
27430 }
27431
27432 if (const class_decl* ty1 = is_class_type(first))
27433 {
27434 const class_decl* ty2 = is_class_type(second);
27435 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
27436 && ty1->get_name() != ty2->get_name())
27437 return false;
27438
27439 if (!indirect_type)
27440 {
27441 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
27442 || (ty1->get_non_static_data_members().size()
27443 != ty2->get_non_static_data_members().size()))
27444 return false;
27445
27446 for (class_or_union::data_members::const_iterator
27447 i = ty1->get_non_static_data_members().begin(),
27448 j = ty2->get_non_static_data_members().begin();
27449 (i != ty1->get_non_static_data_members().end()
27450 && j != ty2->get_non_static_data_members().end());
27451 ++i, ++j)
27452 {
27453 var_decl_sptr dm1 = *i;
27454 var_decl_sptr dm2 = *j;
27455 if (!types_have_similar_structure(dm1->get_type().get(),
27456 dm2->get_type().get(),
27457 indirect_type))
27458 return false;
27459 }
27460 }
27461
27462 return true;
27463 }
27464
27465 if (const union_decl* ty1 = is_union_type(first))
27466 {
27467 const union_decl* ty2 = is_union_type(second);
27468 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
27469 && ty1->get_name() != ty2->get_name())
27470 return false;
27471
27472 if (!indirect_type)
27473 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
27474
27475 return true;
27476 }
27477
27478 if (const array_type_def* ty1 = is_array_type(first))
27479 {
27480 const array_type_def* ty2 = is_array_type(second);
27481 // TODO: Handle int[5][2] vs int[2][5] better.
27482 if (!indirect_type)
27483 {
27484 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
27485 || ty1->get_dimension_count() != ty2->get_dimension_count())
27486 return false;
27487 }
27488
27489 if (!types_have_similar_structure(ty1->get_element_type(),
27490 ty2->get_element_type(),
27491 /*indirect_type=*/true))
27492 return false;
27493
27494 return true;
27495 }
27496
27497 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
27498 {
27499 const array_type_def::subrange_type *ty2 = is_subrange_type(second);
27500 if (ty1->get_upper_bound() != ty2->get_upper_bound()
27501 || ty1->get_lower_bound() != ty2->get_lower_bound()
27502 || ty1->get_language() != ty2->get_language()
27503 || !types_have_similar_structure(ty1->get_underlying_type(),
27504 ty2->get_underlying_type(),
27505 indirect_type))
27506 return false;
27507
27508 return true;
27509 }
27510
27511 if (const function_type* ty1 = is_function_type(first))
27512 {
27513 const function_type* ty2 = is_function_type(second);
27514 if (!types_have_similar_structure(ty1->get_return_type(),
27515 ty2->get_return_type(),
27516 indirect_type))
27517 return false;
27518
27519 if (ty1->get_parameters().size() != ty2->get_parameters().size())
27520 return false;
27521
27522 for (function_type::parameters::const_iterator
27523 i = ty1->get_parameters().begin(),
27524 j = ty2->get_parameters().begin();
27525 (i != ty1->get_parameters().end()
27526 && j != ty2->get_parameters().end());
27527 ++i, ++j)
27528 if (!types_have_similar_structure((*i)->get_type(),
27529 (*j)->get_type(),
27530 indirect_type))
27531 return false;
27532
27533 return true;
27534 }
27535
27536 // All kinds of type should have been handled at this point.
27537 ABG_ASSERT_NOT_REACHED;
27538
27539 return false;
27540 }
27541
27542 /// Look for a data member of a given class, struct or union type and
27543 /// return it.
27544 ///
27545 /// The data member is designated by its name.
27546 ///
27547 /// @param type the class, struct or union type to consider.
27548 ///
27549 /// @param dm_name the name of the data member to lookup.
27550 ///
27551 /// @return the data member iff it was found in @type or NULL if no
27552 /// data member with that name was found.
27553 const var_decl*
lookup_data_member(const type_base * type,const char * dm_name)27554 lookup_data_member(const type_base* type,
27555 const char* dm_name)
27556
27557 {
27558 class_or_union *cou = is_class_or_union_type(type);
27559 if (!cou)
27560 return 0;
27561
27562 return cou->find_data_member(dm_name).get();
27563 }
27564
27565 /// Look for a data member of a given class, struct or union type and
27566 /// return it.
27567 ///
27568 /// The data member is designated by its name.
27569 ///
27570 /// @param type the class, struct or union type to consider.
27571 ///
27572 /// @param dm the data member to lookup.
27573 ///
27574 /// @return the data member iff it was found in @type or NULL if no
27575 /// data member with that name was found.
27576 const var_decl_sptr
lookup_data_member(const type_base_sptr & type,const var_decl_sptr & dm)27577 lookup_data_member(const type_base_sptr& type, const var_decl_sptr& dm)
27578 {
27579 class_or_union_sptr cou = is_class_or_union_type(type);
27580 if (!cou)
27581 return var_decl_sptr();
27582
27583 return cou->find_data_member(dm);
27584 }
27585
27586 /// Get the function parameter designated by its index.
27587 ///
27588 /// Note that the first function parameter has index 0.
27589 ///
27590 /// @param fun the function to consider.
27591 ///
27592 /// @param parm_index the index of the function parameter to get.
27593 ///
27594 /// @return the function parameter designated by its index, of NULL if
27595 /// no function parameter with that index was found.
27596 const function_decl::parameter*
get_function_parameter(const decl_base * fun,unsigned parm_index)27597 get_function_parameter(const decl_base* fun,
27598 unsigned parm_index)
27599 {
27600 function_decl* fn = is_function_decl(fun);
27601 if (!fn)
27602 return 0;
27603
27604 const function_decl::parameters &parms = fn->get_type()->get_parameters();
27605 if (parms.size() <= parm_index)
27606 return 0;
27607
27608 return parms[parm_index].get();
27609 }
27610
27611 /// Build the internal name of the underlying type of an enum.
27612 ///
27613 /// @param base_name the (unqualified) name of the enum the underlying
27614 /// type is destined to.
27615 ///
27616 /// @param is_anonymous true if the underlying type of the enum is to
27617 /// be anonymous.
27618 string
build_internal_underlying_enum_type_name(const string & base_name,bool is_anonymous,uint64_t size)27619 build_internal_underlying_enum_type_name(const string &base_name,
27620 bool is_anonymous,
27621 uint64_t size)
27622 {
27623 std::ostringstream o;
27624
27625 if (is_anonymous)
27626 o << "unnamed-enum";
27627 else
27628 o << "enum-" << base_name;
27629
27630 o << "-underlying-type-" << size;
27631
27632 return o.str();
27633 }
27634
27635 /// Find the first data member of a class or union which name matches
27636 /// a regular expression.
27637 ///
27638 /// @param t the class or union to consider.
27639 ///
27640 /// @param r the regular expression to consider.
27641 ///
27642 /// @return the data member matched by @p r or nil if none was found.
27643 var_decl_sptr
find_first_data_member_matching_regexp(const class_or_union & t,const regex::regex_t_sptr & r)27644 find_first_data_member_matching_regexp(const class_or_union& t,
27645 const regex::regex_t_sptr& r)
27646 {
27647 for (auto data_member : t.get_data_members())
27648 {
27649 if (regex::match(r, data_member->get_name()))
27650 return data_member;
27651 }
27652
27653 return var_decl_sptr();
27654 }
27655
27656 /// Find the last data member of a class or union which name matches
27657 /// a regular expression.
27658 ///
27659 /// @param t the class or union to consider.
27660 ///
27661 /// @param r the regular expression to consider.
27662 ///
27663 /// @return the data member matched by @p r or nil if none was found.
27664 var_decl_sptr
find_last_data_member_matching_regexp(const class_or_union & t,const regex::regex_t_sptr & regex)27665 find_last_data_member_matching_regexp(const class_or_union& t,
27666 const regex::regex_t_sptr& regex)
27667 {
27668 auto d = t.get_data_members().rbegin();
27669 auto e = t.get_data_members().rend();
27670 for (; d != e; ++d)
27671 {
27672 if (regex::match(regex, (*d)->get_name()))
27673 return *d;
27674 }
27675
27676 return var_decl_sptr();
27677 }
27678
27679 bool
traverse(ir_node_visitor &)27680 ir_traversable_base::traverse(ir_node_visitor&)
27681 {return true;}
27682
27683 // <ir_node_visitor stuff>
27684
27685 /// The private data structure of the ir_node_visitor type.
27686 struct ir_node_visitor::priv
27687 {
27688 pointer_set visited_ir_nodes;
27689 bool allow_visiting_already_visited_type_node;
27690
privabigail::ir::ir_node_visitor::priv27691 priv()
27692 : allow_visiting_already_visited_type_node(true)
27693 {}
27694 }; // end struct ir_node_visitory::priv
27695
27696 /// Default Constructor of the ir_node_visitor type.
ir_node_visitor()27697 ir_node_visitor::ir_node_visitor()
27698 : priv_(new priv)
27699 {}
27700
27701 ir_node_visitor::~ir_node_visitor() = default;
27702
27703 /// Set if the walker using this visitor is allowed to re-visit a type
27704 /// node that was previously visited or not.
27705 ///
27706 /// @param f if true, then the walker using this visitor is allowed to
27707 /// re-visit a type node that was previously visited.
27708 void
allow_visiting_already_visited_type_node(bool f)27709 ir_node_visitor::allow_visiting_already_visited_type_node(bool f)
27710 {priv_->allow_visiting_already_visited_type_node = f;}
27711
27712 /// Get if the walker using this visitor is allowed to re-visit a type
27713 /// node that was previously visited or not.
27714 ///
27715 /// @return true iff the walker using this visitor is allowed to
27716 /// re-visit a type node that was previously visited.
27717 bool
allow_visiting_already_visited_type_node() const27718 ir_node_visitor::allow_visiting_already_visited_type_node() const
27719 {return priv_->allow_visiting_already_visited_type_node;}
27720
27721 /// Mark a given type node as having been visited.
27722 ///
27723 /// Note that for this function to work, the type node must have been
27724 /// canonicalized. Otherwise the process is aborted.
27725 ///
27726 /// @param p the type to mark as having been visited.
27727 void
mark_type_node_as_visited(type_base * p)27728 ir_node_visitor::mark_type_node_as_visited(type_base *p)
27729 {
27730 if (allow_visiting_already_visited_type_node())
27731 return;
27732
27733 if (p == 0 || type_node_has_been_visited(p))
27734 return;
27735
27736 type_base* canonical_type = p->get_naked_canonical_type();
27737 ABG_ASSERT(canonical_type);
27738
27739 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
27740 priv_->visited_ir_nodes.insert(canonical_ptr_value);
27741 }
27742
27743 /// Un-mark all visited type nodes.
27744 ///
27745 /// That is, no type node is going to be considered as having been
27746 /// visited anymore.
27747 ///
27748 /// In other words, after invoking this funciton,
27749 /// ir_node_visitor::type_node_has_been_visited() is going to return
27750 /// false on all type nodes.
27751 void
forget_visited_type_nodes()27752 ir_node_visitor::forget_visited_type_nodes()
27753 {priv_->visited_ir_nodes.clear();}
27754
27755 /// Test if a given type node has been marked as visited.
27756 ///
27757 /// @param p the type node to consider.
27758 ///
27759 /// @return true iff the type node @p p has been marked as visited by
27760 /// the function ir_node_visitor::mark_type_node_as_visited.
27761 bool
type_node_has_been_visited(type_base * p) const27762 ir_node_visitor::type_node_has_been_visited(type_base* p) const
27763 {
27764 if (allow_visiting_already_visited_type_node())
27765 return false;
27766
27767 if (p == 0)
27768 return false;
27769
27770 type_base *canonical_type = p->get_naked_canonical_type();
27771 ABG_ASSERT(canonical_type);
27772
27773 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
27774 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
27775 if (it == priv_->visited_ir_nodes.end())
27776 return false;
27777
27778 return true;
27779 }
27780
27781 bool
visit_begin(decl_base *)27782 ir_node_visitor::visit_begin(decl_base*)
27783 {return true;}
27784
27785 bool
visit_end(decl_base *)27786 ir_node_visitor::visit_end(decl_base*)
27787 {return true;}
27788
27789 bool
visit_begin(scope_decl *)27790 ir_node_visitor::visit_begin(scope_decl*)
27791 {return true;}
27792
27793 bool
visit_end(scope_decl *)27794 ir_node_visitor::visit_end(scope_decl*)
27795 {return true;}
27796
27797 bool
visit_begin(type_base *)27798 ir_node_visitor::visit_begin(type_base*)
27799 {return true;}
27800
27801 bool
visit_end(type_base *)27802 ir_node_visitor::visit_end(type_base*)
27803 {return true;}
27804
27805 bool
visit_begin(scope_type_decl * t)27806 ir_node_visitor::visit_begin(scope_type_decl* t)
27807 {return visit_begin(static_cast<type_base*>(t));}
27808
27809 bool
visit_end(scope_type_decl * t)27810 ir_node_visitor::visit_end(scope_type_decl* t)
27811 {return visit_end(static_cast<type_base*>(t));}
27812
27813 bool
visit_begin(type_decl * t)27814 ir_node_visitor::visit_begin(type_decl* t)
27815 {return visit_begin(static_cast<type_base*>(t));}
27816
27817 bool
visit_end(type_decl * t)27818 ir_node_visitor::visit_end(type_decl* t)
27819 {return visit_end(static_cast<type_base*>(t));}
27820
27821 bool
visit_begin(namespace_decl * d)27822 ir_node_visitor::visit_begin(namespace_decl* d)
27823 {return visit_begin(static_cast<decl_base*>(d));}
27824
27825 bool
visit_end(namespace_decl * d)27826 ir_node_visitor::visit_end(namespace_decl* d)
27827 {return visit_end(static_cast<decl_base*>(d));}
27828
27829 bool
visit_begin(qualified_type_def * t)27830 ir_node_visitor::visit_begin(qualified_type_def* t)
27831 {return visit_begin(static_cast<type_base*>(t));}
27832
27833 bool
visit_end(qualified_type_def * t)27834 ir_node_visitor::visit_end(qualified_type_def* t)
27835 {return visit_end(static_cast<type_base*>(t));}
27836
27837 bool
visit_begin(pointer_type_def * t)27838 ir_node_visitor::visit_begin(pointer_type_def* t)
27839 {return visit_begin(static_cast<type_base*>(t));}
27840
27841 bool
visit_end(pointer_type_def * t)27842 ir_node_visitor::visit_end(pointer_type_def* t)
27843 {return visit_end(static_cast<type_base*>(t));}
27844
27845 bool
visit_begin(reference_type_def * t)27846 ir_node_visitor::visit_begin(reference_type_def* t)
27847 {return visit_begin(static_cast<type_base*>(t));}
27848
27849 bool
visit_end(reference_type_def * t)27850 ir_node_visitor::visit_end(reference_type_def* t)
27851 {return visit_end(static_cast<type_base*>(t));}
27852
27853 bool
visit_begin(array_type_def * t)27854 ir_node_visitor::visit_begin(array_type_def* t)
27855 {return visit_begin(static_cast<type_base*>(t));}
27856
27857 bool
visit_end(array_type_def * t)27858 ir_node_visitor::visit_end(array_type_def* t)
27859 {return visit_end(static_cast<type_base*>(t));}
27860
27861 bool
visit_begin(array_type_def::subrange_type * t)27862 ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
27863 {return visit_begin(static_cast<type_base*>(t));}
27864
27865 bool
visit_end(array_type_def::subrange_type * t)27866 ir_node_visitor::visit_end(array_type_def::subrange_type* t)
27867 {return visit_end(static_cast<type_base*>(t));}
27868
27869 bool
visit_begin(enum_type_decl * t)27870 ir_node_visitor::visit_begin(enum_type_decl* t)
27871 {return visit_begin(static_cast<type_base*>(t));}
27872
27873 bool
visit_end(enum_type_decl * t)27874 ir_node_visitor::visit_end(enum_type_decl* t)
27875 {return visit_end(static_cast<type_base*>(t));}
27876
27877 bool
visit_begin(typedef_decl * t)27878 ir_node_visitor::visit_begin(typedef_decl* t)
27879 {return visit_begin(static_cast<type_base*>(t));}
27880
27881 bool
visit_end(typedef_decl * t)27882 ir_node_visitor::visit_end(typedef_decl* t)
27883 {return visit_end(static_cast<type_base*>(t));}
27884
27885 bool
visit_begin(function_type * t)27886 ir_node_visitor::visit_begin(function_type* t)
27887 {return visit_begin(static_cast<type_base*>(t));}
27888
27889 bool
visit_end(function_type * t)27890 ir_node_visitor::visit_end(function_type* t)
27891 {return visit_end(static_cast<type_base*>(t));}
27892
27893 bool
visit_begin(var_decl * d)27894 ir_node_visitor::visit_begin(var_decl* d)
27895 {return visit_begin(static_cast<decl_base*>(d));}
27896
27897 bool
visit_end(var_decl * d)27898 ir_node_visitor::visit_end(var_decl* d)
27899 {return visit_end(static_cast<decl_base*>(d));}
27900
27901 bool
visit_begin(function_decl * d)27902 ir_node_visitor::visit_begin(function_decl* d)
27903 {return visit_begin(static_cast<decl_base*>(d));}
27904
27905 bool
visit_end(function_decl * d)27906 ir_node_visitor::visit_end(function_decl* d)
27907 {return visit_end(static_cast<decl_base*>(d));}
27908
27909 bool
visit_begin(function_decl::parameter * d)27910 ir_node_visitor::visit_begin(function_decl::parameter* d)
27911 {return visit_begin(static_cast<decl_base*>(d));}
27912
27913 bool
visit_end(function_decl::parameter * d)27914 ir_node_visitor::visit_end(function_decl::parameter* d)
27915 {return visit_end(static_cast<decl_base*>(d));}
27916
27917 bool
visit_begin(function_tdecl * d)27918 ir_node_visitor::visit_begin(function_tdecl* d)
27919 {return visit_begin(static_cast<decl_base*>(d));}
27920
27921 bool
visit_end(function_tdecl * d)27922 ir_node_visitor::visit_end(function_tdecl* d)
27923 {return visit_end(static_cast<decl_base*>(d));}
27924
27925 bool
visit_begin(class_tdecl * d)27926 ir_node_visitor::visit_begin(class_tdecl* d)
27927 {return visit_begin(static_cast<decl_base*>(d));}
27928
27929 bool
visit_end(class_tdecl * d)27930 ir_node_visitor::visit_end(class_tdecl* d)
27931 {return visit_end(static_cast<decl_base*>(d));}
27932
27933 bool
visit_begin(class_or_union * t)27934 ir_node_visitor::visit_begin(class_or_union* t)
27935 {return visit_begin(static_cast<type_base*>(t));}
27936
27937 bool
visit_end(class_or_union * t)27938 ir_node_visitor::visit_end(class_or_union* t)
27939 {return visit_end(static_cast<type_base*>(t));}
27940
27941 bool
visit_begin(class_decl * t)27942 ir_node_visitor::visit_begin(class_decl* t)
27943 {return visit_begin(static_cast<type_base*>(t));}
27944
27945 bool
visit_end(class_decl * t)27946 ir_node_visitor::visit_end(class_decl* t)
27947 {return visit_end(static_cast<type_base*>(t));}
27948
27949 bool
visit_begin(union_decl * t)27950 ir_node_visitor::visit_begin(union_decl* t)
27951 {return visit_begin(static_cast<type_base*>(t));}
27952
27953 bool
visit_end(union_decl * t)27954 ir_node_visitor::visit_end(union_decl* t)
27955 {return visit_end(static_cast<type_base*>(t));}
27956
27957 bool
visit_begin(class_decl::base_spec * d)27958 ir_node_visitor::visit_begin(class_decl::base_spec* d)
27959 {return visit_begin(static_cast<decl_base*>(d));}
27960
27961 bool
visit_end(class_decl::base_spec * d)27962 ir_node_visitor::visit_end(class_decl::base_spec* d)
27963 {return visit_end(static_cast<decl_base*>(d));}
27964
27965 bool
visit_begin(member_function_template * d)27966 ir_node_visitor::visit_begin(member_function_template* d)
27967 {return visit_begin(static_cast<decl_base*>(d));}
27968
27969 bool
visit_end(member_function_template * d)27970 ir_node_visitor::visit_end(member_function_template* d)
27971 {return visit_end(static_cast<decl_base*>(d));}
27972
27973 bool
visit_begin(member_class_template * d)27974 ir_node_visitor::visit_begin(member_class_template* d)
27975 {return visit_begin(static_cast<decl_base*>(d));}
27976
27977 bool
visit_end(member_class_template * d)27978 ir_node_visitor::visit_end(member_class_template* d)
27979 {return visit_end(static_cast<decl_base*>(d));}
27980
27981 // </ir_node_visitor stuff>
27982
27983 // <debugging facilities>
27984
27985 /// Generate a different string at each invocation.
27986 ///
27987 /// @return the resulting string.
27988 static string
get_next_string()27989 get_next_string()
27990 {
27991 static __thread size_t counter;
27992 ++counter;
27993 std::ostringstream o;
27994 o << counter;
27995 return o.str();
27996 }
27997
27998 /// Convenience typedef for a hash map of pointer to function_decl and
27999 /// string.
28000 typedef unordered_map<const function_decl*, string,
28001 function_decl::hash,
28002 function_decl::ptr_equal> fns_to_str_map_type;
28003
28004 /// Return a string associated to a given function. Two functions
28005 /// that compare equal would yield the same string, as far as this
28006 /// routine is concerned. And two functions that are different would
28007 /// yield different strings.
28008 ///
28009 /// This is used to debug core diffing issues on functions. The
28010 /// sequence of strings can be given to the 'testdiff2' program that
28011 /// is in the tests/ directory of the source tree, to reproduce core
28012 /// diffing issues on string and thus ease the debugging.
28013 ///
28014 /// @param fn the function to generate a string for.
28015 ///
28016 /// @param m the function_decl* <-> string map to be used by this
28017 /// function to generate strings associated to a function.
28018 ///
28019 /// @return the resulting string.
28020 static const string&
fn_to_str(const function_decl * fn,fns_to_str_map_type & m)28021 fn_to_str(const function_decl* fn,
28022 fns_to_str_map_type& m)
28023 {
28024 fns_to_str_map_type::const_iterator i = m.find(fn);
28025 if (i != m.end())
28026 return i->second;
28027 string s = get_next_string();
28028 return m[fn]= s;
28029 }
28030
28031 /// Generate a sequence of string that matches a given sequence of
28032 /// function. In the resulting sequence, each function is "uniquely
28033 /// representated" by a string. For instance, if the same function "foo"
28034 /// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
28035 /// we don't care about the actual string) would appear at index 1 and 3.
28036 ///
28037 /// @param begin the beginning of the sequence of functions to consider.
28038 ///
28039 /// @param end the end of the sequence of functions. This points to
28040 /// one-passed-the-end of the actual sequence.
28041 ///
28042 /// @param m the function_decl* <-> string map to be used by this
28043 /// function to generate strings associated to a function.
28044 ///
28045 /// @param o the output stream where to emit the generated list of
28046 /// strings to.
28047 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)28048 fns_to_str(vector<function_decl*>::const_iterator begin,
28049 vector<function_decl*>::const_iterator end,
28050 fns_to_str_map_type& m,
28051 std::ostream& o)
28052 {
28053 vector<function_decl*>::const_iterator i;
28054 for (i = begin; i != end; ++i)
28055 o << "'" << fn_to_str(*i, m) << "' ";
28056 }
28057
28058 /// For each sequence of functions given in argument, generate a
28059 /// sequence of string that matches a given sequence of function. In
28060 /// the resulting sequence, each function is "uniquely representated"
28061 /// by a string. For instance, if the same function "foo" appears at
28062 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
28063 /// care about the actual string) would appear at index 1 and 3.
28064 ///
28065 /// @param a_begin the beginning of the sequence of functions to consider.
28066 ///
28067 /// @param a_end the end of the sequence of functions. This points to
28068 /// one-passed-the-end of the actual sequence.
28069 ///
28070 /// @param b_begin the beginning of the second sequence of functions
28071 /// to consider.
28072 ///
28073 /// @param b_end the end of the second sequence of functions.
28074 ///
28075 /// @param m the function_decl* <-> string map to be used by this
28076 /// function to generate strings associated to a function.
28077 ///
28078 /// @param o the output stream where to emit the generated list of
28079 /// strings to.
28080 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)28081 fns_to_str(vector<function_decl*>::const_iterator a_begin,
28082 vector<function_decl*>::const_iterator a_end,
28083 vector<function_decl*>::const_iterator b_begin,
28084 vector<function_decl*>::const_iterator b_end,
28085 fns_to_str_map_type& m,
28086 std::ostream& o)
28087 {
28088 fns_to_str(a_begin, a_end, m, o);
28089 o << "->|<- ";
28090 fns_to_str(b_begin, b_end, m, o);
28091 o << "\n";
28092 }
28093
28094 /// For each sequence of functions given in argument, generate a
28095 /// sequence of string that matches a given sequence of function. In
28096 /// the resulting sequence, each function is "uniquely representated"
28097 /// by a string. For instance, if the same function "foo" appears at
28098 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
28099 /// care about the actual string) would appear at index 1 and 3.
28100 ///
28101 /// @param a_begin the beginning of the sequence of functions to consider.
28102 ///
28103 /// @param a_end the end of the sequence of functions. This points to
28104 /// one-passed-the-end of the actual sequence.
28105 ///
28106 /// @param b_begin the beginning of the second sequence of functions
28107 /// to consider.
28108 ///
28109 /// @param b_end the end of the second sequence of functions.
28110 ///
28111 /// @param o the output stream where to emit the generated list of
28112 /// strings to.
28113 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)28114 fns_to_str(vector<function_decl*>::const_iterator a_begin,
28115 vector<function_decl*>::const_iterator a_end,
28116 vector<function_decl*>::const_iterator b_begin,
28117 vector<function_decl*>::const_iterator b_end,
28118 std::ostream& o)
28119 {
28120 fns_to_str_map_type m;
28121 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
28122 }
28123
28124 // </debugging facilities>
28125
28126 // </class template>
28127
28128 }// end namespace ir
28129 }//end namespace abigail
28130
28131 namespace
28132 {
28133
28134 /// Update the qualified parent name, qualified name and scoped name
28135 /// of a tree decl node.
28136 ///
28137 /// @return true if the tree walking should continue, false otherwise.
28138 ///
28139 /// @param d the tree node to take in account.
28140 bool
do_update(abigail::ir::decl_base * d)28141 qualified_name_setter::do_update(abigail::ir::decl_base* d)
28142 {
28143 std::string parent_qualified_name;
28144 abigail::ir::scope_decl* parent = d->get_scope();
28145 if (parent)
28146 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
28147 else
28148 d->priv_->qualified_parent_name_ = abigail::interned_string();
28149
28150 const abigail::ir::environment& env = d->get_environment();
28151
28152 if (!d->priv_->qualified_parent_name_.empty())
28153 {
28154 if (d->get_name().empty())
28155 d->priv_->qualified_name_ = abigail::interned_string();
28156 else
28157 {
28158 d->priv_->qualified_name_ =
28159 env.intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
28160 d->priv_->internal_qualified_name_ = env.intern(d->get_name());
28161 }
28162 }
28163
28164 if (d->priv_->scoped_name_.empty())
28165 {
28166 if (parent
28167 && !parent->get_is_anonymous()
28168 && !parent->get_name().empty())
28169 d->priv_->scoped_name_ =
28170 env.intern(parent->get_name() + "::" + d->get_name());
28171 else
28172 d->priv_->scoped_name_ =
28173 env.intern(d->get_name());
28174 }
28175
28176 if (!is_scope_decl(d))
28177 return false;
28178
28179 return true;
28180 }
28181
28182 /// This is called when we start visiting a decl node, during the
28183 /// udpate of the qualified name of a given sub-tree.
28184 ///
28185 /// @param d the decl node we are visiting.
28186 ///
28187 /// @return true iff the traversal should keep going.
28188 bool
visit_begin(abigail::ir::decl_base * d)28189 qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
28190 {return do_update(d);}
28191
28192 /// This is called when we start visiting a type node, during the
28193 /// udpate of the qualified name of a given sub-tree.
28194 ///
28195 /// @param d the decl node we are visiting.
28196 ///
28197 /// @return true iff the traversal should keep going.
28198 bool
visit_begin(abigail::ir::type_base * t)28199 qualified_name_setter::visit_begin(abigail::ir::type_base* t)
28200 {
28201 if (abigail::ir::decl_base* d = get_type_declaration(t))
28202 return do_update(d);
28203 return false;
28204 }
28205 }// end anonymous namespace.
28206