1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- mode: C++ -*-
3 //
4 // Copyright (C) 2013-2020 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 <tuple>
22 #include <utility>
23 #include <vector>
24
25 #include "abg-internal.h"
26 // <headers defining libabigail's API go under here>
27 ABG_BEGIN_EXPORT_DECLARATIONS
28
29 #include "abg-interned-str.h"
30 #include "abg-ir.h"
31 #include "abg-corpus.h"
32 #include "abg-corpus-priv.h"
33
34 ABG_END_EXPORT_DECLARATIONS
35 // </headers defining libabigail's API>
36
37 #include "abg-cxx-compat.h" // for abg_compat::optional
38 #include "abg-tools-utils.h"
39 #include "abg-comp-filter.h"
40 #include "abg-ir-priv.h"
41
42 namespace
43 {
44 /// This internal type is a tree walker that walks the sub-tree of a
45 /// type and sets the environment of the type (including its sub-type)
46 /// to a new environment.
47 class environment_setter : public abigail::ir::ir_node_visitor
48 {
49 const abigail::ir::environment* env_;
50
51 public:
environment_setter(const abigail::ir::environment * env)52 environment_setter(const abigail::ir::environment* env)
53 : env_(env)
54 {}
55
56 /// This function is called on each sub-tree node that is a
57 /// declaration. Note that it's also called on some types because
58 /// most types that have a declarations also inherit the type @ref
59 /// decl_base.
60 ///
61 /// @param d the declaration being visited.
62 bool
visit_begin(abigail::ir::decl_base * d)63 visit_begin(abigail::ir::decl_base* d)
64 {
65 if (const abigail::ir::environment* env = d->get_environment())
66 {
67 ABG_ASSERT(env == env_);
68 return false;
69 }
70 else
71 d->set_environment(env_);
72
73 return true;
74
75 }
76
77 /// This function is called on each sub-tree node that is a type.
78 ///
79 /// @param t the type being visited.
80 bool
visit_begin(abigail::ir::type_base * t)81 visit_begin(abigail::ir::type_base* t)
82 {
83 if (abigail::ir::environment* env = t->get_environment())
84 {
85 ABG_ASSERT(env == env_);
86 return false;
87 }
88 else
89 {
90 ABG_ASSERT(!t->get_environment());
91 t->set_environment(env_);
92 }
93 return true;
94 }
95 };
96
97 /// This internal type is a tree walking that is used to set the
98 /// qualified name of a tree of decls and types. It used by the
99 /// function update_qualified_name().
100 class qualified_name_setter : public abigail::ir::ir_node_visitor
101 {
102
103 public:
104 bool
105 do_update(abigail::ir::decl_base* d);
106
107 bool
108 visit_begin(abigail::ir::decl_base* d);
109
110 bool
111 visit_begin(abigail::ir::type_base* d);
112 }; // end class qualified_name_setter
113
114 }// end anon namespace
115
116 namespace abigail
117 {
118
119 // Inject.
120 using std::string;
121 using std::list;
122 using std::vector;
123 using std::unordered_map;
124 using std::dynamic_pointer_cast;
125 using std::static_pointer_cast;
126
127 /// Convenience typedef for a map of string -> string*.
128 typedef unordered_map<string, string*> pool_map_type;
129
130 /// The type of the private data structure of type @ref
131 /// intered_string_pool.
132 struct interned_string_pool::priv
133 {
134 pool_map_type map;
135 }; //end struc struct interned_string_pool::priv
136
137 /// Default constructor.
interned_string_pool()138 interned_string_pool::interned_string_pool()
139 : priv_(new priv)
140 {
141 priv_->map[""] = 0;
142 }
143
144 /// Test if the interned string pool already contains a string with a
145 /// given value.
146 ///
147 /// @param s the string to test for.
148 ///
149 /// @return true if the pool contains a string with the value @p s.
150 bool
has_string(const char * s) const151 interned_string_pool::has_string(const char* s) const
152 {return priv_->map.find(s) != priv_->map.end();}
153
154 /// Get a pointer to the interned string which has a given value.
155 ///
156 /// @param s the value of the interned string to look for.
157 ///
158 /// @return a pointer to the raw string of characters which has the
159 /// value of @p s. Or null if no string with value @p s was interned.
160 const char*
get_string(const char * s) const161 interned_string_pool::get_string(const char* s) const
162 {
163 unordered_map<string, string*>::const_iterator i =
164 priv_->map.find(s);
165 if (i == priv_->map.end())
166 return 0;
167 if (i->second)
168 return i->second->c_str();
169 return "";
170 }
171
172 /// Create an interned string with a given value.
173 ///
174 /// @param str_value the value of the interned string to create.
175 ///
176 /// @return the new created instance of @ref interned_string created.
177 interned_string
create_string(const std::string & str_value)178 interned_string_pool::create_string(const std::string& str_value)
179 {
180 string*& result = priv_->map[str_value];
181 if (!result && !str_value.empty())
182 result = new string(str_value);
183 return interned_string(result);
184 }
185
186 /// Destructor.
~interned_string_pool()187 interned_string_pool::~interned_string_pool()
188 {
189 for (pool_map_type::iterator i = priv_->map.begin();
190 i != priv_->map.end();
191 ++i)
192 if (i->second)
193 delete i->second;
194 }
195
196 /// Equality operator.
197 ///
198 /// @param l the instance of std::string on the left-hand-side of the
199 /// equality operator.
200 ///
201 /// @param r the instance of @ref interned_string on the
202 /// right-hand-side of the equality operator.
203 ///
204 /// @return true iff the two string are equal.
205 bool
operator ==(const std::string & l,const interned_string & r)206 operator==(const std::string& l, const interned_string& r)
207 {return r.operator==(l);}
208
209 bool
operator !=(const std::string & l,const interned_string & r)210 operator!=(const std::string& l, const interned_string& r)
211 {return !(l == r);}
212
213 /// Streaming operator.
214 ///
215 /// Streams an instance of @ref interned_string to an output stream.
216 ///
217 /// @param o the destination output stream.
218 ///
219 /// @param s the instance of @ref interned_string to stream out.
220 ///
221 /// @return the output stream this function just streamed to.
222 std::ostream&
operator <<(std::ostream & o,const interned_string & s)223 operator<<(std::ostream& o, const interned_string& s)
224 {
225 o << static_cast<std::string>(s);
226 return o;
227 }
228
229 /// Concatenation operator.
230 ///
231 /// Concatenate two instances of @ref interned_string, builds an
232 /// instance of std::string with the resulting string and return it.
233 ///
234 /// @param s1 the first string to consider.
235 ///
236 /// @param s2 the second string to consider.
237 ///
238 /// @return the resuting concatenated string.
239 std::string
operator +(const interned_string & s1,const std::string & s2)240 operator+(const interned_string& s1,const std::string& s2)
241 {return static_cast<std::string>(s1) + s2;}
242
243 /// Concatenation operator.
244 ///
245 /// Concatenate two instances of @ref interned_string, builds an
246 /// instance of std::string with the resulting string and return it.
247 ///
248 /// @param s1 the first string to consider.
249 ///
250 /// @param s2 the second string to consider.
251 ///
252 /// @return the resuting concatenated string.
253 std::string
operator +(const std::string & s1,const interned_string & s2)254 operator+(const std::string& s1, const interned_string& s2)
255 {return s1 + static_cast<std::string>(s2);}
256
257 namespace ir
258 {
259
260 static size_t
261 hash_as_canonical_type_or_constant(const type_base *t);
262
263 static bool
264 has_generic_anonymous_internal_type_name(const decl_base *d);
265
266 static interned_string
267 get_generic_anonymous_internal_type_name(const decl_base *d);
268
269 static void
270 update_qualified_name(decl_base * d);
271
272 static void
273 update_qualified_name(decl_base_sptr d);
274
275 void
276 push_composite_type_comparison_operands(const type_base& left,
277 const type_base& right);
278
279 void
280 pop_composite_type_comparison_operands(const type_base& left,
281 const type_base& right);
282
283 bool
284 mark_dependant_types_compared_until(const type_base &r);
285
286 /// Push a pair of operands on the stack of operands of the current
287 /// type comparison, during type canonicalization.
288 ///
289 /// For more information on this, please look at the description of
290 /// the environment::priv::right_type_comp_operands_ data member.
291 ///
292 /// @param left the left-hand-side comparison operand to push.
293 ///
294 /// @param right the right-hand-side comparison operand to push.
295 void
push_composite_type_comparison_operands(const type_base & left,const type_base & right)296 push_composite_type_comparison_operands(const type_base& left,
297 const type_base& right)
298 {
299 const environment * env = left.get_environment();
300 env->priv_->push_composite_type_comparison_operands(&left, &right);
301 }
302
303 /// Pop a pair of operands from the stack of operands to the current
304 /// type comparison.
305 ///
306 /// For more information on this, please look at the description of
307 /// the environment::privright_type_comp_operands_ data member.
308 ///
309 /// @param left the left-hand-side comparison operand we expect to
310 /// pop from the top of the stack. If this doesn't match the
311 /// operand found on the top of the stack, the function aborts.
312 ///
313 /// @param right the right-hand-side comparison operand we expect to
314 /// pop from the bottom of the stack. If this doesn't match the
315 /// operand found on the top of the stack, the function aborts.
316 void
pop_composite_type_comparison_operands(const type_base & left,const type_base & right)317 pop_composite_type_comparison_operands(const type_base& left,
318 const type_base& right)
319 {
320 const environment * env = left.get_environment();
321 env->priv_->pop_composite_type_comparison_operands(&left, &right);
322 }
323
324 /// In the stack of the current types being compared (as part of type
325 /// canonicalization), mark all the types that comes after a certain
326 /// one as NOT being eligible to the canonical type propagation
327 /// optimization.
328 ///
329 /// For a starter, please read about the @ref
330 /// OnTheFlyCanonicalization, aka, "canonical type propagation
331 /// optimization".
332 ///
333 /// To implement that optimization, we need, among other things to
334 /// maintain stack of the types (and their sub-types) being
335 /// currently compared as part of type canonicalization.
336 ///
337 /// Note that we only consider the type that is the right-hand-side
338 /// operand of the comparison because it's that one that is being
339 /// canonicalized and thus, that is not yet canonicalized.
340 ///
341 /// The reason why a type is deemed NON-eligible to the canonical
342 /// type propagation optimization is that it "depends" on
343 /// recursively present type. Let me explain.
344 ///
345 /// Suppose we have a type T that has sub-types named ST0 and ST1.
346 /// Suppose ST1 itself has a sub-type that is T itself. In this
347 /// case, we say that T is a recursive type, because it has T
348 /// (itself) as one of its sub-types:
349 ///
350 /// T
351 /// +-- ST0
352 /// |
353 /// +-- ST1
354 /// +
355 /// |
356 /// +-- T
357 ///
358 /// ST1 is said to "depend" on T because it has T as a sub-type.
359 /// But because T is recursive, then ST1 is said to depend on a
360 /// recursive type. Notice however that ST0 does not depend on any
361 /// recursive type.
362 ///
363 /// When we are at the point of comparing the sub-type T of ST1
364 /// against its counterpart, the stack of the right-hand-side
365 /// operands of the type canonicalization is going to look like
366 /// this:
367 ///
368 /// | T | ST1 |
369 ///
370 /// We don't add the type T to the stack as we detect that T was
371 /// already in there (recursive cycle).
372 ///
373 /// So, this function will basically mark ST1 as being NON-eligible
374 /// to being the target of canonical type propagation, by marking ST1
375 /// as being dependant on T.
376 ///
377 /// @param right the right-hand-side operand of the type comparison.
378 ///
379 /// @return true iff the operation was successful.
380 bool
mark_dependant_types_compared_until(const type_base & r)381 mark_dependant_types_compared_until(const type_base &r)
382 {
383 const environment * env = r.get_environment();
384 return env->priv_->mark_dependant_types_compared_until(&r);
385 }
386
387 /// @brief the location of a token represented in its simplest form.
388 /// Instances of this type are to be stored in a sorted vector, so the
389 /// type must have proper relational operators.
390 class expanded_location
391 {
392 string path_;
393 unsigned line_;
394 unsigned column_;
395
396 expanded_location();
397
398 public:
399
400 friend class location_manager;
401
expanded_location(const string & path,unsigned line,unsigned column)402 expanded_location(const string& path, unsigned line, unsigned column)
403 : path_(path), line_(line), column_(column)
404 {}
405
406 bool
operator ==(const expanded_location & l) const407 operator==(const expanded_location& l) const
408 {
409 return (path_ == l.path_
410 && line_ == l.line_
411 && column_ && l.column_);
412 }
413
414 bool
operator <(const expanded_location & l) const415 operator<(const expanded_location& l) const
416 {
417 if (path_ < l.path_)
418 return true;
419 else if (path_ > l.path_)
420 return false;
421
422 if (line_ < l.line_)
423 return true;
424 else if (line_ > l.line_)
425 return false;
426
427 return column_ < l.column_;
428 }
429 };
430
431 /// Expand the location into a tripplet path, line and column number.
432 ///
433 /// @param path the output parameter where this function sets the
434 /// expanded path.
435 ///
436 /// @param line the output parameter where this function sets the
437 /// expanded line.
438 ///
439 /// @param column the ouptut parameter where this function sets the
440 /// expanded column.
441 void
expand(std::string & path,unsigned & line,unsigned & column) const442 location::expand(std::string& path, unsigned& line, unsigned& column) const
443 {
444 if (!get_location_manager())
445 {
446 // We don't have a location manager maybe because this location
447 // was just freshly instanciated. We still want to be able to
448 // expand to default values.
449 path = "";
450 line = 0;
451 column = 0;
452 return;
453 }
454 get_location_manager()->expand_location(*this, path, line, column);
455 }
456
457
458 /// Expand the location into a string.
459 ///
460 /// @return the string representing the location.
461 string
expand(void) const462 location::expand(void) const
463 {
464 string path, result;
465 unsigned line = 0, column = 0;
466 expand(path, line, column);
467
468 std::ostringstream o;
469 o << path << ":" << line << ":" << column;
470 return o.str();
471 }
472
473 struct location_manager::priv
474 {
475 /// This sorted vector contains the expanded locations of the tokens
476 /// coming from a given ABI Corpus. The index of a given expanded
477 /// location in the table gives us an integer that is used to build
478 /// instance of location types.
479 std::vector<expanded_location> locs;
480 };
481
location_manager()482 location_manager::location_manager()
483 : priv_(new location_manager::priv)
484 {}
485
486 location_manager::~location_manager() = default;
487
488 /// Insert the triplet representing a source locus into our internal
489 /// vector of location triplet. Return an instance of location type,
490 /// built from an integral type that represents the index of the
491 /// source locus triplet into our source locus table.
492 ///
493 /// @param file_path the file path of the source locus
494 /// @param line the line number of the source location
495 /// @param col the column number of the source location
496 location
create_new_location(const std::string & file_path,size_t line,size_t col)497 location_manager::create_new_location(const std::string& file_path,
498 size_t line,
499 size_t col)
500 {
501 expanded_location l(file_path, line, col);
502
503 // Just append the new expanded location to the end of the vector
504 // and return its index. Note that indexes start at 1.
505 priv_->locs.push_back(l);
506 return location(priv_->locs.size(), this);
507 }
508
509 /// Given an instance of location type, return the triplet
510 /// {path,line,column} that represents the source locus. Note that
511 /// the location must have been previously created from the function
512 /// location_manager::create_new_location, otherwise this function yields
513 /// unexpected results, including possibly a crash.
514 ///
515 /// @param location the instance of location type to expand
516 /// @param path the resulting path of the source locus
517 /// @param line the resulting line of the source locus
518 /// @param column the resulting colum of the source locus
519 void
expand_location(const location & location,std::string & path,unsigned & line,unsigned & column) const520 location_manager::expand_location(const location& location,
521 std::string& path,
522 unsigned& line,
523 unsigned& column) const
524 {
525 if (location.value_ == 0)
526 return;
527 expanded_location &l = priv_->locs[location.value_ - 1];
528 path = l.path_;
529 line = l.line_;
530 column = l.column_;
531 }
532
533 typedef unordered_map<function_type_sptr,
534 bool,
535 function_type::hash,
536 type_shared_ptr_equal> fn_type_ptr_map;
537
538 // <type_maps stuff>
539
540 struct type_maps::priv
541 {
542 mutable istring_type_base_wptrs_map_type basic_types_;
543 mutable istring_type_base_wptrs_map_type class_types_;
544 mutable istring_type_base_wptrs_map_type union_types_;
545 mutable istring_type_base_wptrs_map_type enum_types_;
546 mutable istring_type_base_wptrs_map_type typedef_types_;
547 mutable istring_type_base_wptrs_map_type qualified_types_;
548 mutable istring_type_base_wptrs_map_type pointer_types_;
549 mutable istring_type_base_wptrs_map_type reference_types_;
550 mutable istring_type_base_wptrs_map_type array_types_;
551 mutable istring_type_base_wptrs_map_type subrange_types_;
552 mutable istring_type_base_wptrs_map_type function_types_;
553 mutable vector<type_base_wptr> sorted_types_;
554 }; // end struct type_maps::priv
555
type_maps()556 type_maps::type_maps()
557 : priv_(new priv)
558 {}
559
560 type_maps::~type_maps() = default;
561
562 /// Test if the type_maps is empty.
563 ///
564 /// @return true iff the type_maps is empty.
565 bool
empty() const566 type_maps::empty() const
567 {
568 return (basic_types().empty()
569 && class_types().empty()
570 && union_types().empty()
571 && enum_types().empty()
572 && typedef_types().empty()
573 && qualified_types().empty()
574 && pointer_types().empty()
575 && reference_types().empty()
576 && array_types().empty()
577 && subrange_types().empty()
578 && function_types().empty());
579 }
580
581 /// Getter for the map that associates the name of a basic type to the
582 /// vector instances of type_decl_sptr that represents that type.
583 const istring_type_base_wptrs_map_type&
basic_types() const584 type_maps::basic_types() const
585 {return priv_->basic_types_;}
586
587 /// Getter for the map that associates the name of a basic type to the
588 /// vector of instances of @ref type_decl_sptr that represents that
589 /// type.
590 istring_type_base_wptrs_map_type&
basic_types()591 type_maps::basic_types()
592 {return priv_->basic_types_;}
593
594 /// Getter for the map that associates the name of a class type to the
595 /// vector of instances of @ref class_decl_sptr that represents that
596 /// type.
597 const istring_type_base_wptrs_map_type&
class_types() const598 type_maps::class_types() const
599 {return priv_->class_types_;}
600
601 /// Getter for the map that associates the name of a class type to the
602 /// vector of instances of @ref class_decl_sptr that represents that
603 /// type.
604 istring_type_base_wptrs_map_type&
class_types()605 type_maps::class_types()
606 {return priv_->class_types_;}
607
608 /// Getter for the map that associates the name of a union type to the
609 /// vector of instances of @ref union_decl_sptr that represents that
610 /// type.
611 istring_type_base_wptrs_map_type&
union_types()612 type_maps::union_types()
613 {return priv_->union_types_;}
614
615 /// Getter for the map that associates the name of a union type to the
616 /// vector of instances of @ref union_decl_sptr that represents that
617 /// type.
618 const istring_type_base_wptrs_map_type&
union_types() const619 type_maps::union_types() const
620 {return priv_->union_types_;}
621
622 /// Getter for the map that associates the name of an enum type to the
623 /// vector of instances of @ref enum_type_decl_sptr that represents
624 /// that type.
625 istring_type_base_wptrs_map_type&
enum_types()626 type_maps::enum_types()
627 {return priv_->enum_types_;}
628
629 /// Getter for the map that associates the name of an enum type to the
630 /// vector of instances of @ref enum_type_decl_sptr that represents
631 /// that type.
632 const istring_type_base_wptrs_map_type&
enum_types() const633 type_maps::enum_types() const
634 {return priv_->enum_types_;}
635
636 /// Getter for the map that associates the name of a typedef to the
637 /// vector of instances of @ref typedef_decl_sptr that represents tha
638 /// type.
639 istring_type_base_wptrs_map_type&
typedef_types()640 type_maps::typedef_types()
641 {return priv_->typedef_types_;}
642
643 /// Getter for the map that associates the name of a typedef to the
644 /// vector of instances of @ref typedef_decl_sptr that represents tha
645 /// type.
646 const istring_type_base_wptrs_map_type&
typedef_types() const647 type_maps::typedef_types() const
648 {return priv_->typedef_types_;}
649
650 /// Getter for the map that associates the name of a qualified type to
651 /// the vector of instances of @ref qualified_type_def_sptr.
652 istring_type_base_wptrs_map_type&
qualified_types()653 type_maps::qualified_types()
654 {return priv_->qualified_types_;}
655
656 /// Getter for the map that associates the name of a qualified type to
657 /// the vector of instances of @ref qualified_type_def_sptr.
658 const istring_type_base_wptrs_map_type&
qualified_types() const659 type_maps::qualified_types() const
660 {return priv_->qualified_types_;}
661
662 /// Getter for the map that associates the name of a pointer type to
663 /// the vector of instances of @ref pointer_type_def_sptr that
664 /// represents that type.
665 istring_type_base_wptrs_map_type&
pointer_types()666 type_maps::pointer_types()
667 {return priv_->pointer_types_;}
668
669 /// Getter for the map that associates the name of a pointer type to
670 /// the vector of instances of @ref pointer_type_def_sptr that
671 /// represents that type.
672 const istring_type_base_wptrs_map_type&
pointer_types() const673 type_maps::pointer_types() const
674 {return priv_->pointer_types_;}
675
676 /// Getter for the map that associates the name of a reference type to
677 /// the vector of instances of @ref reference_type_def_sptr that
678 /// represents that type.
679 istring_type_base_wptrs_map_type&
reference_types()680 type_maps::reference_types()
681 {return priv_->reference_types_;}
682
683 /// Getter for the map that associates the name of a reference type to
684 /// the vector of instances of @ref reference_type_def_sptr that
685 /// represents that type.
686 const istring_type_base_wptrs_map_type&
reference_types() const687 type_maps::reference_types() const
688 {return priv_->reference_types_;}
689
690 /// Getter for the map that associates the name of an array type to
691 /// the vector of instances of @ref array_type_def_sptr that
692 /// represents that type.
693 istring_type_base_wptrs_map_type&
array_types()694 type_maps::array_types()
695 {return priv_->array_types_;}
696
697 /// Getter for the map that associates the name of an array type to
698 /// the vector of instances of @ref array_type_def_sptr that
699 /// represents that type.
700 const istring_type_base_wptrs_map_type&
array_types() const701 type_maps::array_types() const
702 {return priv_->array_types_;}
703
704 /// Getter for the map that associates the name of a subrange type to
705 /// the vector of instances of @ref array_type_def::subrange_sptr that
706 /// represents that type.
707 istring_type_base_wptrs_map_type&
subrange_types()708 type_maps::subrange_types()
709 {return priv_->subrange_types_;}
710
711 /// Getter for the map that associates the name of a subrange type to
712 /// the vector of instances of @ref array_type_def::subrange_sptr that
713 /// represents that type.
714 const istring_type_base_wptrs_map_type&
subrange_types() const715 type_maps::subrange_types() const
716 {return priv_->subrange_types_;}
717
718 /// Getter for the map that associates the name of a function type to
719 /// the vector of instances of @ref function_type_sptr that represents
720 /// that type.
721 const istring_type_base_wptrs_map_type&
function_types() const722 type_maps::function_types() const
723 {return priv_->function_types_;}
724
725 /// Getter for the map that associates the name of a function type to
726 /// the vector of instances of @ref function_type_sptr that represents
727 /// that type.
728 istring_type_base_wptrs_map_type&
function_types()729 type_maps::function_types()
730 {return priv_->function_types_;}
731
732 /// A comparison functor to compare/sort types based on their pretty
733 /// representations.
734 struct type_name_comp
735 {
736 /// Comparison operator for two instances of @ref type_base.
737 ///
738 /// This compares the two types by lexicographically comparing their
739 /// pretty representation.
740 ///
741 /// @param l the left-most type to compare.
742 ///
743 /// @param r the right-most type to compare.
744 ///
745 /// @return true iff @p l < @p r.
746 bool
operator ()abigail::ir::type_name_comp747 operator()(type_base *l, type_base *r) const
748 {
749 if (l == 0 && r == 0)
750 return false;
751
752 string l_repr = get_pretty_representation(l);
753 string r_repr = get_pretty_representation(r);
754 return l_repr < r_repr;
755 }
756
757 /// Comparison operator for two instances of @ref type_base.
758 ///
759 /// This compares the two types by lexicographically comparing their
760 /// pretty representation.
761 ///
762 /// @param l the left-most type to compare.
763 ///
764 /// @param r the right-most type to compare.
765 ///
766 /// @return true iff @p l < @p r.
767 bool
operator ()abigail::ir::type_name_comp768 operator()(const type_base_sptr &l, const type_base_sptr &r) const
769 {return operator()(l.get(), r.get());}
770
771 /// Comparison operator for two instances of @ref type_base.
772 ///
773 /// This compares the two types by lexicographically comparing their
774 /// pretty representation.
775 ///
776 /// @param l the left-most type to compare.
777 ///
778 /// @param r the right-most type to compare.
779 ///
780 /// @return true iff @p l < @p r.
781 bool
operator ()abigail::ir::type_name_comp782 operator()(const type_base_wptr &l, const type_base_wptr &r) const
783 {return operator()(type_base_sptr(l), type_base_sptr(r));}
784 }; // end struct type_name_comp
785
786 #ifdef WITH_DEBUG_SELF_COMPARISON
787
788 /// This is a function called when the ABG_RETURN* macros defined
789 /// below return false.
790 ///
791 /// The purpose of this function is to ease debugging. To know where
792 /// the equality functions first compare non-equal, we can just set a
793 /// breakpoint on this notify_equality_failed function and run the
794 /// equality functions. Because all the equality functions use the
795 /// ABG_RETURN* macros to return their values, this function is always
796 /// called when any of those equality function return false.
797 ///
798 /// @param l the first operand of the equality.
799 ///
800 /// @param r the second operand of the equality.
801 static void
notify_equality_failed(const type_or_decl_base & l,const type_or_decl_base & r)802 notify_equality_failed(const type_or_decl_base &l __attribute__((unused)),
803 const type_or_decl_base &r __attribute__((unused)))
804 {}
805
806 /// This is a function called when the ABG_RETURN* macros defined
807 /// below return false.
808 ///
809 /// The purpose of this function is to ease debugging. To know where
810 /// the equality functions first compare non-equal, we can just set a
811 /// breakpoint on this notify_equality_failed function and run the
812 /// equality functions. Because all the equality functions use the
813 /// ABG_RETURN* macros to return their values, this function is always
814 /// called when any of those equality function return false.
815 ///
816 /// @param l the first operand of the equality.
817 ///
818 /// @param r the second operand of the equality.
819 static void
notify_equality_failed(const type_or_decl_base * l,const type_or_decl_base * r)820 notify_equality_failed(const type_or_decl_base *l __attribute__((unused)),
821 const type_or_decl_base *r __attribute__((unused)))
822 {}
823
824 #define ABG_RETURN_EQUAL(l, r) \
825 do \
826 { \
827 if (l != r) \
828 notify_equality_failed(l, r); \
829 return (l == r); \
830 } \
831 while(false)
832
833
834 #define ABG_RETURN_FALSE \
835 do \
836 { \
837 notify_equality_failed(l, r); \
838 return false; \
839 } while(false)
840
841 #define ABG_RETURN(value) \
842 do \
843 { \
844 if (value == false) \
845 notify_equality_failed(l, r); \
846 return value; \
847 } while (false)
848
849 #else // WITH_DEBUG_SELF_COMPARISON
850
851 #define ABG_RETURN_FALSE return false
852 #define ABG_RETURN(value) return (value)
853 #define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
854 #endif
855
856 /// Compare two types by comparing their canonical types if present.
857 ///
858 /// If the canonical types are not present (because the types have not
859 /// yet been canonicalized, for instance) then the types are compared
860 /// structurally.
861 ///
862 /// @param l the first type to take into account in the comparison.
863 ///
864 /// @param r the second type to take into account in the comparison.
865 template<typename T>
866 bool
try_canonical_compare(const T * l,const T * r)867 try_canonical_compare(const T *l, const T *r)
868 {
869 #if WITH_DEBUG_TYPE_CANONICALIZATION
870 // We are debugging the canonicalization of a type down the stack.
871 // 'l' is a subtype of a canonical type and 'r' is a subtype of the
872 // type being canonicalized. We are at a point where we can compare
873 // 'l' and 'r' either using canonical comparison (if 'l' and 'r'
874 // have canonical types) or structural comparison.
875 //
876 // Because we are debugging the process of type canonicalization, we
877 // want to compare 'l' and 'r' canonically *AND* structurally. Both
878 // kinds of comparison should yield the same result, otherwise type
879 // canonicalization just failed for the subtype 'r' of the type
880 // being canonicalized.
881 //
882 // In concrete terms, this function is going to be called twice with
883 // the same pair {'l', 'r'} to compare: The first time with
884 // environment::priv_->use_canonical_type_comparison_ set to true,
885 // instructing us to compare them canonically, and the second time
886 // with that boolean set to false, instructing us to compare them
887 // structurally.
888 const environment *env = l->get_environment();
889 if (env->priv_->use_canonical_type_comparison_)
890 {
891 if (const type_base *lc = l->get_naked_canonical_type())
892 if (const type_base *rc = r->get_naked_canonical_type())
893 ABG_RETURN_EQUAL(lc, rc);
894 }
895 return equals(*l, *r, 0);
896 #else
897 if (const type_base *lc = l->get_naked_canonical_type())
898 if (const type_base *rc = r->get_naked_canonical_type())
899 ABG_RETURN_EQUAL(lc, rc);
900 return equals(*l, *r, 0);
901 #endif
902
903
904 }
905
906 /// Detect if a recursive comparison cycle is detected while
907 /// structurally comparing two types (a.k.a member-wise comparison).
908 ///
909 /// @param l the left-hand-side operand of the current comparison.
910 ///
911 /// @param r the right-hand-side operand of the current comparison.
912 ///
913 /// @return true iff a comparison cycle is detected.
914 template<typename T>
915 bool
is_comparison_cycle_detected(T & l,T & r)916 is_comparison_cycle_detected(T& l, T& r)
917 {
918 bool result = (l.priv_->comparison_started(l)
919 || l.priv_->comparison_started(r));
920 return result ;
921 }
922
923 /// This macro is to be used while comparing composite types that
924 /// might recursively refer to themselves. Comparing two such types
925 /// might get us into a cyle.
926 ///
927 /// Practically, if we detect that we are already into comparing 'l'
928 /// and 'r'; then, this is a cycle.
929 //
930 /// To break the cycle, we assume the result of the comparison is true
931 /// for now. Comparing the other sub-types of l & r will tell us later
932 /// if l & r are actually different or not.
933 ///
934 /// In the mean time, returning true from this macro should not be
935 /// used to propagate the canonical type of 'l' onto 'r' as we don't
936 /// know yet if l equals r. All the types that depend on l and r
937 /// can't (and that are in the comparison stack currently) can't have
938 /// their canonical type propagated either. So this macro disallows
939 /// canonical type propagation for those types that depend on a
940 /// recursively defined sub-type for now.
941 ///
942 /// @param l the left-hand-side operand of the comparison.
943 #define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
944 do \
945 { \
946 if (is_comparison_cycle_detected(l, r)) \
947 { \
948 mark_dependant_types_compared_until(r); \
949 return true; \
950 } \
951 } \
952 while(false)
953
954
955 /// Mark a pair of types as being compared.
956 ///
957 /// This is helpful to later detect recursive cycles in the comparison
958 /// stack.
959 ///
960 /// @param l the left-hand-side operand of the comparison.
961 ///
962 /// @parm r the right-hand-side operand of the comparison.
963 template<typename T>
964 void
mark_types_as_being_compared(T & l,T & r)965 mark_types_as_being_compared(T& l, T&r)
966 {
967 l.priv_->mark_as_being_compared(l);
968 l.priv_->mark_as_being_compared(r);
969 push_composite_type_comparison_operands(l, r);
970 }
971
972 /// Mark a pair of types as being not compared anymore.
973 ///
974 /// This is helpful to later detect recursive cycles in the comparison
975 /// stack.
976 ///
977 /// Note that the types must have been passed to
978 /// mark_types_as_being_compared prior to calling this function.
979 ///
980 /// @param l the left-hand-side operand of the comparison.
981 ///
982 /// @parm r the right-hand-side operand of the comparison.
983 template<typename T>
984 void
unmark_types_as_being_compared(T & l,T & r)985 unmark_types_as_being_compared(T& l, T&r)
986 {
987 l.priv_->unmark_as_being_compared(l);
988 l.priv_->unmark_as_being_compared(r);
989 pop_composite_type_comparison_operands(l, 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 (propagate_canonical_type && 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_->right_type_comp_operands_.empty()
1035 && is_type(&r)->priv_->canonical_type_propagated())
1036 {
1037 // Track the object 'r' for which the propagated canonical
1038 // type might be re-initialized if the current comparison
1039 // eventually fails.
1040 env->priv_->types_with_non_confirmed_propagated_ct_.insert
1041 (reinterpret_cast<uintptr_t>(is_type(&r)));
1042 }
1043 else if (value == true && env->priv_->right_type_comp_operands_.empty())
1044 {
1045 // The type provided in the 'r' argument is the type that is
1046 // being canonicalized; 'r' is not a mere subtype being
1047 // compared, it's the whole type being canonicalized. And
1048 // its canonicalization has just succeeded. So let's
1049 // confirm the "canonical type propagation" of all the
1050 // sub-types that were compared during the comparison of
1051 // 'r'.
1052 env->priv_->confirm_ct_propagation(&r);
1053 if (is_type(&r)->priv_->depends_on_recursive_type())
1054 {
1055 is_type(&r)->priv_->set_does_not_depend_on_recursive_type();
1056 env->priv_->remove_from_types_with_non_confirmed_propagated_ct(&r);
1057 }
1058 }
1059 else if (value == false)
1060 {
1061 // The comparison of the current sub-type failed. So all
1062 // the types in
1063 // env->prix_->types_with_non_confirmed_propagated_ct_
1064 // should see their tentatively propagated canonical type
1065 // cancelled.
1066 env->priv_->cancel_ct_propagation(&r);
1067 if (is_type(&r)->priv_->depends_on_recursive_type())
1068 {
1069 // The right-hand-side operand cannot carry any tentative
1070 // canonical type at this point.
1071 is_type(&r)->priv_->clear_propagated_canonical_type();
1072 // Reset the marking of the right-hand-side operand as it no
1073 // longer carries a tentative canonical type that might be
1074 // later cancelled.
1075 is_type(&r)->priv_->set_does_not_depend_on_recursive_type();
1076 env->priv_->remove_from_types_with_non_confirmed_propagated_ct(&r);
1077 }
1078 }
1079 }
1080 ABG_RETURN(value);
1081 }
1082
1083 /// Getter of all types types sorted by their pretty representation.
1084 ///
1085 /// @return a sorted vector of all types sorted by their pretty
1086 /// representation.
1087 const vector<type_base_wptr>&
get_types_sorted_by_name() const1088 type_maps::get_types_sorted_by_name() const
1089 {
1090 if (priv_->sorted_types_.empty())
1091 {
1092 istring_type_base_wptrs_map_type::const_iterator i;
1093 vector<type_base_wptr>::const_iterator j;
1094
1095 for (i = basic_types().begin(); i != basic_types().end(); ++i)
1096 for (j = i->second.begin(); j != i->second.end(); ++j)
1097 priv_->sorted_types_.push_back(*j);
1098
1099 for (i = class_types().begin(); i != class_types().end(); ++i)
1100 for (j = i->second.begin(); j != i->second.end(); ++j)
1101 priv_->sorted_types_.push_back(*j);
1102
1103 for (i = union_types().begin(); i != union_types().end(); ++i)
1104 for (j = i->second.begin(); j != i->second.end(); ++j)
1105 priv_->sorted_types_.push_back(*j);
1106
1107 for (i = enum_types().begin(); i != enum_types().end(); ++i)
1108 for (j = i->second.begin(); j != i->second.end(); ++j)
1109 priv_->sorted_types_.push_back(*j);
1110
1111 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
1112 for (j = i->second.begin(); j != i->second.end(); ++j)
1113 priv_->sorted_types_.push_back(*j);
1114
1115 type_name_comp comp;
1116 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1117 }
1118
1119 return priv_->sorted_types_;
1120 }
1121
1122 // </type_maps stuff>
1123
1124 // <translation_unit stuff>
1125
1126 /// Constructor of translation_unit.
1127 ///
1128 /// @param env the environment of this translation unit. Please note
1129 /// that the life time of the environment must be greater than the
1130 /// life time of the translation unit because the translation uses
1131 /// resources that are allocated in the environment.
1132 ///
1133 /// @param path the location of the translation unit.
1134 ///
1135 /// @param address_size the size of addresses in the translation unit,
1136 /// in bits.
translation_unit(const environment * env,const std::string & path,char address_size)1137 translation_unit::translation_unit(const environment* env,
1138 const std::string& path,
1139 char address_size)
1140 : priv_(new priv(env))
1141 {
1142 priv_->path_ = path;
1143 priv_->address_size_ = address_size;
1144 }
1145
1146 /// Getter of the the global scope of the translation unit.
1147 ///
1148 /// @return the global scope of the current translation unit. If
1149 /// there is not global scope allocated yet, this function creates one
1150 /// and returns it.
1151 const scope_decl_sptr&
get_global_scope() const1152 translation_unit::get_global_scope() const
1153 {
1154 return const_cast<translation_unit*>(this)->get_global_scope();
1155 }
1156
1157 /// Getter of the the global scope of the translation unit.
1158 ///
1159 /// @return the global scope of the current translation unit. If
1160 /// there is not global scope allocated yet, this function creates one
1161 /// and returns it.
1162 scope_decl_sptr&
get_global_scope()1163 translation_unit::get_global_scope()
1164 {
1165 if (!priv_->global_scope_)
1166 {
1167 priv_->global_scope_.reset
1168 (new global_scope(const_cast<translation_unit*>(this)));
1169 // The global scope must be out of the same environment as its
1170 // translation unit.
1171 priv_->global_scope_->
1172 set_environment(const_cast<environment*>(get_environment()));
1173 priv_->global_scope_->set_translation_unit
1174 (const_cast<translation_unit*>(this));
1175 }
1176 return priv_->global_scope_;
1177 }
1178
1179 /// Getter of the types of the current @ref translation_unit.
1180 ///
1181 /// @return the maps of the types of the translation unit.
1182 const type_maps&
get_types() const1183 translation_unit::get_types() const
1184 {return priv_->types_;}
1185
1186 /// Getter of the types of the current @ref translation_unit.
1187 ///
1188 /// @return the maps of the types of the translation unit.
1189 type_maps&
get_types()1190 translation_unit::get_types()
1191 {return priv_->types_;}
1192
1193 /// Get the vector of function types that are used in the current
1194 /// translation unit.
1195 ///
1196 /// @return the vector of function types that are used in the current
1197 /// translation unit.
1198 const vector<function_type_sptr>&
get_live_fn_types() const1199 translation_unit::get_live_fn_types() const
1200 {return priv_->live_fn_types_;}
1201
1202 /// Getter of the environment of the current @ref translation_unit.
1203 ///
1204 /// @return the translation unit of the current translation unit.
1205 const environment*
get_environment() const1206 translation_unit::get_environment() const
1207 {return priv_->env_;}
1208
1209 /// Getter of the environment of the current @ref translation_unit.
1210 ///
1211 /// @return the translation unit of the current translation unit.
1212 environment*
get_environment()1213 translation_unit::get_environment()
1214 {return const_cast<environment*>(priv_->env_);}
1215
1216 /// Setter of the environment of the current @ref translation_unit.
1217 ///
1218 /// @param env the environment.
1219 void
set_environment(const environment * env)1220 translation_unit::set_environment(const environment* env)
1221 {priv_->env_ = env;}
1222
1223 /// Getter of the language of the source code of the translation unit.
1224 ///
1225 /// @return the language of the source code.
1226 translation_unit::language
get_language() const1227 translation_unit::get_language() const
1228 {return priv_->language_;}
1229
1230 /// Setter of the language of the source code of the translation unit.
1231 ///
1232 /// @param l the new language.
1233 void
set_language(language l)1234 translation_unit::set_language(language l)
1235 {priv_->language_ = l;}
1236
1237
1238 /// Get the path of the current translation unit.
1239 ///
1240 /// This path is relative to the build directory of the translation
1241 /// unit as returned by translation_unit::get_compilation_dir_path.
1242 ///
1243 /// @return the relative path of the compilation unit associated to
1244 /// the current instance of translation_unit.
1245 //
1246 const std::string&
get_path() const1247 translation_unit::get_path() const
1248 {return priv_->path_;}
1249
1250 /// Set the path associated to the current instance of
1251 /// translation_unit.
1252 ///
1253 /// This path is relative to the build directory of the translation
1254 /// unit as returned by translation_unit::get_compilation_dir_path.
1255 ///
1256 /// @param a_path the new relative path to set.
1257 void
set_path(const string & a_path)1258 translation_unit::set_path(const string& a_path)
1259 {priv_->path_ = a_path;}
1260
1261
1262 /// Get the path of the directory that was 'current' when the
1263 /// translation unit was compiled.
1264 ///
1265 /// Note that the path returned by translation_unit::get_path is
1266 /// relative to the path returned by this function.
1267 ///
1268 /// @return the compilation directory for the current translation
1269 /// unit.
1270 const std::string&
get_compilation_dir_path() const1271 translation_unit::get_compilation_dir_path() const
1272 {return priv_->comp_dir_path_;}
1273
1274 /// Set the path of the directory that was 'current' when the
1275 /// translation unit was compiled.
1276 ///
1277 /// Note that the path returned by translation_unit::get_path is
1278 /// relative to the path returned by this function.
1279 ///
1280 /// @param the compilation directory for the current translation unit.
1281 void
set_compilation_dir_path(const std::string & d)1282 translation_unit::set_compilation_dir_path(const std::string& d)
1283 {priv_->comp_dir_path_ = d;}
1284
1285 /// Get the concatenation of the build directory and the relative path
1286 /// of the translation unit.
1287 ///
1288 /// @return the absolute path of the translation unit.
1289 const std::string&
get_absolute_path() const1290 translation_unit::get_absolute_path() const
1291 {
1292 if (priv_->abs_path_.empty())
1293 {
1294 string path;
1295 if (!priv_->path_.empty())
1296 {
1297 if (!priv_->comp_dir_path_.empty())
1298 {
1299 path = priv_->comp_dir_path_;
1300 path += "/";
1301 }
1302 path += priv_->path_;
1303 }
1304 priv_->abs_path_ = path;
1305 }
1306
1307 return priv_->abs_path_;
1308 }
1309
1310 /// Set the corpus this translation unit is a member of.
1311 ///
1312 /// Note that adding a translation unit to a @ref corpus automatically
1313 /// triggers a call to this member function.
1314 ///
1315 /// @param corpus the corpus.
1316 void
set_corpus(corpus * c)1317 translation_unit::set_corpus(corpus* c)
1318 {priv_->corp = c;}
1319
1320 /// Get the corpus this translation unit is a member of.
1321 ///
1322 /// @return the parent corpus, or nil if this doesn't belong to any
1323 /// corpus yet.
1324 corpus*
get_corpus()1325 translation_unit::get_corpus()
1326 {return priv_->corp;}
1327
1328 /// Get the corpus this translation unit is a member of.
1329 ///
1330 /// @return the parent corpus, or nil if this doesn't belong to any
1331 /// corpus yet.
1332 const corpus*
get_corpus() const1333 translation_unit::get_corpus() const
1334 {return const_cast<translation_unit*>(this)->get_corpus();}
1335
1336 /// Getter of the location manager for the current translation unit.
1337 ///
1338 /// @return a reference to the location manager for the current
1339 /// translation unit.
1340 location_manager&
get_loc_mgr()1341 translation_unit::get_loc_mgr()
1342 {return priv_->loc_mgr_;}
1343
1344 /// const Getter of the location manager.
1345 ///
1346 /// @return a const reference to the location manager for the current
1347 /// translation unit.
1348 const location_manager&
get_loc_mgr() const1349 translation_unit::get_loc_mgr() const
1350 {return priv_->loc_mgr_;}
1351
1352 /// Tests whether if the current translation unit contains ABI
1353 /// artifacts or not.
1354 ///
1355 /// @return true iff the current translation unit is empty.
1356 bool
is_empty() const1357 translation_unit::is_empty() const
1358 {return get_global_scope()->is_empty();}
1359
1360 /// Getter of the address size in this translation unit.
1361 ///
1362 /// @return the address size, in bits.
1363 char
get_address_size() const1364 translation_unit::get_address_size() const
1365 {return priv_->address_size_;}
1366
1367 /// Setter of the address size in this translation unit.
1368 ///
1369 /// @param a the new address size in bits.
1370 void
set_address_size(char a)1371 translation_unit::set_address_size(char a)
1372 {priv_->address_size_= a;}
1373
1374 /// Getter of the 'is_constructed" flag. It says if the translation
1375 /// unit is fully constructed or not.
1376 ///
1377 /// This flag is important for cases when comparison might depend on
1378 /// if the translation unit is fully built or not. For instance, when
1379 /// reading types from DWARF, the virtual methods of a class are not
1380 /// necessarily fully constructed until we have reached the end of the
1381 /// translation unit. In that case, before we've reached the end of
1382 /// the translation unit, we might not take virtual functions into
1383 /// account when comparing classes.
1384 ///
1385 /// @return true if the translation unit is constructed.
1386 bool
is_constructed() const1387 translation_unit::is_constructed() const
1388 {return priv_->is_constructed_;}
1389
1390 /// Setter of the 'is_constructed" flag. It says if the translation
1391 /// unit is fully constructed or not.
1392 ///
1393 /// This flag is important for cases when comparison might depend on
1394 /// if the translation unit is fully built or not. For instance, when
1395 /// reading types from DWARF, the virtual methods of a class are not
1396 /// necessarily fully constructed until we have reached the end of the
1397 /// translation unit. In that case, before we've reached the end of
1398 /// the translation unit, we might not take virtual functions into
1399 /// account when comparing classes.
1400 ///
1401 /// @param f true if the translation unit is constructed.
1402 void
set_is_constructed(bool f)1403 translation_unit::set_is_constructed(bool f)
1404 {priv_->is_constructed_ = f;}
1405
1406 /// Compare the current translation unit against another one.
1407 ///
1408 /// @param other the other tu to compare against.
1409 ///
1410 /// @return true if the two translation units are equal, false
1411 /// otherwise.
1412 bool
operator ==(const translation_unit & other) const1413 translation_unit::operator==(const translation_unit& other)const
1414 {
1415 if (get_address_size() != other.get_address_size())
1416 return false;
1417
1418 return *get_global_scope() == *other.get_global_scope();
1419 }
1420
1421 /// Inequality operator.
1422 ///
1423 /// @param o the instance of @ref translation_unit to compare the
1424 /// current instance against.
1425 ///
1426 /// @return true iff the current instance is different from @p o.
1427 bool
operator !=(const translation_unit & o) const1428 translation_unit::operator!=(const translation_unit& o) const
1429 {return ! operator==(o);}
1430
1431 /// Ensure that the life time of a function type is bound to the life
1432 /// time of the current translation unit.
1433 ///
1434 /// @param ftype the function time which life time to bind to the life
1435 /// time of the current instance of @ref translation_unit. That is,
1436 /// it's onlyh when the translation unit is destroyed that the
1437 /// function type can be destroyed to.
1438 void
bind_function_type_life_time(function_type_sptr ftype) const1439 translation_unit::bind_function_type_life_time(function_type_sptr ftype) const
1440 {
1441 const environment* env = get_environment();
1442 ABG_ASSERT(env);
1443
1444 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1445
1446 interned_string repr = get_type_name(ftype);
1447 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1448 push_back(ftype);
1449
1450 // The function type must be out of the same environment as its
1451 // translation unit.
1452 if (const environment* e = ftype->get_environment())
1453 ABG_ASSERT(env == e);
1454 ftype->set_environment(const_cast<environment*>(env));
1455
1456 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1457 ABG_ASSERT(existing_tu == this);
1458 else
1459 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1460 }
1461
1462 /// This implements the ir_traversable_base::traverse virtual
1463 /// function.
1464 ///
1465 /// @param v the visitor used on the member nodes of the translation
1466 /// unit during the traversal.
1467 ///
1468 /// @return true if the entire type IR tree got traversed, false
1469 /// otherwise.
1470 bool
traverse(ir_node_visitor & v)1471 translation_unit::traverse(ir_node_visitor& v)
1472 {return get_global_scope()->traverse(v);}
1473
~translation_unit()1474 translation_unit::~translation_unit()
1475 {}
1476
1477 /// Converts a translation_unit::language enumerator into a string.
1478 ///
1479 /// @param l the language enumerator to translate.
1480 ///
1481 /// @return the resulting string.
1482 string
translation_unit_language_to_string(translation_unit::language l)1483 translation_unit_language_to_string(translation_unit::language l)
1484 {
1485 switch (l)
1486 {
1487 case translation_unit::LANG_UNKNOWN:
1488 return "LANG_UNKNOWN";
1489 case translation_unit::LANG_Cobol74:
1490 return "LANG_Cobol74";
1491 case translation_unit::LANG_Cobol85:
1492 return "LANG_Cobol85";
1493 case translation_unit::LANG_C89:
1494 return "LANG_C89";
1495 case translation_unit::LANG_C99:
1496 return "LANG_C99";
1497 case translation_unit::LANG_C11:
1498 return "LANG_C11";
1499 case translation_unit::LANG_C:
1500 return "LANG_C";
1501 case translation_unit::LANG_C_plus_plus_11:
1502 return "LANG_C_plus_plus_11";
1503 case translation_unit::LANG_C_plus_plus_14:
1504 return "LANG_C_plus_plus_14";
1505 case translation_unit::LANG_C_plus_plus:
1506 return "LANG_C_plus_plus";
1507 case translation_unit::LANG_ObjC:
1508 return "LANG_ObjC";
1509 case translation_unit::LANG_ObjC_plus_plus:
1510 return "LANG_ObjC_plus_plus";
1511 case translation_unit::LANG_Fortran77:
1512 return "LANG_Fortran77";
1513 case translation_unit::LANG_Fortran90:
1514 return "LANG_Fortran90";
1515 case translation_unit::LANG_Fortran95:
1516 return "LANG_Fortran95";
1517 case translation_unit::LANG_Ada83:
1518 return "LANG_Ada83";
1519 case translation_unit::LANG_Ada95:
1520 return "LANG_Ada95";
1521 case translation_unit::LANG_Pascal83:
1522 return "LANG_Pascal83";
1523 case translation_unit::LANG_Modula2:
1524 return "LANG_Modula2";
1525 case translation_unit::LANG_Java:
1526 return "LANG_Java";
1527 case translation_unit::LANG_PLI:
1528 return "LANG_PLI";
1529 case translation_unit::LANG_UPC:
1530 return "LANG_UPC";
1531 case translation_unit::LANG_D:
1532 return "LANG_D";
1533 case translation_unit::LANG_Python:
1534 return "LANG_Python";
1535 case translation_unit::LANG_Go:
1536 return "LANG_Go";
1537 case translation_unit::LANG_Mips_Assembler:
1538 return "LANG_Mips_Assembler";
1539 default:
1540 return "LANG_UNKNOWN";
1541 }
1542
1543 return "LANG_UNKNOWN";
1544 }
1545
1546 /// Parse a string representing a language into a
1547 /// translation_unit::language enumerator into a string.
1548 ///
1549 /// @param l the string representing the language.
1550 ///
1551 /// @return the resulting translation_unit::language enumerator.
1552 translation_unit::language
string_to_translation_unit_language(const string & l)1553 string_to_translation_unit_language(const string& l)
1554 {
1555 if (l == "LANG_Cobol74")
1556 return translation_unit::LANG_Cobol74;
1557 else if (l == "LANG_Cobol85")
1558 return translation_unit::LANG_Cobol85;
1559 else if (l == "LANG_C89")
1560 return translation_unit::LANG_C89;
1561 else if (l == "LANG_C99")
1562 return translation_unit::LANG_C99;
1563 else if (l == "LANG_C11")
1564 return translation_unit::LANG_C11;
1565 else if (l == "LANG_C")
1566 return translation_unit::LANG_C;
1567 else if (l == "LANG_C_plus_plus_11")
1568 return translation_unit::LANG_C_plus_plus_11;
1569 else if (l == "LANG_C_plus_plus_14")
1570 return translation_unit::LANG_C_plus_plus_14;
1571 else if (l == "LANG_C_plus_plus")
1572 return translation_unit::LANG_C_plus_plus;
1573 else if (l == "LANG_ObjC")
1574 return translation_unit::LANG_ObjC;
1575 else if (l == "LANG_ObjC_plus_plus")
1576 return translation_unit::LANG_ObjC_plus_plus;
1577 else if (l == "LANG_Fortran77")
1578 return translation_unit::LANG_Fortran77;
1579 else if (l == "LANG_Fortran90")
1580 return translation_unit::LANG_Fortran90;
1581 else if (l == "LANG_Fortran95")
1582 return translation_unit::LANG_Fortran95;
1583 else if (l == "LANG_Ada83")
1584 return translation_unit::LANG_Ada83;
1585 else if (l == "LANG_Ada95")
1586 return translation_unit::LANG_Ada95;
1587 else if (l == "LANG_Pascal83")
1588 return translation_unit::LANG_Pascal83;
1589 else if (l == "LANG_Modula2")
1590 return translation_unit::LANG_Modula2;
1591 else if (l == "LANG_Java")
1592 return translation_unit::LANG_Java;
1593 else if (l == "LANG_PLI")
1594 return translation_unit::LANG_PLI;
1595 else if (l == "LANG_UPC")
1596 return translation_unit::LANG_UPC;
1597 else if (l == "LANG_D")
1598 return translation_unit::LANG_D;
1599 else if (l == "LANG_Python")
1600 return translation_unit::LANG_Python;
1601 else if (l == "LANG_Go")
1602 return translation_unit::LANG_Go;
1603 else if (l == "LANG_Mips_Assembler")
1604 return translation_unit::LANG_Mips_Assembler;
1605
1606 return translation_unit::LANG_UNKNOWN;
1607 }
1608
1609 /// Test if a language enumerator designates the C language.
1610 ///
1611 /// @param l the language enumerator to consider.
1612 ///
1613 /// @return true iff @p l designates the C language.
1614 bool
is_c_language(translation_unit::language l)1615 is_c_language(translation_unit::language l)
1616 {
1617 return (l == translation_unit::LANG_C89
1618 || l == translation_unit::LANG_C99
1619 || l == translation_unit::LANG_C11
1620 || l == translation_unit::LANG_C);
1621 }
1622
1623 /// Test if a language enumerator designates the C++ language.
1624 ///
1625 /// @param l the language enumerator to consider.
1626 ///
1627 /// @return true iff @p l designates the C++ language.
1628 bool
is_cplus_plus_language(translation_unit::language l)1629 is_cplus_plus_language(translation_unit::language l)
1630 {
1631 return (l == translation_unit::LANG_C_plus_plus_03
1632 || l == translation_unit::LANG_C_plus_plus_11
1633 || l == translation_unit::LANG_C_plus_plus_14
1634 || l == translation_unit::LANG_C_plus_plus);
1635 }
1636
1637 /// Test if a language enumerator designates the Java language.
1638 ///
1639 /// @param l the language enumerator to consider.
1640 ///
1641 /// @return true iff @p l designates the Java language.
1642 bool
is_java_language(translation_unit::language l)1643 is_java_language(translation_unit::language l)
1644 {return l == translation_unit::LANG_Java;}
1645
1646 /// Test if a language enumerator designates the Ada language.
1647 ///
1648 /// @param l the language enumerator to consider.
1649 ///
1650 /// @return true iff @p l designates the Ada language.
1651 bool
is_ada_language(translation_unit::language l)1652 is_ada_language(translation_unit::language l)
1653 {
1654 return (l == translation_unit::LANG_Ada83
1655 || l == translation_unit::LANG_Ada95);
1656 }
1657
1658 /// A deep comparison operator for pointers to translation units.
1659 ///
1660 /// @param l the first translation unit to consider for the comparison.
1661 ///
1662 /// @param r the second translation unit to consider for the comparison.
1663 ///
1664 /// @return true if the two translation units are equal, false otherwise.
1665 bool
operator ==(const translation_unit_sptr & l,const translation_unit_sptr & r)1666 operator==(const translation_unit_sptr& l, const translation_unit_sptr& r)
1667 {
1668 if (l.get() == r.get())
1669 return true;
1670
1671 if (!!l != !!r)
1672 return false;
1673
1674 return *l == *r;
1675 }
1676
1677 /// A deep inequality operator for pointers to translation units.
1678 ///
1679 /// @param l the first translation unit to consider for the comparison.
1680 ///
1681 /// @param r the second translation unit to consider for the comparison.
1682 ///
1683 /// @return true iff the two translation units are different.
1684 bool
operator !=(const translation_unit_sptr & l,const translation_unit_sptr & r)1685 operator!=(const translation_unit_sptr& l, const translation_unit_sptr& r)
1686 {return !operator==(l, r);}
1687
1688 // </translation_unit stuff>
1689
1690 // <elf_symbol stuff>
1691 struct elf_symbol::priv
1692 {
1693 const environment* env_;
1694 size_t index_;
1695 size_t size_;
1696 string name_;
1697 elf_symbol::type type_;
1698 elf_symbol::binding binding_;
1699 elf_symbol::version version_;
1700 elf_symbol::visibility visibility_;
1701 bool is_defined_;
1702 // This flag below says if the symbol is a common elf symbol. In
1703 // relocatable files, a common symbol is a symbol defined in a
1704 // section of kind SHN_COMMON.
1705 //
1706 // Note that a symbol of kind STT_COMMON is also considered a common
1707 // symbol. Here is what the gABI says about STT_COMMON and
1708 // SHN_COMMON:
1709 //
1710 // Symbols with type STT_COMMON label uninitialized common
1711 // blocks. In relocatable objects, these symbols are not
1712 // allocated and must have the special section index SHN_COMMON
1713 // (see below). In shared objects and executables these symbols
1714 // must be allocated to some section in the defining object.
1715 //
1716 // In relocatable objects, symbols with type STT_COMMON are
1717 // treated just as other symbols with index SHN_COMMON. If the
1718 // link-editor allocates space for the SHN_COMMON symbol in an
1719 // output section of the object it is producing, it must
1720 // preserve the type of the output symbol as STT_COMMON.
1721 //
1722 // When the dynamic linker encounters a reference to a symbol
1723 // that resolves to a definition of type STT_COMMON, it may (but
1724 // is not required to) change its symbol resolution rules as
1725 // follows: instead of binding the reference to the first symbol
1726 // found with the given name, the dynamic linker searches for
1727 // the first symbol with that name with type other than
1728 // STT_COMMON. If no such symbol is found, it looks for the
1729 // STT_COMMON definition of that name that has the largest size.
1730 bool is_common_;
1731 bool is_in_ksymtab_;
1732 abg_compat::optional<uint32_t> crc_;
1733 abg_compat::optional<std::string> namespace_;
1734 bool is_suppressed_;
1735 elf_symbol_wptr main_symbol_;
1736 elf_symbol_wptr next_alias_;
1737 elf_symbol_wptr next_common_instance_;
1738 string id_string_;
1739
privabigail::ir::elf_symbol::priv1740 priv()
1741 : env_(),
1742 index_(),
1743 size_(),
1744 type_(elf_symbol::NOTYPE_TYPE),
1745 binding_(elf_symbol::GLOBAL_BINDING),
1746 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1747 is_defined_(false),
1748 is_common_(false),
1749 is_in_ksymtab_(false),
1750 crc_(),
1751 namespace_(),
1752 is_suppressed_(false)
1753 {}
1754
privabigail::ir::elf_symbol::priv1755 priv(const environment* e,
1756 size_t i,
1757 size_t s,
1758 const string& n,
1759 elf_symbol::type t,
1760 elf_symbol::binding b,
1761 bool d,
1762 bool c,
1763 const elf_symbol::version& ve,
1764 elf_symbol::visibility vi,
1765 bool is_in_ksymtab,
1766 const abg_compat::optional<uint32_t>& crc,
1767 const abg_compat::optional<std::string>& ns,
1768 bool is_suppressed)
1769 : env_(e),
1770 index_(i),
1771 size_(s),
1772 name_(n),
1773 type_(t),
1774 binding_(b),
1775 version_(ve),
1776 visibility_(vi),
1777 is_defined_(d),
1778 is_common_(c),
1779 is_in_ksymtab_(is_in_ksymtab),
1780 crc_(crc),
1781 namespace_(ns),
1782 is_suppressed_(is_suppressed)
1783 {
1784 if (!is_common_)
1785 is_common_ = type_ == COMMON_TYPE;
1786 }
1787 }; // end struct elf_symbol::priv
1788
1789 /// Default constructor of the @ref elf_symbol type.
1790 ///
1791 /// Note that this constructor is private, so client code cannot use
1792 /// it to create instances of @ref elf_symbol. Rather, client code
1793 /// should use the @ref elf_symbol::create() function to create
1794 /// instances of @ref elf_symbol instead.
elf_symbol()1795 elf_symbol::elf_symbol()
1796 : priv_(new priv)
1797 {}
1798
1799 /// Constructor of the @ref elf_symbol type.
1800 ///
1801 /// Note that this constructor is private, so client code cannot use
1802 /// it to create instances of @ref elf_symbol. Rather, client code
1803 /// should use the @ref elf_symbol::create() function to create
1804 /// instances of @ref elf_symbol instead.
1805 ///
1806 /// @param e the environment we are operating from.
1807 ///
1808 /// @param i the index of the symbol in the (ELF) symbol table.
1809 ///
1810 /// @param s the size of the symbol.
1811 ///
1812 /// @param n the name of the symbol.
1813 ///
1814 /// @param t the type of the symbol.
1815 ///
1816 /// @param b the binding of the symbol.
1817 ///
1818 /// @param d true if the symbol is defined, false otherwise.
1819 ///
1820 /// @param c true if the symbol is a common symbol, false otherwise.
1821 ///
1822 /// @param ve the version of the symbol.
1823 ///
1824 /// @param vi the visibility of the symbol.
1825 ///
1826 /// @param crc the CRC (modversions) value of Linux Kernel symbols
1827 ///
1828 /// @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)1829 elf_symbol::elf_symbol(const environment* e,
1830 size_t i,
1831 size_t s,
1832 const string& n,
1833 type t,
1834 binding b,
1835 bool d,
1836 bool c,
1837 const version& ve,
1838 visibility vi,
1839 bool is_in_ksymtab,
1840 const abg_compat::optional<uint32_t>& crc,
1841 const abg_compat::optional<std::string>& ns,
1842 bool is_suppressed)
1843 : priv_(new priv(e,
1844 i,
1845 s,
1846 n,
1847 t,
1848 b,
1849 d,
1850 c,
1851 ve,
1852 vi,
1853 is_in_ksymtab,
1854 crc,
1855 ns,
1856 is_suppressed))
1857 {}
1858
1859 /// Factory of instances of @ref elf_symbol.
1860 ///
1861 /// This is the function to use to create instances of @ref elf_symbol.
1862 ///
1863 /// @return a (smart) pointer to a newly created instance of @ref
1864 /// elf_symbol.
1865 elf_symbol_sptr
create()1866 elf_symbol::create()
1867 {
1868 elf_symbol_sptr e(new elf_symbol());
1869 e->priv_->main_symbol_ = e;
1870 return e;
1871 }
1872
1873 /// Factory of instances of @ref elf_symbol.
1874 ///
1875 /// This is the function to use to create instances of @ref elf_symbol.
1876 ///
1877 /// @param e the environment we are operating from.
1878 ///
1879 /// @param i the index of the symbol in the (ELF) symbol table.
1880 ///
1881 /// @param s the size of the symbol.
1882 ///
1883 /// @param n the name of the symbol.
1884 ///
1885 /// @param t the type of the symbol.
1886 ///
1887 /// @param b the binding of the symbol.
1888 ///
1889 /// @param d true if the symbol is defined, false otherwise.
1890 ///
1891 /// @param c true if the symbol is a common symbol.
1892 ///
1893 /// @param ve the version of the symbol.
1894 ///
1895 /// @param vi the visibility of the symbol.
1896 ///
1897 /// @param crc the CRC (modversions) value of Linux Kernel symbols
1898 ///
1899 /// @param ns the namespace of Linux Kernel symbols, if any
1900 ///
1901 /// @return a (smart) pointer to a newly created instance of @ref
1902 /// elf_symbol.
1903 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)1904 elf_symbol::create(const environment* e,
1905 size_t i,
1906 size_t s,
1907 const string& n,
1908 type t,
1909 binding b,
1910 bool d,
1911 bool c,
1912 const version& ve,
1913 visibility vi,
1914 bool is_in_ksymtab,
1915 const abg_compat::optional<uint32_t>& crc,
1916 const abg_compat::optional<std::string>& ns,
1917 bool is_suppressed)
1918 {
1919 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
1920 is_in_ksymtab, crc, ns, is_suppressed));
1921 sym->priv_->main_symbol_ = sym;
1922 return sym;
1923 }
1924
1925 /// Test textual equality between two symbols.
1926 ///
1927 /// Textual equality means that the aliases of the compared symbols
1928 /// are not taken into account. Only the name, type, and version of
1929 /// the symbols are compared.
1930 ///
1931 /// @return true iff the two symbols are textually equal.
1932 static bool
textually_equals(const elf_symbol & l,const elf_symbol & r)1933 textually_equals(const elf_symbol&l,
1934 const elf_symbol&r)
1935 {
1936 bool equals = (l.get_name() == r.get_name()
1937 && l.get_type() == r.get_type()
1938 && l.is_public() == r.is_public()
1939 && l.is_defined() == r.is_defined()
1940 && l.is_common_symbol() == r.is_common_symbol()
1941 && l.get_version() == r.get_version()
1942 && l.get_crc() == r.get_crc()
1943 && l.get_namespace() == r.get_namespace());
1944
1945 if (equals && l.is_variable())
1946 // These are variable symbols. Let's compare their symbol size.
1947 // The symbol size in this case is the size taken by the storage
1948 // of the variable. If that size changes, then it's an ABI
1949 // change.
1950 equals = l.get_size() == r.get_size();
1951
1952 return equals;
1953 }
1954
1955 /// Getter of the environment used by the current instance of @ref
1956 /// elf_symbol.
1957 ///
1958 /// @return the enviroment used by the current instance of @ref elf_symbol.
1959 const environment*
get_environment() const1960 elf_symbol::get_environment() const
1961 {return priv_->env_;}
1962
1963 /// Setter of the environment used by the current instance of @ref
1964 /// elf_symbol.
1965 ///
1966 /// @param The new enviroment used by the current instance of @ref
1967 /// elf_symbol.
1968 void
set_environment(const environment * e) const1969 elf_symbol::set_environment(const environment* e) const
1970 {priv_->env_ = e;}
1971
1972 /// Getter for the index
1973 ///
1974 /// @return the index of the symbol.
1975 size_t
get_index() const1976 elf_symbol::get_index() const
1977 {return priv_->index_;}
1978
1979 /// Setter for the index.
1980 ///
1981 /// @param s the new index.
1982 void
set_index(size_t s)1983 elf_symbol::set_index(size_t s)
1984 {priv_->index_ = s;}
1985
1986 /// Getter for the name of the @ref elf_symbol.
1987 ///
1988 /// @return a reference to the name of the @ref symbol.
1989 const string&
get_name() const1990 elf_symbol::get_name() const
1991 {return priv_->name_;}
1992
1993 /// Setter for the name of the current intance of @ref elf_symbol.
1994 ///
1995 /// @param n the new name.
1996 void
set_name(const string & n)1997 elf_symbol::set_name(const string& n)
1998 {
1999 priv_->name_ = n;
2000 priv_->id_string_.clear();
2001 }
2002
2003 /// Getter for the type of the current instance of @ref elf_symbol.
2004 ///
2005 /// @return the type of the elf symbol.
2006 elf_symbol::type
get_type() const2007 elf_symbol::get_type() const
2008 {return priv_->type_;}
2009
2010 /// Setter for the type of the current instance of @ref elf_symbol.
2011 ///
2012 /// @param t the new symbol type.
2013 void
set_type(type t)2014 elf_symbol::set_type(type t)
2015 {priv_->type_ = t;}
2016
2017 /// Getter of the size of the symbol.
2018 ///
2019 /// @return the size of the symbol, in bytes.
2020 size_t
get_size() const2021 elf_symbol::get_size() const
2022 {return priv_->size_;}
2023
2024 /// Setter of the size of the symbol.
2025 ///
2026 /// @param size the new size of the symbol, in bytes.
2027 void
set_size(size_t size)2028 elf_symbol::set_size(size_t size)
2029 {priv_->size_ = size;}
2030
2031 /// Getter for the binding of the current instance of @ref elf_symbol.
2032 ///
2033 /// @return the binding of the symbol.
2034 elf_symbol::binding
get_binding() const2035 elf_symbol::get_binding() const
2036 {return priv_->binding_;}
2037
2038 /// Setter for the binding of the current instance of @ref elf_symbol.
2039 ///
2040 /// @param b the new binding.
2041 void
set_binding(binding b)2042 elf_symbol::set_binding(binding b)
2043 {priv_->binding_ = b;}
2044
2045 /// Getter for the version of the current instanc of @ref elf_symbol.
2046 ///
2047 /// @return the version of the elf symbol.
2048 elf_symbol::version&
get_version() const2049 elf_symbol::get_version() const
2050 {return priv_->version_;}
2051
2052 /// Setter for the version of the current instance of @ref elf_symbol.
2053 ///
2054 /// @param v the new version of the elf symbol.
2055 void
set_version(const version & v)2056 elf_symbol::set_version(const version& v)
2057 {
2058 priv_->version_ = v;
2059 priv_->id_string_.clear();
2060 }
2061
2062 /// Setter of the visibility of the current instance of @ref
2063 /// elf_symbol.
2064 ///
2065 /// @param v the new visibility of the elf symbol.
2066 void
set_visibility(visibility v)2067 elf_symbol::set_visibility(visibility v)
2068 {priv_->visibility_ = v;}
2069
2070 /// Getter of the visibility of the current instance of @ref
2071 /// elf_symbol.
2072 ///
2073 /// @return the visibility of the elf symbol.
2074 elf_symbol::visibility
get_visibility() const2075 elf_symbol::get_visibility() const
2076 {return priv_->visibility_;}
2077
2078 /// Test if the current instance of @ref elf_symbol is defined or not.
2079 ///
2080 /// @return true if the current instance of @ref elf_symbol is
2081 /// defined, false otherwise.
2082 bool
is_defined() const2083 elf_symbol::is_defined() const
2084 {return priv_->is_defined_;}
2085
2086 /// Sets a flag saying if the current instance of @ref elf_symbol is
2087 /// defined
2088 ///
2089 /// @param b the new value of the flag.
2090 void
is_defined(bool d)2091 elf_symbol::is_defined(bool d)
2092 {priv_->is_defined_ = d;}
2093
2094 /// Test if the current instance of @ref elf_symbol is public or not.
2095 ///
2096 /// This tests if the symbol is defined, has default or protected
2097 ///visibility, and either:
2098 /// - has global binding
2099 /// - has weak binding
2100 /// - or has a GNU_UNIQUE binding.
2101 ///
2102 /// return true if the current instance of @ref elf_symbol is public,
2103 /// false otherwise.
2104 bool
is_public() const2105 elf_symbol::is_public() const
2106 {
2107 return (is_defined()
2108 && (get_binding() == GLOBAL_BINDING
2109 || get_binding() == WEAK_BINDING
2110 || get_binding() == GNU_UNIQUE_BINDING)
2111 && (get_visibility() == DEFAULT_VISIBILITY
2112 || get_visibility() == PROTECTED_VISIBILITY));
2113 }
2114
2115 /// Test if the current instance of @ref elf_symbol is a function
2116 /// symbol or not.
2117 ///
2118 /// @return true if the current instance of @ref elf_symbol is a
2119 /// function symbol, false otherwise.
2120 bool
is_function() const2121 elf_symbol::is_function() const
2122 {return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
2123
2124 /// Test if the current instance of @ref elf_symbol is a variable
2125 /// symbol or not.
2126 ///
2127 /// @return true if the current instance of @ref elf_symbol is a
2128 /// variable symbol, false otherwise.
2129 bool
is_variable() const2130 elf_symbol::is_variable() const
2131 {return get_type() == OBJECT_TYPE || get_type() == TLS_TYPE;}
2132
2133 /// Getter of the 'is-in-ksymtab' property.
2134 ///
2135 /// @return true iff the current symbol is in the Linux Kernel
2136 /// specific 'ksymtab' symbol table.
2137 bool
is_in_ksymtab() const2138 elf_symbol::is_in_ksymtab() const
2139 {return priv_->is_in_ksymtab_;}
2140
2141 /// Setter of the 'is-in-ksymtab' property.
2142 ///
2143 /// @param is_in_ksymtab this is true iff the current symbol is in the
2144 /// Linux Kernel specific 'ksymtab' symbol table.
2145 void
set_is_in_ksymtab(bool is_in_ksymtab)2146 elf_symbol::set_is_in_ksymtab(bool is_in_ksymtab)
2147 {priv_->is_in_ksymtab_ = is_in_ksymtab;}
2148
2149 /// Getter of the 'crc' property.
2150 ///
2151 /// @return the CRC (modversions) value for Linux Kernel symbols, if any
2152 const abg_compat::optional<uint32_t>&
get_crc() const2153 elf_symbol::get_crc() const
2154 {return priv_->crc_;}
2155
2156 /// Setter of the 'crc' property.
2157 ///
2158 /// @param crc the new CRC (modversions) value for Linux Kernel symbols
2159 void
set_crc(const abg_compat::optional<uint32_t> & crc)2160 elf_symbol::set_crc(const abg_compat::optional<uint32_t>& crc)
2161 {priv_->crc_ = crc;}
2162
2163 /// Getter of the 'namespace' property.
2164 ///
2165 /// @return the namespace for Linux Kernel symbols, if any
2166 const abg_compat::optional<std::string>&
get_namespace() const2167 elf_symbol::get_namespace() const
2168 {return priv_->namespace_;}
2169
2170 /// Setter of the 'namespace' property.
2171 ///
2172 /// @param ns the new namespace for Linux Kernel symbols, if any
2173 void
set_namespace(const abg_compat::optional<std::string> & ns)2174 elf_symbol::set_namespace(const abg_compat::optional<std::string>& ns)
2175 {priv_->namespace_ = ns;}
2176
2177 /// Getter for the 'is-suppressed' property.
2178 ///
2179 /// @return true iff the current symbol has been suppressed by a
2180 /// suppression specification that was provided in the context that
2181 /// led to the creation of the corpus this ELF symbol belongs to.
2182 bool
is_suppressed() const2183 elf_symbol::is_suppressed() const
2184 {return priv_->is_suppressed_;}
2185
2186 /// Setter for the 'is-suppressed' property.
2187 ///
2188 /// @param true iff the current symbol has been suppressed by a
2189 /// suppression specification that was provided in the context that
2190 /// led to the creation of the corpus this ELF symbol belongs to.
2191 void
set_is_suppressed(bool is_suppressed)2192 elf_symbol::set_is_suppressed(bool is_suppressed)
2193 {priv_->is_suppressed_ = is_suppressed;}
2194
2195 /// @name Elf symbol aliases
2196 ///
2197 /// An alias A for an elf symbol S is a symbol that is defined at the
2198 /// same address as S. S is chained to A through the
2199 /// elf_symbol::get_next_alias() method.
2200 ///
2201 /// When there are several aliases to a symbol, the main symbol is the
2202 /// the first symbol found in the symbol table for a given address.
2203 ///
2204 /// The alias chain is circular. That means if S is the main symbol
2205 /// and A is the alias, S is chained to A and A
2206 /// is chained back to the main symbol S. The last alias in an alias
2207 ///chain is always chained to the main symbol.
2208 ///
2209 /// Thus, when looping over the aliases of an elf_symbol A, detecting
2210 /// an alias that is equal to the main symbol should logically be a
2211 /// loop exit condition.
2212 ///
2213 /// Accessing and adding aliases for instances of elf_symbol is done
2214 /// through the member functions below.
2215
2216 /// @{
2217
2218 /// Get the main symbol of an alias chain.
2219 ///
2220 ///@return the main symbol.
2221 const elf_symbol_sptr
get_main_symbol() const2222 elf_symbol::get_main_symbol() const
2223 {return priv_->main_symbol_.lock();}
2224
2225 /// Get the main symbol of an alias chain.
2226 ///
2227 ///@return the main symbol.
2228 elf_symbol_sptr
get_main_symbol()2229 elf_symbol::get_main_symbol()
2230 {return priv_->main_symbol_.lock();}
2231
2232 /// Tests whether this symbol is the main symbol.
2233 ///
2234 /// @return true iff this symbol is the main symbol.
2235 bool
is_main_symbol() const2236 elf_symbol::is_main_symbol() const
2237 {return get_main_symbol().get() == this;}
2238
2239 /// Get the next alias of the current symbol.
2240 ///
2241 ///@return the alias, or NULL if there is no alias.
2242 elf_symbol_sptr
get_next_alias() const2243 elf_symbol::get_next_alias() const
2244 {return priv_->next_alias_.lock();}
2245
2246
2247 /// Check if the current elf_symbol has an alias.
2248 ///
2249 ///@return true iff the current elf_symbol has an alias.
2250 bool
has_aliases() const2251 elf_symbol::has_aliases() const
2252 {return bool(get_next_alias());}
2253
2254 /// Get the number of aliases to this elf symbol
2255 ///
2256 /// @return the number of aliases to this elf symbol.
2257 int
get_number_of_aliases() const2258 elf_symbol::get_number_of_aliases() const
2259 {
2260 int result = 0;
2261
2262 for (elf_symbol_sptr a = get_next_alias();
2263 a && a.get() != get_main_symbol().get();
2264 a = a->get_next_alias())
2265 ++result;
2266
2267 return result;
2268 }
2269
2270 /// Add an alias to the current elf symbol.
2271 ///
2272 /// @param alias the new alias. Note that this elf_symbol should *NOT*
2273 /// have aliases prior to the invocation of this function.
2274 void
add_alias(const elf_symbol_sptr & alias)2275 elf_symbol::add_alias(const elf_symbol_sptr& alias)
2276 {
2277 if (!alias)
2278 return;
2279
2280 ABG_ASSERT(!alias->has_aliases());
2281 ABG_ASSERT(is_main_symbol());
2282
2283 if (has_aliases())
2284 {
2285 elf_symbol_sptr last_alias;
2286 for (elf_symbol_sptr a = get_next_alias();
2287 a && !a->is_main_symbol();
2288 a = a->get_next_alias())
2289 {
2290 if (a->get_next_alias()->is_main_symbol())
2291 {
2292 ABG_ASSERT(last_alias == 0);
2293 last_alias = a;
2294 }
2295 }
2296 ABG_ASSERT(last_alias);
2297
2298 last_alias->priv_->next_alias_ = alias;
2299 }
2300 else
2301 priv_->next_alias_ = alias;
2302
2303 alias->priv_->next_alias_ = get_main_symbol();
2304 alias->priv_->main_symbol_ = get_main_symbol();
2305 }
2306
2307 /// Update the main symbol for a group of aliased symbols
2308 ///
2309 /// If after the construction of the symbols (in order of discovery), the
2310 /// actual main symbol can be identified (e.g. as the symbol that actually is
2311 /// defined in the code), this method offers a way of updating the main symbol
2312 /// through one of the aliased symbols.
2313 ///
2314 /// For that, locate the new main symbol by name and update all references to
2315 /// the main symbol among the group of aliased symbols.
2316 ///
2317 /// @param name the name of the main symbol
2318 ///
2319 /// @return the new main elf_symbol
2320 elf_symbol_sptr
update_main_symbol(const std::string & name)2321 elf_symbol::update_main_symbol(const std::string& name)
2322 {
2323 ABG_ASSERT(is_main_symbol());
2324 if (!has_aliases() || get_name() == name)
2325 return get_main_symbol();
2326
2327 // find the new main symbol
2328 elf_symbol_sptr new_main;
2329 // we've already checked this; check the rest of the aliases
2330 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2331 a = a->get_next_alias())
2332 if (a->get_name() == name)
2333 {
2334 new_main = a;
2335 break;
2336 }
2337
2338 if (!new_main)
2339 return get_main_symbol();
2340
2341 // now update all main symbol references
2342 priv_->main_symbol_ = new_main;
2343 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
2344 a = a->get_next_alias())
2345 a->priv_->main_symbol_ = new_main;
2346
2347 return new_main;
2348 }
2349
2350 /// Return true if the symbol is a common one.
2351 ///
2352 /// @return true iff the symbol is common.
2353 bool
is_common_symbol() const2354 elf_symbol::is_common_symbol() const
2355 {return priv_->is_common_;}
2356
2357 /// Return true if this common common symbol has other common instances.
2358 ///
2359 /// A common instance of a given common symbol is another common
2360 /// symbol with the same name. Those exist in relocatable files. The
2361 /// linker normally allocates all the instances into a common block in
2362 /// the final output file.
2363 ///
2364 /// Note that the current object must be a common symbol, otherwise,
2365 /// this function aborts.
2366 ///
2367 /// @return true iff the current common symbol has other common
2368 /// instances.
2369 bool
has_other_common_instances() const2370 elf_symbol::has_other_common_instances() const
2371 {
2372 ABG_ASSERT(is_common_symbol());
2373 return bool(get_next_common_instance());
2374 }
2375
2376 /// Get the next common instance of the current common symbol.
2377 ///
2378 /// A common instance of a given common symbol is another common
2379 /// symbol with the same name. Those exist in relocatable files. The
2380 /// linker normally allocates all the instances into a common block in
2381 /// the final output file.
2382 ///
2383 /// @return the next common instance, or nil if there is not any.
2384 elf_symbol_sptr
get_next_common_instance() const2385 elf_symbol::get_next_common_instance() const
2386 {return priv_->next_common_instance_.lock();}
2387
2388 /// Add a common instance to the current common elf symbol.
2389 ///
2390 /// Note that this symbol must be the main symbol. Being the main
2391 /// symbol means being the first common symbol to appear in the symbol
2392 /// table.
2393 ///
2394 /// @param common the other common instance to add.
2395 void
add_common_instance(const elf_symbol_sptr & common)2396 elf_symbol::add_common_instance(const elf_symbol_sptr& common)
2397 {
2398 if (!common)
2399 return;
2400
2401 ABG_ASSERT(!common->has_other_common_instances());
2402 ABG_ASSERT(is_common_symbol());
2403 ABG_ASSERT(is_main_symbol());
2404
2405 if (has_other_common_instances())
2406 {
2407 elf_symbol_sptr last_common_instance;
2408 for (elf_symbol_sptr c = get_next_common_instance();
2409 c && (c.get() != get_main_symbol().get());
2410 c = c->get_next_common_instance())
2411 {
2412 if (c->get_next_common_instance().get() == get_main_symbol().get())
2413 {
2414 ABG_ASSERT(last_common_instance == 0);
2415 last_common_instance = c;
2416 }
2417 }
2418 ABG_ASSERT(last_common_instance);
2419
2420 last_common_instance->priv_->next_common_instance_ = common;
2421 }
2422 else
2423 priv_->next_common_instance_ = common;
2424
2425 common->priv_->next_common_instance_ = get_main_symbol();
2426 common->priv_->main_symbol_ = get_main_symbol();
2427 }
2428
2429 /// Get a string that is representative of a given elf_symbol.
2430 ///
2431 /// If the symbol has a version, then the ID string is the
2432 /// concatenation of the name of the symbol, the '@' character, and
2433 /// the version of the symbol. If the version is the default version
2434 /// of the symbol then the '@' character is replaced by a "@@" string.
2435 ///
2436 /// Otherwise, if the symbol does not have any version, this function
2437 /// returns the name of the symbol.
2438 ///
2439 /// @return a the ID string.
2440 const string&
get_id_string() const2441 elf_symbol::get_id_string() const
2442 {
2443 if (priv_->id_string_.empty())
2444 {
2445 string s = get_name ();
2446
2447 if (!get_version().is_empty())
2448 {
2449 if (get_version().is_default())
2450 s += "@@";
2451 else
2452 s += "@";
2453 s += get_version().str();
2454 }
2455 priv_->id_string_ = s;
2456 }
2457
2458 return priv_->id_string_;
2459 }
2460
2461 /// From the aliases of the current symbol, lookup one with a given name.
2462 ///
2463 /// @param name the name of symbol alias we are looking for.
2464 ///
2465 /// @return the symbol alias that has the name @p name, or nil if none
2466 /// has been found.
2467 elf_symbol_sptr
get_alias_from_name(const string & name) const2468 elf_symbol::get_alias_from_name(const string& name) const
2469 {
2470 if (name == get_name())
2471 return elf_symbol_sptr(priv_->main_symbol_);
2472
2473 for (elf_symbol_sptr a = get_next_alias();
2474 a && a.get() != get_main_symbol().get();
2475 a = a->get_next_alias())
2476 if (a->get_name() == name)
2477 return a;
2478
2479 return elf_symbol_sptr();
2480 }
2481
2482 /// In the list of aliases of a given elf symbol, get the alias that
2483 /// equals this current symbol.
2484 ///
2485 /// @param other the elf symbol to get the potential aliases from.
2486 ///
2487 /// @return the alias of @p other that texually equals the current
2488 /// symbol, or nil if no alias textually equals the current symbol.
2489 elf_symbol_sptr
get_alias_which_equals(const elf_symbol & other) const2490 elf_symbol::get_alias_which_equals(const elf_symbol& other) const
2491 {
2492 for (elf_symbol_sptr a = other.get_next_alias();
2493 a && a.get() != a->get_main_symbol().get();
2494 a = a->get_next_alias())
2495 if (textually_equals(*this, *a))
2496 return a;
2497 return elf_symbol_sptr();
2498 }
2499
2500 /// Return a comma separated list of the id of the current symbol as
2501 /// well as the id string of its aliases.
2502 ///
2503 /// @param syms a map of all the symbols of the corpus the current
2504 /// symbol belongs to.
2505 ///
2506 /// @param include_symbol_itself if set to true, then the name of the
2507 /// current symbol is included in the list of alias names that is emitted.
2508 ///
2509 /// @return the string.
2510 string
get_aliases_id_string(const string_elf_symbols_map_type & syms,bool include_symbol_itself) const2511 elf_symbol::get_aliases_id_string(const string_elf_symbols_map_type& syms,
2512 bool include_symbol_itself) const
2513 {
2514 string result;
2515
2516 if (include_symbol_itself)
2517 result = get_id_string();
2518
2519 vector<elf_symbol_sptr> aliases;
2520 compute_aliases_for_elf_symbol(*this, syms, aliases);
2521 if (!aliases.empty() && include_symbol_itself)
2522 result += ", ";
2523
2524 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2525 i != aliases.end();
2526 ++i)
2527 {
2528 if (i != aliases.begin())
2529 result += ", ";
2530 result += (*i)->get_id_string();
2531 }
2532 return result;
2533 }
2534
2535 /// Return a comma separated list of the id of the current symbol as
2536 /// well as the id string of its aliases.
2537 ///
2538 /// @param include_symbol_itself if set to true, then the name of the
2539 /// current symbol is included in the list of alias names that is emitted.
2540 ///
2541 /// @return the string.
2542 string
get_aliases_id_string(bool include_symbol_itself) const2543 elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2544 {
2545 vector<elf_symbol_sptr> aliases;
2546 if (include_symbol_itself)
2547 aliases.push_back(get_main_symbol());
2548
2549 for (elf_symbol_sptr a = get_next_alias();
2550 a && a.get() != get_main_symbol().get();
2551 a = a->get_next_alias())
2552 aliases.push_back(a);
2553
2554 string result;
2555 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2556 i != aliases.end();
2557 ++i)
2558 {
2559 if (i != aliases.begin())
2560 result += ", ";
2561 result += (*i)->get_id_string();
2562 }
2563
2564 return result;
2565 }
2566
2567 /// Given the ID of a symbol, get the name and the version of said
2568 /// symbol.
2569 ///
2570 /// @param id the symbol ID to consider.
2571 ///
2572 /// @param name the symbol name extracted from the ID. This is set
2573 /// only if the function returned true.
2574 ///
2575 /// @param ver the symbol version extracted from the ID.
2576 bool
get_name_and_version_from_id(const string & id,string & name,string & ver)2577 elf_symbol::get_name_and_version_from_id(const string& id,
2578 string& name,
2579 string& ver)
2580 {
2581 name.clear(), ver.clear();
2582
2583 string::size_type i = id.find('@');
2584 if (i == string::npos)
2585 {
2586 name = id;
2587 return true;
2588 }
2589
2590 name = id.substr(0, i);
2591 ++i;
2592
2593 if (i >= id.size())
2594 return true;
2595
2596 string::size_type j = id.find('@', i);
2597 if (j == string::npos)
2598 j = i;
2599 else
2600 ++j;
2601
2602 if (j >= id.size())
2603 {
2604 ver = "";
2605 return true;
2606 }
2607
2608 ver = id.substr(j);
2609 return true;
2610 }
2611
2612 ///@}
2613
2614 /// Test if two main symbols are textually equal, or, if they have
2615 /// aliases that are textually equal.
2616 ///
2617 /// @param other the symbol to compare against.
2618 ///
2619 /// @return true iff the current instance of elf symbol equals the @p
2620 /// other.
2621 bool
operator ==(const elf_symbol & other) const2622 elf_symbol::operator==(const elf_symbol& other) const
2623 {
2624 bool are_equal = textually_equals(*this, other);
2625 if (!are_equal)
2626 are_equal = bool(get_alias_which_equals(other));
2627 return are_equal;
2628 }
2629
2630 /// Test if the current symbol aliases another one.
2631 ///
2632 /// @param o the other symbol to test against.
2633 ///
2634 /// @return true iff the current symbol aliases @p o.
2635 bool
does_alias(const elf_symbol & o) const2636 elf_symbol::does_alias(const elf_symbol& o) const
2637 {
2638 if (*this == o)
2639 return true;
2640
2641 if (get_main_symbol() == o.get_main_symbol())
2642 return true;
2643
2644 for (elf_symbol_sptr a = get_next_alias();
2645 a && !a->is_main_symbol();
2646 a = a->get_next_alias())
2647 {
2648 if (o == *a)
2649 return true;
2650 }
2651 return false;
2652 }
2653
2654 /// Equality operator for smart pointers to elf_symbol.
2655 ///
2656 /// @param lhs the first elf symbol to consider.
2657 ///
2658 /// @param rhs the second elf symbol to consider.
2659 ///
2660 /// @return true iff @p lhs equals @p rhs.
2661 bool
operator ==(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2662 operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2663 {
2664 if (!!lhs != !!rhs)
2665 return false;
2666
2667 if (!lhs)
2668 return true;
2669
2670 return *lhs == *rhs;
2671 }
2672
2673 /// Inequality operator for smart pointers to elf_symbol.
2674 ///
2675 /// @param lhs the first elf symbol to consider.
2676 ///
2677 /// @param rhs the second elf symbol to consider.
2678 ///
2679 /// @return true iff @p lhs is different from @p rhs.
2680 bool
operator !=(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2681 operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2682 {return !operator==(lhs, rhs);}
2683
2684 /// Test if two symbols alias.
2685 ///
2686 /// @param s1 the first symbol to consider.
2687 ///
2688 /// @param s2 the second symbol to consider.
2689 ///
2690 /// @return true if @p s1 aliases @p s2.
2691 bool
elf_symbols_alias(const elf_symbol & s1,const elf_symbol & s2)2692 elf_symbols_alias(const elf_symbol& s1, const elf_symbol& s2)
2693 {return s1.does_alias(s2) || s2.does_alias(s1);}
2694
2695 void
compute_aliases_for_elf_symbol(const elf_symbol & sym,const string_elf_symbols_map_type & symtab,vector<elf_symbol_sptr> & aliases)2696 compute_aliases_for_elf_symbol(const elf_symbol& sym,
2697 const string_elf_symbols_map_type& symtab,
2698 vector<elf_symbol_sptr>& aliases)
2699 {
2700
2701 if (elf_symbol_sptr a = sym.get_next_alias())
2702 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2703 aliases.push_back(a);
2704 else
2705 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2706 i != symtab.end();
2707 ++i)
2708 for (elf_symbols::const_iterator j = i->second.begin();
2709 j != i->second.end();
2710 ++j)
2711 {
2712 if (**j == sym)
2713 for (elf_symbol_sptr s = (*j)->get_next_alias();
2714 s && !s->is_main_symbol();
2715 s = s->get_next_alias())
2716 aliases.push_back(s);
2717 else
2718 for (elf_symbol_sptr s = (*j)->get_next_alias();
2719 s && !s->is_main_symbol();
2720 s = s->get_next_alias())
2721 if (*s == sym)
2722 aliases.push_back(*j);
2723 }
2724 }
2725
2726 /// Test if two symbols alias.
2727 ///
2728 /// @param s1 the first symbol to consider.
2729 ///
2730 /// @param s2 the second symbol to consider.
2731 ///
2732 /// @return true if @p s1 aliases @p s2.
2733 bool
elf_symbols_alias(const elf_symbol * s1,const elf_symbol * s2)2734 elf_symbols_alias(const elf_symbol* s1, const elf_symbol* s2)
2735 {
2736 if (!!s1 != !!s2)
2737 return false;
2738 if (s1 == s2)
2739 return true;
2740 return elf_symbols_alias(*s1, *s2);
2741 }
2742
2743 /// Test if two symbols alias.
2744 ///
2745 /// @param s1 the first symbol to consider.
2746 ///
2747 /// @param s2 the second symbol to consider.
2748 ///
2749 /// @return true if @p s1 aliases @p s2.
2750 bool
elf_symbols_alias(const elf_symbol_sptr s1,const elf_symbol_sptr s2)2751 elf_symbols_alias(const elf_symbol_sptr s1, const elf_symbol_sptr s2)
2752 {return elf_symbols_alias(s1.get(), s2.get());}
2753
2754 /// Serialize an instance of @ref symbol_type and stream it to a given
2755 /// output stream.
2756 ///
2757 /// @param o the output stream to serialize the symbole type to.
2758 ///
2759 /// @param t the symbol type to serialize.
2760 std::ostream&
operator <<(std::ostream & o,elf_symbol::type t)2761 operator<<(std::ostream& o, elf_symbol::type t)
2762 {
2763 string repr;
2764
2765 switch (t)
2766 {
2767 case elf_symbol::NOTYPE_TYPE:
2768 repr = "unspecified symbol type";
2769 break;
2770 case elf_symbol::OBJECT_TYPE:
2771 repr = "variable symbol type";
2772 break;
2773 case elf_symbol::FUNC_TYPE:
2774 repr = "function symbol type";
2775 break;
2776 case elf_symbol::SECTION_TYPE:
2777 repr = "section symbol type";
2778 break;
2779 case elf_symbol::FILE_TYPE:
2780 repr = "file symbol type";
2781 break;
2782 case elf_symbol::COMMON_TYPE:
2783 repr = "common data object symbol type";
2784 break;
2785 case elf_symbol::TLS_TYPE:
2786 repr = "thread local data object symbol type";
2787 break;
2788 case elf_symbol::GNU_IFUNC_TYPE:
2789 repr = "indirect function symbol type";
2790 break;
2791 default:
2792 {
2793 std::ostringstream s;
2794 s << "unknown symbol type (" << (char)t << ')';
2795 repr = s.str();
2796 }
2797 break;
2798 }
2799
2800 o << repr;
2801 return o;
2802 }
2803
2804 /// Serialize an instance of @ref symbol_binding and stream it to a
2805 /// given output stream.
2806 ///
2807 /// @param o the output stream to serialize the symbole type to.
2808 ///
2809 /// @param b the symbol binding to serialize.
2810 std::ostream&
operator <<(std::ostream & o,elf_symbol::binding b)2811 operator<<(std::ostream& o, elf_symbol::binding b)
2812 {
2813 string repr;
2814
2815 switch (b)
2816 {
2817 case elf_symbol::LOCAL_BINDING:
2818 repr = "local binding";
2819 break;
2820 case elf_symbol::GLOBAL_BINDING:
2821 repr = "global binding";
2822 break;
2823 case elf_symbol::WEAK_BINDING:
2824 repr = "weak binding";
2825 break;
2826 case elf_symbol::GNU_UNIQUE_BINDING:
2827 repr = "GNU unique binding";
2828 break;
2829 default:
2830 {
2831 std::ostringstream s;
2832 s << "unknown binding (" << (unsigned char) b << ")";
2833 repr = s.str();
2834 }
2835 break;
2836 }
2837
2838 o << repr;
2839 return o;
2840 }
2841
2842 /// Serialize an instance of @ref elf_symbol::visibility and stream it
2843 /// to a given output stream.
2844 ///
2845 /// @param o the output stream to serialize the symbole type to.
2846 ///
2847 /// @param v the symbol visibility to serialize.
2848 std::ostream&
operator <<(std::ostream & o,elf_symbol::visibility v)2849 operator<<(std::ostream& o, elf_symbol::visibility v)
2850 {
2851 string repr;
2852
2853 switch (v)
2854 {
2855 case elf_symbol::DEFAULT_VISIBILITY:
2856 repr = "default visibility";
2857 break;
2858 case elf_symbol::PROTECTED_VISIBILITY:
2859 repr = "protected visibility";
2860 break;
2861 case elf_symbol::HIDDEN_VISIBILITY:
2862 repr = "hidden visibility";
2863 break;
2864 case elf_symbol::INTERNAL_VISIBILITY:
2865 repr = "internal visibility";
2866 break;
2867 default:
2868 {
2869 std::ostringstream s;
2870 s << "unknown visibility (" << (unsigned char) v << ")";
2871 repr = s.str();
2872 }
2873 break;
2874 }
2875
2876 o << repr;
2877 return o;
2878 }
2879
2880 /// Convert a string representing a symbol type into an
2881 /// elf_symbol::type.
2882 ///
2883 ///@param s the string to convert.
2884 ///
2885 ///@param t the resulting elf_symbol::type.
2886 ///
2887 /// @return true iff the conversion completed successfully.
2888 bool
string_to_elf_symbol_type(const string & s,elf_symbol::type & t)2889 string_to_elf_symbol_type(const string& s, elf_symbol::type& t)
2890 {
2891 if (s == "no-type")
2892 t = elf_symbol::NOTYPE_TYPE;
2893 else if (s == "object-type")
2894 t = elf_symbol::OBJECT_TYPE;
2895 else if (s == "func-type")
2896 t = elf_symbol::FUNC_TYPE;
2897 else if (s == "section-type")
2898 t = elf_symbol::SECTION_TYPE;
2899 else if (s == "file-type")
2900 t = elf_symbol::FILE_TYPE;
2901 else if (s == "common-type")
2902 t = elf_symbol::COMMON_TYPE;
2903 else if (s == "tls-type")
2904 t = elf_symbol::TLS_TYPE;
2905 else if (s == "gnu-ifunc-type")
2906 t = elf_symbol::GNU_IFUNC_TYPE;
2907 else
2908 return false;
2909
2910 return true;
2911 }
2912
2913 /// Convert a string representing a an elf symbol binding into an
2914 /// elf_symbol::binding.
2915 ///
2916 /// @param s the string to convert.
2917 ///
2918 /// @param b the resulting elf_symbol::binding.
2919 ///
2920 /// @return true iff the conversion completed successfully.
2921 bool
string_to_elf_symbol_binding(const string & s,elf_symbol::binding & b)2922 string_to_elf_symbol_binding(const string& s, elf_symbol::binding& b)
2923 {
2924 if (s == "local-binding")
2925 b = elf_symbol::LOCAL_BINDING;
2926 else if (s == "global-binding")
2927 b = elf_symbol::GLOBAL_BINDING;
2928 else if (s == "weak-binding")
2929 b = elf_symbol::WEAK_BINDING;
2930 else if (s == "gnu-unique-binding")
2931 b = elf_symbol::GNU_UNIQUE_BINDING;
2932 else
2933 return false;
2934
2935 return true;
2936 }
2937
2938 /// Convert a string representing a an elf symbol visibility into an
2939 /// elf_symbol::visibility.
2940 ///
2941 /// @param s the string to convert.
2942 ///
2943 /// @param b the resulting elf_symbol::visibility.
2944 ///
2945 /// @return true iff the conversion completed successfully.
2946 bool
string_to_elf_symbol_visibility(const string & s,elf_symbol::visibility & v)2947 string_to_elf_symbol_visibility(const string& s, elf_symbol::visibility& v)
2948 {
2949 if (s == "default-visibility")
2950 v = elf_symbol::DEFAULT_VISIBILITY;
2951 else if (s == "protected-visibility")
2952 v = elf_symbol::PROTECTED_VISIBILITY;
2953 else if (s == "hidden-visibility")
2954 v = elf_symbol::HIDDEN_VISIBILITY;
2955 else if (s == "internal-visibility")
2956 v = elf_symbol::INTERNAL_VISIBILITY;
2957 else
2958 return false;
2959
2960 return true;
2961 }
2962
2963 /// Test if the type of an ELF symbol denotes a function symbol.
2964 ///
2965 /// @param t the type of the ELF symbol.
2966 ///
2967 /// @return true iff elf symbol type @p t denotes a function symbol
2968 /// type.
2969 bool
elf_symbol_is_function(elf_symbol::type t)2970 elf_symbol_is_function(elf_symbol::type t)
2971 {return t == elf_symbol::FUNC_TYPE;}
2972
2973 /// Test if the type of an ELF symbol denotes a function symbol.
2974 ///
2975 /// @param t the type of the ELF symbol.
2976 ///
2977 /// @return true iff elf symbol type @p t denotes a function symbol
2978 /// type.
2979 bool
elf_symbol_is_variable(elf_symbol::type t)2980 elf_symbol_is_variable(elf_symbol::type t)
2981 {return t == elf_symbol::OBJECT_TYPE;}
2982
2983 // <elf_symbol::version stuff>
2984
2985 struct elf_symbol::version::priv
2986 {
2987 string version_;
2988 bool is_default_;
2989
privabigail::ir::elf_symbol::version::priv2990 priv()
2991 : is_default_(false)
2992 {}
2993
privabigail::ir::elf_symbol::version::priv2994 priv(const string& v,
2995 bool d)
2996 : version_(v),
2997 is_default_(d)
2998 {}
2999 }; // end struct elf_symbol::version::priv
3000
version()3001 elf_symbol::version::version()
3002 : priv_(new priv)
3003 {}
3004
3005 /// @param v the name of the version.
3006 ///
3007 /// @param is_default true if this is a default version.
version(const string & v,bool is_default)3008 elf_symbol::version::version(const string& v,
3009 bool is_default)
3010 : priv_(new priv(v, is_default))
3011 {}
3012
version(const elf_symbol::version & v)3013 elf_symbol::version::version(const elf_symbol::version& v)
3014 : priv_(new priv(v.str(), v.is_default()))
3015 {
3016 }
3017
3018 elf_symbol::version::~version() = default;
3019
3020 /// Cast the version_type into a string that is its name.
3021 ///
3022 /// @return the name of the version.
operator const string&() const3023 elf_symbol::version::operator const string&() const
3024 {return priv_->version_;}
3025
3026 /// Getter for the version name.
3027 ///
3028 /// @return the version name.
3029 const string&
str() const3030 elf_symbol::version::str() const
3031 {return priv_->version_;}
3032
3033 /// Setter for the version name.
3034 ///
3035 /// @param s the version name.
3036 void
str(const string & s)3037 elf_symbol::version::str(const string& s)
3038 {priv_->version_ = s;}
3039
3040 /// Getter for the 'is_default' property of the version.
3041 ///
3042 /// @return true iff this is a default version.
3043 bool
is_default() const3044 elf_symbol::version::is_default() const
3045 {return priv_->is_default_;}
3046
3047 /// Setter for the 'is_default' property of the version.
3048 ///
3049 /// @param f true if this is the default version.
3050 void
is_default(bool f)3051 elf_symbol::version::is_default(bool f)
3052 {priv_->is_default_ = f;}
3053
3054 bool
is_empty() const3055 elf_symbol::version::is_empty() const
3056 {return str().empty();}
3057
3058 /// Compares the current version against another one.
3059 ///
3060 /// @param o the other version to compare the current one to.
3061 ///
3062 /// @return true iff the current version equals @p o.
3063 bool
operator ==(const elf_symbol::version & o) const3064 elf_symbol::version::operator==(const elf_symbol::version& o) const
3065 {return str() == o.str();}
3066
3067 /// Inequality operator.
3068 ///
3069 /// @param o the version to compare against the current one.
3070 ///
3071 /// @return true iff both versions are different.
3072 bool
operator !=(const version & o) const3073 elf_symbol::version::operator!=(const version& o) const
3074 {return !operator==(o);}
3075
3076 /// Assign a version to the current one.
3077 ///
3078 /// @param o the other version to assign to this one.
3079 ///
3080 /// @return a reference to the assigned version.
3081 elf_symbol::version&
operator =(const elf_symbol::version & o)3082 elf_symbol::version::operator=(const elf_symbol::version& o)
3083 {
3084 str(o.str());
3085 is_default(o.is_default());
3086 return *this;
3087 }
3088
3089 // </elf_symbol::version stuff>
3090
3091 // </elf_symbol stuff>
3092
3093 // <class dm_context_rel stuff>
3094 struct dm_context_rel::priv
3095 {
3096 bool is_laid_out_;
3097 size_t offset_in_bits_;
3098 var_decl* anonymous_data_member_;
3099
privabigail::ir::dm_context_rel::priv3100 priv(bool is_static = false)
3101 : is_laid_out_(!is_static),
3102 offset_in_bits_(0),
3103 anonymous_data_member_()
3104 {}
3105
privabigail::ir::dm_context_rel::priv3106 priv(bool is_laid_out, size_t offset_in_bits)
3107 : is_laid_out_(is_laid_out),
3108 offset_in_bits_(offset_in_bits),
3109 anonymous_data_member_()
3110 {}
3111 }; //end struct dm_context_rel::priv
3112
dm_context_rel()3113 dm_context_rel::dm_context_rel()
3114 : context_rel(),
3115 priv_(new priv)
3116 {}
3117
dm_context_rel(scope_decl * s,bool is_laid_out,size_t offset_in_bits,access_specifier a,bool is_static)3118 dm_context_rel::dm_context_rel(scope_decl* s,
3119 bool is_laid_out,
3120 size_t offset_in_bits,
3121 access_specifier a,
3122 bool is_static)
3123 : context_rel(s, a, is_static),
3124 priv_(new priv(is_laid_out, offset_in_bits))
3125 {}
3126
dm_context_rel(scope_decl * s)3127 dm_context_rel::dm_context_rel(scope_decl* s)
3128 : context_rel(s),
3129 priv_(new priv())
3130 {}
3131
3132 bool
get_is_laid_out() const3133 dm_context_rel::get_is_laid_out() const
3134 {return priv_->is_laid_out_;}
3135
3136 void
set_is_laid_out(bool f)3137 dm_context_rel::set_is_laid_out(bool f)
3138 {priv_->is_laid_out_ = f;}
3139
3140 size_t
get_offset_in_bits() const3141 dm_context_rel::get_offset_in_bits() const
3142 {return priv_->offset_in_bits_;}
3143
3144 void
set_offset_in_bits(size_t o)3145 dm_context_rel::set_offset_in_bits(size_t o)
3146 {priv_->offset_in_bits_ = o;}
3147
3148 bool
operator ==(const dm_context_rel & o) const3149 dm_context_rel::operator==(const dm_context_rel& o) const
3150 {
3151 if (!context_rel::operator==(o))
3152 return false;
3153
3154 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3155 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3156 }
3157
3158 bool
operator !=(const dm_context_rel & o) const3159 dm_context_rel::operator!=(const dm_context_rel& o) const
3160 {return !operator==(o);}
3161
3162 /// Return a non-nil value if this data member context relationship
3163 /// has an anonymous data member. That means, if the data member this
3164 /// relation belongs to is part of an anonymous data member.
3165 ///
3166 /// @return the containing anonymous data member of this data member
3167 /// relationship. Nil if there is none.
3168 const var_decl*
get_anonymous_data_member() const3169 dm_context_rel::get_anonymous_data_member() const
3170 {return priv_->anonymous_data_member_;}
3171
3172 /// Set the containing anonymous data member of this data member
3173 /// context relationship. That means that the data member this
3174 /// relation belongs to is part of an anonymous data member.
3175 ///
3176 /// @param anon_dm the containing anonymous data member of this data
3177 /// member relationship. Nil if there is none.
3178 void
set_anonymous_data_member(var_decl * anon_dm)3179 dm_context_rel::set_anonymous_data_member(var_decl* anon_dm)
3180 {priv_->anonymous_data_member_ = anon_dm;}
3181
~dm_context_rel()3182 dm_context_rel::~dm_context_rel()
3183 {}
3184 // </class dm_context_rel stuff>
3185
3186 // <environment stuff>
3187
3188 /// Convenience typedef for a map of interned_string -> bool.
3189 typedef unordered_map<interned_string,
3190 bool, hash_interned_string> interned_string_bool_map_type;
3191
3192
3193 /// Default constructor of the @ref environment type.
environment()3194 environment::environment()
3195 :priv_(new priv)
3196 {}
3197
3198 /// Destructor for the @ref environment type.
~environment()3199 environment::~environment()
3200 {}
3201
3202 /// Getter the map of canonical types.
3203 ///
3204 /// @return the map of canonical types. The key of the map is the
3205 /// hash of the canonical type and its value if the canonical type.
3206 environment::canonical_types_map_type&
get_canonical_types_map()3207 environment::get_canonical_types_map()
3208 {return priv_->canonical_types_;}
3209
3210 /// Getter the map of canonical types.
3211 ///
3212 /// @return the map of canonical types. The key of the map is the
3213 /// hash of the canonical type and its value if the canonical type.
3214 const environment::canonical_types_map_type&
get_canonical_types_map() const3215 environment::get_canonical_types_map() const
3216 {return const_cast<environment*>(this)->get_canonical_types_map();}
3217
3218 /// Helper to detect if a type is either a reference, a pointer, or a
3219 /// qualified type.
3220 static bool
is_ptr_ref_or_qual_type(const type_base * t)3221 is_ptr_ref_or_qual_type(const type_base *t)
3222 {
3223 if (is_pointer_type(t)
3224 || is_reference_type(t)
3225 || is_qualified_type(t))
3226 return true;
3227 return false;
3228 }
3229
3230 /// A functor to sort decls somewhat topologically. That is, types
3231 /// are sorted in a way that makes the ones that are defined "first"
3232 /// to come first.
3233 ///
3234 /// The topological criteria is a lexicographic sort of the definition
3235 /// location of the type. For types that have no location (or the
3236 /// same location), it's their qualified name that is used for the
3237 /// lexicographic sort.
3238 struct decl_topo_comp
3239 {
3240
3241 /// The "Less Than" comparison operator of this functor.
3242 ///
3243 /// @param f the first decl to be considered for the comparison.
3244 ///
3245 /// @param s the second decl to be considered for the comparison.
3246 ///
3247 /// @return true iff @p f is less than @p s.
3248 bool
operator ()abigail::ir::decl_topo_comp3249 operator()(const decl_base *f,
3250 const decl_base *s)
3251 {
3252 if (!!f != !!s)
3253 return f && !s;
3254
3255 if (!f)
3256 return false;
3257
3258 // If a decl has artificial location, then use that one over the
3259 // natural one.
3260 location fl = get_artificial_or_natural_location(f);
3261 location sl = get_artificial_or_natural_location(s);
3262
3263 if (fl.get_value() && sl.get_value())
3264 {
3265 if (fl.get_is_artificial() == sl.get_is_artificial())
3266 {
3267 // The locations of the two artfifacts have the same
3268 // artificial-ness so they can be compared.
3269 string p1, p2;
3270 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3271 fl.expand(p1, l1, c1);
3272 sl.expand(p2, l2, c2);
3273 if (p1 != p2)
3274 return p1 < p2;
3275 if (l1 != l2)
3276 return l1 < l2;
3277 if (c1 != c2)
3278 return c1 < c2;
3279 }
3280 }
3281 else if (!!fl != !!sl)
3282 // So one of the decls doesn't have location data.
3283 // The first decl is less than the second if it's the one not
3284 // having location data.
3285 return !fl && sl;
3286
3287 // We reach this point if location data is useless.
3288 return (get_pretty_representation(f, true)
3289 < get_pretty_representation(s, true));
3290 }
3291
3292 /// The "Less Than" comparison operator of this functor.
3293 ///
3294 /// @param f the first decl to be considered for the comparison.
3295 ///
3296 /// @param s the second decl to be considered for the comparison.
3297 ///
3298 /// @return true iff @p f is less than @p s.
3299 bool
operator ()abigail::ir::decl_topo_comp3300 operator()(const decl_base_sptr &f,
3301 const decl_base_sptr &s)
3302 {return operator()(f.get(), s.get());}
3303
3304 }; // end struct decl_topo_comp
3305
3306 /// A functor to sort types somewhat topologically. That is, types
3307 /// are sorted in a way that makes the ones that are defined "first"
3308 /// to come first.
3309 ///
3310 /// The topological criteria is a lexicographic sort of the definition
3311 /// location of the type. For types that have no location, it's their
3312 /// qualified name that is used for the lexicographic sort.
3313 struct type_topo_comp
3314 {
3315 /// The "Less Than" comparison operator of this functor.
3316 ///
3317 /// @param f the first type to be considered for the comparison.
3318 ///
3319 /// @param s the second type to be considered for the comparison.
3320 ///
3321 /// @return true iff @p f is less than @p s.
3322 bool
operator ()abigail::ir::type_topo_comp3323 operator()(const type_base_sptr &f,
3324 const type_base_sptr &s)
3325 {return operator()(f.get(), s.get());}
3326
3327 /// The "Less Than" comparison operator of this functor.
3328 ///
3329 /// @param f the first type to be considered for the comparison.
3330 ///
3331 /// @param s the second type to be considered for the comparison.
3332 ///
3333 /// @return true iff @p f is less than @p s.
3334 bool
operator ()abigail::ir::type_topo_comp3335 operator()(const type_base *f,
3336 const type_base *s)
3337 {
3338 bool f_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(f);
3339 bool s_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(s);
3340
3341 if (f_is_ptr_ref_or_qual != s_is_ptr_ref_or_qual)
3342 return !f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual;
3343
3344 if (f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual
3345 && !is_decl(f)->get_location() && !is_decl(s)->get_location())
3346 {
3347 string s1 = get_pretty_representation(f, true);
3348 string s2 = get_pretty_representation(s, true);
3349 if (s1 == s2)
3350 if (qualified_type_def * q = is_qualified_type(f))
3351 if (q->get_cv_quals() == qualified_type_def::CV_NONE)
3352 if (!is_qualified_type(s))
3353 // We are looking at two types that are the result of
3354 // an optimization that happens during the IR
3355 // construction. Namely, type f is a cv-qualified
3356 // type with no qualifier (no const, no volatile, no
3357 // nothing, we call it an empty-qualified type).
3358 // These are the result of an optimization which
3359 // removes "redundant qualifiers" from some types.
3360 // For instance, consider a "const reference". The
3361 // const there is redundant because a reference is
3362 // always const. So as a result of the optimizaton
3363 // that type is going to be transformed into an
3364 // empty-qualified reference. If we don't make that
3365 // optimization, then we risk having spurious change
3366 // reports down the road. But then, as a consequence
3367 // of that optimization, we need to sort the
3368 // empty-qualified type and its non-qualified variant
3369 // e.g, to ensure stability in the abixml output; both
3370 // types are logically equal, but here, we decide that
3371 // the empty-qualified one is topologically "less
3372 // than" the non-qualified counterpart.
3373 //
3374 // So here, type f is an empty-qualified type and type
3375 // s is its non-qualified variant. We decide that f
3376 // is topologically less than s.
3377 return true;
3378 return (s1 < s2);
3379 }
3380
3381 decl_base *fd = is_decl(f);
3382 decl_base *sd = is_decl(s);
3383
3384 if (!!fd != !!sd)
3385 return fd && !sd;
3386
3387 if (!fd)
3388 {
3389 type_base *peeled_f = peel_pointer_or_reference_type(f);
3390 type_base *peeled_s = peel_pointer_or_reference_type(s);
3391
3392 fd = is_decl(peeled_f);
3393 sd = is_decl(peeled_s);
3394
3395 if (!!fd != !!sd)
3396 return fd && !sd;
3397
3398 if (!fd)
3399 return (get_pretty_representation(f, true)
3400 < get_pretty_representation(s, true));
3401 }
3402
3403 // From this point, fd and sd should be non-nil
3404 decl_topo_comp decl_comp;
3405 return decl_comp(fd, sd);
3406 }
3407 }; //end struct type_topo_comp
3408
3409 /// Get a @ref type_decl that represents a "void" type for the current
3410 /// environment.
3411 ///
3412 /// @return the @ref type_decl that represents a "void" type.
3413 const type_base_sptr&
get_void_type() const3414 environment::get_void_type() const
3415 {
3416 if (!priv_->void_type_)
3417 priv_->void_type_.reset(new type_decl(const_cast<environment*>(this),
3418 intern("void"),
3419 0, 0, location()));
3420 return priv_->void_type_;
3421 }
3422
3423 /// Get a @ref type_decl instance that represents a the type of a
3424 /// variadic function parameter.
3425 ///
3426 /// @return the Get a @ref type_decl instance that represents a the
3427 /// type of a variadic function parameter.
3428 const type_base_sptr&
get_variadic_parameter_type() const3429 environment::get_variadic_parameter_type() const
3430 {
3431 if (!priv_->variadic_marker_type_)
3432 priv_->variadic_marker_type_.
3433 reset(new type_decl(const_cast<environment*>(this),
3434 intern("variadic parameter type"),
3435 0, 0, location()));
3436 return priv_->variadic_marker_type_;
3437 }
3438
3439 /// Test if the canonicalization of types created out of the current
3440 /// environment is done.
3441 ///
3442 /// @return true iff the canonicalization of types created out of the current
3443 /// environment is done.
3444 bool
canonicalization_is_done() const3445 environment::canonicalization_is_done() const
3446 {return priv_->canonicalization_is_done_;}
3447
3448 /// Set a flag saying if the canonicalization of types created out of
3449 /// the current environment is done or not.
3450 ///
3451 /// Note that this function must only be called by internal code of
3452 /// the library that creates ABI artifacts (e.g, read an abi corpus
3453 /// from elf or from our own xml format and creates representations of
3454 /// types out of it) and thus needs to canonicalize types to speed-up
3455 /// further type comparison.
3456 ///
3457 /// @param f the new value of the flag.
3458 void
canonicalization_is_done(bool f)3459 environment::canonicalization_is_done(bool f)
3460 {priv_->canonicalization_is_done_ = f;}
3461
3462 /// Getter for the "on-the-fly-canonicalization" flag.
3463 ///
3464 /// @return true iff @ref OnTheFlyCanonicalization
3465 /// "on-the-fly-canonicalization" is to be performed during
3466 /// comparison.
3467 bool
do_on_the_fly_canonicalization() const3468 environment::do_on_the_fly_canonicalization() const
3469 {return priv_->do_on_the_fly_canonicalization_;}
3470
3471 /// Setter for the "on-the-fly-canonicalization" flag.
3472 ///
3473 /// @param f If this is true then @ref OnTheFlyCanonicalization
3474 /// "on-the-fly-canonicalization" is to be performed during
3475 /// comparison.
3476 void
do_on_the_fly_canonicalization(bool f)3477 environment::do_on_the_fly_canonicalization(bool f)
3478 {priv_->do_on_the_fly_canonicalization_ = f;}
3479
3480 /// Getter of the "decl-only-class-equals-definition" flag.
3481 ///
3482 /// Usually, a declaration-only class named 'struct foo' compares
3483 /// equal to any class definition named "struct foo'. This is at
3484 /// least true for C++.
3485 ///
3486 /// In C, though, because there can be multiple definitions of 'struct
3487 /// foo' in the binary, a declaration-only "struct foo" might be
3488 /// considered to *NOT* resolve to any of the struct foo defined. In
3489 /// that case, the declaration-only "struct foo" is considered
3490 /// different from the definitions.
3491 ///
3492 /// This flag controls the behaviour of the comparison of an
3493 /// unresolved decl-only class against a definition of the same name.
3494 ///
3495 /// If set to false, the the declaration equals the definition. If
3496 /// set to false, then the decalration is considered different from
3497 /// the declaration.
3498 ///
3499 /// @return the value of the "decl-only-class-equals-definition" flag.
3500 bool
decl_only_class_equals_definition() const3501 environment::decl_only_class_equals_definition() const
3502 {return priv_->decl_only_class_equals_definition_;}
3503
3504 /// Setter of the "decl-only-class-equals-definition" flag.
3505 ///
3506 /// Usually, a declaration-only class named 'struct foo' compares
3507 /// equal to any class definition named "struct foo'. This is at
3508 /// least true for C++.
3509 ///
3510 /// In C, though, because there can be multiple definitions of 'struct
3511 /// foo' in the binary, a declaration-only "struct foo" might be
3512 /// considered to *NOT* resolve to any of the struct foo defined. In
3513 /// that case, the declaration-only "struct foo" is considered
3514 /// different from the definitions.
3515 ///
3516 /// This flag controls the behaviour of the comparison of an
3517 /// unresolved decl-only class against a definition of the same name.
3518 ///
3519 /// If set to false, the the declaration equals the definition. If
3520 /// set to false, then the decalration is considered different from
3521 /// the declaration.
3522 ///
3523 /// @param the new value of the "decl-only-class-equals-definition"
3524 /// flag.
3525 void
decl_only_class_equals_definition(bool f) const3526 environment::decl_only_class_equals_definition(bool f) const
3527 {priv_->decl_only_class_equals_definition_ = f;}
3528
3529 /// Test if a given type is a void type as defined in the current
3530 /// environment.
3531 ///
3532 /// @param t the type to consider.
3533 ///
3534 /// @return true iff @p t is a void type as defined in the current
3535 /// environment.
3536 bool
is_void_type(const type_base_sptr & t) const3537 environment::is_void_type(const type_base_sptr& t) const
3538 {
3539 if (!t)
3540 return false;
3541 return t.get() == get_void_type().get();
3542 }
3543
3544 /// Test if a given type is a void type as defined in the current
3545 /// environment.
3546 ///
3547 /// @param t the type to consider.
3548 ///
3549 /// @return true iff @p t is a void type as defined in the current
3550 /// environment.
3551 bool
is_void_type(const type_base * t) const3552 environment::is_void_type(const type_base* t) const
3553 {
3554 if (!t)
3555 return false;
3556 return t == get_void_type().get();
3557 }
3558
3559 /// Test if a type is a variadic parameter type as defined in the
3560 /// current environment.
3561 ///
3562 /// @param t the type to consider.
3563 ///
3564 /// @return true iff @p t is a variadic parameter type as defined in
3565 /// the current environment.
3566 bool
is_variadic_parameter_type(const type_base * t) const3567 environment::is_variadic_parameter_type(const type_base* t) const
3568 {
3569 if (!t)
3570 return false;
3571 return t == get_variadic_parameter_type().get();
3572 }
3573
3574 /// Test if a type is a variadic parameter type as defined in the
3575 /// current environment.
3576 ///
3577 /// @param t the type to consider.
3578 ///
3579 /// @return true iff @p t is a variadic parameter type as defined in
3580 /// the current environment.
3581 bool
is_variadic_parameter_type(const type_base_sptr & t) const3582 environment::is_variadic_parameter_type(const type_base_sptr& t) const
3583 {return is_variadic_parameter_type(t.get());}
3584
3585 /// Do intern a string.
3586 ///
3587 /// If a value of this string already exists in the interned string
3588 /// pool of the current environment, then this function returns a new
3589 /// interned_string pointing to that already existing string.
3590 /// Otherwise, a new string is created, stored in the interned string
3591 /// pool and a new interned_string instance is created to point to
3592 /// that new intrerned string, and it's return.
3593 ///
3594 /// @param s the value of the string to intern.
3595 ///
3596 /// @return the interned string.
3597 interned_string
intern(const string & s) const3598 environment::intern(const string& s) const
3599 {return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3600
3601 /// Getter of the general configuration object.
3602 ///
3603 /// @return the configuration object.
3604 const config&
get_config() const3605 environment::get_config() const
3606 {return priv_->config_;}
3607
3608 #ifdef WITH_DEBUG_SELF_COMPARISON
3609 /// Setter of the corpus of the input corpus of the self comparison
3610 /// that takes place when doing "abidw --debug-abidiff <binary>".
3611 ///
3612 /// The first invocation of this function sets the first corpus of the
3613 /// self comparison. The second invocation of this very same function
3614 /// sets the second corpus of the self comparison. That second corpus
3615 /// is supposed to come from the abixml serialization of the first
3616 /// corpus.
3617 ///
3618 /// @param c the corpus of the input binary or the corpus of the
3619 /// abixml serialization of the initial binary input.
3620 void
set_self_comparison_debug_input(const corpus_sptr & c)3621 environment::set_self_comparison_debug_input(const corpus_sptr& c)
3622 {
3623 self_comparison_debug_is_on(true);
3624 if (priv_->first_self_comparison_corpus_.expired())
3625 priv_->first_self_comparison_corpus_ = c;
3626 else if (priv_->second_self_comparison_corpus_.expired()
3627 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3628 priv_->second_self_comparison_corpus_ = c;
3629 }
3630
3631 /// Getter for the corpora of the input binary and the intermediate
3632 /// abixml of the self comparison that takes place when doing
3633 /// 'abidw --debug-abidiff <binary>'.
3634 ///
3635 /// @param first_corpus output parameter that is set to the corpus of
3636 /// the input corpus.
3637 ///
3638 /// @param second_corpus output parameter that is set to the corpus of
3639 /// the second corpus.
3640 void
get_self_comparison_debug_inputs(corpus_sptr & first_corpus,corpus_sptr & second_corpus)3641 environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3642 corpus_sptr& second_corpus)
3643 {
3644 first_corpus = priv_->first_self_comparison_corpus_.lock();
3645 second_corpus = priv_->second_self_comparison_corpus_.lock();
3646 }
3647
3648 /// Turn on/off the self comparison debug mode.
3649 ///
3650 /// @param f true iff the self comparison debug mode is turned on.
3651 void
self_comparison_debug_is_on(bool f)3652 environment::self_comparison_debug_is_on(bool f)
3653 {priv_->self_comparison_debug_on_ = f;}
3654
3655 /// Test if we are in the process of the 'self-comparison
3656 /// debugging' as triggered by 'abidw --debug-abidiff' command.
3657 ///
3658 /// @return true if self comparison debug is on.
3659 bool
self_comparison_debug_is_on() const3660 environment::self_comparison_debug_is_on() const
3661 {return priv_->self_comparison_debug_on_;}
3662 #endif
3663
3664 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3665 /// Set the "type canonicalization debugging" mode, triggered by using
3666 /// the command: "abidw --debug-tc".
3667 ///
3668 /// @param flag if true then the type canonicalization debugging mode
3669 /// is enabled.
3670 void
debug_type_canonicalization_is_on(bool flag)3671 environment::debug_type_canonicalization_is_on(bool flag)
3672 {priv_->debug_type_canonicalization_ = flag;}
3673
3674 /// Getter of the "type canonicalization debugging" mode, triggered by
3675 /// using the command: "abidw --debug-tc".
3676 ///
3677 /// @return true iff the type canonicalization debugging mode is
3678 /// enabled.
3679 bool
debug_type_canonicalization_is_on() const3680 environment::debug_type_canonicalization_is_on() const
3681 {return priv_->debug_type_canonicalization_;}
3682 #endif // WITH_DEBUG_TYPE_CANONICALIZATION
3683
3684 /// Get the vector of canonical types which have a given "string
3685 /// representation".
3686 ///
3687 /// @param 'name', the textual representation of the type as returned
3688 /// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3689 /// /*qualified=*/true)
3690 ///
3691 /// This is useful to for debugging purposes as it's handy to use from
3692 /// inside a debugger like GDB.
3693 ///
3694 /// @return a pointer to the vector of canonical types having the
3695 /// representation @p name, or nullptr if no type with that
3696 /// representation exists.
3697 vector<type_base_sptr>*
get_canonical_types(const char * name)3698 environment::get_canonical_types(const char* name)
3699 {
3700 auto ti = get_canonical_types_map().find(name);
3701 if (ti == get_canonical_types_map().end())
3702 return nullptr;
3703 return &ti->second;
3704 }
3705
3706 /// Get a given canonical type which has a given "string
3707 /// representation".
3708 ///
3709 /// @param 'name', the textual representation of the type as returned
3710 /// by type_or_decl_base::get_pretty_representation(/*internal=*/true,
3711 /// /*qualified=*/true).
3712 ///
3713 /// @param index, the index of the type in the vector of types that
3714 /// all have the same textual representation @p 'name'. That vector
3715 /// is returned by the function environment::get_canonical_types().
3716 ///
3717 /// @return the canonical type which has the representation @p name,
3718 /// and which is at index @p index in the vector of canonical types
3719 /// having that same textual representation.
3720 type_base*
get_canonical_type(const char * name,unsigned index)3721 environment::get_canonical_type(const char* name, unsigned index)
3722 {
3723 vector<type_base_sptr> *types = get_canonical_types(name);
3724 if (!types ||index >= types->size())
3725 return nullptr;
3726 return (*types)[index].get();
3727 }
3728
3729 #ifdef WITH_DEBUG_SELF_COMPARISON
3730 /// Get the set of abixml type-id and the pointer value of the
3731 /// (canonical) type it's associated to.
3732 ///
3733 /// This is useful for debugging purposes, especially in the context
3734 /// of the use of the command:
3735 /// 'abidw --debug-abidiff <binary>'.
3736 ///
3737 /// @return the set of abixml type-id and the pointer value of the
3738 /// (canonical) type it's associated to.
3739 unordered_map<string, uintptr_t>&
get_type_id_canonical_type_map() const3740 environment::get_type_id_canonical_type_map() const
3741 {return priv_->type_id_canonical_type_map_;}
3742
3743 /// Getter of the map that associates the values of type pointers to
3744 /// their type-id strings.
3745 ///
3746 /// Note that this map is populated at abixml reading time, (by
3747 /// build_type()) when a given XML element representing a type is
3748 /// read into a corresponding abigail::ir::type_base.
3749 ///
3750 /// This is used only for the purpose of debugging the
3751 /// self-comparison process. That is, when invoking "abidw
3752 /// --debug-abidiff".
3753 ///
3754 /// @return the map that associates the values of type pointers to
3755 /// their type-id strings.
3756 unordered_map<uintptr_t, string>&
get_pointer_type_id_map()3757 environment::get_pointer_type_id_map()
3758 {return priv_->pointer_type_id_map_;}
3759
3760 /// Getter of the type-id that corresponds to the value of a pointer
3761 /// to abigail::ir::type_base that was created from the abixml reader.
3762 ///
3763 /// That value is retrieved from the map returned from
3764 /// environment::get_pointer_type_id_map().
3765 ///
3766 /// That map is populated at abixml reading time, (by build_type())
3767 /// when a given XML element representing a type is read into a
3768 /// corresponding abigail::ir::type_base.
3769 ///
3770 /// This is used only for the purpose of debugging the
3771 /// self-comparison process. That is, when invoking "abidw
3772 /// --debug-abidiff".
3773 ///
3774 /// @return the type-id strings that corresponds
3775 string
get_type_id_from_pointer(uintptr_t ptr)3776 environment::get_type_id_from_pointer(uintptr_t ptr)
3777 {
3778 auto it = get_pointer_type_id_map().find(ptr);
3779 if (it != get_pointer_type_id_map().end())
3780 return it->second;
3781 return "";
3782 }
3783
3784 /// Getter of the canonical type of the artifact designated by a
3785 /// type-id.
3786 ///
3787 /// That type-id was generated by the abixml writer at the emitting
3788 /// time of the abixml file. The corresponding canonical type was
3789 /// stored in the map returned by
3790 /// environment::get_type_id_canonical_type_map().
3791 ///
3792 /// This is useful for debugging purposes, especially in the context
3793 /// of the use of the command:
3794 /// 'abidw --debug-abidiff <binary>'.
3795 ///
3796 /// @return the set of abixml type-id and the pointer value of the
3797 /// (canonical) type it's associated to.
3798 uintptr_t
get_canonical_type_from_type_id(const char * type_id)3799 environment::get_canonical_type_from_type_id(const char* type_id)
3800 {
3801 if (!type_id)
3802 return 0;
3803 auto it = get_type_id_canonical_type_map().find(type_id);
3804 if (it != get_type_id_canonical_type_map().end())
3805 return it->second;
3806 return 0;
3807 }
3808 #endif
3809 // </environment stuff>
3810
3811 // <type_or_decl_base stuff>
3812
3813 /// The private data of @ref type_or_decl_base.
3814 struct type_or_decl_base::priv
3815 {
3816 // This holds the kind of dynamic type of particular instance.
3817 // Yes, this is part of the implementation of a "poor man" runtime
3818 // type identification. We are doing this because profiling shows
3819 // that using dynamic_cast in some places is really to slow and is
3820 // constituting a hotspot. This poor man's implementation made
3821 // things be much faster.
3822 enum type_or_decl_kind kind_;
3823 // This holds the runtime type instance pointer of particular
3824 // instance. In other words, this is the "this pointer" of the
3825 // dynamic type of a particular instance.
3826 void* rtti_;
3827 // This holds a pointer to either the type_base sub-object (if the
3828 // current instance is a type) or the decl_base sub-object (if the
3829 // current instance is a decl). This is used by the is_decl() and
3830 // is_type() functions, which also show up during profiling as
3831 // hotspots, due to their use of dynamic_cast.
3832 void* type_or_decl_ptr_;
3833 bool hashing_started_;
3834 const environment* env_;
3835 translation_unit* translation_unit_;
3836 // The location of an artifact as seen from its input by the
3837 // artifact reader. This might be different from the source
3838 // location advertised by the original emitter of the artifact
3839 // emitter.
3840 location artificial_location_;
3841 // Flags if the current ABI artifact is artificial (i.e, *NOT*
3842 // generated from the initial source code, but rather either
3843 // artificially by the compiler or by libabigail itself).
3844 bool is_artificial_;
3845
3846 /// Constructor of the type_or_decl_base::priv private type.
3847 ///
3848 /// @param e the environment in which the ABI artifact was created.
3849 ///
3850 /// @param k the identifier of the runtime type of the current
3851 /// instance of ABI artifact.
privabigail::ir::type_or_decl_base::priv3852 priv(const environment* e = 0,
3853 enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
3854 : kind_(k),
3855 rtti_(),
3856 type_or_decl_ptr_(),
3857 hashing_started_(),
3858 env_(e),
3859 translation_unit_(),
3860 is_artificial_()
3861 {}
3862
3863 enum type_or_decl_kind
kindabigail::ir::type_or_decl_base::priv3864 kind() const
3865 {return kind_;}
3866
3867 void
kindabigail::ir::type_or_decl_base::priv3868 kind (enum type_or_decl_kind k)
3869 {kind_ |= k;}
3870 }; // end struct type_or_decl_base::priv
3871
3872 /// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
3873 /// bitmap type.
3874 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)3875 operator|(type_or_decl_base::type_or_decl_kind l,
3876 type_or_decl_base::type_or_decl_kind r)
3877 {
3878 return static_cast<type_or_decl_base::type_or_decl_kind>
3879 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
3880 }
3881
3882 /// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
3883 /// bitmap type.
3884 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)3885 operator|=(type_or_decl_base::type_or_decl_kind& l,
3886 type_or_decl_base::type_or_decl_kind r)
3887 {
3888 l = l | r;
3889 return l;
3890 }
3891
3892 /// bitwise "AND" operator for the
3893 /// type_or_decl_base::type_or_decl_kind bitmap type.
3894 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)3895 operator&(type_or_decl_base::type_or_decl_kind l,
3896 type_or_decl_base::type_or_decl_kind r)
3897 {
3898 return static_cast<type_or_decl_base::type_or_decl_kind>
3899 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
3900 }
3901
3902 /// bitwise "A&=" operator for the
3903 /// type_or_decl_base::type_or_decl_kind bitmap type.
3904 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)3905 operator&=(type_or_decl_base::type_or_decl_kind& l,
3906 type_or_decl_base::type_or_decl_kind r)
3907 {
3908 l = l & r;
3909 return l;
3910 }
3911
3912 /// Default constructor of @ref type_or_decl_base.
type_or_decl_base()3913 type_or_decl_base::type_or_decl_base()
3914 :priv_(new priv)
3915 {}
3916
3917 /// Constructor of @ref type_or_decl_base.
3918 ///
3919 /// @param the environment the current ABI artifact is constructed
3920 /// from.
3921 ///
3922 /// @param k the runtime identifier bitmap of the type being built.
type_or_decl_base(const environment * e,enum type_or_decl_kind k)3923 type_or_decl_base::type_or_decl_base(const environment* e,
3924 enum type_or_decl_kind k)
3925 :priv_(new priv(e, k))
3926 {}
3927
3928 /// Copy constructor of @ref type_or_decl_base.
type_or_decl_base(const type_or_decl_base & o)3929 type_or_decl_base::type_or_decl_base(const type_or_decl_base& o)
3930 {*priv_ = *o.priv_;}
3931
3932 /// The destructor of the @ref type_or_decl_base type.
~type_or_decl_base()3933 type_or_decl_base::~type_or_decl_base()
3934 {}
3935
3936 /// Getter of the flag that says if the artefact is artificial.
3937 ///
3938 /// Being artificial means it was not explicitely mentionned in the
3939 /// source code, but was rather artificially created by the compiler
3940 /// or libabigail.
3941 ///
3942 /// @return true iff the declaration is artificial.
3943 bool
get_is_artificial() const3944 type_or_decl_base::get_is_artificial() const
3945 {return priv_->is_artificial_;}
3946
3947 /// Setter of the flag that says if the artefact is artificial.
3948 ///
3949 /// Being artificial means the artefact was not explicitely
3950 /// mentionned in the source code, but was rather artificially created
3951 /// by the compiler or by libabigail.
3952 ///
3953 /// @param f the new value of the flag that says if the artefact is
3954 /// artificial.
3955 void
set_is_artificial(bool f)3956 type_or_decl_base::set_is_artificial(bool f)
3957 {priv_->is_artificial_ = f;}
3958
3959 /// Getter for the "kind" property of @ref type_or_decl_base type.
3960 ///
3961 /// This property holds the identifier bitmap of the runtime type of
3962 /// an ABI artifact.
3963 ///
3964 /// @return the runtime type identifier bitmap of the current ABI
3965 /// artifact.
3966 enum type_or_decl_base::type_or_decl_kind
kind() const3967 type_or_decl_base::kind() const
3968 {return priv_->kind();}
3969
3970 /// Setter for the "kind" property of @ref type_or_decl_base type.
3971 ///
3972 /// This property holds the identifier bitmap of the runtime type of
3973 /// an ABI artifact.
3974 ///
3975 /// @param the runtime type identifier bitmap of the current ABI
3976 /// artifact.
3977 void
kind(enum type_or_decl_kind k)3978 type_or_decl_base::kind(enum type_or_decl_kind k)
3979 {priv_->kind(k);}
3980
3981 /// Getter of the pointer to the runtime type sub-object of the
3982 /// current instance.
3983 ///
3984 /// @return the pointer to the runtime type sub-object of the current
3985 /// instance.
3986 const void*
runtime_type_instance() const3987 type_or_decl_base::runtime_type_instance() const
3988 {return priv_->rtti_;}
3989
3990 /// Getter of the pointer to the runtime type sub-object of the
3991 /// current instance.
3992 ///
3993 /// @return the pointer to the runtime type sub-object of the current
3994 /// instance.
3995 void*
runtime_type_instance()3996 type_or_decl_base::runtime_type_instance()
3997 {return priv_->rtti_;}
3998
3999 /// Setter of the pointer to the runtime type sub-object of the
4000 /// current instance.
4001 ///
4002 /// @param i the new pointer to the runtime type sub-object of the
4003 /// current instance.
4004 void
runtime_type_instance(void * i)4005 type_or_decl_base::runtime_type_instance(void* i)
4006 {
4007 priv_->rtti_ = i;
4008 if (type_base* t = dynamic_cast<type_base*>(this))
4009 priv_->type_or_decl_ptr_ = t;
4010 else if (decl_base *d = dynamic_cast<decl_base*>(this))
4011 priv_->type_or_decl_ptr_ = d;
4012 }
4013
4014 /// Getter of the pointer to either the type_base sub-object of the
4015 /// current instance if it's a type, or to the decl_base sub-object of
4016 /// the current instance if it's a decl.
4017 ///
4018 /// @return the pointer to either the type_base sub-object of the
4019 /// current instance if it's a type, or to the decl_base sub-object of
4020 /// the current instance if it's a decl.
4021 const void*
type_or_decl_base_pointer() const4022 type_or_decl_base::type_or_decl_base_pointer() const
4023 {return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
4024
4025 /// Getter of the pointer to either the type_base sub-object of the
4026 /// current instance if it's a type, or to the decl_base sub-object of
4027 /// the current instance if it's a decl.
4028 ///
4029 /// @return the pointer to either the type_base sub-object of the
4030 /// current instance if it's a type, or to the decl_base sub-object of
4031 /// the current instance if it's a decl.
4032 void*
type_or_decl_base_pointer()4033 type_or_decl_base::type_or_decl_base_pointer()
4034 {return priv_->type_or_decl_ptr_;}
4035
4036 /// Getter for the 'hashing_started' property.
4037 ///
4038 /// @return the 'hashing_started' property.
4039 bool
hashing_started() const4040 type_or_decl_base::hashing_started() const
4041 {return priv_->hashing_started_;}
4042
4043 /// Setter for the 'hashing_started' property.
4044 ///
4045 /// @param b the value to set the 'hashing_property' to.
4046 void
hashing_started(bool b) const4047 type_or_decl_base::hashing_started(bool b) const
4048 {priv_->hashing_started_ = b;}
4049
4050 /// Setter of the environment of the current ABI artifact.
4051 ///
4052 /// This just sets the environment artifact of the current ABI
4053 /// artifact, not on its sub-trees. If you want to set the
4054 /// environment of an ABI artifact including its sub-tree, use the
4055 /// abigail::ir::set_environment_for_artifact() function.
4056 ///
4057 /// @param env the new environment.
4058 void
set_environment(const environment * env)4059 type_or_decl_base::set_environment(const environment* env)
4060 {priv_->env_ = env;}
4061
4062 /// Getter of the environment of the current ABI artifact.
4063 ///
4064 /// @return the environment of the artifact.
4065 const environment*
get_environment() const4066 type_or_decl_base::get_environment() const
4067 {return priv_->env_;}
4068
4069 /// Setter of the artificial location of the artificat.
4070 ///
4071 /// The artificial location is a location that was artificially
4072 /// generated by libabigail, not generated by the original emitter of
4073 /// the ABI meta-data. For instance, when reading an XML element from
4074 /// an abixml file, the artificial location is the source location of
4075 /// the XML element within the file, not the value of the
4076 /// 'location'property that might be carried by the element.
4077 ///
4078 /// Artificial locations might be useful to ensure that abixml emitted
4079 /// by the abixml writer are sorted the same way as the input abixml
4080 /// read by the reader.
4081 ///
4082 /// @param l the new artificial location.
4083 void
set_artificial_location(const location & l)4084 type_or_decl_base::set_artificial_location(const location &l)
4085 {priv_->artificial_location_ = l;}
4086
4087 /// Getter of the artificial location of the artifact.
4088 ///
4089 /// The artificial location is a location that was artificially
4090 /// generated by libabigail, not generated by the original emitter of
4091 /// the ABI meta-data. For instance, when reading an XML element from
4092 /// an abixml file, the artificial location is the source location of
4093 /// the XML element within the file, not the value of the
4094 /// 'location'property that might be carried by the element.
4095 ///
4096 /// Artificial locations might be useful to ensure that the abixml
4097 /// emitted by the abixml writer is sorted the same way as the input
4098 /// abixml read by the reader.
4099 ///
4100 /// @return the new artificial location.
4101 location&
get_artificial_location() const4102 type_or_decl_base::get_artificial_location() const
4103 {return priv_->artificial_location_;}
4104
4105 /// Test if the current ABI artifact carries an artificial location.
4106 ///
4107 /// @return true iff the current ABI artifact carries an artificial location.
4108 bool
has_artificial_location() const4109 type_or_decl_base::has_artificial_location() const
4110 {
4111 return (priv_->artificial_location_
4112 && priv_->artificial_location_.get_is_artificial());
4113 }
4114
4115 /// Getter of the environment of the current ABI artifact.
4116 ///
4117 /// @return the environment of the artifact.
4118 environment*
get_environment()4119 type_or_decl_base::get_environment()
4120 {return const_cast<environment*>(priv_->env_);}
4121
4122 /// Get the @ref corpus this ABI artifact belongs to.
4123 ///
4124 /// @return the corpus this ABI artifact belongs to, or nil if it
4125 /// belongs to none for now.
4126 corpus*
get_corpus()4127 type_or_decl_base::get_corpus()
4128 {
4129 translation_unit* tu = get_translation_unit();
4130 if (!tu)
4131 return 0;
4132 return tu->get_corpus();
4133 }
4134
4135
4136 /// Get the @ref corpus this ABI artifact belongs to.
4137 ///
4138 /// @return the corpus this ABI artifact belongs to, or nil if it
4139 /// belongs to none for now.
4140 const corpus*
get_corpus() const4141 type_or_decl_base::get_corpus() const
4142 {return const_cast<type_or_decl_base*>(this)->get_corpus();}
4143
4144 /// Set the @ref translation_unit this ABI artifact belongs to.
4145 ///
4146 /// Note that adding an ABI artifact to a containining on should
4147 /// invoke this member function.
4148 void
set_translation_unit(translation_unit * tu)4149 type_or_decl_base::set_translation_unit(translation_unit* tu)
4150 {priv_->translation_unit_ = tu;}
4151
4152
4153 /// Get the @ref translation_unit this ABI artifact belongs to.
4154 ///
4155 /// @return the translation unit this ABI artifact belongs to, or nil
4156 /// if belongs to none for now.
4157 translation_unit*
get_translation_unit()4158 type_or_decl_base::get_translation_unit()
4159 {return priv_->translation_unit_;}
4160
4161 /// Get the @ref translation_unit this ABI artifact belongs to.
4162 ///
4163 /// @return the translation unit this ABI artifact belongs to, or nil
4164 /// if belongs to none for now.
4165 const translation_unit*
get_translation_unit() const4166 type_or_decl_base::get_translation_unit() const
4167 {return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
4168
4169 /// Assignment operator for @ref type_or_decl_base.
4170 ///
4171 /// @param o the other instance to assign the current instance to.
4172 ///
4173 /// return a reference to the assigned instance of @ref
4174 /// type_or_decl_base.
4175 type_or_decl_base&
operator =(const type_or_decl_base & o)4176 type_or_decl_base::operator=(const type_or_decl_base& o)
4177 {
4178 *priv_ = *o.priv_;
4179 return *this;
4180 }
4181
4182 /// Traverse the the ABI artifact.
4183 ///
4184 /// @param v the visitor used to traverse the sub-tree nodes of the
4185 /// artifact.
4186 bool
traverse(ir_node_visitor &)4187 type_or_decl_base::traverse(ir_node_visitor&)
4188 {return true;}
4189
4190 /// Set the environment of a given ABI artifact, including recursively
4191 /// setting the environment on the sub-trees of the artifact.
4192 ///
4193 /// @param artifact the artifact to set the environment for.
4194 ///
4195 /// @param env the new environment.
4196 void
set_environment_for_artifact(type_or_decl_base * artifact,const environment * env)4197 set_environment_for_artifact(type_or_decl_base* artifact,
4198 const environment* env)
4199 {
4200 ABG_ASSERT(artifact && env);
4201
4202 ::environment_setter s(env);
4203 artifact->traverse(s);
4204 }
4205
4206 /// Set the environment of a given ABI artifact, including recursively
4207 /// setting the environment on the sub-trees of the artifact.
4208 ///
4209 /// @param artifact the artifact to set the environment for.
4210 ///
4211 /// @param env the new environment.
4212 void
set_environment_for_artifact(type_or_decl_base_sptr artifact,const environment * env)4213 set_environment_for_artifact(type_or_decl_base_sptr artifact,
4214 const environment* env)
4215 {set_environment_for_artifact(artifact.get(), env);}
4216
4217 /// Non-member equality operator for the @type_or_decl_base type.
4218 ///
4219 /// @param lr the left-hand operand of the equality.
4220 ///
4221 /// @param rr the right-hand operatnr of the equality.
4222 ///
4223 /// @return true iff @p lr equals @p rr.
4224 bool
operator ==(const type_or_decl_base & lr,const type_or_decl_base & rr)4225 operator==(const type_or_decl_base& lr, const type_or_decl_base& rr)
4226 {
4227 const type_or_decl_base* l = &lr;
4228 const type_or_decl_base* r = &rr;
4229
4230 const decl_base* dl = dynamic_cast<const decl_base*>(l),
4231 *dr = dynamic_cast<const decl_base*>(r);
4232
4233 if (!!dl != !!dr)
4234 return false;
4235
4236 if (dl && dr)
4237 return *dl == *dr;
4238
4239 const type_base* tl = dynamic_cast<const type_base*>(l),
4240 *tr = dynamic_cast<const type_base*>(r);
4241
4242 if (!!tl != !!tr)
4243 return false;
4244
4245 if (tl && tr)
4246 return *tl == *tr;
4247
4248 return false;
4249 }
4250
4251 /// Non-member equality operator for the @type_or_decl_base type.
4252 ///
4253 /// @param l the left-hand operand of the equality.
4254 ///
4255 /// @param r the right-hand operatnr of the equality.
4256 ///
4257 /// @return true iff @p l equals @p r.
4258 bool
operator ==(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)4259 operator==(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
4260 {
4261 if (!! l != !!r)
4262 return false;
4263
4264 if (!l)
4265 return true;
4266
4267 return *r == *l;
4268 }
4269
4270 /// Non-member inequality operator for the @type_or_decl_base type.
4271 ///
4272 /// @param l the left-hand operand of the equality.
4273 ///
4274 /// @param r the right-hand operator of the equality.
4275 ///
4276 /// @return true iff @p l is different from @p r.
4277 bool
operator !=(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)4278 operator!=(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
4279 {return !operator==(l, r);}
4280
4281 // </type_or_decl_base stuff>
4282
4283 // <Decl definition>
4284
4285 struct decl_base::priv
4286 {
4287 bool in_pub_sym_tab_;
4288 bool is_anonymous_;
4289 location location_;
4290 context_rel *context_;
4291 interned_string name_;
4292 interned_string qualified_parent_name_;
4293 // This temporary qualified name is the cache used for the qualified
4294 // name before the type associated to this decl (if applicable) is
4295 // canonicalized. Once the type is canonicalized, the cached use is
4296 // the data member qualified_parent_name_ above.
4297 interned_string temporary_qualified_name_;
4298 // This is the fully qualified name of the decl. It contains the
4299 // name of the decl and the qualified name of its scope. So if in
4300 // the parent scopes of the decl, there is one anonymous struct,
4301 // somewhere in the name, there is going to by an
4302 // __anonymous_struct__ string, even if the anonymous struct is not
4303 // the direct containing scope of this decl.
4304 interned_string qualified_name_;
4305 // Unline qualified_name_, scoped_name_ contains the name of the
4306 // decl and the name of its scope; not the qualified name of the
4307 // scope.
4308 interned_string scoped_name_;
4309 interned_string linkage_name_;
4310 visibility visibility_;
4311 decl_base_sptr declaration_;
4312 decl_base_wptr definition_of_declaration_;
4313 decl_base* naked_definition_of_declaration_;
4314 bool is_declaration_only_;
4315 typedef_decl_sptr naming_typedef_;
4316
privabigail::ir::decl_base::priv4317 priv()
4318 : in_pub_sym_tab_(false),
4319 is_anonymous_(true),
4320 context_(),
4321 visibility_(VISIBILITY_DEFAULT),
4322 naked_definition_of_declaration_(),
4323 is_declaration_only_(false)
4324 {}
4325
privabigail::ir::decl_base::priv4326 priv(interned_string name, interned_string linkage_name, visibility vis)
4327 : in_pub_sym_tab_(false),
4328 context_(),
4329 name_(name),
4330 qualified_name_(name),
4331 linkage_name_(linkage_name),
4332 visibility_(vis),
4333 naked_definition_of_declaration_(),
4334 is_declaration_only_(false)
4335 {
4336 is_anonymous_ = name_.empty();
4337 }
4338
~privabigail::ir::decl_base::priv4339 ~priv()
4340 {
4341 delete context_;
4342 }
4343 };// end struct decl_base::priv
4344
4345 /// Constructor for the @ref decl_base type.
4346 ///
4347 /// @param e the environment the current @ref decl_base is being
4348 /// created in.
4349 ///
4350 /// @param name the name of the declaration.
4351 ///
4352 /// @param locus the location where to find the declaration in the
4353 /// source code.
4354 ///
4355 /// @param linkage_name the linkage name of the declaration.
4356 ///
4357 /// @param vis the visibility of the declaration.
decl_base(const environment * e,const string & name,const location & locus,const string & linkage_name,visibility vis)4358 decl_base::decl_base(const environment* e,
4359 const string& name,
4360 const location& locus,
4361 const string& linkage_name,
4362 visibility vis)
4363 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4364 priv_(new priv(e->intern(name), e->intern(linkage_name), vis))
4365 {
4366 set_location(locus);
4367 }
4368
4369 /// Constructor.
4370 ///
4371 /// @param e the environment this instance of @ref decl_base is
4372 /// created in.
4373 ///
4374 /// @param name the name of the declaration being constructed.
4375 ///
4376 /// @param locus the source location of the declaration being constructed.
4377 ///
4378 /// @param linkage_name the linkage name of the declaration being
4379 /// constructed.
4380 ///
4381 /// @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)4382 decl_base::decl_base(const environment* e,
4383 const interned_string& name,
4384 const location& locus,
4385 const interned_string& linkage_name,
4386 visibility vis)
4387 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4388 priv_(new priv(name, linkage_name, vis))
4389 {
4390 set_location(locus);
4391 }
4392
4393 /// Constructor for the @ref decl_base type.
4394 ///
4395 ///@param environment the environment this instance of @ref decl_base
4396 /// is being constructed in.
4397 ///
4398 /// @param l the location where to find the declaration in the source
4399 /// code.
decl_base(const environment * e,const location & l)4400 decl_base::decl_base(const environment* e, const location& l)
4401 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4402 priv_(new priv())
4403 {
4404 set_location(l);
4405 }
4406
decl_base(const decl_base & d)4407 decl_base::decl_base(const decl_base& d)
4408 : type_or_decl_base(d)
4409 {
4410 priv_->in_pub_sym_tab_ = d.priv_->in_pub_sym_tab_;
4411 priv_->location_ = d.priv_->location_;
4412 priv_->name_ = d.priv_->name_;
4413 priv_->qualified_parent_name_ = d.priv_->qualified_parent_name_;
4414 priv_->qualified_name_ = d.priv_->qualified_name_;
4415 priv_->linkage_name_ = d.priv_->linkage_name_;
4416 priv_->context_ = d.priv_->context_;
4417 priv_->visibility_ = d.priv_->visibility_;
4418 }
4419
4420 /// Getter for the qualified name.
4421 ///
4422 /// Unlike decl_base::get_qualified_name() this doesn't try to update
4423 /// the qualified name.
4424 ///
4425 /// @return the qualified name.
4426 const interned_string&
peek_qualified_name() const4427 decl_base::peek_qualified_name() const
4428 {return priv_->qualified_name_;}
4429
4430 /// Clear the qualified name of this decl.
4431 ///
4432 /// This is useful to ensure that the cache for the qualified name of
4433 /// the decl is refreshed right after type canonicalization, for
4434 /// instance.
4435 void
clear_qualified_name()4436 decl_base::clear_qualified_name()
4437 {priv_->qualified_name_.clear();}
4438
4439 /// Setter for the qualified name.
4440 ///
4441 /// @param n the new qualified name.
4442 void
set_qualified_name(const interned_string & n) const4443 decl_base::set_qualified_name(const interned_string& n) const
4444 {priv_->qualified_name_ = n;}
4445
4446 /// Getter of the temporary qualified name of the current declaration.
4447 ///
4448 /// This temporary qualified name is used as a qualified name cache by
4449 /// the type for which this is the declaration (when applicable)
4450 /// before the type is canonicalized. Once the type is canonicalized,
4451 /// it's the result of decl_base::peek_qualified_name() that becomes
4452 /// the qualified name cached.
4453 ///
4454 /// @return the temporary qualified name.
4455 const interned_string&
peek_temporary_qualified_name() const4456 decl_base::peek_temporary_qualified_name() const
4457 {return priv_->temporary_qualified_name_;}
4458
4459 /// Setter for the temporary qualified name of the current
4460 /// declaration.
4461 ///
4462 ///@param n the new temporary qualified name.
4463 ///
4464 /// This temporary qualified name is used as a qualified name cache by
4465 /// the type for which this is the declaration (when applicable)
4466 /// before the type is canonicalized. Once the type is canonicalized,
4467 /// it's the result of decl_base::peek_qualified_name() that becomes
4468 /// the qualified name cached.
4469 void
set_temporary_qualified_name(const interned_string & n) const4470 decl_base::set_temporary_qualified_name(const interned_string& n) const
4471 {priv_->temporary_qualified_name_ = n;}
4472
4473 ///Getter for the context relationship.
4474 ///
4475 ///@return the context relationship for the current decl_base.
4476 const context_rel*
get_context_rel() const4477 decl_base::get_context_rel() const
4478 {return priv_->context_;}
4479
4480 ///Getter for the context relationship.
4481 ///
4482 ///@return the context relationship for the current decl_base.
4483 context_rel*
get_context_rel()4484 decl_base::get_context_rel()
4485 {return priv_->context_;}
4486
4487 void
set_context_rel(context_rel * c)4488 decl_base::set_context_rel(context_rel *c)
4489 {priv_->context_ = c;}
4490
4491 /// Get the hash of a decl. If the hash hasn't been computed yet,
4492 /// compute it ans store its value; otherwise, just return the hash.
4493 ///
4494 /// @return the hash of the decl.
4495 size_t
get_hash() const4496 decl_base::get_hash() const
4497 {
4498 size_t result = 0;
4499
4500 if (const type_base* t = dynamic_cast<const type_base*>(this))
4501 {
4502 type_base::dynamic_hash hash;
4503 result = hash(t);
4504 }
4505 else
4506 // If we reach this point, it mean we are missing a virtual
4507 // overload for decl_base::get_hash. Add it!
4508 abort();
4509
4510 return result;
4511 }
4512
4513 /// Test if the decl is defined in a ELF symbol table as a public
4514 /// symbol.
4515 ///
4516 /// @return true iff the decl is defined in a ELF symbol table as a
4517 /// public symbol.
4518 bool
get_is_in_public_symbol_table() const4519 decl_base::get_is_in_public_symbol_table() const
4520 {return priv_->in_pub_sym_tab_;}
4521
4522 /// Set the flag saying if this decl is from a symbol that is in
4523 /// a public symbols table, defined as public (global or weak).
4524 ///
4525 /// @param f the new flag value.
4526 void
set_is_in_public_symbol_table(bool f)4527 decl_base::set_is_in_public_symbol_table(bool f)
4528 {priv_->in_pub_sym_tab_ = f;}
4529
4530 /// Get the location of a given declaration.
4531 ///
4532 /// The location is an abstraction for the tripplet {file path,
4533 /// line, column} that defines where the declaration appeared in the
4534 /// source code.
4535 ///
4536 /// To get the value of the tripplet {file path, line, column} from
4537 /// the @ref location, you need to use the
4538 /// location_manager::expand_location() method.
4539 ///
4540 /// The instance of @ref location_manager that you want is
4541 /// accessible from the instance of @ref translation_unit that the
4542 /// current instance of @ref decl_base belongs to, via a call to
4543 /// translation_unit::get_loc_mgr().
4544 ///
4545 /// @return the location of the current instance of @ref decl_base.
4546 const location&
get_location() const4547 decl_base::get_location() const
4548 {return priv_->location_;}
4549
4550 /// Set the location for a given declaration.
4551 ///
4552 /// The location is an abstraction for the tripplet {file path,
4553 /// line, column} that defines where the declaration appeared in the
4554 /// source code.
4555 ///
4556 /// To create a location from a tripplet {file path, line, column},
4557 /// you need to use the method @ref
4558 /// location_manager::create_new_location().
4559 ///
4560 /// Note that there can be two kinds of location. An artificial
4561 /// location and a non-artificial one. The non-artificial location is
4562 /// the one emitted by the original emitter of the ABI artifact, for
4563 /// instance, if the ABI artifact comes from debug info, then the
4564 /// source location that is present in the debug info represent a
4565 /// non-artificial location. When looking at an abixml file on the
4566 /// other hand, the value of the 'location' attribute of an XML
4567 /// element describing an artifact is the non-artificial location.
4568 /// The artificial location is the location (line number from the
4569 /// beginning of the file) of the XML element within the abixml file.
4570 ///
4571 /// So, if the location that is being set is artificial, note that the
4572 /// type_or_decl_base::has_artificial_location() method of this decl will
4573 /// subsequently return true and that artificial location will have to
4574 /// be retrieved using type_or_decl_base::get_artificial_location().
4575 /// If the location is non-artificial however,
4576 /// type_or_decl_base::has_artificial_location() will subsequently
4577 /// return false and the non-artificial location will have to be
4578 /// retrieved using decl_base::get_location().
4579 ///
4580 /// The instance of @ref location_manager that you want is
4581 /// accessible from the instance of @ref translation_unit that the
4582 /// current instance of @ref decl_base belongs to, via a call to
4583 /// translation_unit::get_loc_mgr().
4584 void
set_location(const location & l)4585 decl_base::set_location(const location& l)
4586 {
4587 if (l.get_is_artificial())
4588 set_artificial_location(l);
4589 else
4590 priv_->location_ = l;
4591 }
4592
4593 /// Setter for the name of the decl.
4594 ///
4595 /// @param n the new name to set.
4596 void
set_name(const string & n)4597 decl_base::set_name(const string& n)
4598 {
4599 priv_->name_ = get_environment()->intern(n);
4600 priv_->is_anonymous_ = n.empty();
4601 }
4602
4603 /// Test if the current declaration is anonymous.
4604 ///
4605 /// Being anonymous means that the declaration was created without a
4606 /// name. This can usually happen for enum or struct types.
4607 ///
4608 /// @return true iff the type is anonymous.
4609 bool
get_is_anonymous() const4610 decl_base::get_is_anonymous() const
4611 {return priv_->is_anonymous_;}
4612
4613 /// Set the "is_anonymous" flag of the current declaration.
4614 ///
4615 /// Being anonymous means that the declaration was created without a
4616 /// name. This can usually happen for enum or struct types.
4617 ///
4618 /// @param f the new value of the flag.
4619 void
set_is_anonymous(bool f)4620 decl_base::set_is_anonymous(bool f)
4621 {priv_->is_anonymous_ = f;}
4622
4623
4624 /// Get the "has_anonymous_parent" flag of the current declaration.
4625 ///
4626 /// Having an anoymous parent means having a anonymous parent scope
4627 /// (containing type or namespace) which is either direct or indirect.
4628 ///
4629 /// @return true iff the current decl has a direct or indirect scope
4630 /// which is anonymous.
4631 bool
get_has_anonymous_parent() const4632 decl_base::get_has_anonymous_parent() const
4633 {
4634 scope_decl *scope = get_scope();
4635 if (!scope)
4636 return false;
4637 return scope->get_is_anonymous();
4638 }
4639
4640 /// @return the logical "OR" of decl_base::get_is_anonymous() and
4641 /// decl_base::get_has_anonymous_parent().
4642 bool
get_is_anonymous_or_has_anonymous_parent() const4643 decl_base::get_is_anonymous_or_has_anonymous_parent() const
4644 {return get_is_anonymous() || get_has_anonymous_parent();}
4645
4646 /// Getter for the naming typedef of the current decl.
4647 ///
4648 /// Consider the C idiom:
4649 ///
4650 /// typedef struct {int member;} foo_type;
4651 ///
4652 /// In that idiom, foo_type is the naming typedef of the anonymous
4653 /// struct that is declared.
4654 ///
4655 /// @return the naming typedef, if any. Otherwise, returns nil.
4656 typedef_decl_sptr
get_naming_typedef() const4657 decl_base::get_naming_typedef() const
4658 {return priv_->naming_typedef_;}
4659
4660 /// Set the naming typedef of the current instance of @ref decl_base.
4661 ///
4662 /// Consider the C idiom:
4663 ///
4664 /// typedef struct {int member;} foo_type;
4665 ///
4666 /// In that idiom, foo_type is the naming typedef of the anonymous
4667 /// struct that is declared.
4668 ///
4669 /// After completion of this function, the decl will not be considered
4670 /// anonymous anymore. It's name is going to be the name of the
4671 /// naming typedef.
4672 ///
4673 /// @param typedef_type the new naming typedef.
4674 void
set_naming_typedef(const typedef_decl_sptr & t)4675 decl_base::set_naming_typedef(const typedef_decl_sptr& t)
4676 {
4677 // A naming typedef is usually for an anonymous type.
4678 ABG_ASSERT(get_is_anonymous()
4679 // Whe the typedef-named decl is saved into abixml, it's
4680 // not anonymous anymore. Its name is the typedef name.
4681 // So when we read it back, we must still be able to
4682 // apply the naming typedef to the decl.
4683 || t->get_name() == get_name());
4684 // Only non canonicalized types can be edited this way.
4685 ABG_ASSERT(is_type(this)
4686 && is_type(this)->get_naked_canonical_type() == nullptr);
4687
4688 priv_->naming_typedef_ = t;
4689 set_name(t->get_name());
4690 set_qualified_name(t->get_qualified_name());
4691 set_is_anonymous(false);
4692 // Now that the qualified type of the decl has changed, let's update
4693 // the qualified names of the member types of this decls.
4694 update_qualified_name(this);
4695 }
4696
4697 /// Getter for the mangled name.
4698 ///
4699 /// @return the new mangled name.
4700 const interned_string&
get_linkage_name() const4701 decl_base::get_linkage_name() const
4702 {return priv_->linkage_name_;}
4703
4704 /// Setter for the linkage name.
4705 ///
4706 /// @param m the new linkage name.
4707 void
set_linkage_name(const string & m)4708 decl_base::set_linkage_name(const string& m)
4709 {
4710 const environment* env = get_environment();
4711 ABG_ASSERT(env);
4712 priv_->linkage_name_ = env->intern(m);
4713 }
4714
4715 /// Getter for the visibility of the decl.
4716 ///
4717 /// @return the new visibility.
4718 decl_base::visibility
get_visibility() const4719 decl_base::get_visibility() const
4720 {return priv_->visibility_;}
4721
4722 /// Setter for the visibility of the decl.
4723 ///
4724 /// @param v the new visibility.
4725 void
set_visibility(visibility v)4726 decl_base::set_visibility(visibility v)
4727 {priv_->visibility_ = v;}
4728
4729 /// Return the type containing the current decl, if any.
4730 ///
4731 /// @return the type that contains the current decl, or NULL if there
4732 /// is none.
4733 scope_decl*
get_scope() const4734 decl_base::get_scope() const
4735 {
4736 if (priv_->context_)
4737 return priv_->context_->get_scope();
4738 return 0;
4739 }
4740
4741 /// Return a copy of the qualified name of the parent of the current
4742 /// decl.
4743 ///
4744 /// @return the newly-built qualified name of the of the current decl.
4745 const interned_string&
get_qualified_parent_name() const4746 decl_base::get_qualified_parent_name() const
4747 {return priv_->qualified_parent_name_;}
4748
4749 /// Getter for the name of the current decl.
4750 ///
4751 /// @return the name of the current decl.
4752 const interned_string&
get_name() const4753 decl_base::get_name() const
4754 {return priv_->name_;}
4755
4756 /// Compute the qualified name of the decl.
4757 ///
4758 /// @param qn the resulting qualified name.
4759 ///
4760 /// @param internal set to true if the call is intended for an
4761 /// internal use (for technical use inside the library itself), false
4762 /// otherwise. If you don't know what this is for, then set it to
4763 /// false.
4764 void
get_qualified_name(interned_string & qn,bool internal) const4765 decl_base::get_qualified_name(interned_string& qn, bool internal) const
4766 {qn = get_qualified_name(internal);}
4767
4768 /// Get the pretty representatin of the current declaration.
4769 ///
4770 ///
4771 /// @param internal set to true if the call is intended to get a
4772 /// representation of the decl (or type) for the purpose of canonical
4773 /// type comparison. This is mainly used in the function
4774 /// type_base::get_canonical_type_for().
4775 ///
4776 /// In other words if the argument for this parameter is true then the
4777 /// call is meant for internal use (for technical use inside the
4778 /// library itself), false otherwise. If you don't know what this is
4779 /// for, then set it to false.
4780 ///
4781 /// @param qualified_name if true, names emitted in the pretty
4782 /// representation are fully qualified.
4783 ///
4784 /// @return the default pretty representation for a decl. This is
4785 /// basically the fully qualified name of the decl optionally prefixed
4786 /// with a meaningful string to add context for the user.
4787 string
get_pretty_representation(bool internal,bool qualified_name) const4788 decl_base::get_pretty_representation(bool internal,
4789 bool qualified_name) const
4790 {
4791 if (internal
4792 && get_is_anonymous()
4793 && has_generic_anonymous_internal_type_name(this))
4794 {
4795 // We are looking at an anonymous enum, union or class and we
4796 // want an *internal* pretty representation for it. All
4797 // anonymous types of this kind in the same namespace must have
4798 // the same internal representation for type canonicalization to
4799 // work properly.
4800 //
4801 // OK, in practise, we are certainly looking at an enum because
4802 // classes and unions should have their own overloaded virtual
4803 // member function for this.
4804 string name = get_generic_anonymous_internal_type_name(this);
4805 if (qualified_name && !get_qualified_parent_name().empty())
4806 name = get_qualified_parent_name() + "::" + name;
4807 return name;
4808 }
4809
4810 if (qualified_name)
4811 return get_qualified_name(internal);
4812 return get_name();
4813 }
4814
4815 /// Return the qualified name of the decl.
4816 ///
4817 /// This is the fully qualified name of the decl. It's made of the
4818 /// concatenation of the name of the decl with the qualified name of
4819 /// its scope.
4820 ///
4821 /// Note that the value returned by this function is computed by @ref
4822 /// update_qualified_name when the decl is added to its scope.
4823 ///
4824 /// @param internal set to true if the call is intended for an
4825 /// internal use (for technical use inside the library itself), false
4826 /// otherwise. If you don't know what this is for, then set it to
4827 /// false.
4828 ///
4829 /// @return the resulting qualified name.
4830 const interned_string&
get_qualified_name(bool) const4831 decl_base::get_qualified_name(bool /*internal*/) const
4832 {return priv_->qualified_name_;}
4833
4834 /// Return the scoped name of the decl.
4835 ///
4836 /// This is made of the concatenation of the name of the decl with the
4837 /// name of its scope. It doesn't contain the qualified name of its
4838 /// scope, unlike what is returned by decl_base::get_qualified_name.
4839 ///
4840 /// Note that the value returned by this function is computed by @ref
4841 /// update_qualified_name when the decl is added to its scope.
4842 ///
4843 /// @return the scoped name of the decl.
4844 const interned_string&
get_scoped_name() const4845 decl_base::get_scoped_name() const
4846 {return priv_->scoped_name_;}
4847
4848 /// If this @ref decl_base is a definition, get its earlier
4849 /// declaration.
4850 ///
4851 /// @return the earlier declaration of the class, if any.
4852 const decl_base_sptr
get_earlier_declaration() const4853 decl_base::get_earlier_declaration() const
4854 {return priv_->declaration_;}
4855
4856 /// set the earlier declaration of this @ref decl_base definition.
4857 ///
4858 /// @param d the earlier declaration to set. Note that it's set only
4859 /// if it's a pure declaration.
4860 void
set_earlier_declaration(const decl_base_sptr & d)4861 decl_base::set_earlier_declaration(const decl_base_sptr& d)
4862 {
4863 if (d && d->get_is_declaration_only())
4864 priv_->declaration_ = d;
4865 }
4866
4867
4868 /// If this @ref decl_base is declaration-only, get its definition, if
4869 /// any.
4870 ///
4871 /// @return the definition of this decl-only @ref decl_base.
4872 const decl_base_sptr
get_definition_of_declaration() const4873 decl_base::get_definition_of_declaration() const
4874 {return priv_->definition_of_declaration_.lock();}
4875
4876 /// If this @ref decl_base is declaration-only, get its definition,
4877 /// if any.
4878 ///
4879 /// Note that this function doesn't return a smart pointer, but rather
4880 /// the underlying pointer managed by the smart pointer. So it's as
4881 /// fast as possible. This getter is to be used in code paths that
4882 /// are proven to be performance hot spots; especially, when comparing
4883 /// sensitive types like enums, classes or unions. Those are compared
4884 /// extremely frequently and thus, their access to the definition of
4885 /// declaration must be fast.
4886 ///
4887 /// @return the definition of the declaration.
4888 const decl_base*
get_naked_definition_of_declaration() const4889 decl_base::get_naked_definition_of_declaration() const
4890 {return priv_->naked_definition_of_declaration_;}
4891
4892 /// Test if a @ref decl_base is a declaration-only decl.
4893 ///
4894 /// @return true iff the current @ref decl_base is declaration-only.
4895 bool
get_is_declaration_only() const4896 decl_base::get_is_declaration_only() const
4897 {return priv_->is_declaration_only_;}
4898
4899 /// Set a flag saying if the @ref enum_type_decl is a declaration-only
4900 /// @ref enum_type_decl.
4901 ///
4902 /// @param f true if the @ref enum_type_decl is a declaration-only
4903 /// @ref enum_type_decl.
4904 void
set_is_declaration_only(bool f)4905 decl_base::set_is_declaration_only(bool f)
4906 {
4907 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
4908
4909 priv_->is_declaration_only_ = f;
4910
4911 if (update_types_lookup_map)
4912 if (scope_decl* s = get_scope())
4913 {
4914 scope_decl::declarations::iterator i;
4915 if (s->find_iterator_for_member(this, i))
4916 maybe_update_types_lookup_map(*i);
4917 else
4918 ABG_ASSERT_NOT_REACHED;
4919 }
4920 }
4921
4922 change_kind
operator |(change_kind l,change_kind r)4923 operator|(change_kind l, change_kind r)
4924 {
4925 return static_cast<change_kind>(static_cast<unsigned>(l)
4926 | static_cast<unsigned>(r));
4927 }
4928
4929 change_kind
operator &(change_kind l,change_kind r)4930 operator&(change_kind l, change_kind r)
4931 {
4932 return static_cast<change_kind>(static_cast<unsigned>(l)
4933 & static_cast<unsigned>(r));
4934 }
4935
4936 change_kind&
operator |=(change_kind & l,change_kind r)4937 operator|=(change_kind& l, change_kind r)
4938 {
4939 l = l | r;
4940 return l;
4941 }
4942
4943 change_kind&
operator &=(change_kind & l,change_kind r)4944 operator&=(change_kind& l, change_kind r)
4945 {
4946 l = l & r;
4947 return l;
4948 }
4949
4950 /// Compare the properties that belong to the "is-a-member-relation"
4951 /// of a decl.
4952 ///
4953 /// For instance, access specifiers are part of the
4954 /// "is-a-member-relation" of a decl.
4955 ///
4956 /// This comparison however doesn't take decl names into account. So
4957 /// typedefs for instance are decls that we want to compare with this
4958 /// function.
4959 ///
4960 /// This function is a sub-routine of the more general 'equals'
4961 /// overload for instances of decl_base.
4962 ///
4963 /// @param l the left-hand side operand of the comparison.
4964 ///
4965 /// @param r the right-hand side operand of the comparison.
4966 ///
4967 /// @return true iff @p l compare equals, as a member decl, to @p r.
4968 bool
maybe_compare_as_member_decls(const decl_base & l,const decl_base & r,change_kind * k)4969 maybe_compare_as_member_decls(const decl_base& l,
4970 const decl_base& r,
4971 change_kind* k)
4972 {
4973 bool result = true;
4974 if (is_member_decl(l) && is_member_decl(r))
4975 {
4976 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
4977 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
4978
4979 access_specifier la = no_access, ra = no_access;
4980 bool member_types_or_functions =
4981 ((is_type(l) && is_type(r))
4982 || (is_function_decl(l) && is_function_decl(r)));
4983
4984 if (member_types_or_functions)
4985 {
4986 // Access specifiers on member types in DWARF is not
4987 // reliable; in the same DSO, the same struct can be either
4988 // a class or a struct, and the access specifiers of its
4989 // member types are not necessarily given, so they
4990 // effectively can be considered differently, again, in the
4991 // same DSO. So, here, let's avoid considering those!
4992 // during comparison.
4993 la = r1->get_access_specifier();
4994 ra = r2->get_access_specifier();
4995 r1->set_access_specifier(no_access);
4996 r2->set_access_specifier(no_access);
4997 }
4998
4999 bool rels_are_different = *r1 != *r2;
5000
5001 if (member_types_or_functions)
5002 {
5003 // restore the access specifiers.
5004 r1->set_access_specifier(la);
5005 r2->set_access_specifier(ra);
5006 }
5007
5008 if (rels_are_different)
5009 {
5010 result = false;
5011 if (k)
5012 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
5013 }
5014 }
5015 ABG_RETURN(result);
5016 }
5017
5018 /// Get the name of a decl for the purpose of comparing two decl
5019 /// names.
5020 ///
5021 /// This is a sub-routine of the 'equal' overload for decl_base.
5022 ///
5023 /// This function takes into account the fact that all anonymous names
5024 /// shall have the same name for the purpose of comparison.
5025 ///
5026 /// For decls that are part of an anonymous scope, only the
5027 /// non-qualified name should be taken into account.
5028 static interned_string
get_decl_name_for_comparison(const decl_base & d)5029 get_decl_name_for_comparison(const decl_base &d)
5030 {
5031 if (has_generic_anonymous_internal_type_name(&d)
5032 && d.get_is_anonymous())
5033 {
5034 // The decl is anonymous. It should have the same name ass the
5035 // other anymous types of the same kind.
5036 string r;
5037 r += get_generic_anonymous_internal_type_name(&d);
5038 return d.get_environment()->intern(r);
5039 }
5040
5041 interned_string n = (is_anonymous_or_typedef_named(d)
5042 || scope_anonymous_or_typedef_named(d))
5043 ? d.get_name()
5044 : d.get_qualified_name(/*internal=*/true);
5045 return n;
5046 }
5047
5048 /// Compares two instances of @ref decl_base.
5049 ///
5050 /// If the two intances are different, set a bitfield to give some
5051 /// insight about the kind of differences there are.
5052 ///
5053 /// @param l the first artifact of the comparison.
5054 ///
5055 /// @param r the second artifact of the comparison.
5056 ///
5057 /// @param k a pointer to a bitfield that gives information about the
5058 /// kind of changes there are between @p l and @p r. This one is set
5059 /// iff it's non-null and if the function returns false.
5060 ///
5061 /// Please note that setting k to a non-null value does have a
5062 /// negative performance impact because even if @p l and @p r are not
5063 /// equal, the function keeps up the comparison in order to determine
5064 /// the different kinds of ways in which they are different.
5065 ///
5066 /// @return true if @p l equals @p r, false otherwise.
5067 bool
equals(const decl_base & l,const decl_base & r,change_kind * k)5068 equals(const decl_base& l, const decl_base& r, change_kind* k)
5069 {
5070 bool result = true;
5071 const interned_string &l_linkage_name = l.get_linkage_name();
5072 const interned_string &r_linkage_name = r.get_linkage_name();
5073 if (!l_linkage_name.empty() && !r_linkage_name.empty())
5074 {
5075 if (l_linkage_name != r_linkage_name)
5076 {
5077 // Linkage names are different. That usually means the two
5078 // decls are different, unless we are looking at two
5079 // function declarations which have two different symbols
5080 // that are aliases of each other.
5081 const function_decl *f1 = is_function_decl(&l),
5082 *f2 = is_function_decl(&r);
5083 if (f1 && f2 && function_decls_alias(*f1, *f2))
5084 ;// The two functions are aliases, so they are not
5085 // different.
5086 else
5087 {
5088 result = false;
5089 if (k)
5090 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
5091 else
5092 ABG_RETURN_FALSE;
5093 }
5094 }
5095 }
5096
5097 // This is the qualified name of the decls that we want to compare.
5098 // We want to use the "internal" version of the qualified name as
5099 // that one is stable even for anonymous decls.
5100 interned_string ln = get_decl_name_for_comparison(l);
5101 interned_string rn = get_decl_name_for_comparison(r);
5102
5103 /// If both of the current decls have an anonymous scope then let's
5104 /// compare their name component by component by properly handling
5105 /// anonymous scopes. That's the slow path.
5106 ///
5107 /// Otherwise, let's just compare their name, the obvious way.
5108 /// That's the fast path because in that case the names are
5109 /// interned_string and comparing them is much faster.
5110 bool decls_are_same = (ln == rn);
5111 if (!decls_are_same
5112 && l.get_is_anonymous()
5113 && !l.get_has_anonymous_parent()
5114 && r.get_is_anonymous()
5115 && !r.get_has_anonymous_parent())
5116 // Both decls are anonymous and their scope are *NOT* anonymous.
5117 // So we consider the decls to have equivalent names (both
5118 // anonymous, remember). We are still in the fast path here.
5119 decls_are_same = true;
5120
5121 if (!decls_are_same
5122 && l.get_has_anonymous_parent()
5123 && r.get_has_anonymous_parent())
5124 // This is the slow path as we are comparing the decl qualified
5125 // names component by component, properly handling anonymous
5126 // scopes.
5127 decls_are_same = tools_utils::decl_names_equal(ln, rn);
5128
5129 if (!decls_are_same)
5130 {
5131 result = false;
5132 if (k)
5133 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
5134 else
5135 ABG_RETURN_FALSE;
5136 }
5137
5138 result &= maybe_compare_as_member_decls(l, r, k);
5139
5140 ABG_RETURN(result);
5141 }
5142
5143 /// Return true iff the two decls have the same name.
5144 ///
5145 /// This function doesn't test if the scopes of the the two decls are
5146 /// equal.
5147 ///
5148 /// Note that this virtual function is to be implemented by classes
5149 /// that extend the \p decl_base class.
5150 bool
operator ==(const decl_base & other) const5151 decl_base::operator==(const decl_base& other) const
5152 {return equals(*this, other, 0);}
5153
5154 /// Inequality operator.
5155 ///
5156 /// @param other to other instance of @ref decl_base to compare the
5157 /// current instance to.
5158 ///
5159 /// @return true iff the current instance of @ref decl_base is
5160 /// different from @p other.
5161 bool
operator !=(const decl_base & other) const5162 decl_base::operator!=(const decl_base& other) const
5163 {return !operator==(other);}
5164
5165 /// Destructor of the @ref decl_base type.
~decl_base()5166 decl_base::~decl_base()
5167 {delete priv_;}
5168
5169 /// This implements the ir_traversable_base::traverse pure virtual
5170 /// function.
5171 ///
5172 /// @param v the visitor used on the member nodes of the translation
5173 /// unit during the traversal.
5174 ///
5175 /// @return true if the entire IR node tree got traversed, false
5176 /// otherwise.
5177 bool
traverse(ir_node_visitor &)5178 decl_base::traverse(ir_node_visitor&)
5179 {
5180 // Do nothing in the base class.
5181 return true;
5182 }
5183
5184 /// Setter of the scope of the current decl.
5185 ///
5186 /// Note that the decl won't hold a reference on the scope. It's
5187 /// rather the scope that holds a reference on its members.
5188 void
set_scope(scope_decl * scope)5189 decl_base::set_scope(scope_decl* scope)
5190 {
5191 if (!priv_->context_)
5192 priv_->context_ = new context_rel(scope);
5193 else
5194 priv_->context_->set_scope(scope);
5195 }
5196
5197 // </decl_base definition>
5198
5199 /// Streaming operator for the decl_base::visibility.
5200 ///
5201 /// @param o the output stream to serialize the visibility to.
5202 ///
5203 /// @param v the visibility to serialize.
5204 ///
5205 /// @return the output stream.
5206 std::ostream&
operator <<(std::ostream & o,decl_base::visibility v)5207 operator<<(std::ostream& o, decl_base::visibility v)
5208 {
5209 string r;
5210 switch (v)
5211 {
5212 case decl_base::VISIBILITY_NONE:
5213 r = "none";
5214 break;
5215 case decl_base::VISIBILITY_DEFAULT:
5216 r = "default";
5217 break;
5218 case decl_base::VISIBILITY_PROTECTED:
5219 r = "protected";
5220 break;
5221 case decl_base::VISIBILITY_HIDDEN:
5222 r = "hidden";
5223 break;
5224 case decl_base::VISIBILITY_INTERNAL:
5225 r = "internal";
5226 break;
5227 }
5228 return o;
5229 }
5230
5231 /// Streaming operator for decl_base::binding.
5232 ///
5233 /// @param o the output stream to serialize the visibility to.
5234 ///
5235 /// @param b the binding to serialize.
5236 ///
5237 /// @return the output stream.
5238 std::ostream&
operator <<(std::ostream & o,decl_base::binding b)5239 operator<<(std::ostream& o, decl_base::binding b)
5240 {
5241 string r;
5242 switch (b)
5243 {
5244 case decl_base::BINDING_NONE:
5245 r = "none";
5246 break;
5247 case decl_base::BINDING_LOCAL:
5248 r = "local";
5249 break;
5250 case decl_base::BINDING_GLOBAL:
5251 r = "global";
5252 break;
5253 case decl_base::BINDING_WEAK:
5254 r = "weak";
5255 break;
5256 }
5257 o << r;
5258 return o;
5259 }
5260
5261 /// Turn equality of shared_ptr of decl_base into a deep equality;
5262 /// that is, make it compare the pointed to objects, not just the
5263 /// pointers.
5264 ///
5265 /// @param l the shared_ptr of decl_base on left-hand-side of the
5266 /// equality.
5267 ///
5268 /// @param r the shared_ptr of decl_base on right-hand-side of the
5269 /// equality.
5270 ///
5271 /// @return true if the decl_base pointed to by the shared_ptrs are
5272 /// equal, false otherwise.
5273 bool
operator ==(const decl_base_sptr & l,const decl_base_sptr & r)5274 operator==(const decl_base_sptr& l, const decl_base_sptr& r)
5275 {
5276 if (l.get() == r.get())
5277 return true;
5278 if (!!l != !!r)
5279 return false;
5280
5281 return *l == *r;
5282 }
5283
5284 /// Inequality operator of shared_ptr of @ref decl_base.
5285 ///
5286 /// This is a deep equality operator, that is, it compares the
5287 /// pointed-to objects, rather than just the pointers.
5288 ///
5289 /// @param l the left-hand-side operand.
5290 ///
5291 /// @param r the right-hand-side operand.
5292 ///
5293 /// @return true iff @p l is different from @p r.
5294 bool
operator !=(const decl_base_sptr & l,const decl_base_sptr & r)5295 operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
5296 {return !operator==(l, r);}
5297
5298 /// Turn equality of shared_ptr of type_base into a deep equality;
5299 /// that is, make it compare the pointed to objects too.
5300 ///
5301 /// @param l the shared_ptr of type_base on left-hand-side of the
5302 /// equality.
5303 ///
5304 /// @param r the shared_ptr of type_base on right-hand-side of the
5305 /// equality.
5306 ///
5307 /// @return true if the type_base pointed to by the shared_ptrs are
5308 /// equal, false otherwise.
5309 bool
operator ==(const type_base_sptr & l,const type_base_sptr & r)5310 operator==(const type_base_sptr& l, const type_base_sptr& r)
5311 {
5312 if (l.get() == r.get())
5313 return true;
5314 if (!!l != !!r)
5315 return false;
5316
5317 return *l == *r;
5318 }
5319
5320 /// Turn inequality of shared_ptr of type_base into a deep equality;
5321 /// that is, make it compare the pointed to objects..
5322 ///
5323 /// @param l the shared_ptr of type_base on left-hand-side of the
5324 /// equality.
5325 ///
5326 /// @param r the shared_ptr of type_base on right-hand-side of the
5327 /// equality.
5328 ///
5329 /// @return true iff the type_base pointed to by the shared_ptrs are
5330 /// different.
5331 bool
operator !=(const type_base_sptr & l,const type_base_sptr & r)5332 operator!=(const type_base_sptr& l, const type_base_sptr& r)
5333 {return !operator==(l, r);}
5334
5335 /// Tests if a declaration has got a scope.
5336 ///
5337 /// @param d the declaration to consider.
5338 ///
5339 /// @return true if the declaration has got a scope, false otherwise.
5340 bool
has_scope(const decl_base & d)5341 has_scope(const decl_base& d)
5342 {return (d.get_scope());}
5343
5344 /// Tests if a declaration has got a scope.
5345 ///
5346 /// @param d the declaration to consider.
5347 ///
5348 /// @return true if the declaration has got a scope, false otherwise.
5349 bool
has_scope(const decl_base_sptr d)5350 has_scope(const decl_base_sptr d)
5351 {return has_scope(*d.get());}
5352
5353 /// Tests if a declaration is a class member.
5354 ///
5355 /// @param d the declaration to consider.
5356 ///
5357 /// @return true if @p d is a class member, false otherwise.
5358 bool
is_member_decl(const decl_base_sptr d)5359 is_member_decl(const decl_base_sptr d)
5360 {return is_at_class_scope(d) || is_method_decl(d);}
5361
5362 /// Tests if a declaration is a class member.
5363 ///
5364 /// @param d the declaration to consider.
5365 ///
5366 /// @return true if @p d is a class member, false otherwise.
5367 bool
is_member_decl(const decl_base * d)5368 is_member_decl(const decl_base* d)
5369 {return is_at_class_scope(d) || is_method_decl(d);}
5370
5371 /// Tests if a declaration is a class member.
5372 ///
5373 /// @param d the declaration to consider.
5374 ///
5375 /// @return true if @p d is a class member, false otherwise.
5376 bool
is_member_decl(const decl_base & d)5377 is_member_decl(const decl_base& d)
5378 {return is_at_class_scope(d) || is_method_decl(d);}
5379
5380 /// Test if a declaration is a @ref scope_decl.
5381 ///
5382 /// @param d the declaration to take in account.
5383 ///
5384 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
5385 /// if d is a @ref scope_decl.
5386 scope_decl*
is_scope_decl(decl_base * d)5387 is_scope_decl(decl_base* d)
5388 {return dynamic_cast<scope_decl*>(d);}
5389
5390 /// Test if a declaration is a @ref scope_decl.
5391 ///
5392 /// @param d the declaration to take in account.
5393 ///
5394 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
5395 /// if d is a @ref scope_decl.
5396 scope_decl_sptr
is_scope_decl(const decl_base_sptr & d)5397 is_scope_decl(const decl_base_sptr& d)
5398 {return dynamic_pointer_cast<scope_decl>(d);}
5399
5400 /// Tests if a type is a class member.
5401 ///
5402 /// @param t the type to consider.
5403 ///
5404 /// @return true if @p t is a class member type, false otherwise.
5405 bool
is_member_type(const type_base_sptr & t)5406 is_member_type(const type_base_sptr& t)
5407 {
5408 decl_base_sptr d = get_type_declaration(t);
5409 return is_member_decl(d);
5410 }
5411
5412 /// Test if a type is user-defined.
5413 ///
5414 /// A type is considered user-defined if it's a
5415 /// struct/class/union/enum that is *NOT* artificial.
5416 ///
5417 /// @param t the type to consider.
5418 ///
5419 /// @return true iff the type @p t is user-defined.
5420 bool
is_user_defined_type(const type_base * t)5421 is_user_defined_type(const type_base* t)
5422 {
5423 if (t == 0)
5424 return false;
5425
5426 t = peel_qualified_or_typedef_type(t);
5427 decl_base *d = is_decl(t);
5428
5429 if ((is_class_or_union_type(t) || is_enum_type(t))
5430 && d && !d->get_is_artificial())
5431 return true;
5432
5433 return false;
5434 }
5435
5436 /// Test if a type is user-defined.
5437 ///
5438 /// A type is considered user-defined if it's a
5439 /// struct/class/union/enum.
5440 ///
5441 ///
5442 /// @param t the type to consider.
5443 ///
5444 /// @return true iff the type @p t is user-defined.
5445 bool
is_user_defined_type(const type_base_sptr & t)5446 is_user_defined_type(const type_base_sptr& t)
5447 {return is_user_defined_type(t.get());}
5448
5449 /// Gets the access specifier for a class member.
5450 ///
5451 /// @param d the declaration of the class member to consider. Note
5452 /// that this must be a class member otherwise the function aborts the
5453 /// current process.
5454 ///
5455 /// @return the access specifier for the class member @p d.
5456 access_specifier
get_member_access_specifier(const decl_base & d)5457 get_member_access_specifier(const decl_base& d)
5458 {
5459 ABG_ASSERT(is_member_decl(d));
5460
5461 const context_rel* c = d.get_context_rel();
5462 ABG_ASSERT(c);
5463
5464 return c->get_access_specifier();
5465 }
5466
5467 /// Gets the access specifier for a class member.
5468 ///
5469 /// @param d the declaration of the class member to consider. Note
5470 /// that this must be a class member otherwise the function aborts the
5471 /// current process.
5472 ///
5473 /// @return the access specifier for the class member @p d.
5474 access_specifier
get_member_access_specifier(const decl_base_sptr & d)5475 get_member_access_specifier(const decl_base_sptr& d)
5476 {return get_member_access_specifier(*d);}
5477
5478 /// Sets the access specifier for a class member.
5479 ///
5480 /// @param d the class member to set the access specifier for. Note
5481 /// that this must be a class member otherwise the function aborts the
5482 /// current process.
5483 ///
5484 /// @param a the new access specifier to set the class member to.
5485 void
set_member_access_specifier(decl_base & d,access_specifier a)5486 set_member_access_specifier(decl_base& d,
5487 access_specifier a)
5488 {
5489 ABG_ASSERT(is_member_decl(d));
5490
5491 context_rel* c = d.get_context_rel();
5492 ABG_ASSERT(c);
5493
5494 c->set_access_specifier(a);
5495 }
5496
5497 /// Sets the access specifier for a class member.
5498 ///
5499 /// @param d the class member to set the access specifier for. Note
5500 /// that this must be a class member otherwise the function aborts the
5501 /// current process.
5502 ///
5503 /// @param a the new access specifier to set the class member to.
5504 void
set_member_access_specifier(const decl_base_sptr & d,access_specifier a)5505 set_member_access_specifier(const decl_base_sptr& d,
5506 access_specifier a)
5507 {set_member_access_specifier(*d, a);}
5508
5509 /// Gets a flag saying if a class member is static or not.
5510 ///
5511 /// @param d the declaration for the class member to consider. Note
5512 /// that this must be a class member otherwise the function aborts the
5513 /// current process.
5514 ///
5515 /// @return true if the class member @p d is static, false otherwise.
5516 bool
get_member_is_static(const decl_base & d)5517 get_member_is_static(const decl_base&d)
5518 {
5519 ABG_ASSERT(is_member_decl(d));
5520
5521 const context_rel* c = d.get_context_rel();
5522 ABG_ASSERT(c);
5523
5524 return c->get_is_static();
5525 }
5526
5527 /// Gets a flag saying if a class member is static or not.
5528 ///
5529 /// @param d the declaration for the class member to consider. Note
5530 /// that this must be a class member otherwise the function aborts the
5531 /// current process.
5532 ///
5533 /// @return true if the class member @p d is static, false otherwise.
5534 bool
get_member_is_static(const decl_base * d)5535 get_member_is_static(const decl_base* d)
5536 {return get_member_is_static(*d);}
5537
5538 /// Gets a flag saying if a class member is static or not.
5539 ///
5540 /// @param d the declaration for the class member to consider. Note
5541 /// that this must be a class member otherwise the function aborts the
5542 /// current process.
5543 ///
5544 /// @return true if the class member @p d is static, false otherwise.
5545 bool
get_member_is_static(const decl_base_sptr & d)5546 get_member_is_static(const decl_base_sptr& d)
5547 {return get_member_is_static(*d);}
5548
5549 /// Test if a var_decl is a data member.
5550 ///
5551 /// @param v the var_decl to consider.
5552 ///
5553 /// @return true if @p v is data member, false otherwise.
5554 bool
is_data_member(const var_decl & v)5555 is_data_member(const var_decl& v)
5556 {return is_at_class_scope(v);}
5557
5558 /// Test if a var_decl is a data member.
5559 ///
5560 /// @param v the var_decl to consider.
5561 ///
5562 /// @return true if @p v is data member, false otherwise.
5563 bool
is_data_member(const var_decl * v)5564 is_data_member(const var_decl* v)
5565 {return is_data_member(*v);}
5566
5567 /// Test if a var_decl is a data member.
5568 ///
5569 /// @param v the var_decl to consider.
5570 ///
5571 /// @return true if @p v is data member, false otherwise.
5572 bool
is_data_member(const var_decl_sptr d)5573 is_data_member(const var_decl_sptr d)
5574 {return is_at_class_scope(d);}
5575
5576 /// Test if a decl is a data member.
5577 ///
5578 /// @param d the decl to consider.
5579 ///
5580 /// @return a pointer to the data member iff @p d is a data member, or
5581 /// a null pointer.
5582 var_decl_sptr
is_data_member(const decl_base_sptr & d)5583 is_data_member(const decl_base_sptr& d)
5584 {
5585 if (var_decl_sptr v = is_var_decl(d))
5586 {
5587 if (is_data_member(v))
5588 return v;
5589 }
5590 return var_decl_sptr();
5591 }
5592
5593 /// Test if a decl is a data member.
5594 ///
5595 /// @param d the decl to consider.
5596 ///
5597 /// @return a pointer to the data member iff @p d is a data member, or
5598 /// a null pointer.
5599 var_decl_sptr
is_data_member(const type_or_decl_base_sptr & d)5600 is_data_member(const type_or_decl_base_sptr& d)
5601 {
5602 if (var_decl_sptr v = is_var_decl(d))
5603 {
5604 if (is_data_member(v))
5605 return v;
5606 }
5607 return var_decl_sptr();
5608 }
5609
5610 /// Test if a decl is a data member.
5611 ///
5612 /// @param d the decl to consider.
5613 ///
5614 /// @return a pointer to the data member iff @p d is a data member, or
5615 /// a null pointer.
5616 var_decl*
is_data_member(const type_or_decl_base * d)5617 is_data_member(const type_or_decl_base* d)
5618 {
5619 if (var_decl *v = is_var_decl(d))
5620 if (is_data_member(v))
5621 return v;
5622 return 0;
5623 }
5624
5625 /// Test if a decl is a data member.
5626 ///
5627 /// @param d the decl to consider.
5628 ///
5629 /// @return a pointer to the data member iff @p d is a data member, or
5630 /// a null pointer.
5631 var_decl*
is_data_member(const decl_base * d)5632 is_data_member(const decl_base *d)
5633 {
5634 if (var_decl *v = is_var_decl(d))
5635 if (is_data_member(v))
5636 return v;
5637 return 0;
5638 }
5639
5640 /// Get the first non-anonymous data member of a given anonymous data
5641 /// member.
5642 ///
5643 /// E.g:
5644 ///
5645 /// struct S
5646 /// {
5647 /// union // <-- for this anonymous data member, the function
5648 /// // returns a.
5649 /// {
5650 /// int a;
5651 /// charb;
5652 /// };
5653 /// };
5654 ///
5655 /// @return anon_dm the anonymous data member to consider.
5656 ///
5657 /// @return the first non-anonymous data member of @p anon_dm. If no
5658 /// data member was found then this function returns @p anon_dm.
5659 const var_decl_sptr
get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)5660 get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
5661 {
5662 if (!anon_dm || !is_anonymous_data_member(anon_dm))
5663 return anon_dm;
5664
5665 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
5666 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5667
5668 if (is_anonymous_data_member(first))
5669 return get_first_non_anonymous_data_member(first);
5670
5671 return first;
5672 }
5673
5674 /// In the context of a given class or union, this function returns
5675 /// the data member that is located after a given data member.
5676 ///
5677 /// @param klass the class or union to consider.
5678 ///
5679 /// @param the data member to consider.
5680 ///
5681 /// @return the data member that is located right after @p
5682 /// data_member.
5683 const var_decl_sptr
get_next_data_member(const class_or_union_sptr & klass,const var_decl_sptr & data_member)5684 get_next_data_member(const class_or_union_sptr &klass,
5685 const var_decl_sptr &data_member)
5686 {
5687 if (!klass ||!data_member)
5688 return var_decl_sptr();
5689
5690 for (class_or_union::data_members::const_iterator it =
5691 klass->get_non_static_data_members().begin();
5692 it != klass->get_non_static_data_members().end();
5693 ++it)
5694 if (**it == *data_member)
5695 {
5696 ++it;
5697 if (it != klass->get_non_static_data_members().end())
5698 return get_first_non_anonymous_data_member(*it);
5699 break;
5700 }
5701
5702 return var_decl_sptr();
5703 }
5704
5705 /// Get the last data member of a class type.
5706 ///
5707 /// @param klass the class type to consider.
5708 var_decl_sptr
get_last_data_member(const class_or_union_sptr & klass)5709 get_last_data_member(const class_or_union_sptr &klass)
5710 {return klass->get_non_static_data_members().back();}
5711
5712 /// Test if a decl is an anonymous data member.
5713 ///
5714 /// @param d the decl to consider.
5715 ///
5716 /// @return true iff @p d is an anonymous data member.
5717 bool
is_anonymous_data_member(const decl_base & d)5718 is_anonymous_data_member(const decl_base& d)
5719 {return is_anonymous_data_member(&d);}
5720
5721 /// Test if a decl is an anonymous data member.
5722 ///
5723 /// @param d the decl to consider.
5724 ///
5725 /// @return the var_decl representing the data member iff @p d is an
5726 /// anonymous data member.
5727 const var_decl*
is_anonymous_data_member(const type_or_decl_base * d)5728 is_anonymous_data_member(const type_or_decl_base* d)
5729 {
5730 if (const var_decl* v = is_data_member(d))
5731 {
5732 if (is_anonymous_data_member(v))
5733 return v;
5734 }
5735 return 0;
5736 }
5737
5738 /// Test if a decl is an anonymous data member.
5739 ///
5740 /// @param d the decl to consider.
5741 ///
5742 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5743 /// it's an anonymous data member. Otherwise returns a nil pointer.
5744 const var_decl*
is_anonymous_data_member(const decl_base * d)5745 is_anonymous_data_member(const decl_base* d)
5746 {
5747 if (const var_decl* v = is_data_member(d))
5748 {
5749 if (is_anonymous_data_member(v))
5750 return v;
5751 }
5752 return 0;
5753 }
5754
5755 /// Test if a decl is an anonymous data member.
5756 ///
5757 /// @param d the decl to consider.
5758 ///
5759 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5760 /// it's an anonymous data member. Otherwise returns a nil pointer.
5761 var_decl_sptr
is_anonymous_data_member(const type_or_decl_base_sptr & d)5762 is_anonymous_data_member(const type_or_decl_base_sptr& d)
5763 {
5764 if (var_decl_sptr v = is_data_member(d))
5765 {
5766 if (is_anonymous_data_member(v))
5767 return v;
5768 }
5769 return var_decl_sptr();
5770 }
5771
5772 /// Test if a decl is an anonymous data member.
5773 ///
5774 /// @param d the decl to consider.
5775 ///
5776 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5777 /// it's an anonymous data member. Otherwise returns a nil pointer.
5778 var_decl_sptr
is_anonymous_data_member(const decl_base_sptr & d)5779 is_anonymous_data_member(const decl_base_sptr& d)
5780 {
5781 if (var_decl_sptr v = is_data_member(d))
5782 return is_anonymous_data_member(v);
5783 return var_decl_sptr();
5784 }
5785
5786 /// Test if a @ref var_decl is an anonymous data member.
5787 ///
5788 /// @param d the @ref var_decl to consider.
5789 ///
5790 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5791 /// it's an anonymous data member. Otherwise returns a nil pointer.
5792 var_decl_sptr
is_anonymous_data_member(const var_decl_sptr & d)5793 is_anonymous_data_member(const var_decl_sptr& d)
5794 {
5795 if (is_anonymous_data_member(d.get()))
5796 return d;
5797 return var_decl_sptr();
5798 }
5799
5800 /// Test if a @ref var_decl is an anonymous data member.
5801 ///
5802 /// @param d the @ref var_decl to consider.
5803 ///
5804 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5805 /// it's an anonymous data member. Otherwise returns a nil pointer.
5806 const var_decl*
is_anonymous_data_member(const var_decl * d)5807 is_anonymous_data_member(const var_decl* d)
5808 {
5809 if (d && is_anonymous_data_member(*d))
5810 return d;
5811 return 0;
5812 }
5813
5814 /// Test if a @ref var_decl is an anonymous data member.
5815 ///
5816 /// @param d the @ref var_decl to consider.
5817 ///
5818 /// @return true iff @p d is an anonymous data member.
5819 bool
is_anonymous_data_member(const var_decl & d)5820 is_anonymous_data_member(const var_decl& d)
5821 {
5822 return (is_data_member(d)
5823 && d.get_is_anonymous()
5824 && d.get_name().empty()
5825 && is_class_or_union_type(d.get_type()));
5826 }
5827
5828 /// Get the @ref class_or_union type of a given anonymous data member.
5829 ///
5830 /// @param d the anonymous data member to consider.
5831 ///
5832 /// @return the @ref class_or_union type of the anonymous data member
5833 /// @p d.
5834 class_or_union*
anonymous_data_member_to_class_or_union(const var_decl * d)5835 anonymous_data_member_to_class_or_union(const var_decl* d)
5836 {
5837 if ((d = is_anonymous_data_member(d)))
5838 return is_class_or_union_type(d->get_type().get());
5839 return 0;
5840 }
5841
5842 /// Test if a data member has annonymous type or not.
5843 ///
5844 /// @param d the data member to consider.
5845 ///
5846 /// @return the anonymous class or union type iff @p turns out to have
5847 /// an anonymous type. Otherwise, returns nil.
5848 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl & d)5849 data_member_has_anonymous_type(const var_decl& d)
5850 {
5851 if (is_data_member(d))
5852 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
5853 if (cou->get_is_anonymous())
5854 return cou;
5855
5856 return class_or_union_sptr();
5857 }
5858
5859 /// Test if a data member has annonymous type or not.
5860 ///
5861 /// @param d the data member to consider.
5862 ///
5863 /// @return the anonymous class or union type iff @p turns out to have
5864 /// an anonymous type. Otherwise, returns nil.
5865 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl * d)5866 data_member_has_anonymous_type(const var_decl* d)
5867 {
5868 if (d)
5869 return data_member_has_anonymous_type(*d);
5870 return class_or_union_sptr();
5871 }
5872
5873 /// Test if a data member has annonymous type or not.
5874 ///
5875 /// @param d the data member to consider.
5876 ///
5877 /// @return the anonymous class or union type iff @p turns out to have
5878 /// an anonymous type. Otherwise, returns nil.
5879 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl_sptr & d)5880 data_member_has_anonymous_type(const var_decl_sptr& d)
5881 {return data_member_has_anonymous_type(d.get());}
5882
5883 /// Get the @ref class_or_union type of a given anonymous data member.
5884 ///
5885 /// @param d the anonymous data member to consider.
5886 ///
5887 /// @return the @ref class_or_union type of the anonymous data member
5888 /// @p d.
5889 class_or_union_sptr
anonymous_data_member_to_class_or_union(const var_decl_sptr & d)5890 anonymous_data_member_to_class_or_union(const var_decl_sptr &d)
5891 {
5892 if (var_decl_sptr v = is_anonymous_data_member(d))
5893 return is_class_or_union_type(v->get_type());
5894 return class_or_union_sptr();
5895 }
5896
5897 /// Test if the scope of a given decl is anonymous or anonymous with a
5898 /// naming typedef.
5899 ///
5900 /// @param d the decl consider.
5901 ///
5902 /// @return true iff the scope of @p d is anonymous or anonymous with
5903 /// a naming typedef.
5904 bool
scope_anonymous_or_typedef_named(const decl_base & d)5905 scope_anonymous_or_typedef_named(const decl_base& d)
5906 {
5907 if (d.get_has_anonymous_parent()
5908 || (d.get_scope() && d.get_scope()->get_naming_typedef()))
5909 return true;
5910 return false;
5911 }
5912
5913 /// Test if a given decl is anonymous or has a naming typedef.
5914 ///
5915 /// @param d the decl to consider.
5916 ///
5917 /// @return true iff @p d is anonymous or has a naming typedef.
5918 bool
is_anonymous_or_typedef_named(const decl_base & d)5919 is_anonymous_or_typedef_named(const decl_base& d)
5920 {
5921 if (d.get_is_anonymous() || d.get_naming_typedef())
5922 return true;
5923 return false;
5924 }
5925
5926 /// Set the offset of a data member into its containing class.
5927 ///
5928 /// @param m the data member to consider.
5929 ///
5930 /// @param o the offset, in bits.
5931 void
set_data_member_offset(var_decl_sptr m,uint64_t o)5932 set_data_member_offset(var_decl_sptr m, uint64_t o)
5933 {
5934 ABG_ASSERT(is_data_member(m));
5935
5936 dm_context_rel* ctxt_rel =
5937 dynamic_cast<dm_context_rel*>(m->get_context_rel());
5938 ABG_ASSERT(ctxt_rel);
5939
5940 ctxt_rel->set_offset_in_bits(o);
5941 }
5942
5943 /// Get the offset of a data member.
5944 ///
5945 /// @param m the data member to consider.
5946 ///
5947 /// @return the offset (in bits) of @p m in its containing class.
5948 uint64_t
get_data_member_offset(const var_decl & m)5949 get_data_member_offset(const var_decl& m)
5950 {
5951 ABG_ASSERT(is_data_member(m));
5952 const dm_context_rel* ctxt_rel =
5953 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
5954 ABG_ASSERT(ctxt_rel);
5955 return ctxt_rel->get_offset_in_bits();
5956 }
5957
5958 /// Get the offset of a data member.
5959 ///
5960 /// @param m the data member to consider.
5961 ///
5962 /// @return the offset (in bits) of @p m in its containing class.
5963 uint64_t
get_data_member_offset(const var_decl_sptr m)5964 get_data_member_offset(const var_decl_sptr m)
5965 {return get_data_member_offset(*m);}
5966
5967 /// Get the offset of a data member.
5968 ///
5969 /// @param m the data member to consider.
5970 ///
5971 /// @return the offset (in bits) of @p m in its containing class.
5972 uint64_t
get_data_member_offset(const decl_base_sptr d)5973 get_data_member_offset(const decl_base_sptr d)
5974 {return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
5975
5976 /// Get the offset of the non-static data member that comes after a
5977 /// given one.
5978 ///
5979 /// If there is no data member after after the one given to this
5980 /// function (maybe because the given one is the last data member of
5981 /// the class type) then the function return false.
5982 ///
5983 /// @param klass the class to consider.
5984 ///
5985 /// @param dm the data member before the one we want to retrieve.
5986 ///
5987 /// @param offset out parameter. This parameter is set by the
5988 /// function to the offset of the data member that comes right after
5989 /// the data member @p dm, iff the function returns true.
5990 ///
5991 /// @return true iff the data member coming right after @p dm was
5992 /// found.
5993 bool
get_next_data_member_offset(const class_or_union_sptr & klass,const var_decl_sptr & dm,uint64_t & offset)5994 get_next_data_member_offset(const class_or_union_sptr& klass,
5995 const var_decl_sptr& dm,
5996 uint64_t& offset)
5997 {
5998 var_decl_sptr next_dm = get_next_data_member(klass, dm);
5999 if (!next_dm)
6000 return false;
6001 offset = get_data_member_offset(next_dm);
6002 return true;
6003 }
6004
6005 /// Get the absolute offset of a data member.
6006 ///
6007 /// If the data member is part of an anonymous data member then this
6008 /// returns the absolute offset -- relative to the beginning of the
6009 /// containing class of the anonymous data member.
6010 ///
6011 /// @param m the data member to consider.
6012 ///
6013 /// @return the aboslute offset of the data member @p m.
6014 uint64_t
get_absolute_data_member_offset(const var_decl & m)6015 get_absolute_data_member_offset(const var_decl& m)
6016 {
6017 ABG_ASSERT(is_data_member(m));
6018 const dm_context_rel* ctxt_rel =
6019 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6020 ABG_ASSERT(ctxt_rel);
6021
6022 const var_decl *containing_anonymous_data_member =
6023 ctxt_rel->get_anonymous_data_member();
6024
6025 uint64_t containing_anonymous_data_member_offset = 0;
6026 if (containing_anonymous_data_member)
6027 containing_anonymous_data_member_offset =
6028 get_absolute_data_member_offset(*containing_anonymous_data_member);
6029
6030 return (ctxt_rel->get_offset_in_bits()
6031 +
6032 containing_anonymous_data_member_offset);
6033 }
6034
6035 /// Get the absolute offset of a data member.
6036 ///
6037 /// If the data member is part of an anonymous data member then this
6038 /// returns the absolute offset -- relative to the beginning of the
6039 /// containing class of the anonymous data member.
6040 ///
6041 /// @param m the data member to consider.
6042 ///
6043 /// @return the aboslute offset of the data member @p m.
6044 uint64_t
get_absolute_data_member_offset(const var_decl_sptr & m)6045 get_absolute_data_member_offset(const var_decl_sptr& m)
6046 {
6047 if (!m)
6048 return 0;
6049 return get_absolute_data_member_offset(*m);
6050 }
6051
6052 /// Get the size of a given variable.
6053 ///
6054 /// @param v the variable to consider.
6055 ///
6056 /// @return the size of variable @p v.
6057 uint64_t
get_var_size_in_bits(const var_decl_sptr & v)6058 get_var_size_in_bits(const var_decl_sptr& v)
6059 {
6060 type_base_sptr t = v->get_type();
6061 ABG_ASSERT(t);
6062
6063 return t->get_size_in_bits();
6064 }
6065
6066 /// Set a flag saying if a data member is laid out.
6067 ///
6068 /// @param m the data member to consider.
6069 ///
6070 /// @param l true if @p m is to be considered as laid out.
6071 void
set_data_member_is_laid_out(var_decl_sptr m,bool l)6072 set_data_member_is_laid_out(var_decl_sptr m, bool l)
6073 {
6074 ABG_ASSERT(is_data_member(m));
6075 dm_context_rel* ctxt_rel =
6076 dynamic_cast<dm_context_rel*>(m->get_context_rel());
6077 ctxt_rel->set_is_laid_out(l);
6078 }
6079
6080 /// Test whether a data member is laid out.
6081 ///
6082 /// @param m the data member to consider.
6083 ///
6084 /// @return true if @p m is laid out, false otherwise.
6085 bool
get_data_member_is_laid_out(const var_decl & m)6086 get_data_member_is_laid_out(const var_decl& m)
6087 {
6088 ABG_ASSERT(is_data_member(m));
6089 const dm_context_rel* ctxt_rel =
6090 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
6091
6092 return ctxt_rel->get_is_laid_out();
6093 }
6094
6095 /// Test whether a data member is laid out.
6096 ///
6097 /// @param m the data member to consider.
6098 ///
6099 /// @return true if @p m is laid out, false otherwise.
6100 bool
get_data_member_is_laid_out(const var_decl_sptr m)6101 get_data_member_is_laid_out(const var_decl_sptr m)
6102 {return get_data_member_is_laid_out(*m);}
6103
6104 /// Test whether a function_decl is a member function.
6105 ///
6106 /// @param f the function_decl to test.
6107 ///
6108 /// @return true if @p f is a member function, false otherwise.
6109 bool
is_member_function(const function_decl & f)6110 is_member_function(const function_decl& f)
6111 {return is_member_decl(f);}
6112
6113 /// Test whether a function_decl is a member function.
6114 ///
6115 /// @param f the function_decl to test.
6116 ///
6117 /// @return true if @p f is a member function, false otherwise.
6118 bool
is_member_function(const function_decl * f)6119 is_member_function(const function_decl* f)
6120 {return is_member_decl(*f);}
6121
6122 /// Test whether a function_decl is a member function.
6123 ///
6124 /// @param f the function_decl to test.
6125 ///
6126 /// @return true if @p f is a member function, false otherwise.
6127 bool
is_member_function(const function_decl_sptr & f)6128 is_member_function(const function_decl_sptr& f)
6129 {return is_member_decl(*f);}
6130
6131 /// Test whether a member function is a constructor.
6132 ///
6133 /// @param f the member function to test.
6134 ///
6135 /// @return true if @p f is a constructor, false otherwise.
6136 bool
get_member_function_is_ctor(const function_decl & f)6137 get_member_function_is_ctor(const function_decl& f)
6138 {
6139 ABG_ASSERT(is_member_function(f));
6140
6141 const method_decl* m = is_method_decl(&f);
6142 ABG_ASSERT(m);
6143
6144 const mem_fn_context_rel* ctxt =
6145 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6146
6147 return ctxt->is_constructor();
6148 }
6149
6150 /// Test whether a member function is a constructor.
6151 ///
6152 /// @param f the member function to test.
6153 ///
6154 /// @return true if @p f is a constructor, false otherwise.
6155 bool
get_member_function_is_ctor(const function_decl_sptr & f)6156 get_member_function_is_ctor(const function_decl_sptr& f)
6157 {return get_member_function_is_ctor(*f);}
6158
6159
6160 /// Setter for the is_ctor property of the member function.
6161 ///
6162 /// @param f the member function to set.
6163 ///
6164 /// @param f the new boolean value of the is_ctor property. Is true
6165 /// if @p f is a constructor, false otherwise.
6166 void
set_member_function_is_ctor(function_decl & f,bool c)6167 set_member_function_is_ctor(function_decl& f, bool c)
6168 {
6169 ABG_ASSERT(is_member_function(f));
6170
6171 method_decl* m = is_method_decl(&f);
6172 ABG_ASSERT(m);
6173
6174 mem_fn_context_rel* ctxt =
6175 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6176
6177 ctxt->is_constructor(c);
6178 }
6179
6180 /// Setter for the is_ctor property of the member function.
6181 ///
6182 /// @param f the member function to set.
6183 ///
6184 /// @param f the new boolean value of the is_ctor property. Is true
6185 /// if @p f is a constructor, false otherwise.
6186 void
set_member_function_is_ctor(const function_decl_sptr & f,bool c)6187 set_member_function_is_ctor(const function_decl_sptr& f, bool c)
6188 {set_member_function_is_ctor(*f, c);}
6189
6190 /// Test whether a member function is a destructor.
6191 ///
6192 /// @param f the function to test.
6193 ///
6194 /// @return true if @p f is a destructor, false otherwise.
6195 bool
get_member_function_is_dtor(const function_decl & f)6196 get_member_function_is_dtor(const function_decl& f)
6197 {
6198 ABG_ASSERT(is_member_function(f));
6199
6200 const method_decl* m = is_method_decl(&f);
6201 ABG_ASSERT(m);
6202
6203 const mem_fn_context_rel* ctxt =
6204 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6205
6206 return ctxt->is_destructor();
6207 }
6208
6209 /// Test whether a member function is a destructor.
6210 ///
6211 /// @param f the function to test.
6212 ///
6213 /// @return true if @p f is a destructor, false otherwise.
6214 bool
get_member_function_is_dtor(const function_decl_sptr & f)6215 get_member_function_is_dtor(const function_decl_sptr& f)
6216 {return get_member_function_is_dtor(*f);}
6217
6218 /// Set the destructor-ness property of a member function.
6219 ///
6220 /// @param f the function to set.
6221 ///
6222 /// @param d true if @p f is a destructor, false otherwise.
6223 void
set_member_function_is_dtor(function_decl & f,bool d)6224 set_member_function_is_dtor(function_decl& f, bool d)
6225 {
6226 ABG_ASSERT(is_member_function(f));
6227
6228 method_decl* m = is_method_decl(&f);
6229 ABG_ASSERT(m);
6230
6231 mem_fn_context_rel* ctxt =
6232 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6233
6234 ctxt->is_destructor(d);
6235 }
6236
6237 /// Set the destructor-ness property of a member function.
6238 ///
6239 /// @param f the function to set.
6240 ///
6241 /// @param d true if @p f is a destructor, false otherwise.
6242 void
set_member_function_is_dtor(const function_decl_sptr & f,bool d)6243 set_member_function_is_dtor(const function_decl_sptr& f, bool d)
6244 {set_member_function_is_dtor(*f, d);}
6245
6246 /// Test whether a member function is const.
6247 ///
6248 /// @param f the function to test.
6249 ///
6250 /// @return true if @p f is const, false otherwise.
6251 bool
get_member_function_is_const(const function_decl & f)6252 get_member_function_is_const(const function_decl& f)
6253 {
6254 ABG_ASSERT(is_member_function(f));
6255
6256 const method_decl* m = is_method_decl(&f);
6257 ABG_ASSERT(m);
6258
6259 const mem_fn_context_rel* ctxt =
6260 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6261
6262 return ctxt->is_const();
6263 }
6264
6265 /// Test whether a member function is const.
6266 ///
6267 /// @param f the function to test.
6268 ///
6269 /// @return true if @p f is const, false otherwise.
6270 bool
get_member_function_is_const(const function_decl_sptr & f)6271 get_member_function_is_const(const function_decl_sptr& f)
6272 {return get_member_function_is_const(*f);}
6273
6274 /// set the const-ness property of a member function.
6275 ///
6276 /// @param f the function to set.
6277 ///
6278 /// @param is_const the new value of the const-ness property of @p f
6279 void
set_member_function_is_const(function_decl & f,bool is_const)6280 set_member_function_is_const(function_decl& f, bool is_const)
6281 {
6282 ABG_ASSERT(is_member_function(f));
6283
6284 method_decl* m = is_method_decl(&f);
6285 ABG_ASSERT(m);
6286
6287 mem_fn_context_rel* ctxt =
6288 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6289
6290 ctxt->is_const(is_const);
6291 }
6292
6293 /// set the const-ness property of a member function.
6294 ///
6295 /// @param f the function to set.
6296 ///
6297 /// @param is_const the new value of the const-ness property of @p f
6298 void
set_member_function_is_const(const function_decl_sptr & f,bool is_const)6299 set_member_function_is_const(const function_decl_sptr& f, bool is_const)
6300 {set_member_function_is_const(*f, is_const);}
6301
6302 /// Test if a virtual member function has a vtable offset set.
6303 ///
6304 /// @param f the virtual member function to consider.
6305 ///
6306 /// @return true iff the virtual member function has its vtable offset
6307 /// set, i.e, if the vtable offset of @p is different from -1.
6308 bool
member_function_has_vtable_offset(const function_decl & f)6309 member_function_has_vtable_offset(const function_decl& f)
6310 {return get_member_function_vtable_offset(f) != -1;}
6311
6312 /// Get the vtable offset of a member function.
6313 ///
6314 /// @param f the member function to consider.
6315 ///
6316 /// @return the vtable offset of @p f. Note that a vtable offset of
6317 /// value -1 means that the member function does *NOT* yet have a
6318 /// vtable offset associated to it.
6319 ssize_t
get_member_function_vtable_offset(const function_decl & f)6320 get_member_function_vtable_offset(const function_decl& f)
6321 {
6322 ABG_ASSERT(is_member_function(f));
6323
6324 const method_decl* m =
6325 dynamic_cast<const method_decl*>(&f);
6326 ABG_ASSERT(m);
6327
6328 const mem_fn_context_rel* ctxt =
6329 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6330
6331 return ctxt->vtable_offset();
6332 }
6333
6334 /// Get the vtable offset of a member function.
6335 ///
6336 /// @param f the member function to consider.
6337 ///
6338 /// @return the vtable offset of @p f. Note that a vtable offset of
6339 /// value -1 means that the member function does *NOT* yet have a
6340 /// vtable offset associated to it.
6341 ssize_t
get_member_function_vtable_offset(const function_decl_sptr & f)6342 get_member_function_vtable_offset(const function_decl_sptr& f)
6343 {return get_member_function_vtable_offset(*f);}
6344
6345 /// Set the vtable offset of a member function.
6346 ///
6347 /// @param f the member function to consider.
6348 ///
6349 /// @param s the new vtable offset. Please note that a vtable offset
6350 /// of value -1 means that the virtual member function does not (yet)
6351 /// have any vtable offset associated to it.
6352 void
set_member_function_vtable_offset(function_decl & f,ssize_t s)6353 set_member_function_vtable_offset(function_decl& f, ssize_t s)
6354 {
6355 ABG_ASSERT(is_member_function(f));
6356
6357 method_decl* m = is_method_decl(&f);
6358 ABG_ASSERT(m);
6359
6360 mem_fn_context_rel* ctxt =
6361 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6362
6363 ctxt->vtable_offset(s);
6364 }
6365
6366 /// Get the vtable offset of a member function.
6367 ///
6368 /// @param f the member function to consider.
6369 ///
6370 /// @param s the new vtable offset. Please note that a vtable offset
6371 /// of value -1 means that the virtual member function does not (yet)
6372 /// have any vtable offset associated to it.
6373 void
set_member_function_vtable_offset(const function_decl_sptr & f,ssize_t s)6374 set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
6375 {return set_member_function_vtable_offset(*f, s);}
6376
6377 /// Test if a given member function is virtual.
6378 ///
6379 /// @param mem_fn the member function to consider.
6380 ///
6381 /// @return true iff a @p mem_fn is virtual.
6382 bool
get_member_function_is_virtual(const function_decl & f)6383 get_member_function_is_virtual(const function_decl& f)
6384 {
6385 ABG_ASSERT(is_member_function(f));
6386
6387 const method_decl* m =
6388 dynamic_cast<const method_decl*>(&f);
6389 ABG_ASSERT(m);
6390
6391 const mem_fn_context_rel* ctxt =
6392 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
6393
6394 return ctxt->is_virtual();
6395 }
6396
6397 /// Test if a given member function is virtual.
6398 ///
6399 /// @param mem_fn the member function to consider.
6400 ///
6401 /// @return true iff a @p mem_fn is virtual.
6402 bool
get_member_function_is_virtual(const function_decl_sptr & mem_fn)6403 get_member_function_is_virtual(const function_decl_sptr& mem_fn)
6404 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6405
6406 /// Test if a given member function is virtual.
6407 ///
6408 /// @param mem_fn the member function to consider.
6409 ///
6410 /// @return true iff a @p mem_fn is virtual.
6411 bool
get_member_function_is_virtual(const function_decl * mem_fn)6412 get_member_function_is_virtual(const function_decl* mem_fn)
6413 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
6414
6415 /// Set the virtual-ness of a member function.
6416 ///
6417 /// @param f the member function to consider.
6418 ///
6419 /// @param is_virtual set to true if the function is virtual.
6420 void
set_member_function_is_virtual(function_decl & f,bool is_virtual)6421 set_member_function_is_virtual(function_decl& f, bool is_virtual)
6422 {
6423 ABG_ASSERT(is_member_function(f));
6424
6425 method_decl* m = is_method_decl(&f);
6426 ABG_ASSERT(m);
6427
6428 mem_fn_context_rel* ctxt =
6429 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
6430
6431 ctxt->is_virtual(is_virtual);
6432 }
6433
6434 /// Set the virtual-ness of a member function.
6435 ///
6436 /// @param f the member function to consider.
6437 ///
6438 /// @param is_virtual set to true if the function is virtual.
6439 void
set_member_function_is_virtual(const function_decl_sptr & fn,bool is_virtual)6440 set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
6441 {
6442 if (fn)
6443 {
6444 set_member_function_is_virtual(*fn, is_virtual);
6445 fixup_virtual_member_function
6446 (dynamic_pointer_cast<method_decl>(fn));
6447 }
6448 }
6449
6450 /// Recursively returns the the underlying type of a typedef. The
6451 /// return type should not be a typedef of anything anymore.
6452 ///
6453 ///
6454 /// Also recursively strip typedefs from the sub-types of the type
6455 /// given in arguments.
6456 ///
6457 /// Note that this function builds types in which typedefs are
6458 /// stripped off. Usually, types are held by their scope, so their
6459 /// life time is bound to the life time of their scope. But as this
6460 /// function cannot really insert the built type into it's scope, it
6461 /// must ensure that the newly built type stays live long enough.
6462 ///
6463 /// So, if the newly built type has a canonical type, this function
6464 /// returns the canonical type. Otherwise, this function ensure that
6465 /// the newly built type has a life time that is the same as the life
6466 /// time of the entire libabigail library.
6467 ///
6468 /// @param type the type to strip the typedefs from.
6469 ///
6470 /// @return the resulting type stripped from its typedefs, or just
6471 /// return @p type if it has no typedef in any of its sub-types.
6472 type_base_sptr
strip_typedef(const type_base_sptr type)6473 strip_typedef(const type_base_sptr type)
6474 {
6475 if (!type)
6476 return type;
6477
6478 // If type is a class type then do not try to strip typedefs from it.
6479 // And if it has no canonical type (which can mean that it's a
6480 // declaration-only class), then, make sure its live for ever and
6481 // return it.
6482 if (class_decl_sptr cl = is_class_type(type))
6483 {
6484 if (!cl->get_canonical_type())
6485 keep_type_alive(type);
6486 return type;
6487 }
6488
6489 environment* env = type->get_environment();
6490 ABG_ASSERT(env);
6491 type_base_sptr t = type;
6492
6493 if (const typedef_decl_sptr ty = is_typedef(t))
6494 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
6495 else if (const reference_type_def_sptr ty = is_reference_type(t))
6496 {
6497 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6498 env));
6499 ABG_ASSERT(p);
6500 t.reset(new reference_type_def(p,
6501 ty->is_lvalue(),
6502 ty->get_size_in_bits(),
6503 ty->get_alignment_in_bits(),
6504 ty->get_location()));
6505 }
6506 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
6507 {
6508 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
6509 env));
6510 ABG_ASSERT(p);
6511 t.reset(new pointer_type_def(p,
6512 ty->get_size_in_bits(),
6513 ty->get_alignment_in_bits(),
6514 ty->get_location()));
6515 }
6516 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
6517 {
6518 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
6519 env));
6520 ABG_ASSERT(p);
6521 t.reset(new qualified_type_def(p,
6522 ty->get_cv_quals(),
6523 ty->get_location()));
6524 }
6525 else if (const array_type_def_sptr ty = is_array_type(t))
6526 {
6527 type_base_sptr p = strip_typedef(ty->get_element_type());
6528 ABG_ASSERT(p);
6529 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
6530 }
6531 else if (const method_type_sptr ty = is_method_type(t))
6532 {
6533 function_decl::parameters parm;
6534 for (function_decl::parameters::const_iterator i =
6535 ty->get_parameters().begin();
6536 i != ty->get_parameters().end();
6537 ++i)
6538 {
6539 function_decl::parameter_sptr p = *i;
6540 type_base_sptr typ = strip_typedef(p->get_type());
6541 ABG_ASSERT(typ);
6542 function_decl::parameter_sptr stripped
6543 (new function_decl::parameter(typ,
6544 p->get_index(),
6545 p->get_name(),
6546 p->get_location(),
6547 p->get_variadic_marker(),
6548 p->get_is_artificial()));
6549 parm.push_back(stripped);
6550 }
6551 type_base_sptr p = strip_typedef(ty->get_return_type());
6552 ABG_ASSERT(!!p == !!ty->get_return_type());
6553 t.reset(new method_type(p, ty->get_class_type(),
6554 parm, ty->get_is_const(),
6555 ty->get_size_in_bits(),
6556 ty->get_alignment_in_bits()));
6557 }
6558 else if (const function_type_sptr ty = is_function_type(t))
6559 {
6560 function_decl::parameters parm;
6561 for (function_decl::parameters::const_iterator i =
6562 ty->get_parameters().begin();
6563 i != ty->get_parameters().end();
6564 ++i)
6565 {
6566 function_decl::parameter_sptr p = *i;
6567 type_base_sptr typ = strip_typedef(p->get_type());
6568 ABG_ASSERT(typ);
6569 function_decl::parameter_sptr stripped
6570 (new function_decl::parameter(typ,
6571 p->get_index(),
6572 p->get_name(),
6573 p->get_location(),
6574 p->get_variadic_marker(),
6575 p->get_is_artificial()));
6576 parm.push_back(stripped);
6577 }
6578 type_base_sptr p = strip_typedef(ty->get_return_type());
6579 ABG_ASSERT(!!p == !!ty->get_return_type());
6580 t.reset(new function_type(p, parm,
6581 ty->get_size_in_bits(),
6582 ty->get_alignment_in_bits()));
6583 }
6584
6585 if (!t->get_environment())
6586 set_environment_for_artifact(t, env);
6587
6588 if (!t->get_translation_unit())
6589 t->set_translation_unit(type->get_translation_unit());
6590
6591 if (!(type->get_canonical_type() && canonicalize(t)))
6592 keep_type_alive(t);
6593
6594 return t->get_canonical_type() ? t->get_canonical_type() : t;
6595 }
6596
6597 /// Strip qualification from a qualified type, when it makes sense.
6598 ///
6599 /// DWARF constructs "const reference". This is redundant because a
6600 /// reference is always const. It also constructs the useless "const
6601 /// void" type. The issue is these redundant types then leak into the
6602 /// IR and make for bad diagnostics.
6603 ///
6604 /// This function thus strips the const qualifier from the type in
6605 /// that case. It might contain code to strip other cases like this
6606 /// in the future.
6607 ///
6608 /// @param t the type to strip const qualification from.
6609 ///
6610 /// @return the stripped type or just return @p t.
6611 decl_base_sptr
strip_useless_const_qualification(const qualified_type_def_sptr t)6612 strip_useless_const_qualification(const qualified_type_def_sptr t)
6613 {
6614 if (!t)
6615 return t;
6616
6617 decl_base_sptr result = t;
6618 type_base_sptr u = t->get_underlying_type();
6619 environment* env = t->get_environment();
6620
6621 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6622 && (is_reference_type(u)))
6623 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6624 && env->is_void_type(u))
6625 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6626 // Let's strip the const qualifier because a reference is always
6627 // 'const' and a const void doesn't make sense. They will just
6628 // lead to spurious changes later down the pipeline, that we'll
6629 // have to deal with by doing painful and error-prone editing of
6630 // the diff IR. Dropping that useless and inconsistent artefact
6631 // right here seems to be a good way to go.
6632 result = is_decl(u);
6633
6634 return result;
6635 }
6636
6637 /// Return the leaf underlying type node of a @ref typedef_decl node.
6638 ///
6639 /// If the underlying type of a @ref typedef_decl node is itself a
6640 /// @ref typedef_decl node, then recursively look at the underlying
6641 /// type nodes to get the first one that is not a a @ref typedef_decl
6642 /// node. This is what a leaf underlying type node means.
6643 ///
6644 /// Otherwise, if the underlying type node of @ref typedef_decl is
6645 /// *NOT* a @ref typedef_decl node, then just return the underlying
6646 /// type node.
6647 ///
6648 /// And if the type node considered is not a @ref typedef_decl node,
6649 /// then just return it.
6650 ///
6651 /// @return the leaf underlying type node of a @p type.
6652 type_base_sptr
peel_typedef_type(const type_base_sptr & type)6653 peel_typedef_type(const type_base_sptr& type)
6654 {
6655 typedef_decl_sptr t = is_typedef(type);
6656 if (!t)
6657 return type;
6658
6659 if (is_typedef(t->get_underlying_type()))
6660 return peel_typedef_type(t->get_underlying_type());
6661 return t->get_underlying_type();
6662 }
6663
6664 /// Return the leaf underlying type node of a @ref typedef_decl node.
6665 ///
6666 /// If the underlying type of a @ref typedef_decl node is itself a
6667 /// @ref typedef_decl node, then recursively look at the underlying
6668 /// type nodes to get the first one that is not a a @ref typedef_decl
6669 /// node. This is what a leaf underlying type node means.
6670 ///
6671 /// Otherwise, if the underlying type node of @ref typedef_decl is
6672 /// *NOT* a @ref typedef_decl node, then just return the underlying
6673 /// type node.
6674 ///
6675 /// And if the type node considered is not a @ref typedef_decl node,
6676 /// then just return it.
6677 ///
6678 /// @return the leaf underlying type node of a @p type.
6679 const type_base*
peel_typedef_type(const type_base * type)6680 peel_typedef_type(const type_base* type)
6681 {
6682 const typedef_decl* t = is_typedef(type);
6683 if (!t)
6684 return type;
6685
6686 return peel_typedef_type(t->get_underlying_type()).get();
6687 }
6688
6689 /// Return the leaf pointed-to type node of a @ref pointer_type_def
6690 /// node.
6691 ///
6692 /// If the pointed-to type of a @ref pointer_type_def node is itself a
6693 /// @ref pointer_type_def node, then recursively look at the
6694 /// pointed-to type nodes to get the first one that is not a a @ref
6695 /// pointer_type_def node. This is what a leaf pointed-to type node
6696 /// means.
6697 ///
6698 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
6699 /// *NOT* a @ref pointer_type_def node, then just return the
6700 /// pointed-to type node.
6701 ///
6702 /// And if the type node considered is not a @ref pointer_type_def
6703 /// node, then just return it.
6704 ///
6705 /// @return the leaf pointed-to type node of a @p type.
6706 type_base_sptr
peel_pointer_type(const type_base_sptr & type)6707 peel_pointer_type(const type_base_sptr& type)
6708 {
6709 pointer_type_def_sptr t = is_pointer_type(type);
6710 if (!t)
6711 return type;
6712
6713 if (is_pointer_type(t->get_pointed_to_type()))
6714 return peel_pointer_type(t->get_pointed_to_type());
6715 return t->get_pointed_to_type();
6716 }
6717
6718 /// Return the leaf pointed-to type node of a @ref pointer_type_def
6719 /// node.
6720 ///
6721 /// If the pointed-to type of a @ref pointer_type_def node is itself a
6722 /// @ref pointer_type_def node, then recursively look at the
6723 /// pointed-to type nodes to get the first one that is not a a @ref
6724 /// pointer_type_def node. This is what a leaf pointed-to type node
6725 /// means.
6726 ///
6727 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
6728 /// *NOT* a @ref pointer_type_def node, then just return the
6729 /// pointed-to type node.
6730 ///
6731 /// And if the type node considered is not a @ref pointer_type_def
6732 /// node, then just return it.
6733 ///
6734 /// @return the leaf pointed-to type node of a @p type.
6735 const type_base*
peel_pointer_type(const type_base * type)6736 peel_pointer_type(const type_base* type)
6737 {
6738 const pointer_type_def* t = is_pointer_type(type);
6739 if (!t)
6740 return type;
6741
6742 return peel_pointer_type(t->get_pointed_to_type()).get();
6743 }
6744
6745 /// Return the leaf pointed-to type node of a @ref reference_type_def
6746 /// node.
6747 ///
6748 /// If the pointed-to type of a @ref reference_type_def node is itself
6749 /// a @ref reference_type_def node, then recursively look at the
6750 /// pointed-to type nodes to get the first one that is not a a @ref
6751 /// reference_type_def node. This is what a leaf pointed-to type node
6752 /// means.
6753 ///
6754 /// Otherwise, if the pointed-to type node of @ref reference_type_def
6755 /// is *NOT* a @ref reference_type_def node, then just return the
6756 /// pointed-to type node.
6757 ///
6758 /// And if the type node considered is not a @ref reference_type_def
6759 /// node, then just return it.
6760 ///
6761 /// @return the leaf pointed-to type node of a @p type.
6762 type_base_sptr
peel_reference_type(const type_base_sptr & type)6763 peel_reference_type(const type_base_sptr& type)
6764 {
6765 reference_type_def_sptr t = is_reference_type(type);
6766 if (!t)
6767 return type;
6768
6769 if (is_reference_type(t->get_pointed_to_type()))
6770 return peel_reference_type(t->get_pointed_to_type());
6771 return t->get_pointed_to_type();
6772 }
6773
6774 /// Return the leaf pointed-to type node of a @ref reference_type_def
6775 /// node.
6776 ///
6777 /// If the pointed-to type of a @ref reference_type_def node is itself
6778 /// a @ref reference_type_def node, then recursively look at the
6779 /// pointed-to type nodes to get the first one that is not a a @ref
6780 /// reference_type_def node. This is what a leaf pointed-to type node
6781 /// means.
6782 ///
6783 /// Otherwise, if the pointed-to type node of @ref reference_type_def
6784 /// is *NOT* a @ref reference_type_def node, then just return the
6785 /// pointed-to type node.
6786 ///
6787 /// And if the type node considered is not a @ref reference_type_def
6788 /// node, then just return it.
6789 ///
6790 /// @return the leaf pointed-to type node of a @p type.
6791 const type_base*
peel_reference_type(const type_base * type)6792 peel_reference_type(const type_base* type)
6793 {
6794 const reference_type_def* t = is_reference_type(type);
6795 if (!t)
6796 return type;
6797
6798 return peel_reference_type(t->get_pointed_to_type()).get();
6799 }
6800
6801 /// Return the leaf element type of an array.
6802 ///
6803 /// If the element type is itself an array, then recursively return
6804 /// the element type of that array itself.
6805 ///
6806 /// @param type the array type to consider. If this is not an array
6807 /// type, this type is returned by the function.
6808 ///
6809 /// @return the leaf element type of the array @p type, or, if it's
6810 /// not an array type, then just return @p.
6811 const type_base_sptr
peel_array_type(const type_base_sptr & type)6812 peel_array_type(const type_base_sptr& type)
6813 {
6814 const array_type_def_sptr t = is_array_type(type);
6815 if (!t)
6816 return type;
6817
6818 return peel_array_type(t->get_element_type());
6819 }
6820
6821 /// Return the leaf element type of an array.
6822 ///
6823 /// If the element type is itself an array, then recursively return
6824 /// the element type of that array itself.
6825 ///
6826 /// @param type the array type to consider. If this is not an array
6827 /// type, this type is returned by the function.
6828 ///
6829 /// @return the leaf element type of the array @p type, or, if it's
6830 /// not an array type, then just return @p.
6831 const type_base*
peel_array_type(const type_base * type)6832 peel_array_type(const type_base* type)
6833 {
6834 const array_type_def* t = is_array_type(type);
6835 if (!t)
6836 return type;
6837
6838 return peel_array_type(t->get_element_type()).get();
6839 }
6840
6841 /// Return the leaf underlying type of a qualified type.
6842 ///
6843 /// If the underlying type is itself a qualified type, then
6844 /// recursively return the first underlying type of that qualified
6845 /// type to return the first underlying type that is not a qualified type.
6846 ///
6847 /// If the underlying type is NOT a qualified type, then just return
6848 /// that underlying type.
6849 ///
6850 /// @param type the qualified type to consider.
6851 ///
6852 /// @return the leaf underlying type.
6853 const type_base*
peel_qualified_type(const type_base * type)6854 peel_qualified_type(const type_base* type)
6855 {
6856 const qualified_type_def* t = is_qualified_type(type);
6857 if (!t)
6858 return type;
6859
6860 return peel_qualified_type(t->get_underlying_type().get());
6861 }
6862
6863 /// Return the leaf underlying type of a qualified type.
6864 ///
6865 /// If the underlying type is itself a qualified type, then
6866 /// recursively return the first underlying type of that qualified
6867 /// type to return the first underlying type that is not a qualified type.
6868 ///
6869 /// If the underlying type is NOT a qualified type, then just return
6870 /// that underlying type.
6871 ///
6872 /// @param type the qualified type to consider.
6873 ///
6874 /// @return the leaf underlying type.
6875 const type_base_sptr
peel_qualified_type(const type_base_sptr & type)6876 peel_qualified_type(const type_base_sptr& type)
6877 {
6878 const qualified_type_def_sptr t = is_qualified_type(type);
6879 if (!t)
6880 return type;
6881
6882 return peel_qualified_type(t->get_underlying_type());
6883 }
6884
6885 /// Return the leaf underlying type of a qualified or typedef type.
6886 ///
6887 /// If the underlying type is itself a qualified or typedef type, then
6888 /// recursively return the first underlying type of that qualified or
6889 /// typedef type to return the first underlying type that is not a
6890 /// qualified or typedef type.
6891 ///
6892 /// If the underlying type is NOT a qualified nor a typedef type, then
6893 /// just return that underlying type.
6894 ///
6895 /// @param type the qualified or typedef type to consider.
6896 ///
6897 /// @return the leaf underlying type.
6898 type_base*
peel_qualified_or_typedef_type(const type_base * type)6899 peel_qualified_or_typedef_type(const type_base* type)
6900 {
6901 while (is_typedef(type) || is_qualified_type(type))
6902 {
6903 if (const typedef_decl* t = is_typedef(type))
6904 type = peel_typedef_type(t);
6905
6906 if (const qualified_type_def* t = is_qualified_type(type))
6907 type = peel_qualified_type(t);
6908 }
6909
6910 return const_cast<type_base*>(type);
6911 }
6912
6913 /// Return the leaf underlying type of a qualified or typedef type.
6914 ///
6915 /// If the underlying type is itself a qualified or typedef type, then
6916 /// recursively return the first underlying type of that qualified or
6917 /// typedef type to return the first underlying type that is not a
6918 /// qualified or typedef type.
6919 ///
6920 /// If the underlying type is NOT a qualified nor a typedef type, then
6921 /// just return that underlying type.
6922 ///
6923 /// @param type the qualified or typedef type to consider.
6924 ///
6925 /// @return the leaf underlying type.
6926 type_base_sptr
peel_qualified_or_typedef_type(const type_base_sptr & t)6927 peel_qualified_or_typedef_type(const type_base_sptr &t)
6928 {
6929 type_base_sptr type = t;
6930 while (is_typedef(type) || is_qualified_type(type))
6931 {
6932 if (typedef_decl_sptr t = is_typedef(type))
6933 type = peel_typedef_type(t);
6934
6935 if (qualified_type_def_sptr t = is_qualified_type(type))
6936 type = peel_qualified_type(t);
6937 }
6938
6939 return type;
6940 }
6941
6942 /// Return the leaf underlying or pointed-to type node of a @ref
6943 /// typedef_decl, @ref pointer_type_def, @ref reference_type_def,
6944 /// or @ref array_type_def node.
6945 ///
6946 /// @param type the type to peel.
6947 ///
6948 /// @return the leaf underlying or pointed-to type node of @p type.
6949 type_base_sptr
peel_typedef_pointer_or_reference_type(const type_base_sptr type)6950 peel_typedef_pointer_or_reference_type(const type_base_sptr type)
6951 {
6952 type_base_sptr typ = type;
6953 while (is_typedef(typ)
6954 || is_pointer_type(typ)
6955 || is_reference_type(typ)
6956 || is_array_type(typ))
6957 {
6958 if (typedef_decl_sptr t = is_typedef(typ))
6959 typ = peel_typedef_type(t);
6960
6961 if (pointer_type_def_sptr t = is_pointer_type(typ))
6962 typ = peel_pointer_type(t);
6963
6964 if (reference_type_def_sptr t = is_reference_type(typ))
6965 typ = peel_reference_type(t);
6966
6967 if (const array_type_def_sptr t = is_array_type(typ))
6968 typ = peel_array_type(t);
6969 }
6970
6971 return typ;
6972 }
6973
6974 /// Return the leaf underlying or pointed-to type node of a @ref
6975 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
6976 /// node.
6977 ///
6978 /// @param type the type to peel.
6979 ///
6980 /// @return the leaf underlying or pointed-to type node of @p type.
6981 type_base*
peel_typedef_pointer_or_reference_type(const type_base * type)6982 peel_typedef_pointer_or_reference_type(const type_base* type)
6983 {
6984 while (is_typedef(type)
6985 || is_pointer_type(type)
6986 || is_reference_type(type)
6987 || is_array_type(type))
6988 {
6989 if (const typedef_decl* t = is_typedef(type))
6990 type = peel_typedef_type(t);
6991
6992 if (const pointer_type_def* t = is_pointer_type(type))
6993 type = peel_pointer_type(t);
6994
6995 if (const reference_type_def* t = is_reference_type(type))
6996 type = peel_reference_type(t);
6997
6998 if (const array_type_def* t = is_array_type(type))
6999 type = peel_array_type(t);
7000 }
7001
7002 return const_cast<type_base*>(type);
7003 }
7004
7005 /// Return the leaf underlying or pointed-to type node of a, @ref
7006 /// pointer_type_def, @ref reference_type_def or @ref
7007 /// qualified_type_def type node.
7008 ///
7009 /// @param type the type to peel.
7010 ///
7011 /// @param peel_qualified_type if true, also peel qualified types.
7012 ///
7013 /// @return the leaf underlying or pointed-to type node of @p type.
7014 type_base*
peel_pointer_or_reference_type(const type_base * type,bool peel_qual_type)7015 peel_pointer_or_reference_type(const type_base *type,
7016 bool peel_qual_type)
7017 {
7018 while (is_pointer_type(type)
7019 || is_reference_type(type)
7020 || is_array_type(type)
7021 || (peel_qual_type && is_qualified_type(type)))
7022 {
7023 if (const pointer_type_def* t = is_pointer_type(type))
7024 type = peel_pointer_type(t);
7025
7026 if (const reference_type_def* t = is_reference_type(type))
7027 type = peel_reference_type(t);
7028
7029 if (const array_type_def* t = is_array_type(type))
7030 type = peel_array_type(t);
7031
7032 if (peel_qual_type)
7033 if (const qualified_type_def* t = is_qualified_type(type))
7034 type = peel_qualified_type(t);
7035 }
7036
7037 return const_cast<type_base*>(type);
7038 }
7039
7040 /// Clone an array type.
7041 ///
7042 /// Note that the element type of the new array is shared witht the
7043 /// old one.
7044 ///
7045 /// @param array the array type to clone.
7046 ///
7047 /// @return a newly built array type. Note that it needs to be added
7048 /// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
7049 /// bound to the one of that scope. Otherwise, its lifetime is bound
7050 /// to the lifetime of its containing shared pointer.
7051 array_type_def_sptr
clone_array(const array_type_def_sptr & array)7052 clone_array(const array_type_def_sptr& array)
7053 {
7054 vector<array_type_def::subrange_sptr> subranges;
7055
7056 for (vector<array_type_def::subrange_sptr>::const_iterator i =
7057 array->get_subranges().begin();
7058 i != array->get_subranges().end();
7059 ++i)
7060 {
7061 array_type_def::subrange_sptr subrange
7062 (new array_type_def::subrange_type(array->get_environment(),
7063 (*i)->get_name(),
7064 (*i)->get_lower_bound(),
7065 (*i)->get_upper_bound(),
7066 (*i)->get_underlying_type(),
7067 (*i)->get_location(),
7068 (*i)->get_language()));
7069 subrange->is_infinite((*i)->is_infinite());
7070 if (scope_decl *scope = (*i)->get_scope())
7071 add_decl_to_scope(subrange, scope);
7072 subranges.push_back(subrange);
7073 }
7074
7075 array_type_def_sptr result
7076 (new array_type_def(array->get_element_type(),
7077 subranges, array->get_location()));
7078
7079 return result;
7080 }
7081
7082 /// Clone a typedef type.
7083 ///
7084 /// Note that the underlying type of the newly constructed typedef is
7085 /// shared with the old one.
7086 ///
7087 /// @param t the typedef to clone.
7088 ///
7089 /// @return the newly constructed typedef. Note that it needs to be
7090 /// added to a scope (e.g, using add_decl_to_scope) for its lifetime
7091 /// to be bound to the one of that scope. Otherwise, its lifetime is
7092 /// bound to the lifetime of its containing shared pointer.
7093 typedef_decl_sptr
clone_typedef(const typedef_decl_sptr & t)7094 clone_typedef(const typedef_decl_sptr& t)
7095 {
7096 if (!t)
7097 return t;
7098
7099 typedef_decl_sptr result
7100 (new typedef_decl(t->get_name(), t->get_underlying_type(),
7101 t->get_location(), t->get_linkage_name(),
7102 t->get_visibility()));
7103 return result;
7104 }
7105
7106 /// Clone a qualifiend type.
7107 ///
7108 /// Note that underlying type of the newly constructed qualified type
7109 /// is shared with the old one.
7110 ///
7111 /// @param t the qualified type to clone.
7112 ///
7113 /// @return the newly constructed qualified type. Note that it needs
7114 /// to be added to a scope (e.g, using add_decl_to_scope) for its
7115 /// lifetime to be bound to the one of that scope. Otherwise, its
7116 /// lifetime is bound to the lifetime of its containing shared
7117 /// pointer.
7118 qualified_type_def_sptr
clone_qualified_type(const qualified_type_def_sptr & t)7119 clone_qualified_type(const qualified_type_def_sptr& t)
7120 {
7121 if (!t)
7122 return t;
7123
7124 qualified_type_def_sptr result
7125 (new qualified_type_def(t->get_underlying_type(),
7126 t->get_cv_quals(), t->get_location()));
7127
7128 return result;
7129 }
7130
7131 /// Clone a typedef, an array or a qualified tree.
7132 ///
7133 /// @param type the typedef, array or qualified tree to clone. any
7134 /// order.
7135 ///
7136 /// @return the cloned type, or NULL if @type was neither a typedef,
7137 /// array nor a qualified type.
7138 static type_base_sptr
clone_typedef_array_qualified_type(type_base_sptr type)7139 clone_typedef_array_qualified_type(type_base_sptr type)
7140 {
7141 if (!type)
7142 return type;
7143
7144 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
7145 type_base_sptr result;
7146
7147 if (typedef_decl_sptr t = is_typedef(type))
7148 result = clone_typedef(is_typedef(t));
7149 else if (qualified_type_def_sptr t = is_qualified_type(type))
7150 result = clone_qualified_type(t);
7151 else if (array_type_def_sptr t = is_array_type(type))
7152 result = clone_array(t);
7153 else
7154 return type_base_sptr();
7155
7156 if (scope)
7157 add_decl_to_scope(is_decl(result), scope);
7158
7159 return result;
7160 }
7161
7162 /// Clone a type tree made of an array or a typedef of array.
7163 ///
7164 /// Note that this can be a tree which root node is a typedef an which
7165 /// sub-tree can be any arbitrary combination of typedef, qualified
7166 /// type and arrays.
7167 ///
7168 /// @param t the array or typedef of qualified array to consider.
7169 ///
7170 /// @return a clone of @p t.
7171 type_base_sptr
clone_array_tree(const type_base_sptr t)7172 clone_array_tree(const type_base_sptr t)
7173 {
7174 ABG_ASSERT(is_typedef_of_array(t) || is_array_type(t));
7175
7176 scope_decl* scope = is_decl(t)->get_scope();
7177 type_base_sptr result = clone_typedef_array_qualified_type(t);
7178 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
7179
7180 type_base_sptr subtree;
7181 if (typedef_decl_sptr type = is_typedef(result))
7182 {
7183 type_base_sptr s =
7184 clone_typedef_array_qualified_type(type->get_underlying_type());
7185 if (s)
7186 {
7187 subtree = s;
7188 type->set_underlying_type(subtree);
7189 }
7190 }
7191 else if (array_type_def_sptr type = is_array_type(result))
7192 {
7193 type_base_sptr s =
7194 clone_typedef_array_qualified_type(type->get_element_type());
7195 if (s)
7196 {
7197 subtree = s;
7198 type->set_element_type(subtree);
7199 }
7200 }
7201 add_decl_to_scope(is_decl(subtree), scope);
7202
7203 for (;;)
7204 {
7205 if (typedef_decl_sptr t = is_typedef(subtree))
7206 {
7207 type_base_sptr s =
7208 clone_typedef_array_qualified_type(t->get_underlying_type());
7209 if (s)
7210 {
7211 scope_decl* scope =
7212 is_decl(t->get_underlying_type())->get_scope();
7213 ABG_ASSERT(scope);
7214 add_decl_to_scope(is_decl(s), scope);
7215 t->set_underlying_type (s);
7216 subtree = s;
7217 }
7218 else
7219 break;
7220 }
7221 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
7222 {
7223 type_base_sptr s =
7224 clone_typedef_array_qualified_type(t->get_underlying_type());
7225 if (s)
7226 {
7227 scope_decl* scope =
7228 is_decl(t->get_underlying_type())->get_scope();
7229 ABG_ASSERT(scope);
7230 add_decl_to_scope(is_decl(s), scope);
7231 t->set_underlying_type(s);
7232 subtree = s;
7233 }
7234 else
7235 break;
7236 }
7237 else if (array_type_def_sptr t = is_array_type(subtree))
7238 {
7239 type_base_sptr e = t->get_element_type();
7240 if (is_typedef(e) || is_qualified_type(e))
7241 {
7242 type_base_sptr s =
7243 clone_typedef_array_qualified_type(e);
7244 if (s)
7245 {
7246 scope_decl* scope = is_decl(e)->get_scope();
7247 ABG_ASSERT(scope);
7248 add_decl_to_scope(is_decl(s), scope);
7249 t->set_element_type(s);
7250 }
7251 else
7252 break;
7253 }
7254 break;
7255 }
7256 else
7257 break;
7258 }
7259 return result;
7260 }
7261
7262 /// Update the qualified name of a given sub-tree.
7263 ///
7264 /// @param d the sub-tree for which to update the qualified name.
7265 static void
update_qualified_name(decl_base * d)7266 update_qualified_name(decl_base * d)
7267 {
7268 ::qualified_name_setter setter;
7269 d->traverse(setter);
7270 }
7271
7272 /// Update the qualified name of a given sub-tree.
7273 ///
7274 /// @param d the sub-tree for which to update the qualified name.
7275 static void
update_qualified_name(decl_base_sptr d)7276 update_qualified_name(decl_base_sptr d)
7277 {return update_qualified_name(d.get());}
7278
7279 // <scope_decl stuff>
7280
7281 /// Hash a type by returning the pointer value of its canonical type.
7282 ///
7283 /// @param l the type to hash.
7284 ///
7285 /// @return the the pointer value of the canonical type of @p l.
7286 size_t
operator ()(const type_base_sptr & l) const7287 canonical_type_hash::operator()(const type_base_sptr& l) const
7288 {return operator()(l.get());}
7289
7290 /// Hash a (canonical) type by returning its pointer value
7291 ///
7292 /// @param l the canonical type to hash.
7293 ///
7294 /// @return the pointer value of the canonical type of @p l.
7295 size_t
operator ()(const type_base * l) const7296 canonical_type_hash::operator()(const type_base *l) const
7297 {return reinterpret_cast<size_t>(l);}
7298
7299 struct scope_decl::priv
7300 {
7301 declarations members_;
7302 declarations sorted_members_;
7303 scopes member_scopes_;
7304 canonical_type_sptr_set_type canonical_types_;
7305 type_base_sptrs_type sorted_canonical_types_;
7306 }; // end struct scope_decl::priv
7307
7308 /// Constructor of the @ref scope_decl type.
7309 ///
7310 /// @param the environment to use for the new instance.
7311 ///
7312 /// @param the name of the scope decl.
7313 ///
7314 /// @param locus the source location where the scope_decl is defined.
7315 ///
7316 /// @param vis the visibility of the declaration.
scope_decl(const environment * env,const string & name,const location & locus,visibility vis)7317 scope_decl::scope_decl(const environment* env,
7318 const string& name,
7319 const location& locus,
7320 visibility vis)
7321 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7322 decl_base(env, name, locus, /*mangled_name=*/name, vis),
7323 priv_(new priv)
7324 {}
7325
7326 /// Constructor of the @ref scope_decl type.
7327 ///
7328 /// @param the environment to use for the new instance.
7329 ///
7330 /// @param l the source location where the scope_decl is defined.
7331 ///
7332 /// @param vis the visibility of the declaration.
scope_decl(const environment * env,location & l)7333 scope_decl::scope_decl(const environment* env, location& l)
7334 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
7335 decl_base(env, "", l),
7336 priv_(new priv)
7337 {}
7338
7339 /// @eturn the set of canonical types of the the current scope.
7340 canonical_type_sptr_set_type&
get_canonical_types()7341 scope_decl::get_canonical_types()
7342 {return priv_->canonical_types_;}
7343
7344 /// @eturn the set of canonical types of the the current scope.
7345 const canonical_type_sptr_set_type&
get_canonical_types() const7346 scope_decl::get_canonical_types() const
7347 {return const_cast<scope_decl*>(this)->get_canonical_types();}
7348
7349 /// Return a vector of sorted canonical types of the current scope.
7350 ///
7351 /// The types are sorted "almost topologically". That means, they are
7352 /// sorted using the lexicographic order of the string representing
7353 /// the location their definition point. If a type doesn't have a
7354 /// location, then its pretty representation is used.
7355 ///
7356 /// @return a vector of sorted canonical types of the current scope.
7357 const type_base_sptrs_type&
get_sorted_canonical_types() const7358 scope_decl::get_sorted_canonical_types() const
7359 {
7360 if (priv_->sorted_canonical_types_.empty())
7361 {
7362 for (canonical_type_sptr_set_type::const_iterator e =
7363 get_canonical_types().begin();
7364 e != get_canonical_types().end();
7365 ++e)
7366 priv_->sorted_canonical_types_.push_back(*e);
7367
7368 type_topo_comp comp;
7369 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7370 priv_->sorted_canonical_types_.end(),
7371 comp);
7372 }
7373 return priv_->sorted_canonical_types_;
7374 }
7375
7376 /// Getter for the member declarations carried by the current @ref
7377 /// scope_decl.
7378 ///
7379 /// @return the member declarations carried by the current @ref
7380 /// scope_decl.
7381 const scope_decl::declarations&
get_member_decls() const7382 scope_decl::get_member_decls() const
7383 {return priv_->members_;}
7384
7385 /// Getter for the member declarations carried by the current @ref
7386 /// scope_decl.
7387 ///
7388 /// @return the member declarations carried by the current @ref
7389 /// scope_decl.
7390 scope_decl::declarations&
get_member_decls()7391 scope_decl::get_member_decls()
7392 {return priv_->members_;}
7393
7394 /// Getter for the sorted member declarations carried by the current
7395 /// @ref scope_decl.
7396 ///
7397 /// @return the sorted member declarations carried by the current @ref
7398 /// scope_decl. The declarations are sorted topologically.
7399 const scope_decl::declarations&
get_sorted_member_decls() const7400 scope_decl::get_sorted_member_decls() const
7401 {
7402 decl_topo_comp comp;
7403 if (priv_->sorted_members_.empty())
7404 {
7405 for (declarations::const_iterator i = get_member_decls().begin();
7406 i != get_member_decls().end();
7407 ++i)
7408 priv_->sorted_members_.push_back(*i);
7409
7410 std::stable_sort(priv_->sorted_members_.begin(),
7411 priv_->sorted_members_.end(),
7412 comp);
7413 }
7414 return priv_->sorted_members_;
7415 }
7416
7417 /// Getter for the number of anonymous classes contained in this
7418 /// scope.
7419 ///
7420 /// @return the number of anonymous classes contained in this scope.
7421 size_t
get_num_anonymous_member_classes() const7422 scope_decl::get_num_anonymous_member_classes() const
7423 {
7424 int result = 0;
7425 for (declarations::const_iterator it = get_member_decls().begin();
7426 it != get_member_decls().end();
7427 ++it)
7428 if (class_decl_sptr t = is_class_type(*it))
7429 if (t->get_is_anonymous())
7430 ++result;
7431
7432 return result;
7433 }
7434
7435 /// Getter for the number of anonymous unions contained in this
7436 /// scope.
7437 ///
7438 /// @return the number of anonymous unions contained in this scope.
7439 size_t
get_num_anonymous_member_unions() const7440 scope_decl::get_num_anonymous_member_unions() const
7441 {
7442 int result = 0;
7443 for (declarations::const_iterator it = get_member_decls().begin();
7444 it != get_member_decls().end();
7445 ++it)
7446 if (union_decl_sptr t = is_union_type(*it))
7447 if (t->get_is_anonymous())
7448 ++result;
7449
7450 return result;
7451 }
7452
7453 /// Getter for the number of anonymous enums contained in this
7454 /// scope.
7455 ///
7456 /// @return the number of anonymous enums contained in this scope.
7457 size_t
get_num_anonymous_member_enums() const7458 scope_decl::get_num_anonymous_member_enums() const
7459 {
7460 int result = 0;
7461 for (declarations::const_iterator it = get_member_decls().begin();
7462 it != get_member_decls().end();
7463 ++it)
7464 if (enum_type_decl_sptr t = is_enum_type(*it))
7465 if (t->get_is_anonymous())
7466 ++result;
7467
7468 return result;
7469 }
7470
7471 /// Getter for the scopes carried by the current scope.
7472 ///
7473 /// @return the scopes carried by the current scope.
7474 scope_decl::scopes&
get_member_scopes()7475 scope_decl::get_member_scopes()
7476 {return priv_->member_scopes_;}
7477
7478 /// Getter for the scopes carried by the current scope.
7479 ///
7480 /// @return the scopes carried by the current scope.
7481 const scope_decl::scopes&
get_member_scopes() const7482 scope_decl::get_member_scopes() const
7483 {return priv_->member_scopes_;}
7484
7485 /// Test if the current scope is empty.
7486 ///
7487 /// @return true iff the current scope is empty.
7488 bool
is_empty() const7489 scope_decl::is_empty() const
7490 {
7491 return (get_member_decls().empty()
7492 && get_canonical_types().empty());
7493 }
7494
7495 /// Add a member decl to this scope. Note that user code should not
7496 /// use this, but rather use add_decl_to_scope.
7497 ///
7498 /// Note that this function updates the qualified name of the member
7499 /// decl that is added. It also sets the scope of the member. Thus,
7500 /// it ABG_ASSERTs that member should not have its scope set, prior to
7501 /// calling this function.
7502 ///
7503 /// @param member the new member decl to add to this scope.
7504 decl_base_sptr
add_member_decl(const decl_base_sptr & member)7505 scope_decl::add_member_decl(const decl_base_sptr& member)
7506 {
7507 ABG_ASSERT(!has_scope(member));
7508
7509 member->set_scope(this);
7510 priv_->members_.push_back(member);
7511
7512 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
7513 priv_->member_scopes_.push_back(m);
7514
7515 update_qualified_name(member);
7516
7517 if (const environment* env = get_environment())
7518 set_environment_for_artifact(member, env);
7519
7520 if (translation_unit* tu = get_translation_unit())
7521 {
7522 if (translation_unit* existing_tu = member->get_translation_unit())
7523 ABG_ASSERT(tu == existing_tu);
7524 else
7525 member->set_translation_unit(tu);
7526 }
7527
7528 maybe_update_types_lookup_map(member);
7529
7530 return member;
7531 }
7532
7533 /// Insert a member decl to this scope, right before an element
7534 /// pointed to by a given iterator. Note that user code should not
7535 /// use this, but rather use insert_decl_into_scope.
7536 ///
7537 /// Note that this function updates the qualified name of the inserted
7538 /// member.
7539 ///
7540 /// @param member the new member decl to add to this scope.
7541 ///
7542 /// @param before an interator pointing to the element before which
7543 /// the new member should be inserted.
7544 decl_base_sptr
insert_member_decl(decl_base_sptr member,declarations::iterator before)7545 scope_decl::insert_member_decl(decl_base_sptr member,
7546 declarations::iterator before)
7547 {
7548 ABG_ASSERT(!member->get_scope());
7549
7550 member->set_scope(this);
7551 priv_->members_.insert(before, member);
7552
7553 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
7554 priv_-> member_scopes_.push_back(m);
7555
7556 update_qualified_name(member);
7557
7558 if (const environment* env = get_environment())
7559 set_environment_for_artifact(member, env);
7560
7561 if (translation_unit* tu = get_translation_unit())
7562 {
7563 if (translation_unit* existing_tu = member->get_translation_unit())
7564 ABG_ASSERT(tu == existing_tu);
7565 else
7566 member->set_translation_unit(tu);
7567 }
7568
7569 maybe_update_types_lookup_map(member);
7570
7571 return member;
7572 }
7573
7574 /// Remove a declaration from the current scope.
7575 ///
7576 /// @param member the declaration to remove from the scope.
7577 void
remove_member_decl(decl_base_sptr member)7578 scope_decl::remove_member_decl(decl_base_sptr member)
7579 {
7580 for (declarations::iterator i = priv_->members_.begin();
7581 i != priv_->members_.end();
7582 ++i)
7583 {
7584 if (**i == *member)
7585 {
7586 priv_->members_.erase(i);
7587 // Do not access i after this point as it's invalided by the
7588 // erase call.
7589 break;
7590 }
7591 }
7592
7593 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
7594 if (scope)
7595 {
7596 for (scopes::iterator i = priv_->member_scopes_.begin();
7597 i != priv_->member_scopes_.end();
7598 ++i)
7599 {
7600 if (**i == *member)
7601 {
7602 priv_->member_scopes_.erase(i);
7603 break;
7604 }
7605 }
7606 }
7607 }
7608
7609 /// Return the hash value for the current instance of scope_decl.
7610 ///
7611 /// This method can trigger the computing of the hash value, if need be.
7612 ///
7613 /// @return the hash value.
7614 size_t
get_hash() const7615 scope_decl::get_hash() const
7616 {
7617 scope_decl::hash hash_scope;
7618 return hash_scope(this);
7619 }
7620
7621 /// Compares two instances of @ref scope_decl.
7622 ///
7623 /// If the two intances are different, set a bitfield to give some
7624 /// insight about the kind of differences there are.
7625 ///
7626 /// @param l the first artifact of the comparison.
7627 ///
7628 /// @param r the second artifact of the comparison.
7629 ///
7630 /// @param k a pointer to a bitfield that gives information about the
7631 /// kind of changes there are between @p l and @p r. This one is set
7632 /// iff @p k is non-null and the function returns false.
7633 ///
7634 /// Please note that setting k to a non-null value does have a
7635 /// negative performance impact because even if @p l and @p r are not
7636 /// equal, the function keeps up the comparison in order to determine
7637 /// the different kinds of ways in which they are different.
7638 ///
7639 /// @return true if @p l equals @p r, false otherwise.
7640 bool
equals(const scope_decl & l,const scope_decl & r,change_kind * k)7641 equals(const scope_decl& l, const scope_decl& r, change_kind* k)
7642 {
7643 bool result = true;
7644
7645 if (!l.decl_base::operator==(r))
7646 {
7647 result = false;
7648 if (k)
7649 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
7650 else
7651 ABG_RETURN_FALSE;
7652 }
7653
7654 scope_decl::declarations::const_iterator i, j;
7655 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
7656 i != l.get_member_decls().end() && j != r.get_member_decls().end();
7657 ++i, ++j)
7658 {
7659 if (**i != **j)
7660 {
7661 result = false;
7662 if (k)
7663 {
7664 *k |= SUBTYPE_CHANGE_KIND;
7665 break;
7666 }
7667 else
7668 ABG_RETURN_FALSE;
7669 }
7670 }
7671
7672 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
7673 {
7674 result = false;
7675 if (k)
7676 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
7677 else
7678 ABG_RETURN_FALSE;
7679 }
7680
7681 ABG_RETURN(result);
7682 }
7683
7684 /// Return true iff both scopes have the same names and have the same
7685 /// member decls.
7686 ///
7687 /// This function doesn't check for equality of the scopes of its
7688 /// arguments.
7689 bool
operator ==(const decl_base & o) const7690 scope_decl::operator==(const decl_base& o) const
7691 {
7692 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
7693 if (!other)
7694 return false;
7695
7696 return equals(*this, *other, 0);
7697 }
7698
7699 /// Equality operator for @ref scope_decl_sptr.
7700 ///
7701 /// @param l the left hand side operand of the equality operator.
7702 ///
7703 /// @pram r the right hand side operand of the equalify operator.
7704 ///
7705 /// @return true iff @p l equals @p r.
7706 bool
operator ==(const scope_decl_sptr & l,const scope_decl_sptr & r)7707 operator==(const scope_decl_sptr& l, const scope_decl_sptr& r)
7708 {
7709 if (!!l != !!r)
7710 return false;
7711 if (l.get() == r.get())
7712 return true;
7713 return *l == *r;
7714 }
7715
7716 /// Inequality operator for @ref scope_decl_sptr.
7717 ///
7718 /// @param l the left hand side operand of the equality operator.
7719 ///
7720 /// @pram r the right hand side operand of the equalify operator.
7721 ///
7722 /// @return true iff @p l equals @p r.
7723 bool
operator !=(const scope_decl_sptr & l,const scope_decl_sptr & r)7724 operator!=(const scope_decl_sptr& l, const scope_decl_sptr& r)
7725 {return !operator==(l, r);}
7726
7727 /// Find a member of the current scope and return an iterator on it.
7728 ///
7729 /// @param decl the scope member to find.
7730 ///
7731 /// @param i the iterator to set to the member @p decl. This is set
7732 /// iff the function returns true.
7733 ///
7734 /// @return true if the member decl was found, false otherwise.
7735 bool
find_iterator_for_member(const decl_base * decl,declarations::iterator & i)7736 scope_decl::find_iterator_for_member(const decl_base* decl,
7737 declarations::iterator& i)
7738 {
7739 if (!decl)
7740 return false;
7741
7742 if (get_member_decls().empty())
7743 {
7744 i = get_member_decls().end();
7745 return false;
7746 }
7747
7748 for (declarations::iterator it = get_member_decls().begin();
7749 it != get_member_decls().end();
7750 ++it)
7751 {
7752 if ((*it).get() == decl)
7753 {
7754 i = it;
7755 return true;
7756 }
7757 }
7758
7759 return false;
7760 }
7761
7762 /// Find a member of the current scope and return an iterator on it.
7763 ///
7764 /// @param decl the scope member to find.
7765 ///
7766 /// @param i the iterator to set to the member @p decl. This is set
7767 /// iff the function returns true.
7768 ///
7769 /// @return true if the member decl was found, false otherwise.
7770 bool
find_iterator_for_member(const decl_base_sptr decl,declarations::iterator & i)7771 scope_decl::find_iterator_for_member(const decl_base_sptr decl,
7772 declarations::iterator& i)
7773 {return find_iterator_for_member(decl.get(), i);}
7774
7775 /// This implements the ir_traversable_base::traverse pure virtual
7776 /// function.
7777 ///
7778 /// @param v the visitor used on the current instance of scope_decl
7779 /// and on its member nodes.
7780 ///
7781 /// @return true if the traversal of the tree should continue, false
7782 /// otherwise.
7783 bool
traverse(ir_node_visitor & v)7784 scope_decl::traverse(ir_node_visitor &v)
7785 {
7786 if (visiting())
7787 return true;
7788
7789 if (v.visit_begin(this))
7790 {
7791 visiting(true);
7792 for (scope_decl::declarations::const_iterator i =
7793 get_member_decls().begin();
7794 i != get_member_decls ().end();
7795 ++i)
7796 if (!(*i)->traverse(v))
7797 break;
7798 visiting(false);
7799 }
7800 return v.visit_end(this);
7801 }
7802
~scope_decl()7803 scope_decl::~scope_decl()
7804 {}
7805
7806 /// Appends a declaration to a given scope, if the declaration
7807 /// doesn't already belong to one.
7808 ///
7809 /// @param decl the declaration to add to the scope
7810 ///
7811 /// @param scope the scope to append the declaration to
7812 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,scope_decl * scope)7813 add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
7814 {
7815 ABG_ASSERT(scope);
7816
7817 if (scope && decl && !decl->get_scope())
7818 decl = scope->add_member_decl(decl);
7819
7820 return decl;
7821 }
7822
7823 /// Appends a declaration to a given scope, if the declaration doesn't
7824 /// already belong to a scope.
7825 ///
7826 /// @param decl the declaration to add append to the scope
7827 ///
7828 /// @param scope the scope to append the decl to
7829 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,const scope_decl_sptr & scope)7830 add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
7831 {return add_decl_to_scope(decl, scope.get());}
7832
7833 /// Remove a given decl from its scope
7834 ///
7835 /// @param decl the decl to remove from its scope.
7836 void
remove_decl_from_scope(decl_base_sptr decl)7837 remove_decl_from_scope(decl_base_sptr decl)
7838 {
7839 if (!decl)
7840 return;
7841
7842 scope_decl* scope = decl->get_scope();
7843 scope->remove_member_decl(decl);
7844 decl->set_scope(0);
7845 }
7846
7847 /// Inserts a declaration into a given scope, before a given IR child
7848 /// node of the scope.
7849 ///
7850 /// @param decl the declaration to insert into the scope.
7851 ///
7852 /// @param before an iterator pointing to the child IR node before
7853 /// which to insert the declaration.
7854 ///
7855 /// @param scope the scope into which to insert the declaration.
7856 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl * scope)7857 insert_decl_into_scope(decl_base_sptr decl,
7858 scope_decl::declarations::iterator before,
7859 scope_decl* scope)
7860 {
7861 if (scope && decl && !decl->get_scope())
7862 {
7863 decl_base_sptr d = scope->insert_member_decl(decl, before);
7864 decl = d;
7865 }
7866 return decl;
7867 }
7868
7869 /// Inserts a declaration into a given scope, before a given IR child
7870 /// node of the scope.
7871 ///
7872 /// @param decl the declaration to insert into the scope.
7873 ///
7874 /// @param before an iterator pointing to the child IR node before
7875 /// which to insert the declaration.
7876 ///
7877 /// @param scope the scope into which to insert the declaration.
7878 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl_sptr scope)7879 insert_decl_into_scope(decl_base_sptr decl,
7880 scope_decl::declarations::iterator before,
7881 scope_decl_sptr scope)
7882 {return insert_decl_into_scope(decl, before, scope.get());}
7883
7884 /// Constructor of the @ref global_scope type.
7885 ///
7886 /// @param tu the translation unit the scope belongs to.
global_scope(translation_unit * tu)7887 global_scope::global_scope(translation_unit *tu)
7888 : type_or_decl_base(tu->get_environment(),
7889 GLOBAL_SCOPE_DECL
7890 | ABSTRACT_DECL_BASE
7891 | ABSTRACT_SCOPE_DECL),
7892 decl_base(tu->get_environment(), "", location()),
7893 scope_decl(tu->get_environment(), "", location()),
7894 translation_unit_(tu)
7895 {
7896 runtime_type_instance(this);
7897 }
7898
7899 /// return the global scope as seen by a given declaration.
7900 ///
7901 /// @param decl the declaration to consider.
7902 ///
7903 /// @return the global scope of the decl, or a null pointer if the
7904 /// decl is not yet added to a translation_unit.
7905 const global_scope*
get_global_scope(const decl_base & decl)7906 get_global_scope(const decl_base& decl)
7907 {
7908 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
7909 return s;
7910
7911 scope_decl* scope = decl.get_scope();
7912 while (scope && !dynamic_cast<global_scope*>(scope))
7913 scope = scope->get_scope();
7914
7915 return scope ? dynamic_cast<global_scope*> (scope) : 0;
7916 }
7917
7918 /// return the global scope as seen by a given declaration.
7919 ///
7920 /// @param decl the declaration to consider.
7921 ///
7922 /// @return the global scope of the decl, or a null pointer if the
7923 /// decl is not yet added to a translation_unit.
7924 const global_scope*
get_global_scope(const decl_base * decl)7925 get_global_scope(const decl_base* decl)
7926 {return get_global_scope(*decl);}
7927
7928 /// Return the global scope as seen by a given declaration.
7929 ///
7930 /// @param decl the declaration to consider.
7931 ///
7932 /// @return the global scope of the decl, or a null pointer if the
7933 /// decl is not yet added to a translation_unit.
7934 const global_scope*
get_global_scope(const shared_ptr<decl_base> decl)7935 get_global_scope(const shared_ptr<decl_base> decl)
7936 {return get_global_scope(decl.get());}
7937
7938 /// Return the a scope S containing a given declaration and that is
7939 /// right under a given scope P.
7940 ///
7941 /// Note that @p scope must come before @p decl in topological
7942 /// order.
7943 ///
7944 /// @param decl the decl for which to find a scope.
7945 ///
7946 /// @param scope the scope under which the resulting scope must be.
7947 ///
7948 /// @return the resulting scope.
7949 const scope_decl*
get_top_most_scope_under(const decl_base * decl,const scope_decl * scope)7950 get_top_most_scope_under(const decl_base* decl,
7951 const scope_decl* scope)
7952 {
7953 if (!decl)
7954 return 0;
7955
7956 if (scope == 0)
7957 return get_global_scope(decl);
7958
7959 // Handle the case where decl is a scope itself.
7960 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
7961 if (!s)
7962 s = decl->get_scope();
7963
7964 if (is_global_scope(s))
7965 return scope;
7966
7967 // Here, decl is in the scope 'scope', or decl and 'scope' are the
7968 // same. The caller needs to be prepared to deal with this case.
7969 if (s == scope)
7970 return s;
7971
7972 while (s && !is_global_scope(s) && s->get_scope() != scope)
7973 s = s->get_scope();
7974
7975 if (!s || is_global_scope(s))
7976 // SCOPE must come before decl in topological order, but I don't
7977 // know how to ensure that ...
7978 return scope;
7979 ABG_ASSERT(s);
7980
7981 return s;
7982 }
7983
7984 /// Return the a scope S containing a given declaration and that is
7985 /// right under a given scope P.
7986 ///
7987 /// @param decl the decl for which to find a scope.
7988 ///
7989 /// @param scope the scope under which the resulting scope must be.
7990 ///
7991 /// @return the resulting scope.
7992 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl * scope)7993 get_top_most_scope_under(const decl_base_sptr decl,
7994 const scope_decl* scope)
7995 {return get_top_most_scope_under(decl.get(), scope);}
7996
7997 /// Return the a scope S containing a given declaration and that is
7998 /// right under a given scope P.
7999 ///
8000 /// @param decl the decl for which to find a scope.
8001 ///
8002 /// @param scope the scope under which the resulting scope must be.
8003 ///
8004 /// @return the resulting scope.
8005 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl_sptr scope)8006 get_top_most_scope_under(const decl_base_sptr decl,
8007 const scope_decl_sptr scope)
8008 {return get_top_most_scope_under(decl, scope.get());}
8009
8010 // </scope_decl stuff>
8011
8012
8013 /// Get the string representation of a CV qualifier bitmap.
8014 ///
8015 /// @param cv_quals the bitmap of CV qualifiers to consider.
8016 ///
8017 /// @return the string representation.
8018 string
get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)8019 get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
8020 {
8021 string repr;
8022 if (cv_quals & qualified_type_def::CV_RESTRICT)
8023 repr = "restrict";
8024 if (cv_quals & qualified_type_def::CV_CONST)
8025 {
8026 if (!repr.empty())
8027 repr += ' ';
8028 repr += "const";
8029 }
8030 if (cv_quals & qualified_type_def::CV_VOLATILE)
8031 {
8032 if (!repr.empty())
8033 repr += ' ';
8034 repr += "volatile";
8035 }
8036 return repr;
8037 }
8038
8039 /// Build and return a copy of the name of an ABI artifact that is
8040 /// either a type or a decl.
8041 ///
8042 /// @param tod the ABI artifact to get the name for.
8043 ///
8044 /// @param qualified if yes, return the qualified name of @p tod;
8045 /// otherwise, return the non-qualified name;
8046 ///
8047 /// @return the name of @p tod.
8048 string
get_name(const type_or_decl_base * tod,bool qualified)8049 get_name(const type_or_decl_base *tod, bool qualified)
8050 {
8051 string result;
8052
8053 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
8054
8055 if (type_base* t = dynamic_cast<type_base*>(a))
8056 result = get_type_name(t, qualified);
8057 else if (decl_base *d = dynamic_cast<decl_base*>(a))
8058 {
8059 if (qualified)
8060 result = d->get_qualified_name();
8061 else
8062 result = d->get_name();
8063 }
8064 else
8065 // We should never reach this point.
8066 abort();
8067
8068 return result;
8069 }
8070
8071 /// Build and return a copy of the name of an ABI artifact that is
8072 /// either a type of a decl.
8073 ///
8074 /// @param tod the ABI artifact to get the name for.
8075 ///
8076 /// @param qualified if yes, return the qualified name of @p tod;
8077 /// otherwise, return the non-qualified name;
8078 ///
8079 /// @return the name of @p tod.
8080 string
get_name(const type_or_decl_base_sptr & tod,bool qualified)8081 get_name(const type_or_decl_base_sptr& tod, bool qualified)
8082 {return get_name(tod.get(), qualified);}
8083
8084 /// Build and return a qualified name from a name and its scope.
8085 ///
8086 /// The name is supposed to be for an entity that is part of the
8087 /// scope.
8088 ///
8089 /// @param the scope to consider.
8090 ///
8091 /// @param name of the name to consider.
8092 ///
8093 /// @return a copy of the string that represents the qualified name.
8094 string
build_qualified_name(const scope_decl * scope,const string & name)8095 build_qualified_name(const scope_decl* scope, const string& name)
8096 {
8097 if (name.empty())
8098 return "";
8099
8100 string qualified_name;
8101 if (scope)
8102 qualified_name = scope->get_qualified_name();
8103
8104 if (qualified_name.empty())
8105 qualified_name = name;
8106 else
8107 qualified_name = qualified_name + "::" + name;
8108
8109 return qualified_name;
8110 }
8111
8112 /// Build and return the qualified name of a type in its scope.
8113 ///
8114 /// @param scope the scope of the type to consider.
8115 ///
8116 /// @param type the type to consider.
8117 string
build_qualified_name(const scope_decl * scope,const type_base_sptr & type)8118 build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
8119 {return build_qualified_name(scope, get_name((type)));}
8120
8121 // </scope_decl stuff>
8122
8123 /// Get the location of the declaration of a given type.
8124 ///
8125 /// @param type the type to consider.
8126 ///
8127 /// @return the location of the declaration of type @p type.
8128 location
get_location(const type_base_sptr & type)8129 get_location(const type_base_sptr& type)
8130 {
8131 if (decl_base_sptr decl = get_type_declaration(type))
8132 return get_location(decl);
8133 return location();
8134 }
8135
8136 /// Get the location of a given declaration.
8137 ///
8138 /// @param decl the declaration to consider.
8139 ///
8140 /// @return the location of the declaration @p decl.
8141 location
get_location(const decl_base_sptr & decl)8142 get_location(const decl_base_sptr& decl)
8143 {
8144 location loc = decl->get_location();
8145 if (!loc)
8146 {
8147 if (class_or_union_sptr c = is_class_or_union_type(decl))
8148 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8149 {
8150 c = is_class_or_union_type(c->get_definition_of_declaration());
8151 loc = c->get_location();
8152 }
8153 }
8154 return loc;
8155 }
8156
8157 /// Get the scope of a given type.
8158 ///
8159 /// @param t the type to consider.
8160 ///
8161 /// @return the scope of type @p t or 0 if the type has no scope yet.
8162 scope_decl*
get_type_scope(type_base * t)8163 get_type_scope(type_base* t)
8164 {
8165 if (!t)
8166 return 0;
8167
8168 decl_base* d = get_type_declaration(t);
8169 if (d)
8170 return d->get_scope();
8171 return 0;
8172 }
8173
8174 /// Get the scope of a given type.
8175 ///
8176 /// @param t the type to consider.
8177 ///
8178 /// @return the scope of type @p t or 0 if the type has no scope yet.
8179 scope_decl*
get_type_scope(const type_base_sptr & t)8180 get_type_scope(const type_base_sptr& t)
8181 {return get_type_scope(t.get());}
8182
8183 /// Get the name of a given type and return a copy of it.
8184 ///
8185 /// @param t the type to consider.
8186 ///
8187 /// @param qualified if true then return the qualified name of the
8188 /// type.
8189 ///
8190 /// @param internal set to true if the call is intended for an
8191 /// internal use (for technical use inside the library itself), false
8192 /// otherwise. If you don't know what this is for, then set it to
8193 /// false.
8194 ///
8195 /// @return a copy of the type name if the type has a name, or the
8196 /// empty string if it does not.
8197 interned_string
get_type_name(const type_base_sptr & t,bool qualified,bool internal)8198 get_type_name(const type_base_sptr& t, bool qualified, bool internal)
8199 {return get_type_name(t.get(), qualified, internal);}
8200
8201 /// Return true iff a decl is for a type type that has a generic
8202 /// anonymous internal type name.
8203 ///
8204 /// @param d the decl to considier.
8205 ///
8206 /// @return true iff @p d is for a type type that has a generic
8207 /// anonymous internal type name.
8208 static bool
has_generic_anonymous_internal_type_name(const decl_base * d)8209 has_generic_anonymous_internal_type_name(const decl_base *d)
8210 {
8211 return is_class_or_union_type(d) || is_enum_type(d);
8212 }
8213
8214 /// Return the generic internal name of an anonymous type.
8215 ///
8216 /// For internal purposes, we want to define a generic name for all
8217 /// anonymous types of a certain kind. For instance, all anonymous
8218 /// structs will be have a generic name of "__anonymous_struct__", all
8219 /// anonymous unions will have a generic name of
8220 /// "__anonymous_union__", etc.
8221 ///
8222 /// That generic name can be used as a hash to put all anonymous types
8223 /// of a certain kind in the same hash table bucket, for instance.
8224 static interned_string
get_generic_anonymous_internal_type_name(const decl_base * d)8225 get_generic_anonymous_internal_type_name(const decl_base *d)
8226 {
8227 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8228
8229 const environment *env = d->get_environment();
8230
8231 interned_string result;
8232 if (is_class_type(d))
8233 result =
8234 env->intern(tools_utils::get_anonymous_struct_internal_name_prefix());
8235 else if (is_union_type(d))
8236 result =
8237 env->intern(tools_utils::get_anonymous_union_internal_name_prefix());
8238 else if (is_enum_type(d))
8239 result =
8240 env->intern(tools_utils::get_anonymous_enum_internal_name_prefix());
8241 else
8242 ABG_ASSERT_NOT_REACHED;
8243
8244 return result;
8245 }
8246
8247 /// Get the name of a given type and return a copy of it.
8248 ///
8249 /// @param t the type to consider.
8250 ///
8251 /// @param qualified if true then return the qualified name of the
8252 /// type.
8253 ///
8254 /// @param internal set to true if the call is intended for an
8255 /// internal use (for technical use inside the library itself), false
8256 /// otherwise. If you don't know what this is for, then set it to
8257 /// false.
8258 ///
8259 /// @return a copy of the type name if the type has a name, or the
8260 /// empty string if it does not.
8261 interned_string
get_type_name(const type_base * t,bool qualified,bool internal)8262 get_type_name(const type_base* t, bool qualified, bool internal)
8263 {
8264 const decl_base* d = dynamic_cast<const decl_base*>(t);
8265 if (!d)
8266 {
8267 const function_type* fn_type = is_function_type(t);
8268 ABG_ASSERT(fn_type);
8269 return fn_type->get_cached_name(internal);
8270 }
8271
8272 // All anonymous types of a given kind get to have the same internal
8273 // name for internal purpose. This to allow them to be compared
8274 // among themselves during type canonicalization.
8275 if (internal && d->get_is_anonymous())
8276 {
8277 string r;
8278 r += get_generic_anonymous_internal_type_name(d);
8279 return t->get_environment()->intern(r);
8280 }
8281
8282 if (qualified)
8283 return d->get_qualified_name(internal);
8284 return d->get_name();
8285 }
8286
8287 /// Get the name of a given type and return a copy of it.
8288 ///
8289 /// @param t the type to consider.
8290 ///
8291 /// @param qualified if true then return the qualified name of the
8292 /// type.
8293 ///
8294 /// @param internal set to true if the call is intended for an
8295 /// internal use (for technical use inside the library itself), false
8296 /// otherwise. If you don't know what this is for, then set it to
8297 /// false.
8298 ///
8299 /// @return a copy of the type name if the type has a name, or the
8300 /// empty string if it does not.
8301 interned_string
get_type_name(const type_base & t,bool qualified,bool internal)8302 get_type_name(const type_base& t, bool qualified, bool internal)
8303 {return get_type_name(&t, qualified, internal);}
8304
8305 /// Get the name of the pointer to a given type.
8306 ///
8307 /// @param pointed_to_type the pointed-to-type to consider.
8308 ///
8309 /// @param qualified this is true if the resulting name should be of a
8310 /// pointer to a *fully-qualified* pointed-to-type.
8311 ///
8312 /// @param internal true if the name is for libabigail-internal
8313 /// purposes.
8314 ///
8315 /// @return the name (string representation) of the pointer.
8316 interned_string
get_name_of_pointer_to_type(const type_base & pointed_to_type,bool qualified,bool internal)8317 get_name_of_pointer_to_type(const type_base& pointed_to_type,
8318 bool qualified, bool internal)
8319 {
8320 const environment* env = pointed_to_type.get_environment();
8321 ABG_ASSERT(env);
8322
8323 string tn = get_type_name(pointed_to_type, qualified, internal);
8324 tn = tn + "*";
8325
8326 return env->intern(tn);
8327 }
8328
8329 /// Get the name of the reference to a given type.
8330 ///
8331 /// @param pointed_to_type the pointed-to-type to consider.
8332 ///
8333 /// @param qualified this is true if the resulting name should be of a
8334 /// reference to a *fully-qualified* pointed-to-type.
8335 ///
8336 /// @param internal true if the name is for libabigail-internal
8337 /// purposes.
8338 ///
8339 /// @return the name (string representation) of the reference.
8340 interned_string
get_name_of_reference_to_type(const type_base & pointed_to_type,bool lvalue_reference,bool qualified,bool internal)8341 get_name_of_reference_to_type(const type_base& pointed_to_type,
8342 bool lvalue_reference,
8343 bool qualified, bool internal)
8344 {
8345 const environment* env = pointed_to_type.get_environment();
8346 ABG_ASSERT(env);
8347
8348 string name = get_type_name(pointed_to_type, qualified, internal);
8349 if (lvalue_reference)
8350 name = name + "&";
8351 else
8352 name = name + "&&";
8353
8354 return env->intern(name);
8355 }
8356
8357 /// Get the name of a qualified type, given the underlying type and
8358 /// its qualifiers.
8359 ///
8360 /// @param underlying_type the underlying type to consider.
8361 ///
8362 /// @param quals the CV qualifiers of the name.
8363 ///
8364 /// @param qualified true if we should consider the fully qualified
8365 /// name of @p underlying_type.
8366 ///
8367 /// @param internal true if the result is to be used for
8368 /// libabigail-internal purposes.
8369 ///
8370 /// @return the name (string representation) of the qualified type.
8371 interned_string
get_name_of_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,bool qualified,bool internal)8372 get_name_of_qualified_type(const type_base_sptr& underlying_type,
8373 qualified_type_def::CV quals,
8374 bool qualified, bool internal)
8375 {
8376 const environment* env = underlying_type->get_environment();
8377 ABG_ASSERT(env);
8378
8379 string quals_repr = get_string_representation_of_cv_quals(quals);
8380 string name = get_type_name(underlying_type, qualified, internal);
8381
8382 if (quals_repr.empty() && internal)
8383 // We are asked to return the internal name, that might be used
8384 // for type canonicalization. For that canonicalization, we need
8385 // to make a difference between a no-op qualified type which
8386 // underlying type is foo (the qualified type is named "none
8387 // foo"), and the name of foo, which is just "foo".
8388 //
8389 // Please remember that this has to be kept in sync with what is
8390 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
8391 // change this code here, please change that code there too.
8392 quals_repr = "";
8393
8394 if (!quals_repr.empty())
8395 {
8396 if (is_pointer_type(underlying_type)
8397 || is_reference_type(underlying_type)
8398 || is_array_type(underlying_type))
8399 {
8400 name += " ";
8401 name += quals_repr;
8402 }
8403 else
8404 name = quals_repr + " " + name;
8405 }
8406
8407 return env->intern(name);
8408 }
8409
8410 /// Get the name of a given function type and return a copy of it.
8411 ///
8412 /// @param fn_type the function type to consider.
8413 ///
8414 /// @param internal set to true if the call is intended for an
8415 /// internal use (for technical use inside the library itself), false
8416 /// otherwise. If you don't know what this is for, then set it to
8417 /// false.
8418 ///
8419 /// @return a copy of the function type name
8420 interned_string
get_function_type_name(const function_type_sptr & fn_type,bool internal)8421 get_function_type_name(const function_type_sptr& fn_type,
8422 bool internal)
8423 {return get_function_type_name(fn_type.get(), internal);}
8424
8425 /// Get the name of a given function type and return a copy of it.
8426 ///
8427 /// @param fn_type the function type to consider.
8428 ///
8429 /// @param internal set to true if the call is intended for an
8430 /// internal use (for technical use inside the library itself), false
8431 /// otherwise. If you don't know what this is for, then set it to
8432 /// false.
8433 ///
8434 /// @return a copy of the function type name
8435 interned_string
get_function_type_name(const function_type * fn_type,bool internal)8436 get_function_type_name(const function_type* fn_type,
8437 bool internal)
8438 {
8439 ABG_ASSERT(fn_type);
8440
8441 if (const method_type* method = is_method_type(fn_type))
8442 return get_method_type_name(method, internal);
8443
8444 return get_function_type_name(*fn_type, internal);
8445 }
8446
8447 /// Get the name of a given function type and return a copy of it.
8448 ///
8449 /// @param fn_type the function type to consider.
8450 ///
8451 /// @param internal set to true if the call is intended for an
8452 /// internal use (for technical use inside the library itself), false
8453 /// otherwise. If you don't know what this is for, then set it to
8454 /// false.
8455 ///
8456 /// @return a copy of the function type name
8457 interned_string
get_function_type_name(const function_type & fn_type,bool internal)8458 get_function_type_name(const function_type& fn_type,
8459 bool internal)
8460 {
8461 std::ostringstream o;
8462 type_base_sptr return_type = fn_type.get_return_type();
8463 const environment* env = fn_type.get_environment();
8464 ABG_ASSERT(env);
8465
8466 o << get_pretty_representation(return_type, internal);
8467
8468 o << " (";
8469 for (function_type::parameters::const_iterator i =
8470 fn_type.get_parameters().begin();
8471 i != fn_type.get_parameters().end();
8472 ++i)
8473 {
8474 if (i != fn_type.get_parameters().begin())
8475 o << ", ";
8476 o << get_pretty_representation((*i)->get_type(), internal);
8477 }
8478 o <<")";
8479
8480 return env->intern(o.str());
8481 }
8482
8483 /// Get the name of a given method type and return a copy of it.
8484 ///
8485 /// @param fn_type the function type to consider.
8486 ///
8487 /// @param internal set to true if the call is intended for an
8488 /// internal use (for technical use inside the library itself), false
8489 /// otherwise. If you don't know what this is for, then set it to
8490 /// false.
8491 ///
8492 /// @return a copy of the function type name
8493 interned_string
get_method_type_name(const method_type_sptr fn_type,bool internal)8494 get_method_type_name(const method_type_sptr fn_type,
8495 bool internal)
8496 {return get_method_type_name(fn_type.get(), internal);}
8497
8498 /// Get the name of a given method type and return a copy of it.
8499 ///
8500 /// @param fn_type the function type to consider.
8501 ///
8502 /// @param internal set to true if the call is intended for an
8503 /// internal use (for technical use inside the library itself), false
8504 /// otherwise. If you don't know what this is for, then set it to
8505 /// false.
8506 ///
8507 /// @return a copy of the function type name
8508 interned_string
get_method_type_name(const method_type * fn_type,bool internal)8509 get_method_type_name(const method_type* fn_type,
8510 bool internal)
8511 {
8512 if (fn_type)
8513 return get_method_type_name(*fn_type, internal);
8514
8515 return interned_string();
8516 }
8517
8518 /// Get the name of a given method type and return a copy of it.
8519 ///
8520 /// @param fn_type the function type to consider.
8521 ///
8522 /// @param internal set to true if the call is intended for an
8523 /// internal use (for technical use inside the library itself), false
8524 /// otherwise. If you don't know what this is for, then set it to
8525 /// false.
8526 ///
8527 /// @return a copy of the function type name
8528 interned_string
get_method_type_name(const method_type & fn_type,bool internal)8529 get_method_type_name(const method_type& fn_type,
8530 bool internal)
8531 {
8532 std::ostringstream o;
8533 type_base_sptr return_type= fn_type.get_return_type();
8534 const environment* env = fn_type.get_environment();
8535 ABG_ASSERT(env);
8536
8537 if (return_type)
8538 o << return_type->get_cached_pretty_representation(internal);
8539 else
8540 // There are still some abixml files out there in which "void"
8541 // can be expressed as an empty type.
8542 o << "void";
8543
8544 class_or_union_sptr class_type = fn_type.get_class_type();
8545 ABG_ASSERT(class_type);
8546
8547 o << " (" << class_type->get_qualified_name(internal) << "::*)"
8548 << " (";
8549
8550 for (function_type::parameters::const_iterator i =
8551 fn_type.get_parameters().begin();
8552 i != fn_type.get_parameters().end();
8553 ++i)
8554 {
8555 if (i != fn_type.get_parameters().begin())
8556 o << ", ";
8557 if (*i)
8558 o << (*i)->get_type()->get_cached_pretty_representation(internal);
8559 else
8560 // There are still some abixml files out there in which "void"
8561 // can be expressed as an empty type.
8562 o << "void";
8563 }
8564 o <<")";
8565
8566 return env->intern(o.str());
8567 }
8568
8569 /// Build and return a copy of the pretty representation of an ABI
8570 /// artifact that could be either a type of a decl.
8571 ///
8572 /// param tod the ABI artifact to consider.
8573 ///
8574 /// @param internal set to true if the call is intended for an
8575 /// internal use (for technical use inside the library itself), false
8576 /// otherwise. If you don't know what this is for, then set it to
8577 /// false.
8578 ///
8579 /// @return a copy of the pretty representation of an ABI artifact
8580 /// that could be either a type of a decl.
8581 string
get_pretty_representation(const type_or_decl_base * tod,bool internal)8582 get_pretty_representation(const type_or_decl_base* tod, bool internal)
8583 {
8584 string result;
8585
8586 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
8587 result = get_pretty_representation(t, internal);
8588 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
8589 result = get_pretty_representation(d, internal);
8590 else
8591 // We should never reach this point
8592 abort();
8593
8594 return result;
8595 }
8596
8597 /// Build and return a copy of the pretty representation of an ABI
8598 /// artifact that could be either a type of a decl.
8599 ///
8600 /// param tod the ABI artifact to consider.
8601 ///
8602 /// @param internal set to true if the call is intended for an
8603 /// internal use (for technical use inside the library itself), false
8604 /// otherwise. If you don't know what this is for, then set it to
8605 /// false.
8606 ///
8607 /// @return a copy of the pretty representation of an ABI artifact
8608 /// that could be either a type of a decl.
8609 string
get_pretty_representation(const type_or_decl_base_sptr & tod,bool internal)8610 get_pretty_representation(const type_or_decl_base_sptr& tod, bool internal)
8611 {return get_pretty_representation(tod.get(), internal);}
8612
8613 /// Get a copy of the pretty representation of a decl.
8614 ///
8615 /// @param d the decl to consider.
8616 ///
8617 /// @param internal set to true if the call is intended for an
8618 /// internal use (for technical use inside the library itself), false
8619 /// otherwise. If you don't know what this is for, then set it to
8620 /// false.
8621 ///
8622 /// @return the pretty representation of the decl.
8623 string
get_pretty_representation(const decl_base * d,bool internal)8624 get_pretty_representation(const decl_base* d, bool internal)
8625 {
8626 if (!d)
8627 return "";
8628 return d->get_pretty_representation(internal);
8629 }
8630
8631 /// Get a copy of the pretty representation of a type.
8632 ///
8633 /// @param d the type to consider.
8634 ///
8635 /// @param internal set to true if the call is intended for an
8636 /// internal use (for technical use inside the library itself), false
8637 /// otherwise. If you don't know what this is for, then set it to
8638 /// false.
8639 ///
8640 /// @return the pretty representation of the type.
8641 string
get_pretty_representation(const type_base * t,bool internal)8642 get_pretty_representation(const type_base* t, bool internal)
8643 {
8644 if (!t)
8645 return "void";
8646 if (const function_type* fn_type = is_function_type(t))
8647 return get_pretty_representation(fn_type, internal);
8648
8649 const decl_base* d = get_type_declaration(t);
8650 ABG_ASSERT(d);
8651 return get_pretty_representation(d, internal);
8652 }
8653
8654 /// Get a copy of the pretty representation of a decl.
8655 ///
8656 /// @param d the decl to consider.
8657 ///
8658 /// @param internal set to true if the call is intended for an
8659 /// internal use (for technical use inside the library itself), false
8660 /// otherwise. If you don't know what this is for, then set it to
8661 /// false.
8662 ///
8663 /// @return the pretty representation of the decl.
8664 string
get_pretty_representation(const decl_base_sptr & d,bool internal)8665 get_pretty_representation(const decl_base_sptr& d, bool internal)
8666 {return get_pretty_representation(d.get(), internal);}
8667
8668 /// Get a copy of the pretty representation of a type.
8669 ///
8670 /// @param d the type to consider.
8671 ///
8672 /// @param internal set to true if the call is intended for an
8673 /// internal use (for technical use inside the library itself), false
8674 /// otherwise. If you don't know what this is for, then set it to
8675 /// false.
8676 ///
8677 /// @return the pretty representation of the type.
8678 string
get_pretty_representation(const type_base_sptr & t,bool internal)8679 get_pretty_representation(const type_base_sptr& t, bool internal)
8680 {return get_pretty_representation(t.get(), internal);}
8681
8682 /// Get the pretty representation of a function type.
8683 ///
8684 /// @param fn_type the function type to consider.
8685 ///
8686 /// @param internal set to true if the call is intended for an
8687 /// internal use (for technical use inside the library itself), false
8688 /// otherwise. If you don't know what this is for, then set it to
8689 /// false.
8690 ///
8691 /// @return the string represenation of the function type.
8692 string
get_pretty_representation(const function_type_sptr & fn_type,bool internal)8693 get_pretty_representation(const function_type_sptr& fn_type,
8694 bool internal)
8695 {return get_pretty_representation(fn_type.get(), internal);}
8696
8697 /// Get the pretty representation of a function type.
8698 ///
8699 /// @param fn_type the function type to consider.
8700 ///
8701 /// @param internal set to true if the call is intended for an
8702 /// internal use (for technical use inside the library itself), false
8703 /// otherwise. If you don't know what this is for, then set it to
8704 /// false.
8705 ///
8706 /// @return the string represenation of the function type.
8707 string
get_pretty_representation(const function_type * fn_type,bool internal)8708 get_pretty_representation(const function_type* fn_type, bool internal)
8709 {
8710 if (!fn_type)
8711 return "void";
8712
8713 if (const method_type* method = is_method_type(fn_type))
8714 return get_pretty_representation(method, internal);
8715
8716 return get_pretty_representation(*fn_type, internal);
8717 }
8718
8719 /// Get the pretty representation of a function type.
8720 ///
8721 /// @param fn_type the function type to consider.
8722 ///
8723 /// @param internal set to true if the call is intended for an
8724 /// internal use (for technical use inside the library itself), false
8725 /// otherwise. If you don't know what this is for, then set it to
8726 /// false.
8727 ///
8728 /// @return the string represenation of the function type.
8729 string
get_pretty_representation(const function_type & fn_type,bool internal)8730 get_pretty_representation(const function_type& fn_type, bool internal)
8731 {
8732 std::ostringstream o;
8733 o << "function type " << get_function_type_name(fn_type, internal);
8734 return o.str();
8735 }
8736
8737 /// Get the pretty representation of a method type.
8738 ///
8739 /// @param method the method type to consider.
8740 ///
8741 /// @param internal set to true if the call is intended for an
8742 /// internal use (for technical use inside the library itself), false
8743 /// otherwise. If you don't know what this is for, then set it to
8744 /// false.
8745 ///
8746 /// @return the string represenation of the method type.
8747 string
get_pretty_representation(const method_type & method,bool internal)8748 get_pretty_representation(const method_type& method, bool internal)
8749 {
8750 std::ostringstream o;
8751 o << "method type " << get_method_type_name(method, internal);
8752 return o.str();
8753 }
8754
8755 /// Get the pretty representation of a method type.
8756 ///
8757 /// @param method the method type to consider.
8758 ///
8759 /// @param internal set to true if the call is intended for an
8760 /// internal use (for technical use inside the library itself), false
8761 /// otherwise. If you don't know what this is for, then set it to
8762 /// false.
8763 ///
8764 /// @return the string represenation of the method type.
8765 string
get_pretty_representation(const method_type * method,bool internal)8766 get_pretty_representation(const method_type* method, bool internal)
8767 {
8768 if (!method)
8769 return "void";
8770 return get_pretty_representation(*method, internal);
8771 }
8772
8773 /// Get the pretty representation of a method type.
8774 ///
8775 /// @param method the method type to consider.
8776 ///
8777 /// @param internal set to true if the call is intended for an
8778 /// internal use (for technical use inside the library itself), false
8779 /// otherwise. If you don't know what this is for, then set it to
8780 /// false.
8781 ///
8782 /// @return the string represenation of the method type.
8783 string
get_pretty_representation(const method_type_sptr method,bool internal)8784 get_pretty_representation(const method_type_sptr method, bool internal)
8785 {return get_pretty_representation(method.get(), internal);}
8786
8787 /// Get the flat representation of an instance of @ref class_or_union
8788 /// type.
8789 ///
8790 /// The flat representation of a given @ref class_or_union type is the
8791 /// actual definition of the type, for instance:
8792 ///
8793 /// struct foo {int a; char b;}
8794 ///
8795 ///@param cou the instance of @ref class_or_union to consider.
8796 ///
8797 ///@param indent the identation spaces to use in the representation.
8798 ///
8799 ///@param one_line if true, then the flat representation stands on one
8800 ///line. Otherwise, it stands on multiple lines.
8801 ///
8802 ///@return the resulting flat representation.
8803 string
get_class_or_union_flat_representation(const class_or_union & cou,const string & indent,bool one_line,bool internal,bool qualified_names)8804 get_class_or_union_flat_representation(const class_or_union& cou,
8805 const string& indent,
8806 bool one_line,
8807 bool internal,
8808 bool qualified_names)
8809 {
8810 string repr;
8811 string local_indent = " ";
8812
8813 if (class_decl* clazz = is_class_type(&cou))
8814 {
8815 repr = indent;
8816 if (!internal && clazz->is_struct())
8817 repr += "struct";
8818 else
8819 repr += "class";
8820 }
8821 else if (is_union_type(cou))
8822 repr = indent + "union";
8823 else
8824 return "";
8825
8826 repr += " ";
8827
8828 string name = cou.get_qualified_name();
8829
8830 if (!cou.get_is_anonymous())
8831 repr += name;
8832
8833 repr += "{";
8834
8835 if (!one_line)
8836 repr += "\n";
8837
8838 string real_indent;
8839 const class_or_union::data_members &dmems = cou.get_data_members();
8840 for (class_or_union::data_members::const_iterator dm = dmems.begin();
8841 dm != dmems.end();
8842 ++dm)
8843 {
8844 if (dm != dmems.begin())
8845 {
8846 if (one_line)
8847 real_indent = " ";
8848 else
8849 real_indent = "\n" + indent + local_indent;
8850 }
8851
8852 if (var_decl_sptr v = is_anonymous_data_member(*dm))
8853 repr +=
8854 get_class_or_union_flat_representation
8855 (anonymous_data_member_to_class_or_union(*dm),
8856 real_indent, one_line, internal, qualified_names);
8857 else
8858 {
8859 if (one_line)
8860 {
8861 if (dm != dmems.begin())
8862 repr += real_indent;
8863 repr += (*dm)->get_pretty_representation(internal,
8864 qualified_names);
8865 }
8866 else
8867 repr +=
8868 real_indent+ (*dm)->get_pretty_representation(internal,
8869 qualified_names);
8870 }
8871 repr += ";";
8872 }
8873
8874 if (one_line)
8875 repr += "}";
8876 else
8877 repr += indent + "}";
8878
8879 return repr;
8880 }
8881
8882 /// Get the flat representation of an instance of @ref class_or_union
8883 /// type.
8884 ///
8885 /// The flat representation of a given @ref class_or_union type is the
8886 /// actual definition of the type, for instance:
8887 ///
8888 /// struct foo {int a; char b;}
8889 ///
8890 ///@param cou the instance of @ref class_or_union to consider.
8891 ///
8892 ///@param indent the identation spaces to use in the representation.
8893 ///
8894 ///@param one_line if true, then the flat representation stands on one
8895 ///line. Otherwise, it stands on multiple lines.
8896 ///
8897 ///@return the resulting flat representation.
8898 string
get_class_or_union_flat_representation(const class_or_union * cou,const string & indent,bool one_line,bool internal,bool qualified_names)8899 get_class_or_union_flat_representation(const class_or_union* cou,
8900 const string& indent,
8901 bool one_line,
8902 bool internal,
8903 bool qualified_names)
8904 {
8905 if (cou)
8906 return get_class_or_union_flat_representation(*cou, indent, one_line,
8907 internal, qualified_names);
8908 return "";
8909 }
8910
8911 /// Get the flat representation of an instance of @ref class_or_union
8912 /// type.
8913 ///
8914 /// The flat representation of a given @ref class_or_union type is the
8915 /// actual definition of the type, for instance:
8916 ///
8917 /// struct foo {int a; char b;}
8918 ///
8919 ///@param cou the instance of @ref class_or_union to consider.
8920 ///
8921 ///@param indent the identation spaces to use in the representation.
8922 ///
8923 ///@param one_line if true, then the flat representation stands on one
8924 ///line. Otherwise, it stands on multiple lines.
8925 ///
8926 ///@return the resulting flat representation.
8927 string
get_class_or_union_flat_representation(const class_or_union_sptr & cou,const string & indent,bool one_line,bool internal,bool qualified_names)8928 get_class_or_union_flat_representation(const class_or_union_sptr& cou,
8929 const string& indent,
8930 bool one_line,
8931 bool internal,
8932 bool qualified_names)
8933 {return get_class_or_union_flat_representation(cou.get(),
8934 indent,
8935 one_line,
8936 internal,
8937 qualified_names);}
8938
8939 /// Get the textual representation of a type for debugging purposes.
8940 ///
8941 /// If the type is a class/union, this shows the data members, virtual
8942 /// member functions, size, pointer value of its canonical type, etc.
8943 /// Otherwise, this just shows the name of the artifact as returned by
8944 /// type_or_decl_base:get_pretty_representation().
8945 ///
8946 /// @param artifact the artifact to show a debugging representation of.
8947 ///
8948 /// @return a debugging string representation of @p artifact.
8949 string
get_debug_representation(const type_or_decl_base * artifact)8950 get_debug_representation(const type_or_decl_base* artifact)
8951 {
8952 if (!artifact)
8953 return string("");
8954
8955 class_or_union * c = is_class_or_union_type(artifact);
8956 if (c)
8957 {
8958 class_decl *clazz = is_class_type(c);
8959 string name = c->get_qualified_name();
8960 std::ostringstream o;
8961 o << name;
8962
8963 if (clazz)
8964 {
8965 if (!clazz->get_base_specifiers().empty())
8966 o << " :" << std::endl;
8967 for (auto &b : clazz->get_base_specifiers())
8968 {
8969 o << " ";
8970 if (b->get_is_virtual())
8971 o << "virtual ";
8972 o << b->get_base_class()->get_qualified_name()
8973 << std::endl;
8974 }
8975 }
8976 o << std::endl
8977 << "{"
8978 << " // size in bits: " << c->get_size_in_bits() << "\n"
8979 << " // is-declaration-only: " << c->get_is_declaration_only() << "\n"
8980 << " // definition point: " << get_natural_or_artificial_location(c).expand() << "\n"
8981 << " // translation unit: " << c->get_translation_unit()->get_absolute_path() << std::endl
8982 << " // @: " << std::hex << is_type(c)
8983 << ", @canonical: " << c->get_canonical_type().get() << std::dec
8984 << "\n\n";
8985
8986 for (auto m : c->get_data_members())
8987 {
8988 type_base_sptr t = m->get_type();
8989 t = peel_typedef_pointer_or_reference_type(t);
8990
8991 o << " "
8992 << m->get_pretty_representation(/*internal=*/false,
8993 /*qualified=*/false)
8994 << ";";
8995
8996 if (t && t->get_canonical_type())
8997 o << " // uses canonical type '@"
8998 << std::hex << t->get_canonical_type().get() << std::dec;
8999
9000 o << "'" << std::endl;
9001 }
9002
9003 if (clazz && clazz->has_vtable())
9004 {
9005 o << " // virtual member functions\n\n";
9006 for (auto f : clazz->get_virtual_mem_fns())
9007 o << " " << f->get_pretty_representation(/*internal=*/false,
9008 /*qualified=*/false)
9009 << ";" << std::endl;
9010 }
9011
9012 o << "};" << std::endl;
9013
9014 return o.str();
9015 }
9016 else if (const enum_type_decl* e = is_enum_type(artifact))
9017 {
9018 string name = e->get_qualified_name();
9019 std::ostringstream o;
9020 o << name
9021 << " : "
9022 << e->get_underlying_type()->get_pretty_representation(/*internal=*/false,
9023 true)
9024 << "\n"
9025 << "{\n"
9026 << " // size in bits: " << e->get_size_in_bits() << "\n"
9027 << " // is-declaration-only: " << e->get_is_declaration_only() << "\n"
9028 << " // definition point: " << get_natural_or_artificial_location(e).expand() << "\n"
9029 << " // translation unit: "
9030 << e->get_translation_unit()->get_absolute_path() << "\n"
9031 << " // @: " << std::hex << is_type(e)
9032 << ", @canonical: " << e->get_canonical_type().get() << std::dec
9033 << "\n\n";
9034
9035 for (const auto &enom : e->get_enumerators())
9036 o << " " << enom.get_name() << " = " << enom.get_value() << ",\n";
9037
9038 o << "};\n";
9039
9040 return o.str();
9041 }
9042 return artifact->get_pretty_representation(/*internal=*/true,
9043 /*qualified=*/true);
9044 }
9045
9046 /// Get a given data member, referred to by its name, of a class type.
9047 ///
9048 /// @param clazz the class to consider.
9049 ///
9050 /// @param member_name name of the data member to get.
9051 ///
9052 /// @return the resulting data member or nullptr if none was found.
9053 var_decl_sptr
get_data_member(class_or_union * clazz,const char * member_name)9054 get_data_member(class_or_union *clazz, const char* member_name)
9055 {
9056 if (!clazz)
9057 return var_decl_sptr();
9058 return clazz->find_data_member(member_name);
9059 }
9060
9061 /// Get a given data member, referred to by its name, of a class type.
9062 ///
9063 /// @param clazz the class to consider.
9064 ///
9065 /// @param member_name name of the data member to get.
9066 ///
9067 /// @return the resulting data member or nullptr if none was found.
9068 var_decl_sptr
get_data_member(type_base * clazz,const char * member_name)9069 get_data_member(type_base *clazz, const char* member_name)
9070 {return get_data_member(is_class_or_union_type(clazz), member_name);}
9071
9072 /// Get the non-artificial (natural) location of a decl.
9073 ///
9074 /// If the decl doesn't have a natural location then return its
9075 /// artificial one.
9076 ///
9077 /// @param decl the decl to consider.
9078 ///
9079 /// @return the natural location @p decl if it has one; otherwise,
9080 /// return its artificial one.
9081 const location&
get_natural_or_artificial_location(const decl_base * decl)9082 get_natural_or_artificial_location(const decl_base* decl)
9083 {
9084 ABG_ASSERT(decl);
9085
9086 if (decl->get_location())
9087 return decl->get_location();
9088 return decl->get_artificial_location();
9089 }
9090
9091 /// Get the artificial location of a decl.
9092 ///
9093 /// If the decl doesn't have an artificial location then return its
9094 /// natural one.
9095 ///
9096 /// @param decl the decl to consider.
9097 ///
9098 /// @return the artificial location @p decl if it has one; otherwise,
9099 /// return its natural one.
9100 const location&
get_artificial_or_natural_location(const decl_base * decl)9101 get_artificial_or_natural_location(const decl_base* decl)
9102 {
9103 ABG_ASSERT(decl);
9104
9105 if (decl->has_artificial_location())
9106 return decl->get_artificial_location();
9107 return decl->get_location();
9108 }
9109
9110 /// Emit a textual representation of an artifact to std error stream
9111 /// for debugging purposes.
9112 ///
9113 /// This is useful to invoke from within a command line debugger like
9114 /// GDB to help make sense of a given ABI artifact.
9115 ///
9116 /// @param artifact the ABI artifact to emit the debugging
9117 /// representation for.
9118 ///
9119 /// @return the artifact @p artifact.
9120 type_or_decl_base*
debug(const type_or_decl_base * artifact)9121 debug(const type_or_decl_base* artifact)
9122 {
9123 std::cerr << get_debug_representation(artifact) << std::endl;
9124 return const_cast<type_or_decl_base*>(artifact);
9125 }
9126
9127 /// Emit a textual representation of an artifact to std error stream
9128 /// for debugging purposes.
9129 ///
9130 /// This is useful to invoke from within a command line debugger like
9131 /// GDB to help make sense of a given ABI artifact.
9132 ///
9133 /// @param artifact the ABI artifact to emit the debugging
9134 /// representation for.
9135 ///
9136 /// @return the artifact @p artifact.
9137 type_base*
debug(const type_base * artifact)9138 debug(const type_base* artifact)
9139 {
9140 debug(static_cast<const type_or_decl_base*>(artifact));
9141 return const_cast<type_base*>(artifact);
9142 }
9143
9144 /// Emit a textual representation of an artifact to std error stream
9145 /// for debugging purposes.
9146 ///
9147 /// This is useful to invoke from within a command line debugger like
9148 /// GDB to help make sense of a given ABI artifact.
9149 ///
9150 /// @param artifact the ABI artifact to emit the debugging
9151 /// representation for.
9152 ///
9153 /// @return the artifact @p artifact.
9154 decl_base*
debug(const decl_base * artifact)9155 debug(const decl_base* artifact)
9156 {
9157 debug(static_cast<const type_or_decl_base*>(artifact));
9158 return const_cast<decl_base*>(artifact);
9159 }
9160
9161 /// Test if two ABI artifacts are equal.
9162 ///
9163 /// This can be useful when used from the command line of a debugger
9164 /// like GDB.
9165 ///
9166 /// @param l the first ABI artifact to consider in the comparison.
9167 ///
9168 /// @param r the second ABI artifact to consider in the comparison.
9169 ///
9170 /// @return true iff @p l equals @p r.
9171 bool
debug_equals(const type_or_decl_base * l,const type_or_decl_base * r)9172 debug_equals(const type_or_decl_base *l, const type_or_decl_base *r)
9173 {
9174 if (!!l != !!r)
9175 return false;
9176 if (!l && !r)
9177 return true;
9178
9179 return (*l == *r);
9180 }
9181
9182 /// By looking at the language of the TU a given ABI artifact belongs
9183 /// to, test if the ONE Definition Rule should apply.
9184 ///
9185 /// To date, it applies to c++, java and ada.
9186 ///
9187 /// @param artifact the ABI artifact to consider.
9188 ///
9189 /// @return true iff the One Definition Rule should apply.
9190 bool
odr_is_relevant(const type_or_decl_base & artifact)9191 odr_is_relevant(const type_or_decl_base& artifact)
9192 {
9193 translation_unit::language l =
9194 artifact.get_translation_unit()->get_language();
9195
9196 if (is_cplus_plus_language(l)
9197 || is_java_language(l)
9198 || is_ada_language(l))
9199 return true;
9200
9201 return false;
9202 }
9203
9204 /// Get the declaration for a given type.
9205 ///
9206 /// @param t the type to consider.
9207 ///
9208 /// @return the declaration for the type to return.
9209 const decl_base*
get_type_declaration(const type_base * t)9210 get_type_declaration(const type_base* t)
9211 {return dynamic_cast<const decl_base*>(t);}
9212
9213 /// Get the declaration for a given type.
9214 ///
9215 /// @param t the type to consider.
9216 ///
9217 /// @return the declaration for the type to return.
9218 decl_base*
get_type_declaration(type_base * t)9219 get_type_declaration(type_base* t)
9220 {return dynamic_cast<decl_base*>(t);}
9221
9222 /// Get the declaration for a given type.
9223 ///
9224 /// @param t the type to consider.
9225 ///
9226 /// @return the declaration for the type to return.
9227 decl_base_sptr
get_type_declaration(const type_base_sptr t)9228 get_type_declaration(const type_base_sptr t)
9229 {return dynamic_pointer_cast<decl_base>(t);}
9230
9231 /// Test if two types are equal modulo a typedef.
9232 ///
9233 /// Type A and B are compatible if
9234 ///
9235 /// - A and B are equal
9236 /// - or if one type is a typedef of the other one.
9237 ///
9238 /// @param type1 the first type to consider.
9239 ///
9240 /// @param type2 the second type to consider.
9241 ///
9242 /// @return true iff @p type1 and @p type2 are compatible.
9243 bool
types_are_compatible(const type_base_sptr type1,const type_base_sptr type2)9244 types_are_compatible(const type_base_sptr type1,
9245 const type_base_sptr type2)
9246 {
9247 if (!type1 || !type2)
9248 return false;
9249
9250 if (type1 == type2)
9251 return true;
9252
9253 // Normally we should strip typedefs entirely, but this is
9254 // potentially costly, especially on binaries with huge changesets
9255 // like the Linux Kernel. So we just get the leaf types for now.
9256 //
9257 // Maybe there should be an option by which users accepts to pay the
9258 // CPU usage toll in exchange for finer filtering?
9259
9260 // type_base_sptr t1 = strip_typedef(type1);
9261 // type_base_sptr t2 = strip_typedef(type2);
9262
9263 type_base_sptr t1 = peel_typedef_type(type1);
9264 type_base_sptr t2 = peel_typedef_type(type2);
9265
9266 return t1 == t2;
9267 }
9268
9269 /// Test if two types are equal modulo a typedef.
9270 ///
9271 /// Type A and B are compatible if
9272 ///
9273 /// - A and B are equal
9274 /// - or if one type is a typedef of the other one.
9275 ///
9276 /// @param type1 the declaration of the first type to consider.
9277 ///
9278 /// @param type2 the declaration of the second type to consider.
9279 ///
9280 /// @return true iff @p type1 and @p type2 are compatible.
9281 bool
types_are_compatible(const decl_base_sptr d1,const decl_base_sptr d2)9282 types_are_compatible(const decl_base_sptr d1,
9283 const decl_base_sptr d2)
9284 {return types_are_compatible(is_type(d1), is_type(d2));}
9285
9286 /// Return the translation unit a declaration belongs to.
9287 ///
9288 /// @param decl the declaration to consider.
9289 ///
9290 /// @return the resulting translation unit, or null if the decl is not
9291 /// yet added to a translation unit.
9292 translation_unit*
get_translation_unit(const decl_base & decl)9293 get_translation_unit(const decl_base& decl)
9294 {return const_cast<translation_unit*>(decl.get_translation_unit());}
9295
9296 /// Return the translation unit a declaration belongs to.
9297 ///
9298 /// @param decl the declaration to consider.
9299 ///
9300 /// @return the resulting translation unit, or null if the decl is not
9301 /// yet added to a translation unit.
9302 translation_unit*
get_translation_unit(const decl_base * decl)9303 get_translation_unit(const decl_base* decl)
9304 {return decl ? get_translation_unit(*decl) : 0;}
9305
9306 /// Return the translation unit a declaration belongs to.
9307 ///
9308 /// @param decl the declaration to consider.
9309 ///
9310 /// @return the resulting translation unit, or null if the decl is not
9311 /// yet added to a translation unit.
9312 translation_unit*
get_translation_unit(const shared_ptr<decl_base> decl)9313 get_translation_unit(const shared_ptr<decl_base> decl)
9314 {return get_translation_unit(decl.get());}
9315
9316 /// Tests whether if a given scope is the global scope.
9317 ///
9318 /// @param scope the scope to consider.
9319 ///
9320 /// @return true iff the current scope is the global one.
9321 bool
is_global_scope(const scope_decl & scope)9322 is_global_scope(const scope_decl& scope)
9323 {return !!dynamic_cast<const global_scope*>(&scope);}
9324
9325 /// Tests whether if a given scope is the global scope.
9326 ///
9327 /// @param scope the scope to consider.
9328 ///
9329 /// @return the @ref global_scope* representing the scope @p scope or
9330 /// 0 if @p scope is not a global scope.
9331 const global_scope*
is_global_scope(const scope_decl * scope)9332 is_global_scope(const scope_decl* scope)
9333 {return dynamic_cast<const global_scope*>(scope);}
9334
9335 /// Tests whether if a given scope is the global scope.
9336 ///
9337 /// @param scope the scope to consider.
9338 ///
9339 /// @return true iff the current scope is the global one.
9340 bool
is_global_scope(const shared_ptr<scope_decl> scope)9341 is_global_scope(const shared_ptr<scope_decl>scope)
9342 {return is_global_scope(scope.get());}
9343
9344 /// Tests whether a given declaration is at global scope.
9345 ///
9346 /// @param decl the decl to consider.
9347 ///
9348 /// @return true iff decl is at global scope.
9349 bool
is_at_global_scope(const decl_base & decl)9350 is_at_global_scope(const decl_base& decl)
9351 {return (is_global_scope(decl.get_scope()));}
9352
9353 /// Tests whether a given declaration is at global scope.
9354 ///
9355 /// @param decl the decl to consider.
9356 ///
9357 /// @return true iff decl is at global scope.
9358 bool
is_at_global_scope(const decl_base_sptr decl)9359 is_at_global_scope(const decl_base_sptr decl)
9360 {return (decl && is_global_scope(decl->get_scope()));}
9361
9362 /// Tests whether a given declaration is at global scope.
9363 ///
9364 /// @param decl the decl to consider.
9365 ///
9366 /// @return true iff decl is at global scope.
9367 bool
is_at_global_scope(const decl_base * decl)9368 is_at_global_scope(const decl_base* decl)
9369 {return is_at_global_scope(*decl);}
9370
9371 /// Tests whether a given decl is at class scope.
9372 ///
9373 /// @param decl the decl to consider.
9374 ///
9375 /// @return true iff decl is at class scope.
9376 class_or_union*
is_at_class_scope(const decl_base_sptr decl)9377 is_at_class_scope(const decl_base_sptr decl)
9378 {return is_at_class_scope(decl.get());}
9379
9380 /// Tests whether a given decl is at class scope.
9381 ///
9382 /// @param decl the decl to consider.
9383 ///
9384 /// @return true iff decl is at class scope.
9385 class_or_union*
is_at_class_scope(const decl_base * decl)9386 is_at_class_scope(const decl_base* decl)
9387 {
9388 if (!decl)
9389 return 0;
9390
9391 return is_at_class_scope(*decl);
9392 }
9393
9394 /// Tests whether a given decl is at class scope.
9395 ///
9396 /// @param decl the decl to consider.
9397 ///
9398 /// @return true iff decl is at class scope.
9399 class_or_union*
is_at_class_scope(const decl_base & decl)9400 is_at_class_scope(const decl_base& decl)
9401 {
9402 scope_decl* scope = decl.get_scope();
9403 if (class_or_union* cl = is_class_type(scope))
9404 return cl;
9405 if (class_or_union* cl = is_union_type(scope))
9406 return cl;
9407 return 0;
9408 }
9409
9410 /// Find a data member inside an anonymous data member.
9411 ///
9412 /// An anonymous data member has a type which is a class or union.
9413 /// This function looks for a data member inside the type of that
9414 /// anonymous data member.
9415 ///
9416 /// @param anon_dm the anonymous data member to consider.
9417 ///
9418 /// @param name the name of the data member to look for.
9419 var_decl_sptr
find_data_member_from_anonymous_data_member(const var_decl_sptr & anon_dm,const string & name)9420 find_data_member_from_anonymous_data_member(const var_decl_sptr& anon_dm,
9421 const string& name)
9422 {
9423 const class_or_union* containing_class_or_union =
9424 anonymous_data_member_to_class_or_union(anon_dm.get());
9425
9426 if (!containing_class_or_union)
9427 return var_decl_sptr();
9428
9429 var_decl_sptr result = containing_class_or_union->find_data_member(name);
9430 return result;
9431 }
9432
9433 /// Tests whether a given decl is at template scope.
9434 ///
9435 /// Note that only template parameters , types that are compositions,
9436 /// and template patterns (function or class) can be at template scope.
9437 ///
9438 /// @param decl the decl to consider.
9439 ///
9440 /// @return true iff the decl is at template scope.
9441 bool
is_at_template_scope(const shared_ptr<decl_base> decl)9442 is_at_template_scope(const shared_ptr<decl_base> decl)
9443 {return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
9444
9445 /// Tests whether a decl is a template parameter.
9446 ///
9447 /// @param decl the decl to consider.
9448 ///
9449 /// @return true iff decl is a template parameter.
9450 bool
is_template_parameter(const shared_ptr<decl_base> decl)9451 is_template_parameter(const shared_ptr<decl_base> decl)
9452 {
9453 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
9454 || dynamic_pointer_cast<non_type_tparameter>(decl)
9455 || dynamic_pointer_cast<template_tparameter>(decl)));
9456 }
9457
9458 /// Test whether a declaration is a @ref function_decl.
9459 ///
9460 /// @param d the declaration to test for.
9461 ///
9462 /// @return a shared pointer to @ref function_decl if @p d is a @ref
9463 /// function_decl. Otherwise, a nil shared pointer.
9464 function_decl*
is_function_decl(const type_or_decl_base * d)9465 is_function_decl(const type_or_decl_base* d)
9466 {return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
9467
9468 /// Test whether a declaration is a @ref function_decl.
9469 ///
9470 /// @param d the declaration to test for.
9471 ///
9472 /// @return true if @p d is a function_decl.
9473 bool
is_function_decl(const type_or_decl_base & d)9474 is_function_decl(const type_or_decl_base& d)
9475 {return is_function_decl(&d);}
9476
9477 /// Test whether a declaration is a @ref function_decl.
9478 ///
9479 /// @param d the declaration to test for.
9480 ///
9481 /// @return a shared pointer to @ref function_decl if @p d is a @ref
9482 /// function_decl. Otherwise, a nil shared pointer.
9483 function_decl_sptr
is_function_decl(const type_or_decl_base_sptr & d)9484 is_function_decl(const type_or_decl_base_sptr& d)
9485 {return dynamic_pointer_cast<function_decl>(d);}
9486
9487 /// Test whether a declaration is a @ref function_decl.
9488 ///
9489 /// @param d the declaration to test for.
9490 ///
9491 /// @return a pointer to @ref function_decl if @p d is a @ref
9492 /// function_decl. Otherwise, a nil shared pointer.
9493 function_decl::parameter*
is_function_parameter(const type_or_decl_base * tod)9494 is_function_parameter(const type_or_decl_base* tod)
9495 {
9496 return dynamic_cast<function_decl::parameter*>
9497 (const_cast<type_or_decl_base*>(tod));
9498 }
9499
9500 /// Test whether an ABI artifact is a @ref function_decl.
9501 ///
9502 /// @param tod the declaration to test for.
9503 ///
9504 /// @return a pointer to @ref function_decl if @p d is a @ref
9505 /// function_decl. Otherwise, a nil shared pointer.
9506 function_decl::parameter_sptr
is_function_parameter(const type_or_decl_base_sptr tod)9507 is_function_parameter(const type_or_decl_base_sptr tod)
9508 {return dynamic_pointer_cast<function_decl::parameter>(tod);}
9509
9510 /// Test if an ABI artifact is a declaration.
9511 ///
9512 /// @param d the artifact to consider.
9513 ///
9514 /// @param return the declaration sub-object of @p d if it's a
9515 /// declaration, or NULL if it is not.
9516 decl_base*
is_decl(const type_or_decl_base * d)9517 is_decl(const type_or_decl_base* d)
9518 {
9519 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
9520 {
9521 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
9522 // The artifact is a decl-only (like a function or a
9523 // variable). That is, it's not a type that also has a
9524 // declaration. In this case, we are in the fast path and we
9525 // have a pointer to the decl sub-object handy. Just return
9526 // it ...
9527 return reinterpret_cast<decl_base*>
9528 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
9529
9530 // ... Otherwise, we are in the slow path, which is that the
9531 // artifact is a type which has a declaration. In that case,
9532 // let's use the slow dynamic_cast because we don't have the
9533 // pointer to the decl sub-object handily present.
9534 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
9535 }
9536 return 0;
9537 }
9538
9539 /// Test if an ABI artifact is a declaration.
9540 ///
9541 /// @param d the artifact to consider.
9542 ///
9543 /// @param return the declaration sub-object of @p d if it's a
9544 /// declaration, or NULL if it is not.
9545 decl_base_sptr
is_decl(const type_or_decl_base_sptr & d)9546 is_decl(const type_or_decl_base_sptr& d)
9547 {return dynamic_pointer_cast<decl_base>(d);}
9548
9549 /// Test if an ABI artifact is a declaration.
9550 ///
9551 /// This is done using a slow path that uses dynamic_cast.
9552 ///
9553 /// @param d the artifact to consider.
9554 ///
9555 /// @param return the declaration sub-object of @p d if it's a
9556 decl_base*
is_decl_slow(const type_or_decl_base * t)9557 is_decl_slow(const type_or_decl_base* t)
9558 {return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
9559
9560 /// Test if an ABI artifact is a declaration.
9561 ///
9562 /// This is done using a slow path that uses dynamic_cast.
9563 ///
9564 /// @param d the artifact to consider.
9565 ///
9566 /// @param return the declaration sub-object of @p d if it's a
9567 decl_base_sptr
is_decl_slow(const type_or_decl_base_sptr & t)9568 is_decl_slow(const type_or_decl_base_sptr& t)
9569 {return dynamic_pointer_cast<decl_base>(t);}
9570
9571 /// Test whether a declaration is a type.
9572 ///
9573 /// @param d the IR artefact to test for.
9574 ///
9575 /// @return true if the artifact is a type, false otherwise.
9576 bool
is_type(const type_or_decl_base & tod)9577 is_type(const type_or_decl_base& tod)
9578 {
9579 if (dynamic_cast<const type_base*>(&tod))
9580 return true;
9581 return false;
9582 }
9583
9584 /// Test whether a declaration is a type.
9585 ///
9586 /// @param d the IR artefact to test for.
9587 ///
9588 /// @return true if the artifact is a type, false otherwise.
9589 type_base*
is_type(const type_or_decl_base * t)9590 is_type(const type_or_decl_base* t)
9591 {
9592 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
9593 return reinterpret_cast<type_base*>
9594 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
9595
9596 return 0;
9597 }
9598
9599 /// Test whether a declaration is a type.
9600 ///
9601 /// @param d the IR artefact to test for.
9602 ///
9603 /// @return true if the artifact is a type, false otherwise.
9604 type_base_sptr
is_type(const type_or_decl_base_sptr & tod)9605 is_type(const type_or_decl_base_sptr& tod)
9606 {return dynamic_pointer_cast<type_base>(tod);}
9607
9608 /// Test whether a declaration is a type.
9609 ///
9610 /// @param d the declaration to test for.
9611 ///
9612 /// @return true if the declaration is a type, false otherwise.
9613
9614 /// Test if a given type is anonymous.
9615 ///
9616 /// Note that this function considers that an anonymous class that is
9617 /// named by a typedef is not anonymous anymore. This is the C idiom:
9618 ///
9619 /// typedef struct {int member;} s_type;
9620 ///
9621 /// The typedef s_type becomes the name of the originally anonymous
9622 /// struct.
9623 ///
9624 /// @param t the type to consider.
9625 ///
9626 /// @return true iff @p t is anonymous.
9627 bool
is_anonymous_type(const type_base * t)9628 is_anonymous_type(const type_base* t)
9629 {
9630 const decl_base* d = get_type_declaration(t);
9631 if (d)
9632 if (d->get_is_anonymous())
9633 {
9634 if (class_or_union *cou = is_class_or_union_type(t))
9635 {
9636 // An anonymous class that is named by a typedef is not
9637 // considered anonymous anymore.
9638 if (!cou->get_naming_typedef())
9639 return true;
9640 }
9641 else
9642 return true;
9643 }
9644 return false;
9645 }
9646
9647 /// Test if a given type is anonymous.
9648 ///
9649 /// @param t the type to consider.
9650 ///
9651 /// @return true iff @p t is anonymous.
9652 bool
is_anonymous_type(const type_base_sptr & t)9653 is_anonymous_type(const type_base_sptr& t)
9654 {return is_anonymous_type(t.get());}
9655
9656 /// Test whether a type is a type_decl (a builtin type).
9657 ///
9658 /// @return the type_decl* for @t if it's type_decl, otherwise, return
9659 /// nil.
9660 const type_decl*
is_type_decl(const type_or_decl_base * t)9661 is_type_decl(const type_or_decl_base* t)
9662 {return dynamic_cast<const type_decl*>(t);}
9663
9664 /// Test whether a type is a type_decl (a builtin type).
9665 ///
9666 /// @return the type_decl_sptr for @t if it's type_decl, otherwise,
9667 /// return nil.
9668 type_decl_sptr
is_type_decl(const type_or_decl_base_sptr & t)9669 is_type_decl(const type_or_decl_base_sptr& t)
9670 {return dynamic_pointer_cast<type_decl>(t);}
9671
9672 /// Test whether a type is a typedef.
9673 ///
9674 /// @param t the type to test for.
9675 ///
9676 /// @return the typedef declaration of the @p t, or NULL if it's not a
9677 /// typedef.
9678 typedef_decl_sptr
is_typedef(const type_or_decl_base_sptr t)9679 is_typedef(const type_or_decl_base_sptr t)
9680 {return dynamic_pointer_cast<typedef_decl>(t);}
9681
9682 /// Test whether a type is a typedef.
9683 ///
9684 /// @param t the declaration of the type to test for.
9685 ///
9686 /// @return the typedef declaration of the @p t, or NULL if it's not a
9687 /// typedef.
9688 const typedef_decl*
is_typedef(const type_base * t)9689 is_typedef(const type_base* t)
9690 {return dynamic_cast<const typedef_decl*>(t);}
9691
9692 /// Test whether a type is a typedef.
9693 ///
9694 /// @param t the declaration of the type to test for.
9695 ///
9696 /// @return the typedef declaration of the @p t, or NULL if it's not a
9697 /// typedef.
9698 typedef_decl*
is_typedef(type_base * t)9699 is_typedef(type_base* t)
9700 {return dynamic_cast<typedef_decl*>(t);}
9701
9702 /// Test if a type is an enum. This function looks through typedefs.
9703 ///
9704 /// @parm t the type to consider.
9705 ///
9706 /// @return the enum_decl if @p t is an @ref enum_decl or null
9707 /// otherwise.
9708 enum_type_decl_sptr
is_compatible_with_enum_type(const type_base_sptr & t)9709 is_compatible_with_enum_type(const type_base_sptr& t)
9710 {
9711 if (!t)
9712 return enum_type_decl_sptr();
9713
9714 // Normally we should strip typedefs entirely, but this is
9715 // potentially costly, especially on binaries with huge changesets
9716 // like the Linux Kernel. So we just get the leaf types for now.
9717 //
9718 // Maybe there should be an option by which users accepts to pay the
9719 // CPU usage toll in exchange for finer filtering?
9720
9721 // type_base_sptr ty = strip_typedef(t);
9722 type_base_sptr ty = peel_typedef_type(t);;
9723 return is_enum_type(ty);
9724 }
9725
9726 /// Test if a type is an enum. This function looks through typedefs.
9727 ///
9728 /// @parm t the type to consider.
9729 ///
9730 /// @return the enum_decl if @p t is an @ref enum_decl or null
9731 /// otherwise.
9732 enum_type_decl_sptr
is_compatible_with_enum_type(const decl_base_sptr & t)9733 is_compatible_with_enum_type(const decl_base_sptr& t)
9734 {return is_compatible_with_enum_type(is_type(t));}
9735
9736 /// Test if a decl is an enum_type_decl
9737 ///
9738 /// @param d the decl to test for.
9739 ///
9740 /// @return the enum_type_decl* if @p d is an enum, nil otherwise.
9741 const enum_type_decl*
is_enum_type(const type_or_decl_base * d)9742 is_enum_type(const type_or_decl_base* d)
9743 {return dynamic_cast<const enum_type_decl*>(d);}
9744
9745 /// Test if a decl is an enum_type_decl
9746 ///
9747 /// @param d the decl to test for.
9748 ///
9749 /// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
9750 enum_type_decl_sptr
is_enum_type(const type_or_decl_base_sptr & d)9751 is_enum_type(const type_or_decl_base_sptr& d)
9752 {return dynamic_pointer_cast<enum_type_decl>(d);}
9753
9754 /// Test if a type is a class. This function looks through typedefs.
9755 ///
9756 /// @parm t the type to consider.
9757 ///
9758 /// @return the class_decl if @p t is a class_decl or null otherwise.
9759 class_decl_sptr
is_compatible_with_class_type(const type_base_sptr & t)9760 is_compatible_with_class_type(const type_base_sptr& t)
9761 {
9762 if (!t)
9763 return class_decl_sptr();
9764
9765 // Normally we should strip typedefs entirely, but this is
9766 // potentially costly, especially on binaries with huge changesets
9767 // like the Linux Kernel. So we just get the leaf types for now.
9768 //
9769 // Maybe there should be an option by which users accepts to pay the
9770 // CPU usage toll in exchange for finer filtering?
9771
9772 // type_base_sptr ty = strip_typedef(t);
9773 type_base_sptr ty = peel_typedef_type(t);
9774 return is_class_type(ty);
9775 }
9776
9777 /// Test if a type is a class. This function looks through typedefs.
9778 ///
9779 /// @parm t the type to consider.
9780 ///
9781 /// @return the class_decl if @p t is a class_decl or null otherwise.
9782 class_decl_sptr
is_compatible_with_class_type(const decl_base_sptr & t)9783 is_compatible_with_class_type(const decl_base_sptr& t)
9784 {return is_compatible_with_class_type(is_type(t));}
9785
9786 /// Test whether a type is a class.
9787 ///
9788 /// @parm t the type to consider.
9789 ///
9790 /// @return true iff @p t is a class_decl.
9791 bool
is_class_type(const type_or_decl_base & t)9792 is_class_type(const type_or_decl_base& t)
9793 {return is_class_type(&t);}
9794
9795 /// Test whether a type is a class.
9796 ///
9797 /// @parm t the type to consider.
9798 ///
9799 /// @return the class_decl if @p t is a class_decl or null otherwise.
9800 class_decl*
is_class_type(const type_or_decl_base * t)9801 is_class_type(const type_or_decl_base* t)
9802 {
9803 if (!t)
9804 return 0;
9805
9806 if (t->kind() & type_or_decl_base::CLASS_TYPE)
9807 return reinterpret_cast<class_decl*>
9808 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
9809
9810 return 0;
9811 }
9812
9813 /// Test whether a type is a class.
9814 ///
9815 /// @parm t the type to consider.
9816 ///
9817 /// @return the class_decl if @p t is a class_decl or null otherwise.
9818 class_decl_sptr
is_class_type(const type_or_decl_base_sptr & d)9819 is_class_type(const type_or_decl_base_sptr& d)
9820 {return dynamic_pointer_cast<class_decl>(d);}
9821
9822
9823 /// Test wheter a type is a declaration-only class.
9824 ///
9825 /// @param t the type to considier.
9826 ///
9827 /// @return true iff @p t is a declaration-only class.
9828 bool
is_declaration_only_class_or_union_type(const type_base * t)9829 is_declaration_only_class_or_union_type(const type_base *t)
9830 {
9831 if (const class_or_union *klass = is_class_or_union_type(t))
9832 return klass->get_is_declaration_only();
9833 return false;
9834 }
9835
9836 /// Test wheter a type is a declaration-only class.
9837 ///
9838 /// @param t the type to considier.
9839 ///
9840 /// @return true iff @p t is a declaration-only class.
9841 bool
is_declaration_only_class_type(const type_base_sptr & t)9842 is_declaration_only_class_type(const type_base_sptr& t)
9843 {return is_declaration_only_class_or_union_type(t.get());}
9844
9845 /// Test if a type is a @ref class_or_union.
9846 ///
9847 /// @param t the type to consider.
9848 ///
9849 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
9850 /// nil otherwise.
9851 class_or_union*
is_class_or_union_type(const type_or_decl_base * t)9852 is_class_or_union_type(const type_or_decl_base* t)
9853 {return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
9854
9855 /// Test if a type is a @ref class_or_union.
9856 ///
9857 /// @param t the type to consider.
9858 ///
9859 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
9860 /// nil otherwise.
9861 shared_ptr<class_or_union>
is_class_or_union_type(const shared_ptr<type_or_decl_base> & t)9862 is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
9863 {return dynamic_pointer_cast<class_or_union>(t);}
9864
9865 /// Test if a type is a @ref union_decl.
9866 ///
9867 /// @param t the type to consider.
9868 ///
9869 /// @return true iff @p t is a union_decl.
9870 bool
is_union_type(const type_or_decl_base & t)9871 is_union_type(const type_or_decl_base& t)
9872 {return is_union_type(&t);}
9873
9874 /// Test if a type is a @ref union_decl.
9875 ///
9876 /// @param t the type to consider.
9877 ///
9878 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
9879 /// otherwise.
9880 union_decl*
is_union_type(const type_or_decl_base * t)9881 is_union_type(const type_or_decl_base* t)
9882 {return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
9883
9884 /// Test if a type is a @ref union_decl.
9885 ///
9886 /// @param t the type to consider.
9887 ///
9888 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
9889 /// otherwise.
9890 union_decl_sptr
is_union_type(const shared_ptr<type_or_decl_base> & t)9891 is_union_type(const shared_ptr<type_or_decl_base>& t)
9892 {return dynamic_pointer_cast<union_decl>(t);}
9893
9894 /// Test whether a type is a pointer_type_def.
9895 ///
9896 /// @param t the type to test.
9897 ///
9898 /// @return the @ref pointer_type_def_sptr if @p t is a
9899 /// pointer_type_def, null otherwise.
9900 pointer_type_def*
is_pointer_type(type_or_decl_base * t)9901 is_pointer_type(type_or_decl_base* t)
9902 {
9903 if (!t)
9904 return 0;
9905
9906 if (t->kind() & type_or_decl_base::POINTER_TYPE)
9907 return reinterpret_cast<pointer_type_def*>
9908 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
9909
9910 return 0;
9911 }
9912
9913 /// Test whether a type is a pointer_type_def.
9914 ///
9915 /// @param t the type to test.
9916 ///
9917 /// @return the @ref pointer_type_def_sptr if @p t is a
9918 /// pointer_type_def, null otherwise.
9919 const pointer_type_def*
is_pointer_type(const type_or_decl_base * t)9920 is_pointer_type(const type_or_decl_base* t)
9921 {
9922 return is_pointer_type(const_cast<type_or_decl_base*>(t));
9923 }
9924
9925 /// Test whether a type is a pointer_type_def.
9926 ///
9927 /// @param t the type to test.
9928 ///
9929 /// @return the @ref pointer_type_def_sptr if @p t is a
9930 /// pointer_type_def, null otherwise.
9931 pointer_type_def_sptr
is_pointer_type(const type_or_decl_base_sptr & t)9932 is_pointer_type(const type_or_decl_base_sptr &t)
9933 {return dynamic_pointer_cast<pointer_type_def>(t);}
9934
9935 /// Test whether a type is a reference_type_def.
9936 ///
9937 /// @param t the type to test.
9938 ///
9939 /// @return the @ref reference_type_def_sptr if @p t is a
9940 /// reference_type_def, null otherwise.
9941 reference_type_def*
is_reference_type(type_or_decl_base * t)9942 is_reference_type(type_or_decl_base* t)
9943 {return dynamic_cast<reference_type_def*>(t);}
9944
9945 /// Test whether a type is a reference_type_def.
9946 ///
9947 /// @param t the type to test.
9948 ///
9949 /// @return the @ref reference_type_def_sptr if @p t is a
9950 /// reference_type_def, null otherwise.
9951 const reference_type_def*
is_reference_type(const type_or_decl_base * t)9952 is_reference_type(const type_or_decl_base* t)
9953 {return dynamic_cast<const reference_type_def*>(t);}
9954
9955 /// Test whether a type is a reference_type_def.
9956 ///
9957 /// @param t the type to test.
9958 ///
9959 /// @return the @ref reference_type_def_sptr if @p t is a
9960 /// reference_type_def, null otherwise.
9961 reference_type_def_sptr
is_reference_type(const type_or_decl_base_sptr & t)9962 is_reference_type(const type_or_decl_base_sptr& t)
9963 {return dynamic_pointer_cast<reference_type_def>(t);}
9964
9965 /// Test if a type is a pointer to void type.
9966 ///
9967 /// Note that this looks trough typedefs or CV qualifiers to look for
9968 /// the void pointer.
9969 ///
9970 /// @param type the type to consider.
9971 ///
9972 /// @return the actual void pointer if @p is a void pointer or NULL if
9973 /// it's not.
9974 const type_base*
is_void_pointer_type(const type_base * type)9975 is_void_pointer_type(const type_base* type)
9976 {
9977 type = peel_qualified_or_typedef_type(type);
9978
9979 const pointer_type_def * t = is_pointer_type(type);
9980 if (!t)
9981 return 0;
9982
9983 // Look through typedefs in the pointed-to type as well.
9984 type_base * ty = t->get_pointed_to_type().get();
9985 ty = peel_qualified_or_typedef_type(ty);
9986 if (ty->get_environment()->is_void_type(ty))
9987 return ty;
9988
9989 return 0;
9990 }
9991
9992 /// Test whether a type is a reference_type_def.
9993 ///
9994 /// @param t the type to test.
9995 ///
9996 /// @return the @ref reference_type_def_sptr if @p t is a
9997 /// reference_type_def, null otherwise.
9998 qualified_type_def*
is_qualified_type(const type_or_decl_base * t)9999 is_qualified_type(const type_or_decl_base* t)
10000 {return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
10001
10002 /// Test whether a type is a qualified_type_def.
10003 ///
10004 /// @param t the type to test.
10005 ///
10006 /// @return the @ref qualified_type_def_sptr if @p t is a
10007 /// qualified_type_def, null otherwise.
10008 qualified_type_def_sptr
is_qualified_type(const type_or_decl_base_sptr & t)10009 is_qualified_type(const type_or_decl_base_sptr& t)
10010 {return dynamic_pointer_cast<qualified_type_def>(t);}
10011
10012 /// Test whether a type is a function_type.
10013 ///
10014 /// @param t the type to test.
10015 ///
10016 /// @return the @ref function_type_sptr if @p t is a
10017 /// function_type, null otherwise.
10018 function_type_sptr
is_function_type(const type_or_decl_base_sptr & t)10019 is_function_type(const type_or_decl_base_sptr& t)
10020 {return dynamic_pointer_cast<function_type>(t);}
10021
10022 /// Test whether a type is a function_type.
10023 ///
10024 /// @param t the type to test.
10025 ///
10026 /// @return the @ref function_type_sptr if @p t is a
10027 /// function_type, null otherwise.
10028 function_type*
is_function_type(type_or_decl_base * t)10029 is_function_type(type_or_decl_base* t)
10030 {return dynamic_cast<function_type*>(t);}
10031
10032 /// Test whether a type is a function_type.
10033 ///
10034 /// @param t the type to test.
10035 ///
10036 /// @return the @ref function_type_sptr if @p t is a
10037 /// function_type, null otherwise.
10038 const function_type*
is_function_type(const type_or_decl_base * t)10039 is_function_type(const type_or_decl_base* t)
10040 {return dynamic_cast<const function_type*>(t);}
10041
10042 /// Test whether a type is a method_type.
10043 ///
10044 /// @param t the type to test.
10045 ///
10046 /// @return the @ref method_type_sptr if @p t is a
10047 /// method_type, null otherwise.
10048 method_type_sptr
is_method_type(const type_or_decl_base_sptr & t)10049 is_method_type(const type_or_decl_base_sptr& t)
10050 {return dynamic_pointer_cast<method_type>(t);}
10051
10052 /// Test whether a type is a method_type.
10053 ///
10054 /// @param t the type to test.
10055 ///
10056 /// @return the @ref method_type_sptr if @p t is a
10057 /// method_type, null otherwise.
10058 const method_type*
is_method_type(const type_or_decl_base * t)10059 is_method_type(const type_or_decl_base* t)
10060 {return dynamic_cast<const method_type*>(t);}
10061
10062 /// Test whether a type is a method_type.
10063 ///
10064 /// @param t the type to test.
10065 ///
10066 /// @return the @ref method_type_sptr if @p t is a
10067 /// method_type, null otherwise.
10068 method_type*
is_method_type(type_or_decl_base * t)10069 is_method_type(type_or_decl_base* t)
10070 {return dynamic_cast<method_type*>(t);}
10071
10072 /// If a class (or union) is a decl-only class, get its definition.
10073 /// Otherwise, just return the initial class.
10074 ///
10075 /// @param the_class the class (or union) to consider.
10076 ///
10077 /// @return either the definition of the class, or the class itself.
10078 class_or_union*
look_through_decl_only_class(class_or_union * the_class)10079 look_through_decl_only_class(class_or_union* the_class)
10080 {return is_class_or_union_type(look_through_decl_only(the_class));}
10081
10082 /// If a class (or union) is a decl-only class, get its definition.
10083 /// Otherwise, just return the initial class.
10084 ///
10085 /// @param klass the class (or union) to consider.
10086 ///
10087 /// @return either the definition of the class, or the class itself.
10088 class_or_union_sptr
look_through_decl_only_class(class_or_union_sptr klass)10089 look_through_decl_only_class(class_or_union_sptr klass)
10090 {return is_class_or_union_type(look_through_decl_only(klass));}
10091
10092 /// If an enum is a decl-only enum, get its definition.
10093 /// Otherwise, just return the initial enum.
10094 ///
10095 /// @param enom the enum to consider.
10096 ///
10097 /// @return either the definition of the enum, or the enum itself.
10098 enum_type_decl_sptr
look_through_decl_only_enum(enum_type_decl_sptr enom)10099 look_through_decl_only_enum(enum_type_decl_sptr enom)
10100 {return is_enum_type(look_through_decl_only(enom));}
10101
10102 /// If a decl is decl-only enum, get its definition. Otherwise, just
10103 /// return the initial decl.
10104 ///
10105 /// @param d the decl to consider.
10106 ///
10107 /// @return either the definition of the enum, or the decl itself.
10108 decl_base*
look_through_decl_only(decl_base * d)10109 look_through_decl_only(decl_base* d)
10110 {
10111 decl_base_sptr decl(d, sptr_utils::noop_deleter());
10112 return look_through_decl_only(decl).get();
10113 }
10114
10115 /// If a decl is decl-only get its definition. Otherwise, just return nil.
10116 ///
10117 /// @param d the decl to consider.
10118 ///
10119 /// @return either the definition of the decl, or nil.
10120 decl_base_sptr
look_through_decl_only(decl_base_sptr d)10121 look_through_decl_only(decl_base_sptr d)
10122 {
10123 if (!d)
10124 return d;
10125
10126 while (d->get_is_declaration_only())
10127 {
10128 decl_base_sptr definition = d->get_definition_of_declaration();
10129 if (!definition)
10130 break;
10131 d = definition;
10132 }
10133
10134 return d;
10135 }
10136
10137 /// Tests if a declaration is a variable declaration.
10138 ///
10139 /// @param decl the decl to test.
10140 ///
10141 /// @return the var_decl_sptr iff decl is a variable declaration; nil
10142 /// otherwise.
10143 var_decl*
is_var_decl(const type_or_decl_base * tod)10144 is_var_decl(const type_or_decl_base* tod)
10145 {return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
10146
10147 /// Tests if a declaration is a variable declaration.
10148 ///
10149 /// @param decl the decl to test.
10150 ///
10151 /// @return the var_decl_sptr iff decl is a variable declaration; nil
10152 /// otherwise.
10153 var_decl_sptr
is_var_decl(const type_or_decl_base_sptr & decl)10154 is_var_decl(const type_or_decl_base_sptr& decl)
10155 {return dynamic_pointer_cast<var_decl>(decl);}
10156
10157 /// Tests if a declaration is a namespace declaration.
10158 ///
10159 /// @param d the decalration to consider.
10160 ///
10161 /// @return the namespace declaration if @p d is a namespace.
10162 namespace_decl_sptr
is_namespace(const decl_base_sptr & d)10163 is_namespace(const decl_base_sptr& d)
10164 {return dynamic_pointer_cast<namespace_decl>(d);}
10165
10166 /// Tests if a declaration is a namespace declaration.
10167 ///
10168 /// @param d the decalration to consider.
10169 ///
10170 /// @return the namespace declaration if @p d is a namespace.
10171 namespace_decl*
is_namespace(const decl_base * d)10172 is_namespace(const decl_base* d)
10173 {return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
10174
10175 /// Tests whether a decl is a template parameter composition type.
10176 ///
10177 /// @param decl the declaration to consider.
10178 ///
10179 /// @return true iff decl is a template parameter composition type.
10180 bool
is_template_parm_composition_type(const shared_ptr<decl_base> decl)10181 is_template_parm_composition_type(const shared_ptr<decl_base> decl)
10182 {
10183 return (decl
10184 && is_at_template_scope(decl)
10185 && is_type(decl)
10186 && !is_template_parameter(decl));
10187 }
10188
10189 /// Test whether a decl is the pattern of a function template.
10190 ///
10191 /// @param decl the decl to consider.
10192 ///
10193 /// @return true iff decl is the pattern of a function template.
10194 bool
is_function_template_pattern(const shared_ptr<decl_base> decl)10195 is_function_template_pattern(const shared_ptr<decl_base> decl)
10196 {
10197 return (decl
10198 && dynamic_pointer_cast<function_decl>(decl)
10199 && dynamic_cast<template_decl*>(decl->get_scope()));
10200 }
10201
10202 /// Test if a type is an array_type_def.
10203 ///
10204 /// @param type the type to consider.
10205 ///
10206 /// @return true iff @p type is an array_type_def.
10207 array_type_def*
is_array_type(const type_or_decl_base * type)10208 is_array_type(const type_or_decl_base* type)
10209 {return dynamic_cast<array_type_def*>(const_cast<type_or_decl_base*>(type));}
10210
10211 /// Test if a type is an array_type_def.
10212 ///
10213 /// @param type the type to consider.
10214 ///
10215 /// @return true iff @p type is an array_type_def.
10216 array_type_def_sptr
is_array_type(const type_or_decl_base_sptr & type)10217 is_array_type(const type_or_decl_base_sptr& type)
10218 {return dynamic_pointer_cast<array_type_def>(type);}
10219
10220 /// Tests if the element of a given array is a qualified type.
10221 ///
10222 /// @param array the array type to consider.
10223 ///
10224 /// @return the qualified element of the array iff it's a qualified
10225 /// type. Otherwise, return a nil object.
10226 qualified_type_def_sptr
is_array_of_qualified_element(const array_type_def_sptr & array)10227 is_array_of_qualified_element(const array_type_def_sptr& array)
10228 {
10229 if (!array)
10230 return qualified_type_def_sptr();
10231
10232 return is_qualified_type(array->get_element_type());
10233 }
10234
10235 /// Test if an array type is an array to a qualified element type.
10236 ///
10237 /// @param type the array type to consider.
10238 ///
10239 /// @return true the array @p type iff it's an array to a qualified
10240 /// element type.
10241 array_type_def_sptr
is_array_of_qualified_element(const type_base_sptr & type)10242 is_array_of_qualified_element(const type_base_sptr& type)
10243 {
10244 if (array_type_def_sptr array = is_array_type(type))
10245 if (is_array_of_qualified_element(array))
10246 return array;
10247
10248 return array_type_def_sptr();
10249 }
10250
10251 /// Test if a type is a typedef of an array.
10252 ///
10253 /// Note that the function looks through qualified and typedefs types
10254 /// of the underlying type of the current typedef. In other words, if
10255 /// we are looking at a typedef of a CV-qualified array, or at a
10256 /// typedef of a CV-qualified typedef of an array, this function will
10257 /// still return TRUE.
10258 ///
10259 /// @param t the type to consider.
10260 ///
10261 /// @return true if t is a typedef which underlying type is an array.
10262 /// That array might be either cv-qualified array or a typedef'ed
10263 /// array, or a combination of both.
10264 array_type_def_sptr
is_typedef_of_array(const type_base_sptr & t)10265 is_typedef_of_array(const type_base_sptr& t)
10266 {
10267 array_type_def_sptr result;
10268
10269 if (typedef_decl_sptr typdef = is_typedef(t))
10270 {
10271 type_base_sptr u =
10272 peel_qualified_or_typedef_type(typdef->get_underlying_type());
10273 result = is_array_type(u);
10274 }
10275
10276 return result;
10277 }
10278
10279 /// Test if a type is an array_type_def::subrange_type.
10280 ///
10281 /// @param type the type to consider.
10282 ///
10283 /// @return the array_type_def::subrange_type which @p type is a type
10284 /// of, or nil if it's not of that type.
10285 array_type_def::subrange_type*
is_subrange_type(const type_or_decl_base * type)10286 is_subrange_type(const type_or_decl_base *type)
10287 {
10288 return dynamic_cast<array_type_def::subrange_type*>
10289 (const_cast<type_or_decl_base*>(type));
10290 }
10291
10292 /// Test if a type is an array_type_def::subrange_type.
10293 ///
10294 /// @param type the type to consider.
10295 ///
10296 /// @return the array_type_def::subrange_type which @p type is a type
10297 /// of, or nil if it's not of that type.
10298 array_type_def::subrange_sptr
is_subrange_type(const type_or_decl_base_sptr & type)10299 is_subrange_type(const type_or_decl_base_sptr &type)
10300 {return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
10301
10302 /// Tests whether a decl is a template.
10303 ///
10304 /// @param decl the decl to consider.
10305 ///
10306 /// @return true iff decl is a function template, class template, or
10307 /// template template parameter.
10308 bool
is_template_decl(const shared_ptr<decl_base> decl)10309 is_template_decl(const shared_ptr<decl_base> decl)
10310 {return decl && dynamic_pointer_cast<template_decl>(decl);}
10311
10312 /// This enum describe the kind of entity to lookup, while using the
10313 /// lookup API.
10314 enum lookup_entity_kind
10315 {
10316 LOOKUP_ENTITY_TYPE,
10317 LOOKUP_ENTITY_VAR,
10318 };
10319
10320 /// Find the first relevant delimiter (the "::" string) in a fully
10321 /// qualified C++ type name, starting from a given position. The
10322 /// delimiter returned separates a type name from the name of its
10323 /// context.
10324 ///
10325 /// This is supposed to work correctly on names in cases like this:
10326 ///
10327 /// foo<ns1::name1, ns2::name2>
10328 ///
10329 /// In that case when called with with parameter @p begin set to 0, no
10330 /// delimiter is returned, because the type name in this case is:
10331 /// 'foo<ns1::name1, ns2::name2>'.
10332 ///
10333 /// But in this case:
10334 ///
10335 /// foo<p1, bar::name>::some_type
10336 ///
10337 /// The "::" returned is the one right before 'some_type'.
10338 ///
10339 /// @param fqn the fully qualified name of the type to consider.
10340 ///
10341 /// @param begin the position from which to look for the delimiter.
10342 ///
10343 /// @param delim_pos out parameter. Is set to the position of the
10344 /// delimiter iff the function returned true.
10345 ///
10346 /// @return true iff the function found and returned the delimiter.
10347 static bool
find_next_delim_in_cplus_type(const string & fqn,size_t begin,size_t & delim_pos)10348 find_next_delim_in_cplus_type(const string& fqn,
10349 size_t begin,
10350 size_t& delim_pos)
10351 {
10352 int angle_count = 0;
10353 bool found = false;
10354 size_t i = begin;
10355 for (; i < fqn.size(); ++i)
10356 {
10357 if (fqn[i] == '<')
10358 ++angle_count;
10359 else if (fqn[i] == '>')
10360 --angle_count;
10361 else if (i + 1 < fqn.size()
10362 && !angle_count
10363 && fqn[i] == ':'
10364 && fqn[i+1] == ':')
10365 {
10366 delim_pos = i;
10367 found = true;
10368 break;
10369 }
10370 }
10371 return found;
10372 }
10373
10374 /// Decompose a fully qualified name into the list of its components.
10375 ///
10376 /// @param fqn the fully qualified name to decompose.
10377 ///
10378 /// @param comps the resulting list of component to fill.
10379 void
fqn_to_components(const string & fqn,list<string> & comps)10380 fqn_to_components(const string& fqn,
10381 list<string>& comps)
10382 {
10383 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
10384 do
10385 {
10386 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
10387 comp_end = fqn_size;
10388
10389 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
10390 comps.push_back(comp);
10391
10392 comp_begin = comp_end + 2;
10393 if (comp_begin >= fqn_size)
10394 break;
10395 } while (true);
10396 }
10397
10398 /// Turn a set of qualified name components (that name a type) into a
10399 /// qualified name string.
10400 ///
10401 /// @param comps the name components
10402 ///
10403 /// @return the resulting string, which would be the qualified name of
10404 /// a type.
10405 string
components_to_type_name(const list<string> & comps)10406 components_to_type_name(const list<string>& comps)
10407 {
10408 string result;
10409 for (list<string>::const_iterator c = comps.begin();
10410 c != comps.end();
10411 ++c)
10412 if (c == comps.begin())
10413 result = *c;
10414 else
10415 result += "::" + *c;
10416 return result;
10417 }
10418
10419 /// This predicate returns true if a given container iterator points
10420 /// to the last element of the container, false otherwise.
10421 ///
10422 /// @tparam T the type of the container of the iterator.
10423 ///
10424 /// @param container the container the iterator points into.
10425 ///
10426 /// @param i the iterator to consider.
10427 ///
10428 /// @return true iff the iterator points to the last element of @p
10429 /// container.
10430 template<typename T>
10431 static bool
iterator_is_last(T & container,typename T::const_iterator i)10432 iterator_is_last(T& container,
10433 typename T::const_iterator i)
10434 {
10435 typename T::const_iterator next = i;
10436 ++next;
10437 return (next == container.end());
10438 }
10439
10440 //--------------------------------
10441 // <type and decls lookup stuff>
10442 // ------------------------------
10443
10444 /// Lookup all the type*s* that have a given fully qualified name.
10445 ///
10446 /// @param type_name the fully qualified name of the type to
10447 /// lookup.
10448 ///
10449 /// @param type_map the map to look into.
10450 ///
10451 /// @return the vector containing the types named @p type_name. If
10452 /// the lookup didn't yield any type, then this function returns nil.
10453 static const type_base_wptrs_type*
lookup_types_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)10454 lookup_types_in_map(const interned_string& type_name,
10455 const istring_type_base_wptrs_map_type& type_map)
10456 {
10457 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
10458 if (i != type_map.end())
10459 return &i->second;
10460 return 0;
10461 }
10462
10463 /// Lookup a type (with a given name) in a map that associates a type
10464 /// name to a type. If there are several types with a given name,
10465 /// then return the last of such types, that is, the last one that got
10466 /// registered.
10467 ///
10468 /// @tparam TypeKind the type of the type this function is supposed to
10469 /// return.
10470 ///
10471 /// @param type_name the name of the type to lookup.
10472 ///
10473 /// @param type_map the map in which to look.
10474 ///
10475 /// @return a shared_ptr to the type found. If no type was found or
10476 /// if the type found was not of type @p TypeKind then the function
10477 /// returns nil.
10478 template <class TypeKind>
10479 static shared_ptr<TypeKind>
lookup_type_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)10480 lookup_type_in_map(const interned_string& type_name,
10481 const istring_type_base_wptrs_map_type& type_map)
10482 {
10483 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
10484 if (i != type_map.end())
10485 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
10486 return shared_ptr<TypeKind>();
10487 }
10488
10489 /// Lookup a basic type from a translation unit.
10490 ///
10491 /// This is done by looking the type up in the type map that is
10492 /// maintained in the translation unit. So this is as fast as
10493 /// possible.
10494 ///
10495 /// @param type_name the name of the basic type to look for.
10496 ///
10497 /// @param tu the translation unit to look into.
10498 ///
10499 /// @return the basic type found or nil if no basic type was found.
10500 type_decl_sptr
lookup_basic_type(const interned_string & type_name,const translation_unit & tu)10501 lookup_basic_type(const interned_string& type_name, const translation_unit& tu)
10502 {
10503 return lookup_type_in_map<type_decl>(type_name,
10504 tu.get_types().basic_types());
10505 }
10506
10507 /// Lookup a basic type from a translation unit.
10508 ///
10509 /// This is done by looking the type up in the type map that is
10510 /// maintained in the translation unit. So this is as fast as
10511 /// possible.
10512 ///
10513 /// @param type_name the name of the basic type to look for.
10514 ///
10515 /// @param tu the translation unit to look into.
10516 ///
10517 /// @return the basic type found or nil if no basic type was found.
10518 type_decl_sptr
lookup_basic_type(const string & type_name,const translation_unit & tu)10519 lookup_basic_type(const string& type_name, const translation_unit& tu)
10520 {
10521 const environment* env = tu.get_environment();
10522 ABG_ASSERT(env);
10523
10524 interned_string s = env->intern(type_name);
10525 return lookup_basic_type(s, tu);
10526 }
10527
10528 /// Lookup a class type from a translation unit.
10529 ///
10530 /// This is done by looking the type up in the type map that is
10531 /// maintained in the translation unit. So this is as fast as
10532 /// possible.
10533 ///
10534 /// @param fqn the fully qualified name of the class type node to look
10535 /// up.
10536 ///
10537 /// @param tu the translation unit to perform lookup from.
10538 ///
10539 /// @return the declaration of the class type IR node found, NULL
10540 /// otherwise.
10541 class_decl_sptr
lookup_class_type(const string & fqn,const translation_unit & tu)10542 lookup_class_type(const string& fqn, const translation_unit& tu)
10543 {
10544 const environment* env = tu.get_environment();
10545 ABG_ASSERT(env);
10546
10547 interned_string s = env->intern(fqn);
10548 return lookup_class_type(s, tu);
10549 }
10550
10551 /// Lookup a class type from a translation unit.
10552 ///
10553 /// This is done by looking the type up in the type map that is
10554 /// maintained in the translation unit. So this is as fast as
10555 /// possible.
10556 ///
10557 /// @param type_name the name of the class type to look for.
10558 ///
10559 /// @param tu the translation unit to look into.
10560 ///
10561 /// @return the class type found or nil if no class type was found.
10562 class_decl_sptr
lookup_class_type(const interned_string & type_name,const translation_unit & tu)10563 lookup_class_type(const interned_string& type_name, const translation_unit& tu)
10564 {
10565 return lookup_type_in_map<class_decl>(type_name,
10566 tu.get_types().class_types());
10567 }
10568
10569 /// Lookup a union type from a translation unit.
10570 ///
10571 /// This is done by looking the type up in the type map that is
10572 /// maintained in the translation unit. So this is as fast as
10573 /// possible.
10574 ///
10575 /// @param type_name the name of the union type to look for.
10576 ///
10577 /// @param tu the translation unit to look into.
10578 ///
10579 /// @return the union type found or nil if no union type was found.
10580 union_decl_sptr
lookup_union_type(const interned_string & type_name,const translation_unit & tu)10581 lookup_union_type(const interned_string& type_name, const translation_unit& tu)
10582 {
10583 return lookup_type_in_map<union_decl>(type_name,
10584 tu.get_types().union_types());
10585 }
10586
10587 /// Lookup a union type from a translation unit.
10588 ///
10589 /// This is done by looking the type up in the type map that is
10590 /// maintained in the translation unit. So this is as fast as
10591 /// possible.
10592 ///
10593 /// @param fqn the fully qualified name of the type to lookup.
10594 ///
10595 /// @param tu the translation unit to look into.
10596 ///
10597 /// @return the union type found or nil if no union type was found.
10598 union_decl_sptr
lookup_union_type(const string & fqn,const translation_unit & tu)10599 lookup_union_type(const string& fqn, const translation_unit& tu)
10600 {
10601 const environment* env = tu.get_environment();
10602 ABG_ASSERT(env);
10603
10604 interned_string s = env->intern(fqn);
10605 return lookup_union_type(s, tu);
10606 }
10607
10608 /// Lookup a union type in a given corpus, from its location.
10609 ///
10610 /// @param loc the location of the union type to look for.
10611 ///
10612 /// @param corp the corpus to look it from.
10613 ///
10614 /// @return the resulting union_decl.
10615 union_decl_sptr
lookup_union_type_per_location(const interned_string & loc,const corpus & corp)10616 lookup_union_type_per_location(const interned_string &loc, const corpus& corp)
10617 {
10618 const istring_type_base_wptrs_map_type& m =
10619 corp.get_type_per_loc_map().union_types();
10620 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
10621
10622 return result;
10623 }
10624
10625 /// Lookup a union type in a given corpus, from its location.
10626 ///
10627 /// @param loc the location of the union type to look for.
10628 ///
10629 /// @param corp the corpus to look it from.
10630 ///
10631 /// @return the resulting union_decl.
10632 union_decl_sptr
lookup_union_type_per_location(const string & loc,const corpus & corp)10633 lookup_union_type_per_location(const string& loc, const corpus& corp)
10634 {
10635 const environment* env = corp.get_environment();
10636 ABG_ASSERT(env);
10637
10638 return lookup_union_type_per_location(env->intern(loc), corp);
10639 }
10640
10641 /// Lookup an enum type from a translation unit.
10642 ///
10643 /// This is done by looking the type up in the type map that is
10644 /// maintained in the translation unit. So this is as fast as
10645 /// possible.
10646 ///
10647 /// @param type_name the name of the enum type to look for.
10648 ///
10649 /// @param tu the translation unit to look into.
10650 ///
10651 /// @return the enum type found or nil if no enum type was found.
10652 enum_type_decl_sptr
lookup_enum_type(const interned_string & type_name,const translation_unit & tu)10653 lookup_enum_type(const interned_string& type_name, const translation_unit& tu)
10654 {
10655 return lookup_type_in_map<enum_type_decl>(type_name,
10656 tu.get_types().enum_types());
10657 }
10658
10659 /// Lookup an enum type from a translation unit.
10660 ///
10661 /// This is done by looking the type up in the type map that is
10662 /// maintained in the translation unit. So this is as fast as
10663 /// possible.
10664 ///
10665 /// @param type_name the name of the enum type to look for.
10666 ///
10667 /// @param tu the translation unit to look into.
10668 ///
10669 /// @return the enum type found or nil if no enum type was found.
10670 enum_type_decl_sptr
lookup_enum_type(const string & type_name,const translation_unit & tu)10671 lookup_enum_type(const string& type_name, const translation_unit& tu)
10672 {
10673 const environment* env = tu.get_environment();
10674 ABG_ASSERT(env);
10675
10676 interned_string s = env->intern(type_name);
10677 return lookup_enum_type(s, tu);
10678 }
10679
10680 /// Lookup a typedef type from a translation unit.
10681 ///
10682 /// This is done by looking the type up in the type map that is
10683 /// maintained in the translation unit. So this is as fast as
10684 /// possible.
10685 ///
10686 /// @param type_name the name of the typedef type to look for.
10687 ///
10688 /// @param tu the translation unit to look into.
10689 ///
10690 /// @return the typedef type found or nil if no typedef type was
10691 /// found.
10692 typedef_decl_sptr
lookup_typedef_type(const interned_string & type_name,const translation_unit & tu)10693 lookup_typedef_type(const interned_string& type_name,
10694 const translation_unit& tu)
10695 {
10696 return lookup_type_in_map<typedef_decl>(type_name,
10697 tu.get_types().typedef_types());
10698 }
10699
10700 /// Lookup a typedef type from a translation unit.
10701 ///
10702 /// This is done by looking the type up in the type map that is
10703 /// maintained in the translation unit. So this is as fast as
10704 /// possible.
10705 ///
10706 /// @param type_name the name of the typedef type to look for.
10707 ///
10708 /// @param tu the translation unit to look into.
10709 ///
10710 /// @return the typedef type found or nil if no typedef type was
10711 /// found.
10712 typedef_decl_sptr
lookup_typedef_type(const string & type_name,const translation_unit & tu)10713 lookup_typedef_type(const string& type_name, const translation_unit& tu)
10714 {
10715 const environment* env = tu.get_environment();
10716 ABG_ASSERT(env);
10717
10718 interned_string s = env->intern(type_name);
10719 return lookup_typedef_type(s, tu);
10720 }
10721
10722 /// Lookup a qualified type from a translation unit.
10723 ///
10724 /// This is done by looking the type up in the type map that is
10725 /// maintained in the translation unit. So this is as fast as
10726 /// possible.
10727 ///
10728 /// @param type_name the name of the qualified type to look for.
10729 ///
10730 /// @param tu the translation unit to look into.
10731 ///
10732 /// @return the qualified type found or nil if no qualified type was
10733 /// found.
10734 qualified_type_def_sptr
lookup_qualified_type(const interned_string & type_name,const translation_unit & tu)10735 lookup_qualified_type(const interned_string& type_name,
10736 const translation_unit& tu)
10737 {
10738 const type_maps& m = tu.get_types();
10739 return lookup_type_in_map<qualified_type_def>(type_name,
10740 m.qualified_types());
10741 }
10742
10743 /// Lookup a qualified type from a translation unit.
10744 ///
10745 /// This is done by looking the type up in the type map that is
10746 /// maintained in the translation unit. So this is as fast as
10747 /// possible.
10748 ///
10749 /// @param underlying_type the underying type of the qualified type to
10750 /// look up.
10751 ///
10752 /// @param quals the CV-qualifiers of the qualified type to look for.
10753 ///
10754 /// @param tu the translation unit to look into.
10755 ///
10756 /// @return the qualified type found or nil if no qualified type was
10757 /// found.
10758 qualified_type_def_sptr
lookup_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,const translation_unit & tu)10759 lookup_qualified_type(const type_base_sptr& underlying_type,
10760 qualified_type_def::CV quals,
10761 const translation_unit& tu)
10762 {
10763 interned_string type_name = get_name_of_qualified_type(underlying_type,
10764 quals);
10765 return lookup_qualified_type(type_name, tu);
10766 }
10767
10768 /// Lookup a pointer type from a translation unit.
10769 ///
10770 /// This is done by looking the type up in the type map that is
10771 /// maintained in the translation unit. So this is as fast as
10772 /// possible.
10773 ///
10774 /// @param type_name the name of the pointer type to look for.
10775 ///
10776 /// @param tu the translation unit to look into.
10777 ///
10778 /// @return the pointer type found or nil if no pointer type was
10779 /// found.
10780 pointer_type_def_sptr
lookup_pointer_type(const interned_string & type_name,const translation_unit & tu)10781 lookup_pointer_type(const interned_string& type_name,
10782 const translation_unit& tu)
10783 {
10784 const type_maps& m = tu.get_types();
10785 return lookup_type_in_map<pointer_type_def>(type_name,
10786 m.pointer_types());
10787 }
10788
10789 /// Lookup a pointer type from a translation unit.
10790 ///
10791 /// This is done by looking the type up in the type map that is
10792 /// maintained in the translation unit. So this is as fast as
10793 /// possible.
10794 ///
10795 /// @param type_name the name of the pointer type to look for.
10796 ///
10797 /// @param tu the translation unit to look into.
10798 ///
10799 /// @return the pointer type found or nil if no pointer type was
10800 /// found.
10801 pointer_type_def_sptr
lookup_pointer_type(const string & type_name,const translation_unit & tu)10802 lookup_pointer_type(const string& type_name, const translation_unit& tu)
10803 {
10804 const environment* env = tu.get_environment();
10805 ABG_ASSERT(env);
10806
10807 interned_string s = env->intern(type_name);
10808 return lookup_pointer_type(s, tu);
10809 }
10810
10811 /// Lookup a pointer type from a translation unit.
10812 ///
10813 /// This is done by looking the type up in the type map that is
10814 /// maintained in the translation unit. So this is as fast as
10815 /// possible.
10816 ///
10817 /// @param pointed_to_type the pointed-to-type of the pointer to look for.
10818 ///
10819 /// @param tu the translation unit to look into.
10820 ///
10821 /// @return the pointer type found or nil if no pointer type was
10822 /// found.
10823 pointer_type_def_sptr
lookup_pointer_type(const type_base_sptr & pointed_to_type,const translation_unit & tu)10824 lookup_pointer_type(const type_base_sptr& pointed_to_type,
10825 const translation_unit& tu)
10826 {
10827 interned_string type_name = get_name_of_pointer_to_type(*pointed_to_type);
10828 return lookup_pointer_type(type_name, tu);
10829 }
10830
10831 /// Lookup a reference type from a translation unit.
10832 ///
10833 /// This is done by looking the type up in the type map that is
10834 /// maintained in the translation unit. So this is as fast as
10835 /// possible.
10836 ///
10837 /// @param type_name the name of the reference type to look for.
10838 ///
10839 /// @param tu the translation unit to look into.
10840 ///
10841 /// @return the reference type found or nil if no reference type was
10842 /// found.
10843 reference_type_def_sptr
lookup_reference_type(const interned_string & type_name,const translation_unit & tu)10844 lookup_reference_type(const interned_string& type_name,
10845 const translation_unit& tu)
10846 {
10847 const type_maps& m = tu.get_types();
10848 return lookup_type_in_map<reference_type_def>(type_name,
10849 m.reference_types());
10850 }
10851
10852 /// Lookup a reference type from a translation unit.
10853 ///
10854 /// This is done by looking the type up in the type map that is
10855 /// maintained in the translation unit. So this is as fast as
10856 /// possible.
10857 ///
10858 /// @param pointed_to_type the pointed-to-type of the reference to
10859 /// look up.
10860 ///
10861 /// @param tu the translation unit to look into.
10862 ///
10863 /// @return the reference type found or nil if no reference type was
10864 /// found.
10865 const reference_type_def_sptr
lookup_reference_type(const type_base_sptr & pointed_to_type,bool lvalue_reference,const translation_unit & tu)10866 lookup_reference_type(const type_base_sptr& pointed_to_type,
10867 bool lvalue_reference,
10868 const translation_unit& tu)
10869 {
10870 interned_string type_name =
10871 get_name_of_reference_to_type(*pointed_to_type, lvalue_reference);
10872 return lookup_reference_type(type_name, tu);
10873 }
10874
10875 /// Lookup an array type from a translation unit.
10876 ///
10877 /// This is done by looking the type up in the type map that is
10878 /// maintained in the translation unit. So this is as fast as
10879 /// possible.
10880 ///
10881 /// @param type_name the name of the array type to look for.
10882 ///
10883 /// @param tu the translation unit to look into.
10884 ///
10885 /// @return the array type found or nil if no array type was found.
10886 array_type_def_sptr
lookup_array_type(const interned_string & type_name,const translation_unit & tu)10887 lookup_array_type(const interned_string& type_name,
10888 const translation_unit& tu)
10889 {
10890 const type_maps& m = tu.get_types();
10891 return lookup_type_in_map<array_type_def>(type_name,
10892 m.array_types());
10893 }
10894
10895 /// Lookup a function type from a translation unit.
10896 ///
10897 /// This is done by looking the type up in the type map that is
10898 /// maintained in the translation unit. So this is as fast as
10899 /// possible.
10900 ///
10901 /// @param type_name the name of the type to lookup.
10902 ///
10903 /// @param tu the translation unit to look into.
10904 ///
10905 /// @return the function type found, or NULL of none was found.
10906 function_type_sptr
lookup_function_type(const interned_string & type_name,const translation_unit & tu)10907 lookup_function_type(const interned_string& type_name,
10908 const translation_unit& tu)
10909 {
10910 const type_maps& m = tu.get_types();
10911 return lookup_type_in_map<function_type>(type_name,
10912 m.function_types());
10913 }
10914
10915 /// Lookup a function type from a translation unit.
10916 ///
10917 /// This walks all the function types held by the translation unit and
10918 /// compare their sub-type *names*. If the names match then return
10919 /// the function type found in the translation unit.
10920 ///
10921 /// @param t the function type to look for.
10922 ///
10923 /// @param tu the translation unit to look into.
10924 ///
10925 /// @return the function type found, or NULL of none was found.
10926 function_type_sptr
lookup_function_type(const function_type & t,const translation_unit & tu)10927 lookup_function_type(const function_type& t,
10928 const translation_unit& tu)
10929 {
10930 interned_string type_name = get_type_name(t);
10931 return lookup_function_type(type_name, tu);
10932 }
10933
10934 /// Lookup a function type from a translation unit.
10935 ///
10936 /// This is done by looking the type up in the type map that is
10937 /// maintained in the translation unit. So this is as fast as
10938 /// possible.
10939 ///
10940 /// @param t the function type to look for.
10941 ///
10942 /// @param tu the translation unit to look into.
10943 ///
10944 /// @return the function type found, or NULL of none was found.
10945 function_type_sptr
lookup_function_type(const function_type_sptr & t,const translation_unit & tu)10946 lookup_function_type(const function_type_sptr& t,
10947 const translation_unit& tu)
10948 {return lookup_function_type(*t, tu);}
10949
10950 /// Lookup a type in a translation unit.
10951 ///
10952 /// @param fqn the fully qualified name of the type to lookup.
10953 ///
10954 /// @param tu the translation unit to consider.
10955 ///
10956 /// @return the declaration of the type if found, NULL otherwise.
10957 const type_base_sptr
lookup_type(const interned_string & fqn,const translation_unit & tu)10958 lookup_type(const interned_string& fqn,
10959 const translation_unit& tu)
10960 {
10961 type_base_sptr result;
10962 ((result = lookup_typedef_type(fqn, tu))
10963 || (result = lookup_class_type(fqn, tu))
10964 || (result = lookup_union_type(fqn, tu))
10965 || (result = lookup_enum_type(fqn, tu))
10966 || (result = lookup_qualified_type(fqn, tu))
10967 || (result = lookup_pointer_type(fqn, tu))
10968 || (result = lookup_reference_type(fqn, tu))
10969 || (result = lookup_array_type(fqn, tu))
10970 || (result = lookup_function_type(fqn, tu))
10971 || (result = lookup_basic_type(fqn, tu)));
10972
10973 return result;
10974 }
10975
10976 /// Lookup a type in a translation unit, starting from the global
10977 /// namespace.
10978 ///
10979 /// @param fqn the fully qualified name of the type to lookup.
10980 ///
10981 /// @param tu the translation unit to consider.
10982 ///
10983 /// @return the declaration of the type if found, NULL otherwise.
10984 type_base_sptr
lookup_type(const string & fqn,const translation_unit & tu)10985 lookup_type(const string& fqn, const translation_unit& tu)
10986 {
10987 const environment *env = tu.get_environment();
10988 ABG_ASSERT(env);
10989 interned_string ifqn = env->intern(fqn);
10990 return lookup_type(ifqn, tu);
10991 }
10992
10993 /// Lookup a type from a translation unit.
10994 ///
10995 /// @param fqn the components of the fully qualified name of the node
10996 /// to look up.
10997 ///
10998 /// @param tu the translation unit to perform lookup from.
10999 ///
11000 /// @return the declaration of the IR node found, NULL otherwise.
11001 const type_base_sptr
lookup_type(const type_base_sptr type,const translation_unit & tu)11002 lookup_type(const type_base_sptr type,
11003 const translation_unit& tu)
11004 {
11005 interned_string type_name = get_type_name(type);
11006 return lookup_type(type_name, tu);
11007 }
11008
11009 /// Lookup a type in a scope.
11010 ///
11011 /// This is really slow as it walks the member types of the scope in
11012 /// sequence to find the type with a given name.
11013 ///
11014 /// If possible, users should prefer looking up types from the
11015 /// enclosing translation unit or even ABI corpus because both the
11016 /// translation unit and the corpus have a map of type, indexed by
11017 /// their name. Looking up a type from those maps is thus much
11018 /// faster.
11019 ///
11020 /// @param fqn the fully qualified name of the type to lookup.
11021 ///
11022 /// @param skope the scope to look into.
11023 ///
11024 /// @return the declaration of the type if found, NULL otherwise.
11025 const type_base_sptr
lookup_type_in_scope(const string & fqn,const scope_decl_sptr & skope)11026 lookup_type_in_scope(const string& fqn,
11027 const scope_decl_sptr& skope)
11028 {
11029 list<string> comps;
11030 fqn_to_components(fqn, comps);
11031 return lookup_type_in_scope(comps, skope);
11032 }
11033
11034 /// Lookup a @ref var_decl in a scope.
11035 ///
11036 /// @param fqn the fuly qualified name of the @var_decl to lookup.
11037 ///
11038 /// @param skope the scope to look into.
11039 ///
11040 /// @return the declaration of the @ref var_decl if found, NULL
11041 /// otherwise.
11042 const decl_base_sptr
lookup_var_decl_in_scope(const string & fqn,const scope_decl_sptr & skope)11043 lookup_var_decl_in_scope(const string& fqn,
11044 const scope_decl_sptr& skope)
11045 {
11046 list<string> comps;
11047 fqn_to_components(fqn, comps);
11048 return lookup_var_decl_in_scope(comps, skope);
11049 }
11050
11051 /// A generic function (template) to get the name of a node, whatever
11052 /// node it is. This has to be specialized for the kind of node we
11053 /// want.
11054 ///
11055 /// Note that a node is a member of a scope.
11056 ///
11057 /// @tparam NodeKind the kind of node to consider.
11058 ///
11059 /// @param node the node to get the name from.
11060 ///
11061 /// @return the name of the node.
11062 template<typename NodeKind>
11063 static const interned_string&
11064 get_node_name(shared_ptr<NodeKind> node);
11065
11066 /// Gets the name of a class_decl node.
11067 ///
11068 /// @param node the decl_base node to get the name from.
11069 ///
11070 /// @return the name of the node.
11071 template<>
11072 const interned_string&
get_node_name(class_decl_sptr node)11073 get_node_name(class_decl_sptr node)
11074 {return node->get_name();}
11075
11076 /// Gets the name of a type_base node.
11077 ///
11078 /// @param node the type_base node to get the name from.
11079 ///
11080 /// @return the name of the node.
11081 template<>
11082 const interned_string&
get_node_name(type_base_sptr node)11083 get_node_name(type_base_sptr node)
11084 {return get_type_declaration(node)->get_name();}
11085
11086 /// Gets the name of a var_decl node.
11087 ///
11088 /// @param node the var_decl node to get the name from.
11089 ///
11090 /// @return the name of the node.
11091 template<>
11092 const interned_string&
get_node_name(var_decl_sptr node)11093 get_node_name(var_decl_sptr node)
11094 {return node->get_name();}
11095
11096 /// Generic function to get the declaration of a given node, whatever
11097 /// it is. There has to be specializations for the kind of the nodes
11098 /// we want to support.
11099 ///
11100 /// @tparam NodeKind the type of the node we are looking at.
11101 ///
11102 /// @return the declaration.
11103 template<typename NodeKind>
11104 static decl_base_sptr
11105 convert_node_to_decl(shared_ptr<NodeKind> node);
11106
11107 /// Lookup a node in a given scope.
11108 ///
11109 /// @tparam the type of the node to lookup.
11110 ///
11111 /// @param fqn the components of the fully qualified name of the node
11112 /// to lookup.
11113 ///
11114 /// @param skope the scope to look into.
11115 ///
11116 /// @return the declaration of the looked up node, or NULL if it
11117 /// wasn't found.
11118 template<typename NodeKind>
11119 static const type_or_decl_base_sptr
lookup_node_in_scope(const list<string> & fqn,const scope_decl_sptr & skope)11120 lookup_node_in_scope(const list<string>& fqn,
11121 const scope_decl_sptr& skope)
11122 {
11123 type_or_decl_base_sptr resulting_decl;
11124 shared_ptr<NodeKind> node;
11125 bool it_is_last = false;
11126 scope_decl_sptr cur_scope = skope, new_scope, scope;
11127
11128 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
11129 {
11130 new_scope.reset();
11131 it_is_last = iterator_is_last(fqn, c);
11132 for (scope_decl::declarations::const_iterator m =
11133 cur_scope->get_member_decls().begin();
11134 m != cur_scope->get_member_decls().end();
11135 ++m)
11136 {
11137 if (!it_is_last)
11138 {
11139 // looking for a scope
11140 scope = dynamic_pointer_cast<scope_decl>(*m);
11141 if (scope && scope->get_name() == *c)
11142 {
11143 new_scope = scope;
11144 break;
11145 }
11146 }
11147 else
11148 {
11149 //looking for a final type.
11150 node = dynamic_pointer_cast<NodeKind>(*m);
11151 if (node && get_node_name(node) == *c)
11152 {
11153 if (class_decl_sptr cl =
11154 dynamic_pointer_cast<class_decl>(node))
11155 if (cl->get_is_declaration_only()
11156 && !cl->get_definition_of_declaration())
11157 continue;
11158 resulting_decl = node;
11159 break;
11160 }
11161 }
11162 }
11163 if (!new_scope && !resulting_decl)
11164 return decl_base_sptr();
11165 cur_scope = new_scope;
11166 }
11167 ABG_ASSERT(resulting_decl);
11168 return resulting_decl;
11169 }
11170
11171 /// lookup a type in a scope.
11172 ///
11173 ///
11174 /// This is really slow as it walks the member types of the scope in
11175 /// sequence to find the type with a given name.
11176 ///
11177 /// If possible, users should prefer looking up types from the
11178 /// enclosing translation unit or even ABI corpus because both the
11179 /// translation unit and the corpus have a map of type, indexed by
11180 /// their name. Looking up a type from those maps is thus much
11181 /// faster.
11182 ///
11183 /// @param comps the components of the fully qualified name of the
11184 /// type to lookup.
11185 ///
11186 /// @param skope the scope to look into.
11187 ///
11188 /// @return the declaration of the type found.
11189 const type_base_sptr
lookup_type_in_scope(const list<string> & comps,const scope_decl_sptr & scope)11190 lookup_type_in_scope(const list<string>& comps,
11191 const scope_decl_sptr& scope)
11192 {return is_type(lookup_node_in_scope<type_base>(comps, scope));}
11193
11194 /// lookup a type in a scope.
11195 ///
11196 /// This is really slow as it walks the member types of the scope in
11197 /// sequence to find the type with a given name.
11198 ///
11199 /// If possible, users should prefer looking up types from the
11200 /// enclosing translation unit or even ABI corpus because both the
11201 /// translation unit and the corpus have a map of type, indexed by
11202 /// their name. Looking up a type from those maps is thus much
11203 /// faster.
11204 ///
11205 /// @param type the type to look for.
11206 ///
11207 /// @param access_path a vector of scopes the path of scopes to follow
11208 /// before reaching the scope into which to look for @p type. Note
11209 /// that the deepest scope (the one immediately containing @p type) is
11210 /// at index 0 of this vector, and the top-most scope is the last
11211 /// element of the vector.
11212 ///
11213 /// @param scope the top-most scope into which to look for @p type.
11214 ///
11215 /// @return the scope found in @p scope, or NULL if it wasn't found.
11216 static const type_base_sptr
lookup_type_in_scope(const type_base & type,const vector<scope_decl * > & access_path,const scope_decl * scope)11217 lookup_type_in_scope(const type_base& type,
11218 const vector<scope_decl*>& access_path,
11219 const scope_decl* scope)
11220 {
11221 vector<scope_decl*> a = access_path;
11222 type_base_sptr result;
11223
11224 scope_decl* first_scope = 0;
11225 if (!a.empty())
11226 {
11227 first_scope = a.back();
11228 ABG_ASSERT(first_scope->get_name() == scope->get_name());
11229 a.pop_back();
11230 }
11231
11232 if (a.empty())
11233 {
11234 interned_string n = get_type_name(type, false);
11235 for (scope_decl::declarations::const_iterator i =
11236 scope->get_member_decls().begin();
11237 i != scope->get_member_decls().end();
11238 ++i)
11239 if (is_type(*i) && (*i)->get_name() == n)
11240 {
11241 result = is_type(*i);
11242 break;
11243 }
11244 }
11245 else
11246 {
11247 first_scope = a.back();
11248 interned_string scope_name, cur_scope_name = first_scope->get_name();
11249 for (scope_decl::scopes::const_iterator i =
11250 scope->get_member_scopes().begin();
11251 i != scope->get_member_scopes().end();
11252 ++i)
11253 {
11254 scope_name = (*i)->get_name();
11255 if (scope_name == cur_scope_name)
11256 {
11257 result = lookup_type_in_scope(type, a, (*i).get());
11258 break;
11259 }
11260 }
11261 }
11262 return result;
11263 }
11264
11265 /// lookup a type in a scope.
11266 ///
11267 /// This is really slow as it walks the member types of the scope in
11268 /// sequence to find the type with a given name.
11269 ///
11270 /// If possible, users should prefer looking up types from the
11271 /// enclosing translation unit or even ABI corpus because both the
11272 /// translation unit and the corpus have a map of type, indexed by
11273 /// their name. Looking up a type from those maps is thus much
11274 /// faster.
11275 ///
11276 /// @param type the type to look for.
11277 ///
11278 /// @param scope the top-most scope into which to look for @p type.
11279 ///
11280 /// @return the scope found in @p scope, or NULL if it wasn't found.
11281 static const type_base_sptr
lookup_type_in_scope(const type_base_sptr type,const scope_decl * scope)11282 lookup_type_in_scope(const type_base_sptr type,
11283 const scope_decl* scope)
11284 {
11285 if (!type || is_function_type(type))
11286 return type_base_sptr();
11287
11288 decl_base_sptr type_decl = get_type_declaration(type);
11289 ABG_ASSERT(type_decl);
11290 vector<scope_decl*> access_path;
11291 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
11292 {
11293 access_path.push_back(s);
11294 if (is_global_scope(s))
11295 break;
11296 }
11297 return lookup_type_in_scope(*type, access_path, scope);
11298 }
11299
11300 /// Lookup a type from a translation unit by walking the scopes of the
11301 /// translation unit in sequence and looking into them.
11302 ///
11303 /// This is really slow as it walks the member types of the scopes in
11304 /// sequence to find the type with a given name.
11305 ///
11306 /// If possible, users should prefer looking up types from the
11307 /// translation unit or even ABI corpus in a more direct way, by using
11308 /// the lookup_type() functins.
11309 ///
11310 ///
11311 /// This is because both the translation unit and the corpus have a
11312 /// map of types, indexed by their name. Looking up a type from those
11313 /// maps is thus much faster. @param fqn the components of the fully
11314 /// qualified name of the node to look up.
11315 ///
11316 /// @param tu the translation unit to perform lookup from.
11317 ///
11318 /// @return the declaration of the IR node found, NULL otherwise.
11319 const type_base_sptr
lookup_type_through_scopes(const type_base_sptr type,const translation_unit & tu)11320 lookup_type_through_scopes(const type_base_sptr type,
11321 const translation_unit& tu)
11322 {
11323 if (function_type_sptr fn_type = is_function_type(type))
11324 return lookup_function_type(fn_type, tu);
11325 return lookup_type_in_scope(type, tu.get_global_scope().get());
11326 }
11327
11328 /// lookup a var_decl in a scope.
11329 ///
11330 /// @param comps the components of the fully qualified name of the
11331 /// var_decl to lookup.
11332 ///
11333 /// @param skope the scope to look into.
11334 const decl_base_sptr
lookup_var_decl_in_scope(const std::list<string> & comps,const scope_decl_sptr & skope)11335 lookup_var_decl_in_scope(const std::list<string>& comps,
11336 const scope_decl_sptr& skope)
11337 {return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
11338
11339 /// Lookup an IR node from a translation unit.
11340 ///
11341 /// @tparam NodeKind the type of the IR node to lookup from the
11342 /// translation unit.
11343 ///
11344 /// @param fqn the components of the fully qualified name of the node
11345 /// to look up.
11346 ///
11347 /// @param tu the translation unit to perform lookup from.
11348 ///
11349 /// @return the declaration of the IR node found, NULL otherwise.
11350 template<typename NodeKind>
11351 static const type_or_decl_base_sptr
lookup_node_in_translation_unit(const list<string> & fqn,const translation_unit & tu)11352 lookup_node_in_translation_unit(const list<string>& fqn,
11353 const translation_unit& tu)
11354 {return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
11355
11356 /// Lookup a type from a translation unit by walking its scopes in
11357 /// sequence and by looking into them.
11358 ///
11359 /// This is much slower than using the lookup_type() function.
11360 ///
11361 /// @param fqn the components of the fully qualified name of the node
11362 /// to look up.
11363 ///
11364 /// @param tu the translation unit to perform lookup from.
11365 ///
11366 /// @return the declaration of the IR node found, NULL otherwise.
11367 type_base_sptr
lookup_type_through_scopes(const list<string> & fqn,const translation_unit & tu)11368 lookup_type_through_scopes(const list<string>& fqn,
11369 const translation_unit& tu)
11370 {return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
11371
11372
11373 /// Lookup a class type from a translation unit by walking its scopes
11374 /// in sequence and by looking into them.
11375 ///
11376 /// This is much slower than using the lookup_class_type() function
11377 /// because it walks all the scopes of the translation unit in
11378 /// sequence and lookup the types to find one that has a given name.
11379 ///
11380 /// @param fqn the components of the fully qualified name of the class
11381 /// type node to look up.
11382 ///
11383 /// @param tu the translation unit to perform lookup from.
11384 ///
11385 /// @return the declaration of the class type IR node found, NULL
11386 /// otherwise.
11387 class_decl_sptr
lookup_class_type_through_scopes(const list<string> & fqn,const translation_unit & tu)11388 lookup_class_type_through_scopes(const list<string>& fqn,
11389 const translation_unit& tu)
11390 {return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
11391
11392 /// Lookup a basic type from all the translation units of a given
11393 /// corpus.
11394 ///
11395 /// @param fqn the components of the fully qualified name of the basic
11396 /// type node to look up.
11397 ///
11398 /// @param tu the translation unit to perform lookup from.
11399 ///
11400 /// @return the declaration of the basic type IR node found, NULL
11401 /// otherwise.
11402 static type_decl_sptr
lookup_basic_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11403 lookup_basic_type_through_translation_units(const interned_string& type_name,
11404 const corpus& abi_corpus)
11405 {
11406 type_decl_sptr result;
11407
11408 for (translation_units::const_iterator tu =
11409 abi_corpus.get_translation_units().begin();
11410 tu != abi_corpus.get_translation_units().end();
11411 ++tu)
11412 if ((result = lookup_basic_type(type_name, **tu)))
11413 break;
11414
11415 return result;
11416 }
11417
11418 /// Lookup a union type from all the translation units of a given
11419 /// corpus.
11420 ///
11421 /// @param fqn the components of the fully qualified name of the union
11422 /// type node to look up.
11423 ///
11424 /// @param tu the translation unit to perform lookup from.
11425 ///
11426 /// @return the declaration of the union type IR node found, NULL
11427 /// otherwise.
11428 static union_decl_sptr
lookup_union_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11429 lookup_union_type_through_translation_units(const interned_string& type_name,
11430 const corpus & abi_corpus)
11431 {
11432 union_decl_sptr result;
11433
11434 for (translation_units::const_iterator tu =
11435 abi_corpus.get_translation_units().begin();
11436 tu != abi_corpus.get_translation_units().end();
11437 ++tu)
11438 if ((result = lookup_union_type(type_name, **tu)))
11439 break;
11440
11441 return result;
11442 }
11443
11444 /// Lookup an enum type from all the translation units of a given
11445 /// corpus.
11446 ///
11447 /// @param fqn the components of the fully qualified name of the enum
11448 /// type node to look up.
11449 ///
11450 /// @param tu the translation unit to perform lookup from.
11451 ///
11452 /// @return the declaration of the enum type IR node found, NULL
11453 /// otherwise.
11454 static enum_type_decl_sptr
lookup_enum_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11455 lookup_enum_type_through_translation_units(const interned_string& type_name,
11456 const corpus & abi_corpus)
11457 {
11458 enum_type_decl_sptr result;
11459
11460 for (translation_units::const_iterator tu =
11461 abi_corpus.get_translation_units().begin();
11462 tu != abi_corpus.get_translation_units().end();
11463 ++tu)
11464 if ((result = lookup_enum_type(type_name, **tu)))
11465 break;
11466
11467 return result;
11468 }
11469
11470 /// Lookup a typedef type definition in all the translation units of a
11471 /// given ABI corpus.
11472 ///
11473 /// @param @param qn the fully qualified name of the typedef type to lookup.
11474 ///
11475 /// @param abi_corpus the ABI corpus which to look the type up in.
11476 ///
11477 /// @return the type definition if any was found, or a NULL pointer.
11478 static typedef_decl_sptr
lookup_typedef_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11479 lookup_typedef_type_through_translation_units(const interned_string& type_name,
11480 const corpus & abi_corpus)
11481 {
11482 typedef_decl_sptr result;
11483
11484 for (translation_units::const_iterator tu =
11485 abi_corpus.get_translation_units().begin();
11486 tu != abi_corpus.get_translation_units().end();
11487 ++tu)
11488 if ((result = lookup_typedef_type(type_name, **tu)))
11489 break;
11490
11491 return result;
11492 }
11493
11494 /// Lookup a qualified type definition in all the translation units of a
11495 /// given ABI corpus.
11496 ///
11497 /// @param @param qn the fully qualified name of the qualified type to
11498 /// lookup.
11499 ///
11500 /// @param abi_corpus the ABI corpus which to look the type up in.
11501 ///
11502 /// @return the type definition if any was found, or a NULL pointer.
11503 static qualified_type_def_sptr
lookup_qualified_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)11504 lookup_qualified_type_through_translation_units(const interned_string& t_name,
11505 const corpus & abi_corpus)
11506 {
11507 qualified_type_def_sptr result;
11508
11509 for (translation_units::const_iterator tu =
11510 abi_corpus.get_translation_units().begin();
11511 tu != abi_corpus.get_translation_units().end();
11512 ++tu)
11513 if ((result = lookup_qualified_type(t_name, **tu)))
11514 break;
11515
11516 return result;
11517 }
11518
11519 /// Lookup a pointer type definition in all the translation units of a
11520 /// given ABI corpus.
11521 ///
11522 /// @param @param qn the fully qualified name of the pointer type to
11523 /// lookup.
11524 ///
11525 /// @param abi_corpus the ABI corpus which to look the type up in.
11526 ///
11527 /// @return the type definition if any was found, or a NULL pointer.
11528 static pointer_type_def_sptr
lookup_pointer_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11529 lookup_pointer_type_through_translation_units(const interned_string& type_name,
11530 const corpus & abi_corpus)
11531 {
11532 pointer_type_def_sptr result;
11533
11534 for (translation_units::const_iterator tu =
11535 abi_corpus.get_translation_units().begin();
11536 tu != abi_corpus.get_translation_units().end();
11537 ++tu)
11538 if ((result = lookup_pointer_type(type_name, **tu)))
11539 break;
11540
11541 return result;
11542 }
11543
11544 /// Lookup a reference type definition in all the translation units of a
11545 /// given ABI corpus.
11546 ///
11547 /// @param @param qn the fully qualified name of the reference type to
11548 /// lookup.
11549 ///
11550 /// @param abi_corpus the ABI corpus which to look the type up in.
11551 ///
11552 /// @return the type definition if any was found, or a NULL pointer.
11553 static reference_type_def_sptr
lookup_reference_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)11554 lookup_reference_type_through_translation_units(const interned_string& t_name,
11555 const corpus & abi_corpus)
11556 {
11557 reference_type_def_sptr result;
11558
11559 for (translation_units::const_iterator tu =
11560 abi_corpus.get_translation_units().begin();
11561 tu != abi_corpus.get_translation_units().end();
11562 ++tu)
11563 if ((result = lookup_reference_type(t_name, **tu)))
11564 break;
11565
11566 return result;
11567 }
11568
11569 /// Lookup a array type definition in all the translation units of a
11570 /// given ABI corpus.
11571 ///
11572 /// @param @param qn the fully qualified name of the array type to
11573 /// lookup.
11574 ///
11575 /// @param abi_corpus the ABI corpus which to look the type up in.
11576 ///
11577 /// @return the type definition if any was found, or a NULL pointer.
11578 static array_type_def_sptr
lookup_array_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11579 lookup_array_type_through_translation_units(const interned_string& type_name,
11580 const corpus & abi_corpus)
11581 {
11582 array_type_def_sptr result;
11583
11584 for (translation_units::const_iterator tu =
11585 abi_corpus.get_translation_units().begin();
11586 tu != abi_corpus.get_translation_units().end();
11587 ++tu)
11588 if ((result = lookup_array_type(type_name, **tu)))
11589 break;
11590
11591 return result;
11592 }
11593
11594 /// Lookup a function type definition in all the translation units of
11595 /// a given ABI corpus.
11596 ///
11597 /// @param @param qn the fully qualified name of the function type to
11598 /// lookup.
11599 ///
11600 /// @param abi_corpus the ABI corpus which to look the type up in.
11601 ///
11602 /// @return the type definition if any was found, or a NULL pointer.
11603 static function_type_sptr
lookup_function_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)11604 lookup_function_type_through_translation_units(const interned_string& type_name,
11605 const corpus & abi_corpus)
11606 {
11607 function_type_sptr result;
11608
11609 for (translation_units::const_iterator tu =
11610 abi_corpus.get_translation_units().begin();
11611 tu != abi_corpus.get_translation_units().end();
11612 ++tu)
11613 if ((result = lookup_function_type(type_name, **tu)))
11614 break;
11615
11616 return result;
11617 }
11618
11619 /// Lookup a type definition in all the translation units of a given
11620 /// ABI corpus.
11621 ///
11622 /// @param @param qn the fully qualified name of the type to lookup.
11623 ///
11624 /// @param abi_corpus the ABI corpus which to look the type up in.
11625 ///
11626 /// @return the type definition if any was found, or a NULL pointer.
11627 type_base_sptr
lookup_type_through_translation_units(const string & qn,const corpus & abi_corpus)11628 lookup_type_through_translation_units(const string& qn,
11629 const corpus& abi_corpus)
11630 {
11631 type_base_sptr result;
11632
11633 for (translation_units::const_iterator tu =
11634 abi_corpus.get_translation_units().begin();
11635 tu != abi_corpus.get_translation_units().end();
11636 ++tu)
11637 if ((result = lookup_type(qn, **tu)))
11638 break;
11639
11640 return result;
11641 }
11642
11643 /// Lookup a type from a given translation unit present in a give corpus.
11644 ///
11645 /// @param type_name the name of the type to look for.
11646 ///
11647 /// @parm tu_path the path of the translation unit to consider.
11648 ///
11649 /// @param corp the corpus to consider.
11650 ///
11651 /// @return the resulting type, if any.
11652 type_base_sptr
lookup_type_from_translation_unit(const string & type_name,const string & tu_path,const corpus & corp)11653 lookup_type_from_translation_unit(const string& type_name,
11654 const string& tu_path,
11655 const corpus& corp)
11656 {
11657 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
11658 if (i == corp.priv_->path_tu_map.end())
11659 return type_base_sptr();
11660
11661 translation_unit_sptr tu = i->second;
11662 ABG_ASSERT(tu);
11663
11664 type_base_sptr t = lookup_type(type_name, *tu);
11665 return t;
11666 }
11667
11668 /// Look into an ABI corpus for a function type.
11669 ///
11670 /// @param fn_type the function type to be looked for in the ABI
11671 /// corpus.
11672 ///
11673 /// @param corpus the ABI corpus into which to look for the function
11674 /// type.
11675 ///
11676 /// @return the function type found in the corpus.
11677 function_type_sptr
lookup_or_synthesize_fn_type(const function_type_sptr & fn_t,const corpus & corpus)11678 lookup_or_synthesize_fn_type(const function_type_sptr& fn_t,
11679 const corpus& corpus)
11680 {
11681 ABG_ASSERT(fn_t);
11682
11683 function_type_sptr result;
11684
11685 if ((result = lookup_function_type(fn_t, corpus)))
11686 return result;
11687
11688 for (translation_units::const_iterator i =
11689 corpus.get_translation_units().begin();
11690 i != corpus.get_translation_units().end();
11691 ++i)
11692 if ((result = synthesize_function_type_from_translation_unit(*fn_t,
11693 **i)))
11694 return result;
11695
11696 return result;
11697 }
11698
11699 /// Look into a given corpus to find a type which has the same
11700 /// qualified name as a giventype.
11701 ///
11702 /// If the per-corpus type map is non-empty (because the corpus allows
11703 /// the One Definition Rule) then the type islooked up in that
11704 /// per-corpus type map. Otherwise, the type is looked-up in each
11705 /// translation unit.
11706 ///
11707 /// @param t the type which has the same qualified name as the type we
11708 /// are looking for.
11709 ///
11710 /// @param corp the ABI corpus to look into for the type.
11711 type_decl_sptr
lookup_basic_type(const type_decl & t,const corpus & corp)11712 lookup_basic_type(const type_decl& t, const corpus& corp)
11713 {return lookup_basic_type(t.get_name(), corp);}
11714
11715 /// Look into a given corpus to find a basic type which has a given
11716 /// qualified name.
11717 ///
11718 /// If the per-corpus type map is non-empty (because the corpus allows
11719 /// the One Definition Rule) then the type islooked up in that
11720 /// per-corpus type map. Otherwise, the type is looked-up in each
11721 /// translation unit.
11722 ///
11723 /// @param qualified_name the qualified name of the basic type to look
11724 /// for.
11725 ///
11726 /// @param corp the corpus to look into.
11727 type_decl_sptr
lookup_basic_type(const interned_string & qualified_name,const corpus & corp)11728 lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
11729 {
11730 const istring_type_base_wptrs_map_type& m = corp.get_types().basic_types();
11731 type_decl_sptr result;
11732
11733 if (!m.empty())
11734 result = lookup_type_in_map<type_decl>(qualified_name, m);
11735 else
11736 result = lookup_basic_type_through_translation_units(qualified_name, corp);
11737
11738 return result;
11739 }
11740
11741 /// Lookup a @ref type_decl type from a given corpus, by its location.
11742 ///
11743 /// @param loc the location to consider.
11744 ///
11745 /// @param corp the corpus to consider.
11746 ///
11747 /// @return the resulting basic type, if any.
11748 type_decl_sptr
lookup_basic_type_per_location(const interned_string & loc,const corpus & corp)11749 lookup_basic_type_per_location(const interned_string &loc,
11750 const corpus &corp)
11751 {
11752 const istring_type_base_wptrs_map_type& m =
11753 corp.get_type_per_loc_map().basic_types();
11754 type_decl_sptr result;
11755
11756 result = lookup_type_in_map<type_decl>(loc, m);
11757
11758 return result;
11759 }
11760
11761 /// Lookup a @ref type_decl type from a given corpus, by its location.
11762 ///
11763 /// @param loc the location to consider.
11764 ///
11765 /// @param corp the corpus to consider.
11766 ///
11767 /// @return the resulting basic type, if any.
11768 type_decl_sptr
lookup_basic_type_per_location(const string & loc,const corpus & corp)11769 lookup_basic_type_per_location(const string &loc, const corpus &corp)
11770 {
11771 const environment* env = corp.get_environment();
11772 ABG_ASSERT(env);
11773
11774 return lookup_basic_type_per_location(env->intern(loc), corp);
11775 }
11776
11777 /// Look into a given corpus to find a basic type which has a given
11778 /// qualified name.
11779 ///
11780 /// If the per-corpus type map is non-empty (because the corpus allows
11781 /// the One Definition Rule) then the type islooked up in that
11782 /// per-corpus type map. Otherwise, the type is looked-up in each
11783 /// translation unit.
11784 ///
11785 /// @param qualified_name the qualified name of the basic type to look
11786 /// for.
11787 ///
11788 /// @param corp the corpus to look into.
11789 type_decl_sptr
lookup_basic_type(const string & qualified_name,const corpus & corp)11790 lookup_basic_type(const string& qualified_name, const corpus& corp)
11791 {
11792 return lookup_basic_type(corp.get_environment()->intern(qualified_name),
11793 corp);
11794 }
11795
11796 /// Look into a given corpus to find a class type which has the same
11797 /// qualified name as a given type.
11798 ///
11799 /// If the per-corpus type map is non-empty (because the corpus allows
11800 /// the One Definition Rule) then the type islooked up in that
11801 /// per-corpus type map. Otherwise, the type is looked-up in each
11802 /// translation unit.
11803 ///
11804 /// @param t the class decl type which has the same qualified name as
11805 /// the type we are looking for.
11806 ///
11807 /// @param corp the corpus to look into.
11808 class_decl_sptr
lookup_class_type(const class_decl & t,const corpus & corp)11809 lookup_class_type(const class_decl& t, const corpus& corp)
11810 {
11811 interned_string s = get_type_name(t);
11812 return lookup_class_type(s, corp);
11813 }
11814
11815 /// Look into a given corpus to find a class type which has a given
11816 /// qualified name.
11817 ///
11818 /// If the per-corpus type map is non-empty (because the corpus allows
11819 /// the One Definition Rule) then the type islooked up in that
11820 /// per-corpus type map. Otherwise, the type is looked-up in each
11821 /// translation unit.
11822 ///
11823 /// @param qualified_name the qualified name of the type to look for.
11824 ///
11825 /// @param corp the corpus to look into.
11826 class_decl_sptr
lookup_class_type(const string & qualified_name,const corpus & corp)11827 lookup_class_type(const string& qualified_name, const corpus& corp)
11828 {
11829 interned_string s = corp.get_environment()->intern(qualified_name);
11830 return lookup_class_type(s, corp);
11831 }
11832
11833 /// Look into a given corpus to find a class type which has a given
11834 /// qualified name.
11835 ///
11836 /// If the per-corpus type map is non-empty (because the corpus allows
11837 /// the One Definition Rule) then the type islooked up in that
11838 /// per-corpus type map. Otherwise, the type is looked-up in each
11839 /// translation unit.
11840 ///
11841 /// @param qualified_name the qualified name of the type to look for.
11842 ///
11843 /// @param corp the corpus to look into.
11844 class_decl_sptr
lookup_class_type(const interned_string & qualified_name,const corpus & corp)11845 lookup_class_type(const interned_string& qualified_name, const corpus& corp)
11846 {
11847 const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
11848
11849 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
11850
11851 return result;
11852 }
11853
11854 /// Look into a given corpus to find the class type*s* that have a
11855 /// given qualified name.
11856 ///
11857 /// @param qualified_name the qualified name of the type to look for.
11858 ///
11859 /// @param corp the corpus to look into.
11860 ///
11861 /// @return the vector of class types named @p qualified_name.
11862 const type_base_wptrs_type *
lookup_class_types(const interned_string & qualified_name,const corpus & corp)11863 lookup_class_types(const interned_string& qualified_name, const corpus& corp)
11864 {
11865 const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
11866
11867 return lookup_types_in_map(qualified_name, m);
11868 }
11869
11870 /// Look into a given corpus to find the class type*s* that have a
11871 /// given qualified name.
11872 ///
11873 /// @param qualified_name the qualified name of the type to look for.
11874 ///
11875 /// @param corp the corpus to look into.
11876 ///
11877 /// @return the vector of class types that which name is @p qualified_name.
11878 const type_base_wptrs_type*
lookup_class_types(const string & qualified_name,const corpus & corp)11879 lookup_class_types(const string& qualified_name, const corpus& corp)
11880 {
11881 interned_string s = corp.get_environment()->intern(qualified_name);
11882 return lookup_class_types(s, corp);
11883 }
11884
11885 /// Look up a @ref class_decl from a given corpus by its location.
11886 ///
11887 /// @param loc the location to consider.
11888 ///
11889 /// @param corp the corpus to consider.
11890 ///
11891 /// @return the resulting class decl, if any.
11892 class_decl_sptr
lookup_class_type_per_location(const interned_string & loc,const corpus & corp)11893 lookup_class_type_per_location(const interned_string& loc,
11894 const corpus& corp)
11895 {
11896 const istring_type_base_wptrs_map_type& m =
11897 corp.get_type_per_loc_map().class_types();
11898 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
11899
11900 return result;
11901 }
11902
11903 /// Look up a @ref class_decl from a given corpus by its location.
11904 ///
11905 /// @param loc the location to consider.
11906 ///
11907 /// @param corp the corpus to consider.
11908 ///
11909 /// @return the resulting class decl, if any.
11910 class_decl_sptr
lookup_class_type_per_location(const string & loc,const corpus & corp)11911 lookup_class_type_per_location(const string &loc, const corpus &corp)
11912 {
11913 const environment* env = corp.get_environment();
11914 ABG_ASSERT(env);
11915
11916 return lookup_class_type_per_location(env->intern(loc), corp);
11917 }
11918
11919 /// Look into a given corpus to find a union type which has a given
11920 /// qualified name.
11921 ///
11922 /// If the per-corpus type map is non-empty (because the corpus allows
11923 /// the One Definition Rule) then the type islooked up in that
11924 /// per-corpus type map. Otherwise, the type is looked-up in each
11925 /// translation unit.
11926 ///
11927 /// @param qualified_name the qualified name of the type to look for.
11928 ///
11929 /// @param corp the corpus to look into.
11930 union_decl_sptr
lookup_union_type(const interned_string & type_name,const corpus & corp)11931 lookup_union_type(const interned_string& type_name, const corpus& corp)
11932 {
11933 const istring_type_base_wptrs_map_type& m = corp.get_types().union_types();
11934
11935 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
11936 if (!result)
11937 result = lookup_union_type_through_translation_units(type_name, corp);
11938
11939 return result;
11940 }
11941
11942 /// Look into a given corpus to find a union type which has a given
11943 /// qualified name.
11944 ///
11945 /// If the per-corpus type map is non-empty (because the corpus allows
11946 /// the One Definition Rule) then the type islooked up in that
11947 /// per-corpus type map. Otherwise, the type is looked-up in each
11948 /// translation unit.
11949 ///
11950 /// @param qualified_name the qualified name of the type to look for.
11951 ///
11952 /// @param corp the corpus to look into.
11953 union_decl_sptr
lookup_union_type(const string & type_name,const corpus & corp)11954 lookup_union_type(const string& type_name, const corpus& corp)
11955 {
11956 interned_string s = corp.get_environment()->intern(type_name);
11957 return lookup_union_type(s, corp);
11958 }
11959
11960 /// Look into a given corpus to find an enum type which has the same
11961 /// qualified name as a given enum type.
11962 ///
11963 /// If the per-corpus type map is non-empty (because the corpus allows
11964 /// the One Definition Rule) then the type islooked up in that
11965 /// per-corpus type map. Otherwise, the type is looked-up in each
11966 /// translation unit.
11967 ///
11968 /// @param t the enum type which has the same qualified name as the
11969 /// type we are looking for.
11970 ///
11971 /// @param corp the corpus to look into.
11972 enum_type_decl_sptr
lookup_enum_type(const enum_type_decl & t,const corpus & corp)11973 lookup_enum_type(const enum_type_decl& t, const corpus& corp)
11974 {
11975 interned_string s = get_type_name(t);
11976 return lookup_enum_type(s, corp);
11977 }
11978
11979 /// Look into a given corpus to find an enum type which has a given
11980 /// qualified name.
11981 ///
11982 /// If the per-corpus type map is non-empty (because the corpus allows
11983 /// the One Definition Rule) then the type islooked up in that
11984 /// per-corpus type map. Otherwise, the type is looked-up in each
11985 /// translation unit.
11986 ///
11987 /// @param qualified_name the qualified name of the enum type to look
11988 /// for.
11989 ///
11990 /// @param corp the corpus to look into.
11991 enum_type_decl_sptr
lookup_enum_type(const string & qualified_name,const corpus & corp)11992 lookup_enum_type(const string& qualified_name, const corpus& corp)
11993 {
11994 interned_string s = corp.get_environment()->intern(qualified_name);
11995 return lookup_enum_type(s, corp);
11996 }
11997
11998 /// Look into a given corpus to find an enum type which has a given
11999 /// qualified name.
12000 ///
12001 /// If the per-corpus type map is non-empty (because the corpus allows
12002 /// the One Definition Rule) then the type islooked up in that
12003 /// per-corpus type map. Otherwise, the type is looked-up in each
12004 /// translation unit.
12005 ///
12006 /// @param qualified_name the qualified name of the enum type to look
12007 /// for.
12008 ///
12009 /// @param corp the corpus to look into.
12010 enum_type_decl_sptr
lookup_enum_type(const interned_string & qualified_name,const corpus & corp)12011 lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
12012 {
12013 const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
12014
12015 enum_type_decl_sptr result =
12016 lookup_type_in_map<enum_type_decl>(qualified_name, m);
12017 if (!result)
12018 result = lookup_enum_type_through_translation_units(qualified_name, corp);
12019
12020 return result;
12021 }
12022
12023 /// Look into a given corpus to find the enum type*s* that have a
12024 /// given qualified name.
12025 ///
12026 /// @param qualified_name the qualified name of the type to look for.
12027 ///
12028 /// @param corp the corpus to look into.
12029 ///
12030 /// @return the vector of enum types that which name is @p qualified_name.
12031 const type_base_wptrs_type *
lookup_enum_types(const interned_string & qualified_name,const corpus & corp)12032 lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
12033 {
12034 const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
12035
12036 return lookup_types_in_map(qualified_name, m);
12037 }
12038
12039 /// Look into a given corpus to find the enum type*s* that have a
12040 /// given qualified name.
12041 ///
12042 /// @param qualified_name the qualified name of the type to look for.
12043 ///
12044 /// @param corp the corpus to look into.
12045 ///
12046 /// @return the vector of enum types that which name is @p qualified_name.
12047 const type_base_wptrs_type*
lookup_enum_types(const string & qualified_name,const corpus & corp)12048 lookup_enum_types(const string& qualified_name, const corpus& corp)
12049 {
12050 interned_string s = corp.get_environment()->intern(qualified_name);
12051 return lookup_enum_types(s, corp);
12052 }
12053
12054 /// Look up an @ref enum_type_decl from a given corpus, by its location.
12055 ///
12056 /// @param loc the location to consider.
12057 ///
12058 /// @param corp the corpus to look the type from.
12059 ///
12060 /// @return the resulting enum type, if any.
12061 enum_type_decl_sptr
lookup_enum_type_per_location(const interned_string & loc,const corpus & corp)12062 lookup_enum_type_per_location(const interned_string &loc, const corpus& corp)
12063 {
12064 const istring_type_base_wptrs_map_type& m =
12065 corp.get_type_per_loc_map().enum_types();
12066 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
12067
12068 return result;
12069 }
12070
12071 /// Look up an @ref enum_type_decl from a given corpus, by its location.
12072 ///
12073 /// @param loc the location to consider.
12074 ///
12075 /// @param corp the corpus to look the type from.
12076 ///
12077 /// @return the resulting enum type, if any.
12078 enum_type_decl_sptr
lookup_enum_type_per_location(const string & loc,const corpus & corp)12079 lookup_enum_type_per_location(const string &loc, const corpus &corp)
12080 {
12081 const environment* env = corp.get_environment();
12082 ABG_ASSERT(env);
12083
12084 return lookup_enum_type_per_location(env->intern(loc), corp);
12085 }
12086
12087 /// Look into a given corpus to find a typedef type which has the
12088 /// same qualified name as a given typedef type.
12089 ///
12090 /// If the per-corpus type map is non-empty (because the corpus allows
12091 /// the One Definition Rule) then the type islooked up in that
12092 /// per-corpus type map. Otherwise, the type is looked-up in each
12093 /// translation unit.
12094 ///
12095 /// @param t the typedef type which has the same qualified name as the
12096 /// typedef type we are looking for.
12097 ///
12098 /// @param corp the corpus to look into.
12099 typedef_decl_sptr
lookup_typedef_type(const typedef_decl & t,const corpus & corp)12100 lookup_typedef_type(const typedef_decl& t, const corpus& corp)
12101 {
12102 interned_string s = get_type_name(t);
12103 return lookup_typedef_type(s, corp);
12104 }
12105
12106 /// Look into a given corpus to find a typedef type which has the
12107 /// same qualified name as a given typedef type.
12108 ///
12109 /// If the per-corpus type map is non-empty (because the corpus allows
12110 /// the One Definition Rule) then the type islooked up in that
12111 /// per-corpus type map. Otherwise, the type is looked-up in each
12112 /// translation unit.
12113 ///
12114 /// @param t the typedef type which has the same qualified name as the
12115 /// typedef type we are looking for.
12116 ///
12117 /// @param corp the corpus to look into.
12118 typedef_decl_sptr
lookup_typedef_type(const string & qualified_name,const corpus & corp)12119 lookup_typedef_type(const string& qualified_name, const corpus& corp)
12120 {
12121 interned_string s = corp.get_environment()->intern(qualified_name);
12122 return lookup_typedef_type(s, corp);
12123 }
12124
12125 /// Look into a given corpus to find a typedef type which has a
12126 /// given qualified name.
12127 ///
12128 /// If the per-corpus type map is non-empty (because the corpus allows
12129 /// the One Definition Rule) then the type islooked up in that
12130 /// per-corpus type map. Otherwise, the type is looked-up in each
12131 /// translation unit.
12132 ///
12133 /// @param qualified_name the qualified name of the typedef type to
12134 /// look for.
12135 ///
12136 /// @param corp the corpus to look into.
12137 typedef_decl_sptr
lookup_typedef_type(const interned_string & qualified_name,const corpus & corp)12138 lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
12139 {
12140 const istring_type_base_wptrs_map_type& m = corp.get_types().typedef_types();
12141
12142 typedef_decl_sptr result =
12143 lookup_type_in_map<typedef_decl>(qualified_name, m);
12144 if (!result)
12145 result = lookup_typedef_type_through_translation_units(qualified_name,
12146 corp);
12147
12148 return result;
12149 }
12150
12151 /// Lookup a @ref typedef_decl from a corpus, by its location.
12152 ///
12153 /// @param loc the location to consider.
12154 ///
12155 /// @param corp the corpus to consider.
12156 ///
12157 /// @return the typedef_decl found, if any.
12158 typedef_decl_sptr
lookup_typedef_type_per_location(const interned_string & loc,const corpus & corp)12159 lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
12160 {
12161 const istring_type_base_wptrs_map_type& m =
12162 corp.get_type_per_loc_map().typedef_types();
12163 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
12164
12165 return result;
12166 }
12167
12168 /// Lookup a @ref typedef_decl from a corpus, by its location.
12169 ///
12170 /// @param loc the location to consider.
12171 ///
12172 /// @param corp the corpus to consider.
12173 ///
12174 /// @return the typedef_decl found, if any.
12175 typedef_decl_sptr
lookup_typedef_type_per_location(const string & loc,const corpus & corp)12176 lookup_typedef_type_per_location(const string &loc, const corpus &corp)
12177 {
12178 const environment* env = corp.get_environment();
12179 ABG_ASSERT(env);
12180
12181 return lookup_typedef_type_per_location(env->intern(loc), corp);
12182 }
12183
12184 /// Look into a corpus to find a class, union or typedef type which
12185 /// has a given qualified name.
12186 ///
12187 /// If the per-corpus type map is non-empty (because the corpus allows
12188 /// the One Definition Rule) then the type islooked up in that
12189 /// per-corpus type map. Otherwise, the type is looked-up in each
12190 /// translation unit.
12191 ///
12192 /// @param qualified_name the name of the type to find.
12193 ///
12194 /// @param corp the corpus to look into.
12195 ///
12196 /// @return the typedef or class type found.
12197 type_base_sptr
lookup_class_or_typedef_type(const string & qualified_name,const corpus & corp)12198 lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
12199 {
12200 type_base_sptr result = lookup_class_type(qualified_name, corp);
12201 if (!result)
12202 result = lookup_union_type(qualified_name, corp);
12203
12204 if (!result)
12205 result = lookup_typedef_type(qualified_name, corp);
12206 return result;
12207 }
12208
12209 /// Look into a corpus to find a class, typedef or enum type which has
12210 /// a given qualified name.
12211 ///
12212 /// If the per-corpus type map is non-empty (because the corpus allows
12213 /// the One Definition Rule) then the type islooked up in that
12214 /// per-corpus type map. Otherwise, the type is looked-up in each
12215 /// translation unit.
12216 ///
12217 /// @param qualified_name the qualified name of the type to look for.
12218 ///
12219 /// @param corp the corpus to look into.
12220 ///
12221 /// @return the typedef, class or enum type found.
12222 type_base_sptr
lookup_class_typedef_or_enum_type(const string & qualified_name,const corpus & corp)12223 lookup_class_typedef_or_enum_type(const string& qualified_name,
12224 const corpus& corp)
12225 {
12226 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
12227 if (!result)
12228 result = lookup_enum_type(qualified_name, corp);
12229
12230 return result;
12231 }
12232
12233 /// Look into a given corpus to find a qualified type which has the
12234 /// same qualified name as a given type.
12235 ///
12236 /// @param t the type which has the same qualified name as the
12237 /// qualified type we are looking for.
12238 ///
12239 /// @param corp the corpus to look into.
12240 ///
12241 /// @return the qualified type found.
12242 qualified_type_def_sptr
lookup_qualified_type(const qualified_type_def & t,const corpus & corp)12243 lookup_qualified_type(const qualified_type_def& t, const corpus& corp)
12244 {
12245 interned_string s = get_type_name(t);
12246 return lookup_qualified_type(s, corp);
12247 }
12248
12249 /// Look into a given corpus to find a qualified type which has a
12250 /// given qualified name.
12251 ///
12252 /// @param qualified_name the qualified name of the type to look for.
12253 ///
12254 /// @param corp the corpus to look into.
12255 ///
12256 /// @return the type found.
12257 qualified_type_def_sptr
lookup_qualified_type(const interned_string & qualified_name,const corpus & corp)12258 lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
12259 {
12260 const istring_type_base_wptrs_map_type& m =
12261 corp.get_types().qualified_types();
12262
12263 qualified_type_def_sptr result =
12264 lookup_type_in_map<qualified_type_def>(qualified_name, m);
12265
12266 if (!result)
12267 result = lookup_qualified_type_through_translation_units(qualified_name,
12268 corp);
12269
12270 return result;
12271 }
12272
12273 /// Look into a given corpus to find a pointer type which has the same
12274 /// qualified name as a given pointer type.
12275 ///
12276 /// @param t the pointer type which has the same qualified name as the
12277 /// type we are looking for.
12278 ///
12279 /// @param corp the corpus to look into.
12280 ///
12281 /// @return the pointer type found.
12282 pointer_type_def_sptr
lookup_pointer_type(const pointer_type_def & t,const corpus & corp)12283 lookup_pointer_type(const pointer_type_def& t, const corpus& corp)
12284 {
12285 interned_string s = get_type_name(t);
12286 return lookup_pointer_type(s, corp);
12287 }
12288
12289 /// Look into a given corpus to find a pointer type which has a given
12290 /// qualified name.
12291 ///
12292 /// If the per-corpus type map is non-empty (because the corpus allows
12293 /// the One Definition Rule) then the type islooked up in that
12294 /// per-corpus type map. Otherwise, the type is looked-up in each
12295 /// translation unit.
12296 ///
12297 /// @param qualified_name the qualified name of the pointer type to
12298 /// look for.
12299 ///
12300 /// @param corp the corpus to look into.
12301 ///
12302 /// @return the pointer type found.
12303 pointer_type_def_sptr
lookup_pointer_type(const interned_string & qualified_name,const corpus & corp)12304 lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
12305 {
12306 const istring_type_base_wptrs_map_type& m = corp.get_types().pointer_types();
12307
12308 pointer_type_def_sptr result =
12309 lookup_type_in_map<pointer_type_def>(qualified_name, m);
12310 if (!result)
12311 result = lookup_pointer_type_through_translation_units(qualified_name,
12312 corp);
12313
12314 return result;
12315 }
12316
12317 /// Look into a given corpus to find a reference type which has the
12318 /// same qualified name as a given reference type.
12319 ///
12320 /// If the per-corpus type map is non-empty (because the corpus allows
12321 /// the One Definition Rule) then the type islooked up in that
12322 /// per-corpus type map. Otherwise, the type is looked-up in each
12323 /// translation unit.
12324 ///
12325 /// @param t the reference type which has the same qualified name as
12326 /// the reference type we are looking for.
12327 ///
12328 /// @param corp the corpus to look into.
12329 ///
12330 /// @return the reference type found.
12331 reference_type_def_sptr
lookup_reference_type(const reference_type_def & t,const corpus & corp)12332 lookup_reference_type(const reference_type_def& t, const corpus& corp)
12333 {
12334 interned_string s = get_type_name(t);
12335 return lookup_reference_type(s, corp);
12336 }
12337
12338 /// Look into a given corpus to find a reference type which has a
12339 /// given qualified name.
12340 ///
12341 /// If the per-corpus type map is non-empty (because the corpus allows
12342 /// the One Definition Rule) then the type islooked up in that
12343 /// per-corpus type map. Otherwise, the type is looked-up in each
12344 /// translation unit.
12345 ///
12346 /// @param qualified_name the qualified name of the reference type to
12347 /// look for.
12348 ///
12349 /// @param corp the corpus to look into.
12350 ///
12351 /// @return the reference type found.
12352 reference_type_def_sptr
lookup_reference_type(const interned_string & qualified_name,const corpus & corp)12353 lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
12354 {
12355 const istring_type_base_wptrs_map_type& m =
12356 corp.get_types().reference_types();
12357
12358 reference_type_def_sptr result =
12359 lookup_type_in_map<reference_type_def>(qualified_name, m);
12360 if (!result)
12361 result = lookup_reference_type_through_translation_units(qualified_name,
12362 corp);
12363
12364 return result;
12365 }
12366
12367 /// Look into a given corpus to find an array type which has a given
12368 /// qualified name.
12369 ///
12370 /// If the per-corpus type map is non-empty (because the corpus allows
12371 /// the One Definition Rule) then the type islooked up in that
12372 /// per-corpus type map. Otherwise, the type is looked-up in each
12373 /// translation unit.
12374 ///
12375 /// @param qualified_name the qualified name of the array type to look
12376 /// for.
12377 ///
12378 /// @param corp the corpus to look into.
12379 ///
12380 /// @return the array type found.
12381 array_type_def_sptr
lookup_array_type(const array_type_def & t,const corpus & corp)12382 lookup_array_type(const array_type_def& t, const corpus& corp)
12383 {
12384 interned_string s = get_type_name(t);
12385 return lookup_array_type(s, corp);
12386 }
12387
12388 /// Look into a given corpus to find an array type which has the same
12389 /// qualified name as a given array type.
12390 ///
12391 /// If the per-corpus type map is non-empty (because the corpus allows
12392 /// the One Definition Rule) then the type islooked up in that
12393 /// per-corpus type map. Otherwise, the type is looked-up in each
12394 /// translation unit.
12395 ///
12396 /// @param t the type which has the same qualified name as the type we
12397 /// are looking for.
12398 ///
12399 /// @param corp the corpus to look into.
12400 ///
12401 /// @return the type found.
12402 array_type_def_sptr
lookup_array_type(const interned_string & qualified_name,const corpus & corp)12403 lookup_array_type(const interned_string& qualified_name, const corpus& corp)
12404 {
12405 const istring_type_base_wptrs_map_type& m = corp.get_types().array_types();
12406
12407 array_type_def_sptr result =
12408 lookup_type_in_map<array_type_def>(qualified_name, m);
12409 if (!result)
12410 result = lookup_array_type_through_translation_units(qualified_name, corp);
12411
12412 return result;
12413 }
12414
12415 /// Look into a given corpus to find a function type which has the same
12416 /// qualified name as a given function type.
12417 ///
12418 /// If the per-corpus type map is non-empty (because the corpus allows
12419 /// the One Definition Rule) then the type islooked up in that
12420 /// per-corpus type map. Otherwise, the type is looked-up in each
12421 /// translation unit.
12422 ///
12423 /// @param t the function type which has the same qualified name as
12424 /// the function type we are looking for.
12425 ///
12426 /// @param corp the corpus to look into.
12427 ///
12428 /// @return the function type found.
12429 function_type_sptr
lookup_function_type(const function_type & t,const corpus & corp)12430 lookup_function_type(const function_type&t, const corpus& corp)
12431 {
12432 interned_string type_name = get_type_name(t);
12433 return lookup_function_type(type_name, corp);
12434 }
12435
12436 /// Look into a given corpus to find a function type which has the same
12437 /// qualified name as a given function type.
12438 ///
12439 /// If the per-corpus type map is non-empty (because the corpus allows
12440 /// the One Definition Rule) then the type islooked up in that
12441 /// per-corpus type map. Otherwise, the type is looked-up in each
12442 /// translation unit.
12443 ///
12444 /// @param t the function type which has the same qualified name as
12445 /// the function type we are looking for.
12446 ///
12447 /// @param corp the corpus to look into.
12448 ///
12449 /// @return the function type found.
12450 function_type_sptr
lookup_function_type(const function_type_sptr & fn_t,const corpus & corpus)12451 lookup_function_type(const function_type_sptr& fn_t,
12452 const corpus& corpus)
12453 {
12454 if (fn_t)
12455 return lookup_function_type(*fn_t, corpus);
12456 return function_type_sptr();
12457 }
12458
12459 /// Look into a given corpus to find a function type which has a given
12460 /// qualified name.
12461 ///
12462 /// If the per-corpus type map is non-empty (because the corpus allows
12463 /// the One Definition Rule) then the type islooked up in that
12464 /// per-corpus type map. Otherwise, the type is looked-up in each
12465 /// translation unit.
12466 ///
12467 /// @param qualified_name the qualified name of the function type to
12468 /// look for.
12469 ///
12470 /// @param corp the corpus to look into.
12471 ///
12472 /// @return the function type found.
12473 function_type_sptr
lookup_function_type(const interned_string & qualified_name,const corpus & corp)12474 lookup_function_type(const interned_string& qualified_name, const corpus& corp)
12475 {
12476 const istring_type_base_wptrs_map_type& m = corp.get_types().function_types();
12477
12478 function_type_sptr result =
12479 lookup_type_in_map<function_type>(qualified_name, m);
12480 if (!result)
12481 result = lookup_function_type_through_translation_units(qualified_name,
12482 corp);
12483
12484 return result;
12485 }
12486
12487 /// Look into a given corpus to find a type which has a given
12488 /// qualified name.
12489 ///
12490 /// If the per-corpus type map is non-empty (because the corpus allows
12491 /// the One Definition Rule) then the type islooked up in that
12492 /// per-corpus type map. Otherwise, the type is looked-up in each
12493 /// translation unit.
12494 ///
12495 /// @param qualified_name the qualified name of the function type to
12496 /// look for.
12497 ///
12498 /// @param corp the corpus to look into.
12499 ///
12500 /// @return the function type found.
12501 type_base_sptr
lookup_type(const interned_string & n,const corpus & corp)12502 lookup_type(const interned_string& n, const corpus& corp)
12503 {
12504 type_base_sptr result;
12505
12506 ((result = lookup_basic_type(n, corp))
12507 || (result = lookup_class_type(n, corp))
12508 || (result = lookup_union_type(n, corp))
12509 || (result = lookup_enum_type(n, corp))
12510 || (result = lookup_typedef_type(n, corp))
12511 || (result = lookup_qualified_type(n, corp))
12512 || (result = lookup_pointer_type(n, corp))
12513 || (result = lookup_reference_type(n, corp))
12514 || (result = lookup_array_type(n, corp))
12515 || (result= lookup_function_type(n, corp)));
12516
12517 return result;
12518 }
12519
12520 /// Lookup a type from a corpus, by its location.
12521 ///
12522 /// @param loc the location to consider.
12523 ///
12524 /// @param corp the corpus to look the type from.
12525 ///
12526 /// @return the resulting type, if any found.
12527 type_base_sptr
lookup_type_per_location(const interned_string & loc,const corpus & corp)12528 lookup_type_per_location(const interned_string& loc, const corpus& corp)
12529 {
12530 // TODO: finish this.
12531
12532 //TODO: when we fully support types indexed by their location, this
12533 //function should return a vector of types because at each location,
12534 //there can be several types that are defined (yay, C and C++,
12535 //*sigh*).
12536
12537 type_base_sptr result;
12538 ((result = lookup_basic_type_per_location(loc, corp))
12539 || (result = lookup_class_type_per_location(loc, corp))
12540 || (result = lookup_union_type_per_location(loc, corp))
12541 || (result = lookup_enum_type_per_location(loc, corp))
12542 || (result = lookup_typedef_type_per_location(loc, corp)));
12543
12544 return result;
12545 }
12546
12547 /// Look into a given corpus to find a type
12548 ///
12549 /// If the per-corpus type map is non-empty (because the corpus allows
12550 /// the One Definition Rule) then the type islooked up in that
12551 /// per-corpus type map. Otherwise, the type is looked-up in each
12552 /// translation unit.
12553 ///
12554 /// @param qualified_name the qualified name of the function type to
12555 /// look for.
12556 ///
12557 /// @param corp the corpus to look into.
12558 ///
12559 /// @return the function type found.
12560 type_base_sptr
lookup_type(const type_base & t,const corpus & corp)12561 lookup_type(const type_base&t, const corpus& corp)
12562 {
12563 interned_string n = get_type_name(t);
12564 return lookup_type(n, corp);
12565 }
12566
12567 /// Look into a given corpus to find a type
12568 ///
12569 /// If the per-corpus type map is non-empty (because the corpus allows
12570 /// the One Definition Rule) then the type islooked up in that
12571 /// per-corpus type map. Otherwise, the type is looked-up in each
12572 /// translation unit.
12573 ///
12574 /// @param qualified_name the qualified name of the function type to
12575 /// look for.
12576 ///
12577 /// @param corp the corpus to look into.
12578 ///
12579 /// @return the function type found.
12580 type_base_sptr
lookup_type(const type_base_sptr & t,const corpus & corp)12581 lookup_type(const type_base_sptr&t, const corpus& corp)
12582 {
12583 if (t)
12584 return lookup_type(*t, corp);
12585 return type_base_sptr();
12586 }
12587
12588 /// Update the map that associates a fully qualified name of a given
12589 /// type to that type.
12590 ///
12591 ///
12592 /// @param type the type we are considering.
12593 ///
12594 /// @param types_map the map to update. It's a map that assciates a
12595 /// fully qualified name of a type to the type itself.
12596 ///
12597 /// @param use_type_name_as_key if true, use the name of the type as
12598 /// the key to look it up later. If false, then use the location of
12599 /// the type as a key to look it up later.
12600 ///
12601 /// @return true iff the type was added to the map.
12602 template<typename TypeKind>
12603 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)12604 maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
12605 istring_type_base_wptrs_map_type& types_map,
12606 bool use_type_name_as_key = true)
12607 {
12608 interned_string s;
12609
12610 if (use_type_name_as_key)
12611 s = get_type_name(type);
12612 else if (location l = type->get_location())
12613 {
12614 string str = l.expand();
12615 s = type->get_environment()->intern(str);
12616 }
12617
12618 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
12619 bool result = false;
12620
12621 if (i == types_map.end())
12622 {
12623 types_map[s].push_back(type);
12624 result = true;
12625 }
12626 else
12627 i->second.push_back(type);
12628
12629 return result;
12630 }
12631
12632 /// This is the specialization for type @ref class_decl of the
12633 /// function template:
12634 ///
12635 /// maybe_update_types_lookup_map<T>(scope_decl*,
12636 /// const shared_ptr<T>&,
12637 /// istring_type_base_wptrs_map_type&)
12638 ///
12639 /// @param class_type the type to consider.
12640 ///
12641 /// @param types_map the type map to update.
12642 ///
12643 /// @return true iff the type was added to the map.
12644 template<>
12645 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)12646 maybe_update_types_lookup_map<class_decl>(const class_decl_sptr& class_type,
12647 istring_type_base_wptrs_map_type& map,
12648 bool use_type_name_as_key)
12649 {
12650 class_decl_sptr type = class_type;
12651
12652 bool update_qname_map = true;
12653 if (type->get_is_declaration_only())
12654 {
12655 if (class_decl_sptr def =
12656 is_class_type(class_type->get_definition_of_declaration()))
12657 type = def;
12658 else
12659 update_qname_map = false;
12660 }
12661
12662 if (!update_qname_map)
12663 return false;
12664
12665 interned_string s;
12666 if (use_type_name_as_key)
12667 {
12668 string qname = type->get_qualified_name();
12669 s = type->get_environment()->intern(qname);
12670 }
12671 else if (location l = type->get_location())
12672 {
12673 string str = l.expand();
12674 s = type->get_environment()->intern(str);
12675 }
12676
12677 bool result = false;
12678 istring_type_base_wptrs_map_type::iterator i = map.find(s);
12679 if (i == map.end())
12680 {
12681 map[s].push_back(type);
12682 result = true;
12683 }
12684 else
12685 i->second.push_back(type);
12686
12687 return result;
12688 }
12689
12690 /// This is the specialization for type @ref function_type of the
12691 /// function template:
12692 ///
12693 /// maybe_update_types_lookup_map<T>(scope_decl*,
12694 /// const shared_ptr<T>&,
12695 /// istring_type_base_wptrs_map_type&)
12696 ///
12697 /// @param scope the scope of the type to consider.
12698 ///
12699 /// @param class_type the type to consider.
12700 ///
12701 /// @param types_map the type map to update.
12702 ///
12703 /// @return true iff the type was added to the map.
12704 template<>
12705 bool
maybe_update_types_lookup_map(const function_type_sptr & type,istring_type_base_wptrs_map_type & types_map,bool)12706 maybe_update_types_lookup_map<function_type>
12707 (const function_type_sptr& type,
12708 istring_type_base_wptrs_map_type& types_map,
12709 bool /*use_type_name_as_key*/)
12710 {
12711 bool result = false;
12712 interned_string s = get_type_name(type);
12713 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
12714 if (i == types_map.end())
12715 {
12716 types_map[s].push_back(type);
12717 result = true;
12718 }
12719 else
12720 i->second.push_back(type);
12721
12722 return result;
12723 }
12724
12725 /// Update the map that associates the fully qualified name of a basic
12726 /// type with the type itself.
12727 ///
12728 /// The per-translation unit type map is updated if no type with this
12729 /// name was already existing in that map.
12730 ///
12731 /// If no type with this name did already exist in the per-corpus type
12732 /// map, then that per-corpus type map is updated. Otherwise, that
12733 /// type is erased from that per-corpus map.
12734 ///
12735 /// @param basic_type the basic type to consider.
12736 void
maybe_update_types_lookup_map(const type_decl_sptr & basic_type)12737 maybe_update_types_lookup_map(const type_decl_sptr& basic_type)
12738 {
12739 if (translation_unit *tu = basic_type->get_translation_unit())
12740 maybe_update_types_lookup_map<type_decl>
12741 (basic_type, tu->get_types().basic_types());
12742
12743 if (corpus *type_corpus = basic_type->get_corpus())
12744 {
12745 maybe_update_types_lookup_map<type_decl>
12746 (basic_type,
12747 type_corpus->priv_->get_types().basic_types());
12748
12749 maybe_update_types_lookup_map<type_decl>
12750 (basic_type,
12751 type_corpus->get_type_per_loc_map().basic_types(),
12752 /*use_type_name_as_key*/false);
12753
12754 if (corpus *group = type_corpus->get_group())
12755 {
12756 maybe_update_types_lookup_map<type_decl>
12757 (basic_type,
12758 group->priv_->get_types().basic_types());
12759
12760 maybe_update_types_lookup_map<type_decl>
12761 (basic_type,
12762 group->get_type_per_loc_map().basic_types(),
12763 /*use_type_name_as_key*/false);
12764 }
12765 }
12766
12767 }
12768
12769 /// Update the map that associates the fully qualified name of a class
12770 /// type with the type itself.
12771 ///
12772 /// The per-translation unit type map is updated if no type with this
12773 /// name was already existing in that map.
12774 ///
12775 /// If no type with this name did already exist in the per-corpus type
12776 /// map, then that per-corpus type map is updated. Otherwise, that
12777 /// type is erased from that per-corpus map.
12778 ///
12779 /// @param class_type the class type to consider.
12780 void
maybe_update_types_lookup_map(const class_decl_sptr & class_type)12781 maybe_update_types_lookup_map(const class_decl_sptr& class_type)
12782 {
12783 if (translation_unit *tu = class_type->get_translation_unit())
12784 maybe_update_types_lookup_map<class_decl>
12785 (class_type, tu->get_types().class_types());
12786
12787 if (corpus *type_corpus = class_type->get_corpus())
12788 {
12789 maybe_update_types_lookup_map<class_decl>
12790 (class_type,
12791 type_corpus->priv_->get_types().class_types());
12792
12793 maybe_update_types_lookup_map<class_decl>
12794 (class_type,
12795 type_corpus->get_type_per_loc_map().class_types(),
12796 /*use_type_name_as_key*/false);
12797
12798 if (corpus *group = type_corpus->get_group())
12799 {
12800 maybe_update_types_lookup_map<class_decl>
12801 (class_type,
12802 group->priv_->get_types().class_types());
12803
12804 maybe_update_types_lookup_map<class_decl>
12805 (class_type,
12806 group->get_type_per_loc_map().class_types(),
12807 /*use_type_name_as_key*/false);
12808 }
12809 }
12810 }
12811
12812 /// Update the map that associates the fully qualified name of a union
12813 /// type with the type itself.
12814 ///
12815 /// The per-translation unit type map is updated if no type with this
12816 /// name was already existing in that map.
12817 ///
12818 /// If no type with this name did already exist in the per-corpus type
12819 /// map, then that per-corpus type map is updated. Otherwise, that
12820 /// type is erased from that per-corpus map.
12821 ///
12822 /// @param union_type the union type to consider.
12823 void
maybe_update_types_lookup_map(const union_decl_sptr & union_type)12824 maybe_update_types_lookup_map(const union_decl_sptr& union_type)
12825 {
12826 if (translation_unit *tu = union_type->get_translation_unit())
12827 maybe_update_types_lookup_map<union_decl>
12828 (union_type, tu->get_types().union_types());
12829
12830 if (corpus *type_corpus = union_type->get_corpus())
12831 {
12832 maybe_update_types_lookup_map<union_decl>
12833 (union_type,
12834 type_corpus->priv_->get_types().union_types());
12835
12836 maybe_update_types_lookup_map<union_decl>
12837 (union_type,
12838 type_corpus->get_type_per_loc_map().union_types(),
12839 /*use_type_name_as_key*/false);
12840
12841 if (corpus *group = type_corpus->get_group())
12842 {
12843 maybe_update_types_lookup_map<union_decl>
12844 (union_type,
12845 group->priv_->get_types().union_types());
12846
12847 maybe_update_types_lookup_map<union_decl>
12848 (union_type,
12849 group->get_type_per_loc_map().union_types(),
12850 /*use_type_name_as_key*/false);
12851 }
12852 }
12853 }
12854
12855 /// Update the map that associates the fully qualified name of an enum
12856 /// type with the type itself.
12857 ///
12858 /// The per-translation unit type map is updated if no type with this
12859 /// name was already existing in that map.
12860 ///
12861 /// If no type with this name did already exist in the per-corpus type
12862 /// map, then that per-corpus type map is updated. Otherwise, that
12863 /// type is erased from that per-corpus map.
12864 ///
12865 /// @param enum_type the type to consider.
12866 void
maybe_update_types_lookup_map(const enum_type_decl_sptr & enum_type)12867 maybe_update_types_lookup_map(const enum_type_decl_sptr& enum_type)
12868 {
12869 if (translation_unit *tu = enum_type->get_translation_unit())
12870 maybe_update_types_lookup_map<enum_type_decl>
12871 (enum_type, tu->get_types().enum_types());
12872
12873 if (corpus *type_corpus = enum_type->get_corpus())
12874 {
12875 maybe_update_types_lookup_map<enum_type_decl>
12876 (enum_type,
12877 type_corpus->priv_->get_types().enum_types());
12878
12879 maybe_update_types_lookup_map<enum_type_decl>
12880 (enum_type,
12881 type_corpus->get_type_per_loc_map().enum_types(),
12882 /*use_type_name_as_key*/false);
12883
12884 if (corpus *group = type_corpus->get_group())
12885 {
12886 maybe_update_types_lookup_map<enum_type_decl>
12887 (enum_type,
12888 group->priv_->get_types().enum_types());
12889
12890 maybe_update_types_lookup_map<enum_type_decl>
12891 (enum_type,
12892 group->get_type_per_loc_map().enum_types(),
12893 /*use_type_name_as_key*/false);
12894 }
12895 }
12896
12897 }
12898
12899 /// Update the map that associates the fully qualified name of a
12900 /// typedef type with the type itself.
12901 ///
12902 /// The per-translation unit type map is updated if no type with this
12903 /// name was already existing in that map.
12904 ///
12905 /// If no type with this name did already exist in the per-corpus type
12906 /// map, then that per-corpus type map is updated. Otherwise, that
12907 /// type is erased from that per-corpus map.
12908 ///
12909 /// @param typedef_type the type to consider.
12910 void
maybe_update_types_lookup_map(const typedef_decl_sptr & typedef_type)12911 maybe_update_types_lookup_map(const typedef_decl_sptr& typedef_type)
12912 {
12913 if (translation_unit *tu = typedef_type->get_translation_unit())
12914 maybe_update_types_lookup_map<typedef_decl>
12915 (typedef_type, tu->get_types().typedef_types());
12916
12917 if (corpus *type_corpus = typedef_type->get_corpus())
12918 {
12919 maybe_update_types_lookup_map<typedef_decl>
12920 (typedef_type,
12921 type_corpus->priv_->get_types().typedef_types());
12922
12923 maybe_update_types_lookup_map<typedef_decl>
12924 (typedef_type,
12925 type_corpus->get_type_per_loc_map().typedef_types(),
12926 /*use_type_name_as_key*/false);
12927
12928 if (corpus *group = type_corpus->get_group())
12929 {
12930 maybe_update_types_lookup_map<typedef_decl>
12931 (typedef_type,
12932 group->priv_->get_types().typedef_types());
12933
12934 maybe_update_types_lookup_map<typedef_decl>
12935 (typedef_type,
12936 group->get_type_per_loc_map().typedef_types(),
12937 /*use_type_name_as_key*/false);
12938 }
12939 }
12940 }
12941
12942 /// Update the map that associates the fully qualified name of a
12943 /// qualified type with the type itself.
12944 ///
12945 /// The per-translation unit type map is updated if no type with this
12946 /// name was already existing in that map.
12947 ///
12948 /// If no type with this name did already exist in the per-corpus type
12949 /// map, then that per-corpus type map is updated. Otherwise, that
12950 /// type is erased from that per-corpus map.
12951 ///
12952 /// @param qualified_type the type to consider.
12953 void
maybe_update_types_lookup_map(const qualified_type_def_sptr & qualified_type)12954 maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
12955 {
12956 if (translation_unit *tu = qualified_type->get_translation_unit())
12957 maybe_update_types_lookup_map<qualified_type_def>
12958 (qualified_type, tu->get_types().qualified_types());
12959
12960 if (corpus *type_corpus = qualified_type->get_corpus())
12961 {
12962 maybe_update_types_lookup_map<qualified_type_def>
12963 (qualified_type,
12964 type_corpus->priv_->get_types().qualified_types());
12965
12966 if (corpus *group = type_corpus->get_group())
12967 {
12968 maybe_update_types_lookup_map<qualified_type_def>
12969 (qualified_type,
12970 group->priv_->get_types().qualified_types());
12971 }
12972 }
12973 }
12974
12975 /// Update the map that associates the fully qualified name of a
12976 /// pointer type with the type itself.
12977 ///
12978 /// The per-translation unit type map is updated if no type with this
12979 /// name was already existing in that map.
12980 ///
12981 /// If no type with this name did already exist in the per-corpus type
12982 /// map, then that per-corpus type map is updated. Otherwise, that
12983 /// type is erased from that per-corpus map.
12984 ///
12985 /// @param pointer_type the type to consider.
12986 void
maybe_update_types_lookup_map(const pointer_type_def_sptr & pointer_type)12987 maybe_update_types_lookup_map(const pointer_type_def_sptr& pointer_type)
12988 {
12989 if (translation_unit *tu = pointer_type->get_translation_unit())
12990 maybe_update_types_lookup_map<pointer_type_def>
12991 (pointer_type, tu->get_types().pointer_types());
12992
12993 if (corpus *type_corpus = pointer_type->get_corpus())
12994 {
12995 maybe_update_types_lookup_map<pointer_type_def>
12996 (pointer_type,
12997 type_corpus->priv_->get_types().pointer_types());
12998
12999 if (corpus *group = type_corpus->get_group())
13000 {
13001 maybe_update_types_lookup_map<pointer_type_def>
13002 (pointer_type,
13003 group->priv_->get_types().pointer_types());
13004 }
13005 }
13006 }
13007
13008 /// Update the map that associates the fully qualified name of a
13009 /// reference type with the type itself.
13010 ///
13011 /// The per-translation unit type map is updated if no type with this
13012 /// name was already existing in that map.
13013 ///
13014 /// If no type with this name did already exist in the per-corpus type
13015 /// map, then that per-corpus type map is updated. Otherwise, that
13016 /// type is erased from that per-corpus map.
13017 ///
13018 /// @param reference_type the type to consider.
13019 void
maybe_update_types_lookup_map(const reference_type_def_sptr & reference_type)13020 maybe_update_types_lookup_map(const reference_type_def_sptr& reference_type)
13021 {
13022 if (translation_unit *tu = reference_type->get_translation_unit())
13023 maybe_update_types_lookup_map<reference_type_def>
13024 (reference_type, tu->get_types().reference_types());
13025
13026 if (corpus *type_corpus = reference_type->get_corpus())
13027 {
13028 maybe_update_types_lookup_map<reference_type_def>
13029 (reference_type,
13030 type_corpus->priv_->get_types().reference_types());
13031
13032 if (corpus *group = type_corpus->get_group())
13033 {
13034 maybe_update_types_lookup_map<reference_type_def>
13035 (reference_type,
13036 group->priv_->get_types().reference_types());
13037 }
13038 }
13039 }
13040
13041 /// Update the map that associates the fully qualified name of a type
13042 /// with the type itself.
13043 ///
13044 /// The per-translation unit type map is updated if no type with this
13045 /// name was already existing in that map.
13046 ///
13047 /// If no type with this name did already exist in the per-corpus type
13048 /// map, then that per-corpus type map is updated. Otherwise, that
13049 /// type is erased from that per-corpus map.
13050 ///
13051 /// @param array_type the type to consider.
13052 void
maybe_update_types_lookup_map(const array_type_def_sptr & array_type)13053 maybe_update_types_lookup_map(const array_type_def_sptr& array_type)
13054 {
13055 if (translation_unit *tu = array_type->get_translation_unit())
13056 maybe_update_types_lookup_map<array_type_def>
13057 (array_type, tu->get_types().array_types());
13058
13059 if (corpus *type_corpus = array_type->get_corpus())
13060 {
13061 maybe_update_types_lookup_map<array_type_def>
13062 (array_type,
13063 type_corpus->priv_->get_types().array_types());
13064
13065 maybe_update_types_lookup_map<array_type_def>
13066 (array_type,
13067 type_corpus->get_type_per_loc_map().array_types(),
13068 /*use_type_name_as_key*/false);
13069
13070 if (corpus *group = type_corpus->get_group())
13071 {
13072 maybe_update_types_lookup_map<array_type_def>
13073 (array_type,
13074 group->priv_->get_types().array_types());
13075
13076 maybe_update_types_lookup_map<array_type_def>
13077 (array_type,
13078 group->get_type_per_loc_map().array_types(),
13079 /*use_type_name_as_key*/false);
13080 }
13081 }
13082 }
13083
13084 /// Update the map that associates the fully qualified name of a type
13085 /// with the type itself.
13086 ///
13087 /// The per-translation unit type map is updated if no type with this
13088 /// name was already existing in that map.
13089 ///
13090 /// If no type with this name did already exist in the per-corpus type
13091 /// map, then that per-corpus type map is updated. Otherwise, that
13092 /// type is erased from that per-corpus map.
13093 ///
13094 /// @param subrange_type the type to consider.
13095 void
maybe_update_types_lookup_map(const array_type_def::subrange_sptr & subrange_type)13096 maybe_update_types_lookup_map
13097 (const array_type_def::subrange_sptr& subrange_type)
13098 {
13099 if (translation_unit *tu = subrange_type->get_translation_unit())
13100 maybe_update_types_lookup_map<array_type_def::subrange_type>
13101 (subrange_type, tu->get_types().subrange_types());
13102
13103 if (corpus *type_corpus = subrange_type->get_corpus())
13104 {
13105 maybe_update_types_lookup_map<array_type_def::subrange_type>
13106 (subrange_type,
13107 type_corpus->priv_->get_types().subrange_types());
13108
13109 maybe_update_types_lookup_map<array_type_def::subrange_type>
13110 (subrange_type,
13111 type_corpus->get_type_per_loc_map().subrange_types(),
13112 /*use_type_name_as_key*/false);
13113
13114 if (corpus *group = subrange_type->get_corpus())
13115 {
13116 maybe_update_types_lookup_map<array_type_def::subrange_type>
13117 (subrange_type,
13118 group->priv_->get_types().subrange_types());
13119
13120 maybe_update_types_lookup_map<array_type_def::subrange_type>
13121 (subrange_type,
13122 group->get_type_per_loc_map().subrange_types(),
13123 /*use_type_name_as_key*/false);
13124 }
13125 }
13126 }
13127
13128 /// Update the map that associates the fully qualified name of a
13129 /// function type with the type itself.
13130 ///
13131 /// The per-translation unit type map is updated if no type with this
13132 /// name was already existing in that map.
13133 ///
13134 /// If no type with this name did already exist in the per-corpus type
13135 /// map, then that per-corpus type map is updated. Otherwise, that
13136 /// type is erased from that per-corpus map.
13137 ///
13138 /// @param scope the scope of the function type.
13139 /// @param fn_type the type to consider.
13140 void
maybe_update_types_lookup_map(const function_type_sptr & fn_type)13141 maybe_update_types_lookup_map(const function_type_sptr& fn_type)
13142 {
13143 if (translation_unit *tu = fn_type->get_translation_unit())
13144 maybe_update_types_lookup_map<function_type>
13145 (fn_type, tu->get_types().function_types());
13146
13147 if (corpus *type_corpus = fn_type->get_corpus())
13148 {
13149 maybe_update_types_lookup_map<function_type>
13150 (fn_type,
13151 type_corpus->priv_->get_types().function_types());
13152
13153 if (corpus *group = fn_type->get_corpus())
13154 {
13155 maybe_update_types_lookup_map<function_type>
13156 (fn_type,
13157 group->priv_->get_types().function_types());
13158 }
13159 }
13160 }
13161
13162 /// Update the map that associates the fully qualified name of a type
13163 /// declaration with the type itself.
13164 ///
13165 /// The per-translation unit type map is updated if no type with this
13166 /// name was already existing in that map.
13167 ///
13168 /// If no type with this name did already exist in the per-corpus type
13169 /// map, then that per-corpus type map is updated. Otherwise, that
13170 /// type is erased from that per-corpus map.
13171 ///
13172 /// @param decl the declaration of the type to consider.
13173 void
maybe_update_types_lookup_map(const decl_base_sptr & decl)13174 maybe_update_types_lookup_map(const decl_base_sptr& decl)
13175 {
13176 if (!is_type(decl))
13177 return;
13178
13179 if (type_decl_sptr basic_type = is_type_decl(decl))
13180 maybe_update_types_lookup_map(basic_type);
13181 else if (class_decl_sptr class_type = is_class_type(decl))
13182 maybe_update_types_lookup_map(class_type);
13183 else if (union_decl_sptr union_type = is_union_type(decl))
13184 maybe_update_types_lookup_map(union_type);
13185 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
13186 maybe_update_types_lookup_map(enum_type);
13187 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
13188 maybe_update_types_lookup_map(typedef_type);
13189 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
13190 maybe_update_types_lookup_map(qualified_type);
13191 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
13192 maybe_update_types_lookup_map(pointer_type);
13193 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
13194 maybe_update_types_lookup_map(reference_type);
13195 else if (array_type_def_sptr array_type = is_array_type(decl))
13196 maybe_update_types_lookup_map(array_type);
13197 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
13198 maybe_update_types_lookup_map(subrange_type);
13199 else
13200 ABG_ASSERT_NOT_REACHED;
13201 }
13202
13203 /// Update the map that associates the fully qualified name of a type
13204 /// with the type itself.
13205 ///
13206 /// The per-translation unit type map is updated if no type with this
13207 /// name was already existing in that map.
13208 ///
13209 /// If no type with this name did already exist in the per-corpus type
13210 /// map, then that per-corpus type map is updated. Otherwise, that
13211 /// type is erased from that per-corpus map.
13212 ///
13213 /// @param type the type to consider.
13214 void
maybe_update_types_lookup_map(const type_base_sptr & type)13215 maybe_update_types_lookup_map(const type_base_sptr& type)
13216 {
13217 if (decl_base_sptr decl = get_type_declaration(type))
13218 maybe_update_types_lookup_map(decl);
13219 else
13220 ABG_ASSERT_NOT_REACHED;
13221 }
13222
13223 //--------------------------------
13224 // </type and decls lookup stuff>
13225 // ------------------------------
13226
13227 /// In a translation unit, lookup a given type or synthesize it if
13228 /// it's a qualified type.
13229 ///
13230 /// So this function first looks the type up in the translation unit.
13231 /// If it's found, then OK, it's returned. Otherwise, if it's a
13232 /// qualified, reference or pointer or function type (a composite
13233 /// type), lookup the underlying type, synthesize the type we want
13234 /// from it and return it.
13235 ///
13236 /// If the underlying types is not not found, then give up and return
13237 /// nil.
13238 ///
13239 /// @return the type that was found or the synthesized type.
13240 type_base_sptr
synthesize_type_from_translation_unit(const type_base_sptr & type,translation_unit & tu)13241 synthesize_type_from_translation_unit(const type_base_sptr& type,
13242 translation_unit& tu)
13243 {
13244 type_base_sptr result;
13245
13246 result = lookup_type(type, tu);
13247
13248 if (!result)
13249 {
13250 if (qualified_type_def_sptr qual = is_qualified_type(type))
13251 {
13252 type_base_sptr underlying_type =
13253 synthesize_type_from_translation_unit(qual->get_underlying_type(),
13254 tu);
13255 if (underlying_type)
13256 {
13257 result.reset(new qualified_type_def(underlying_type,
13258 qual->get_cv_quals(),
13259 qual->get_location()));
13260 }
13261 }
13262 else if (pointer_type_def_sptr p = is_pointer_type(type))
13263 {
13264 type_base_sptr pointed_to_type =
13265 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
13266 tu);
13267 if (pointed_to_type)
13268 {
13269 result.reset(new pointer_type_def(pointed_to_type,
13270 p->get_size_in_bits(),
13271 p->get_alignment_in_bits(),
13272 p->get_location()));
13273 result->set_environment(pointed_to_type->get_environment());
13274 }
13275 }
13276 else if (reference_type_def_sptr r = is_reference_type(type))
13277 {
13278 type_base_sptr pointed_to_type =
13279 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
13280 if (pointed_to_type)
13281 {
13282 result.reset(new reference_type_def(pointed_to_type,
13283 r->is_lvalue(),
13284 r->get_size_in_bits(),
13285 r->get_alignment_in_bits(),
13286 r->get_location()));
13287 result->set_environment(pointed_to_type->get_environment());
13288 }
13289 }
13290 else if (function_type_sptr f = is_function_type(type))
13291 result = synthesize_function_type_from_translation_unit(*f, tu);
13292
13293 if (result)
13294 {
13295 add_decl_to_scope(is_decl(result), tu.get_global_scope());
13296 canonicalize(result);
13297 }
13298 }
13299
13300 if (result)
13301 tu.priv_->synthesized_types_.push_back(result);
13302
13303 return result;
13304 }
13305
13306 /// In a translation unit, lookup the sub-types that make up a given
13307 /// function type and if the sub-types are all found, synthesize and
13308 /// return a function_type with them.
13309 ///
13310 /// This function is like lookup_function_type_in_translation_unit()
13311 /// execept that it constructs the function type from the sub-types
13312 /// found in the translation, rather than just looking for the
13313 /// function types held by the translation unit. This can be useful
13314 /// if the translation unit doesnt hold the function type we are
13315 /// looking for (i.e, lookup_function_type_in_translation_unit()
13316 /// returned NULL) but we still want to see if the sub-types of the
13317 /// function types are present in the translation unit.
13318 ///
13319 /// @param fn_type the function type to consider.
13320 ///
13321 /// @param tu the translation unit to look into.
13322 ///
13323 /// @return the resulting synthesized function type if all its
13324 /// sub-types have been found, NULL otherwise.
13325 function_type_sptr
synthesize_function_type_from_translation_unit(const function_type & fn_type,translation_unit & tu)13326 synthesize_function_type_from_translation_unit(const function_type& fn_type,
13327 translation_unit& tu)
13328 {
13329 function_type_sptr nil = function_type_sptr();
13330
13331 environment* env = tu.get_environment();
13332 ABG_ASSERT(env);
13333
13334 type_base_sptr return_type = fn_type.get_return_type();
13335 type_base_sptr result_return_type;
13336 if (!return_type || env->is_void_type(return_type))
13337 result_return_type = env->get_void_type();
13338 else
13339 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
13340 if (!result_return_type)
13341 return nil;
13342
13343 function_type::parameters parms;
13344 type_base_sptr parm_type;
13345 function_decl::parameter_sptr parm;
13346 for (function_type::parameters::const_iterator i =
13347 fn_type.get_parameters().begin();
13348 i != fn_type.get_parameters().end();
13349 ++i)
13350 {
13351 type_base_sptr t = (*i)->get_type();
13352 parm_type = synthesize_type_from_translation_unit(t, tu);
13353 if (!parm_type)
13354 return nil;
13355 parm.reset(new function_decl::parameter(parm_type,
13356 (*i)->get_index(),
13357 (*i)->get_name(),
13358 (*i)->get_location(),
13359 (*i)->get_variadic_marker(),
13360 (*i)->get_is_artificial()));
13361 parms.push_back(parm);
13362 }
13363
13364 class_or_union_sptr class_type;
13365 const method_type* method = is_method_type(&fn_type);
13366 if (method)
13367 {
13368 class_type = is_class_or_union_type
13369 (synthesize_type_from_translation_unit(method->get_class_type(), tu));
13370 ABG_ASSERT(class_type);
13371 }
13372
13373 function_type_sptr result_fn_type;
13374
13375 if (class_type)
13376 result_fn_type.reset(new method_type(result_return_type,
13377 class_type,
13378 parms,
13379 method->get_is_const(),
13380 fn_type.get_size_in_bits(),
13381 fn_type.get_alignment_in_bits()));
13382 else
13383 result_fn_type.reset(new function_type(result_return_type,
13384 parms,
13385 fn_type.get_size_in_bits(),
13386 fn_type.get_alignment_in_bits()));
13387
13388 tu.priv_->synthesized_types_.push_back(result_fn_type);
13389 // The new synthesized type must be in the same environment as its
13390 // translation unit.
13391 result_fn_type->set_environment(tu.get_environment());
13392 tu.bind_function_type_life_time(result_fn_type);
13393
13394 canonicalize(result_fn_type);
13395 return result_fn_type;
13396 }
13397
13398 /// Demangle a C++ mangled name and return the resulting string
13399 ///
13400 /// @param mangled_name the C++ mangled name to demangle.
13401 ///
13402 /// @return the resulting mangled name.
13403 string
demangle_cplus_mangled_name(const string & mangled_name)13404 demangle_cplus_mangled_name(const string& mangled_name)
13405 {
13406 if (mangled_name.empty())
13407 return "";
13408
13409 size_t l = 0;
13410 int status = 0;
13411 char * str = abi::__cxa_demangle(mangled_name.c_str(),
13412 NULL, &l, &status);
13413 string demangled_name = mangled_name;
13414 if (str)
13415 {
13416 ABG_ASSERT(status == 0);
13417 demangled_name = str;
13418 free(str);
13419 str = 0;
13420 }
13421 return demangled_name;
13422 }
13423
13424 /// Return either the type given in parameter if it's non-null, or the
13425 /// void type.
13426 ///
13427 /// @param t the type to consider.
13428 ///
13429 /// @param env the environment to use. If NULL, just abort the
13430 /// process.
13431 ///
13432 /// @return either @p t if it is non-null, or the void type.
13433 type_base_sptr
type_or_void(const type_base_sptr t,const environment * env)13434 type_or_void(const type_base_sptr t, const environment* env)
13435 {
13436 type_base_sptr r;
13437
13438 if (t)
13439 r = t;
13440 else
13441 {
13442 ABG_ASSERT(env);
13443 r = type_base_sptr(env->get_void_type());
13444 }
13445
13446 return r;
13447 }
13448
~global_scope()13449 global_scope::~global_scope()
13450 {
13451 }
13452
13453 static bool
13454 maybe_propagate_canonical_type(const type_base& lhs_type,
13455 const type_base& rhs_type);
13456
13457 /// Test if two types are eligible to the "Linux Kernel Fast Type
13458 /// Comparison Optimization", a.k.a LKFTCO.
13459 ///
13460 /// Two types T1 and T2 (who are presumably of the same name and kind)
13461 /// are eligible to the LKFTCO if they fulfill the following criteria/
13462 ///
13463 /// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
13464 /// either class, union or enums.
13465 ///
13466 /// 2/ They are defined in the same translation unit.
13467 ///
13468 /// @param t1 the first type to consider.
13469 ///
13470 /// @param t2 the second type to consider.
13471 ///
13472 /// @return true iff t1 and t2 are eligible to the LKFTCO.
13473 static bool
types_defined_same_linux_kernel_corpus_public(const type_base & t1,const type_base & t2)13474 types_defined_same_linux_kernel_corpus_public(const type_base& t1,
13475 const type_base& t2)
13476 {
13477 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
13478 string t1_file_path, t2_file_path;
13479
13480 /// If the t1 (and t2) are classes/unions/enums from the same linux
13481 /// kernel corpus, let's move on. Otherwise bail out.
13482 if (!(t1_corpus && t2_corpus
13483 && t1_corpus == t2_corpus
13484 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
13485 && (is_class_or_union_type(&t1)
13486 || is_enum_type(&t1))))
13487 return false;
13488
13489 class_or_union *c1 = 0, *c2 = 0;
13490 c1 = is_class_or_union_type(&t1);
13491 c2 = is_class_or_union_type(&t2);
13492
13493 // Two anonymous class types with no naming typedefs cannot be
13494 // eligible to this optimization.
13495 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
13496 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
13497 return false;
13498
13499 // Two anonymous classes with naming typedefs should have the same
13500 // typedef name.
13501 if (c1
13502 && c2
13503 && c1->get_is_anonymous() && c1->get_naming_typedef()
13504 && c2->get_is_anonymous() && c2->get_naming_typedef())
13505 if (c1->get_naming_typedef()->get_name()
13506 != c2->get_naming_typedef()->get_name())
13507 return false;
13508
13509 // Two anonymous enum types cannot be eligible to this optimization.
13510 if (const enum_type_decl *e1 = is_enum_type(&t1))
13511 if (const enum_type_decl *e2 = is_enum_type(&t2))
13512 if (e1->get_is_anonymous() || e2->get_is_anonymous())
13513 return false;
13514
13515 // Look through declaration-only types. That is, get the associated
13516 // definition type.
13517 c1 = look_through_decl_only_class(c1);
13518 c2 = look_through_decl_only_class(c2);
13519
13520 if (c1 && c2)
13521 {
13522 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
13523 {
13524 if (c1->get_environment()->decl_only_class_equals_definition())
13525 // At least one of classes/union is declaration-only.
13526 // Because we are in a context in which a declaration-only
13527 // class/union is equal to all definitions of that
13528 // class/union, we can assume that the two types are
13529 // equal.
13530 return true;
13531 }
13532 }
13533
13534 if (t1.get_size_in_bits() != t2.get_size_in_bits())
13535 return false;
13536
13537 // Look at the file names of the locations of t1 and t2. If they
13538 // are equal, then t1 and t2 are defined in the same file.
13539 {
13540 location l;
13541
13542 if (c1)
13543 l = c1->get_location();
13544 else
13545 l = dynamic_cast<const decl_base&>(t1).get_location();
13546
13547 unsigned line = 0, col = 0;
13548 if (l)
13549 l.expand(t1_file_path, line, col);
13550 if (c2)
13551 l = c2->get_location();
13552 else
13553 l = dynamic_cast<const decl_base&>(t2).get_location();
13554 if (l)
13555 l.expand(t2_file_path, line, col);
13556 }
13557
13558 if (t1_file_path.empty() || t2_file_path.empty())
13559 return false;
13560
13561 if (t1_file_path == t2_file_path)
13562 return true;
13563
13564 return false;
13565 }
13566
13567
13568 /// Compare a type T against a canonical type.
13569 ///
13570 /// This function is called during the canonicalization process of the
13571 /// type T. T is called the "candidate type" because it's in the
13572 /// process of being canonicalized. Meaning, it's going to be
13573 /// compared to a canonical type C. If T equals C, then the canonical
13574 /// type of T is C.
13575 ///
13576 /// The purpose of this function is to allow the debugging of the
13577 /// canonicalization of T, if that debugging is activated by
13578 /// configuring the libabigail package with
13579 /// --enable-debug-type-canonicalization and by running "abidw
13580 /// --debug-tc". In that case, T is going to be compared to C twice:
13581 /// once with canonical equality and once with structural equality.
13582 /// The two comparisons must be equal. Otherwise, the
13583 /// canonicalization process is said to be faulty and this function
13584 /// aborts.
13585 ///
13586 /// This is a sub-routine of type_base::get_canonical_type_for.
13587 ///
13588 /// @param canonical_type the canonical type to compare the candidate
13589 /// type against.
13590 ///
13591 /// @param candidate_type the candidate type to compare against the
13592 /// canonical type.
13593 ///
13594 /// @return true iff @p canonical_type equals @p candidate_type.
13595 ///
13596 static bool
compare_types_during_canonicalization(const type_base_sptr & canonical_type,const type_base_sptr & candidate_type)13597 compare_types_during_canonicalization(const type_base_sptr& canonical_type,
13598 const type_base_sptr& candidate_type)
13599 {
13600 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
13601 environment *env = canonical_type->get_environment();
13602 if (env->debug_type_canonicalization_is_on())
13603 {
13604 bool canonical_equality = false, structural_equality = false;
13605 env->priv_->use_canonical_type_comparison_ = true;
13606 canonical_equality = canonical_type == candidate_type;
13607 env->priv_->use_canonical_type_comparison_ = false;
13608 structural_equality = canonical_type == candidate_type;
13609 if (canonical_equality != structural_equality)
13610 {
13611 std::cerr << "structural & canonical equality different for type: "
13612 << canonical_type->get_pretty_representation(true, true)
13613 << std::endl;
13614 ABG_ASSERT_NOT_REACHED;
13615 }
13616 return structural_equality;
13617 }
13618 #endif //end WITH_DEBUG_TYPE_CANONICALIZATION
13619 return canonical_type == candidate_type;
13620 }
13621
13622 /// Compute the canonical type for a given instance of @ref type_base.
13623 ///
13624 /// Consider two types T and T'. The canonical type of T, denoted
13625 /// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
13626 /// otherwise, to compare two types, one just needs to compare their
13627 /// canonical types using pointer equality. That makes type
13628 /// comparison faster than the structural comparison performed by the
13629 /// abigail::ir::equals() overloads.
13630 ///
13631 /// If there is not yet any canonical type for @p t, then @p t is its
13632 /// own canonical type. Otherwise, this function returns the
13633 /// canonical type of @p t which is the canonical type that has the
13634 /// same hash value as @p t and that structurally equals @p t. Note
13635 /// that after invoking this function, the life time of the returned
13636 /// canonical time is then equals to the life time of the current
13637 /// process.
13638 ///
13639 /// @param t a smart pointer to instance of @ref type_base we want to
13640 /// compute a canonical type for.
13641 ///
13642 /// @return the canonical type for the current instance of @ref
13643 /// type_base.
13644 type_base_sptr
get_canonical_type_for(type_base_sptr t)13645 type_base::get_canonical_type_for(type_base_sptr t)
13646 {
13647 if (!t)
13648 return t;
13649
13650 environment* env = t->get_environment();
13651 ABG_ASSERT(env);
13652
13653 if (is_non_canonicalized_type(t))
13654 // This type should not be canonicalized!
13655 return type_base_sptr();
13656
13657 bool decl_only_class_equals_definition =
13658 (odr_is_relevant(*t) || env->decl_only_class_equals_definition());
13659
13660 class_or_union_sptr class_or_union = is_class_or_union_type(t);
13661
13662 // Look through declaration-only classes when we are dealing with
13663 // C++ or languages where we assume the "One Definition Rule". In
13664 // that context, we assume that a declaration-only non-anonymous
13665 // class equals all fully defined classes of the same name.
13666 //
13667 // Otherwise, all classes, including declaration-only classes are
13668 // canonicalized and only canonical comparison is going to be used
13669 // in the system.
13670 if (decl_only_class_equals_definition)
13671 if (class_or_union)
13672 {
13673 class_or_union = look_through_decl_only_class(class_or_union);
13674 if (class_or_union->get_is_declaration_only())
13675 return type_base_sptr();
13676 else
13677 t = class_or_union;
13678 }
13679
13680 class_decl_sptr is_class = is_class_type(t);
13681 if (t->get_canonical_type())
13682 return t->get_canonical_type();
13683
13684 // For classes and union, ensure that an anonymous class doesn't
13685 // have a linkage name. If it does in the future, then me must be
13686 // mindful that the linkage name respects the type identity
13687 // constraints which states that "if two linkage names are different
13688 // then the two types are different".
13689 ABG_ASSERT(!class_or_union
13690 || !class_or_union->get_is_anonymous()
13691 || class_or_union->get_linkage_name().empty());
13692
13693 // We want the pretty representation of the type, but for an
13694 // internal use, not for a user-facing purpose.
13695 //
13696 // If two classe types Foo are declared, one as a class and the
13697 // other as a struct, but are otherwise equivalent, we want their
13698 // pretty representation to be the same. Hence the 'internal'
13699 // argument of ir::get_pretty_representation() is set to true here.
13700 // So in this case, the pretty representation of Foo is going to be
13701 // "class Foo", regardless of its struct-ness. This also applies to
13702 // composite types which would have "class Foo" as a sub-type.
13703 string repr = t->get_cached_pretty_representation(/*internal=*/true);
13704
13705 // If 't' already has a canonical type 'inside' its corpus
13706 // (t_corpus), then this variable is going to contain that canonical
13707 // type.
13708 type_base_sptr canonical_type_present_in_corpus;
13709 environment::canonical_types_map_type& types =
13710 env->get_canonical_types_map();
13711
13712 type_base_sptr result;
13713 environment::canonical_types_map_type::iterator i = types.find(repr);
13714 if (i == types.end())
13715 {
13716 vector<type_base_sptr> v;
13717 v.push_back(t);
13718 types[repr] = v;
13719 result = t;
13720 }
13721 else
13722 {
13723 vector<type_base_sptr> &v = i->second;
13724 // Let's compare 't' structurally (i.e, compare its sub-types
13725 // recursively) against the canonical types of the system. If it
13726 // equals a given canonical type C, then it means C is the
13727 // canonical type of 't'. Otherwise, if 't' is different from
13728 // all the canonical types of the system, then it means 't' is a
13729 // canonical type itself.
13730 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
13731 it != v.rend();
13732 ++it)
13733 {
13734 // Before the "*it == it" comparison below is done, let's
13735 // perform on-the-fly-canonicalization. For C types, let's
13736 // consider that an unresolved struct declaration 'struct S'
13737 // is different from a definition 'struct S'. This is
13738 // because normally, at this point all the declarations of
13739 // struct S that are compatible with the definition of
13740 // struct S have already been resolved to that definition,
13741 // during the DWARF parsing. The remaining unresolved
13742 // declaration are thus considered different. With this
13743 // setup we can properly handle cases of two *different*
13744 // struct S being defined in the same binary (in different
13745 // translation units), and a third struct S being only
13746 // declared as an opaque type in a third translation unit of
13747 // its own, with no definition in there. In that case, the
13748 // declaration-only struct S should be left alone and not
13749 // resolved to any of the two definitions of struct S.
13750 bool saved_decl_only_class_equals_definition =
13751 env->decl_only_class_equals_definition();
13752 env->do_on_the_fly_canonicalization(true);
13753 // Compare types by considering that decl-only classes don't
13754 // equal their definition.
13755 env->decl_only_class_equals_definition(false);
13756 bool equal = (types_defined_same_linux_kernel_corpus_public(**it, *t)
13757 || compare_types_during_canonicalization(*it, t));
13758 // Restore the state of the on-the-fly-canonicalization and
13759 // the decl-only-class-being-equal-to-a-matching-definition
13760 // flags.
13761 env->do_on_the_fly_canonicalization(false);
13762 env->decl_only_class_equals_definition
13763 (saved_decl_only_class_equals_definition);
13764 if (equal)
13765 {
13766 result = *it;
13767 break;
13768 }
13769 }
13770 #ifdef WITH_DEBUG_SELF_COMPARISON
13771 if (env->self_comparison_debug_is_on())
13772 {
13773 // So we are debugging the canonicalization process,
13774 // possibly via the use of 'abidw --debug-abidiff <binary>'.
13775 corpus_sptr corp1, corp2;
13776 env->get_self_comparison_debug_inputs(corp1, corp2);
13777 if (corp1 && corp2 && t->get_corpus() == corp2.get())
13778 {
13779 // If 't' comes from the second corpus, then it *must*
13780 // be equal to its matching canonical type coming from
13781 // the first corpus because the second corpus is the
13782 // abixml representation of the first corpus. In other
13783 // words, all types coming from the second corpus must
13784 // have canonical types coming from the first corpus.
13785 if (result)
13786 {
13787 if (!env->priv_->
13788 check_canonical_type_from_abixml_during_self_comp(t,
13789 result))
13790 // The canonical type of the type re-read from abixml
13791 // type doesn't match the canonical type that was
13792 // initially serialized down.
13793 std::cerr << "error: wrong canonical type for '"
13794 << repr
13795 << "' / type: @"
13796 << std::hex
13797 << t.get()
13798 << "/ canon: @"
13799 << result.get()
13800 << std::endl;
13801 }
13802 else //!result
13803 {
13804 uintptr_t ptr_val = reinterpret_cast<uintptr_t>(t.get());
13805 string type_id = env->get_type_id_from_pointer(ptr_val);
13806 if (type_id.empty())
13807 type_id = "type-id-<not-found>";
13808 // We are in the case where 't' is different from all
13809 // the canonical types of the same name that come from
13810 // the first corpus.
13811 //
13812 // If 't' indeed comes from the second corpus then this
13813 // clearly is a canonicalization failure.
13814 //
13815 // There was a problem either during the serialization
13816 // of 't' into abixml, or during the de-serialization
13817 // from abixml into abigail::ir. Further debugging is
13818 // needed to determine what that root cause problem is.
13819 //
13820 // Note that the first canonicalization problem of this
13821 // kind must be fixed before looking at the subsequent
13822 // ones, because the later might well just be
13823 // consequences of the former.
13824 std::cerr << "error: wrong induced canonical type for '"
13825 << repr
13826 << "' from second corpus"
13827 << ", ptr: " << std::hex << t.get()
13828 << "type-id: " << type_id
13829 << std::endl;
13830 }
13831 }
13832 }
13833 #endif
13834
13835 if (!result)
13836 {
13837 v.push_back(t);
13838 result = t;
13839 }
13840 }
13841
13842 return result;
13843 }
13844
13845 /// This method is invoked automatically right after the current
13846 /// instance of @ref class_decl has been canonicalized.
13847 void
on_canonical_type_set()13848 type_base::on_canonical_type_set()
13849 {}
13850
13851 /// This is a subroutine of the canonicalize() function.
13852 ///
13853 /// When the canonical type C of type T has just been computed, there
13854 /// can be cases where T has member functions that C doesn't have.
13855 ///
13856 /// This is possible because non virtual member functions are not
13857 /// taken in account when comparing two types.
13858 ///
13859 /// In that case, this function updates C so that it contains the
13860 /// member functions.
13861 ///
13862 /// There can also be cases where C has a method M which is not linked
13863 /// to any underlying symbol, whereas in T, M is to link to an
13864 /// underlying symbol. In that case, this function updates M in C so
13865 /// that it's linked to the same underlying symbol as for M in T.
13866 static void
maybe_adjust_canonical_type(const type_base_sptr & canonical,const type_base_sptr & type)13867 maybe_adjust_canonical_type(const type_base_sptr& canonical,
13868 const type_base_sptr& type)
13869 {
13870 if (!canonical
13871 // If 'type' is *NOT* a newly canonicalized type ...
13872 || type->get_naked_canonical_type()
13873 // ... or if 'type' is it's own canonical type, then get out.
13874 || type.get() == canonical.get())
13875 return;
13876
13877 if (class_decl_sptr cl = is_class_type(type))
13878 {
13879 class_decl_sptr canonical_class = is_class_type(canonical);
13880
13881 if (canonical_class)
13882 {
13883 // Set symbols of member functions that might be missing
13884 // theirs.
13885 for (class_decl::member_functions::const_iterator i =
13886 cl->get_member_functions().begin();
13887 i != cl->get_member_functions().end();
13888 ++i)
13889 if ((*i)->get_symbol())
13890 {
13891 if (method_decl *m = canonical_class->
13892 find_member_function((*i)->get_linkage_name()))
13893 {
13894 elf_symbol_sptr s1 = (*i)->get_symbol();
13895 if (s1 && !m->get_symbol())
13896 // Method 'm' in the canonical type is not
13897 // linked to the underlying symbol of '*i'.
13898 // Let's link it now. have th
13899 m->set_symbol(s1);
13900 }
13901 else
13902 // There is a member function defined and publicly
13903 // exported in the other class, and the canonical
13904 // class doesn't have that member function. Let's
13905 // copy that member function to the canonical class
13906 // then.
13907 copy_member_function (canonical_class, *i);
13908 }
13909 }
13910 }
13911
13912 // If an artificial function type equals a non-artfificial one in
13913 // the system, then the canonical type of both should be deemed
13914 // non-artificial. This is important because only non-artificial
13915 // canonical function types are emitted out into abixml, so if don't
13916 // do this we risk missing to emit some function types.
13917 if (is_function_type(type))
13918 if (type->get_is_artificial() != canonical->get_is_artificial())
13919 canonical->set_is_artificial(false);
13920 }
13921
13922 /// Compute the canonical type of a given type.
13923 ///
13924 /// It means that after invoking this function, comparing the intance
13925 /// instance @ref type_base and another one (on which
13926 /// type_base::enable_canonical_equality() would have been invoked as
13927 /// well) is performed by just comparing the pointer values of the
13928 /// canonical types of both types. That equality comparison is
13929 /// supposedly faster than structural comparison of the types.
13930 ///
13931 /// @param t a smart pointer to the instance of @ref type_base for
13932 /// which to compute the canonical type. After this call,
13933 /// t->get_canonical_type() will return the newly computed canonical
13934 /// type.
13935 ///
13936 /// @return the canonical type computed for @p t.
13937 type_base_sptr
canonicalize(type_base_sptr t)13938 canonicalize(type_base_sptr t)
13939 {
13940 if (!t)
13941 return t;
13942
13943 if (t->get_canonical_type())
13944 return t->get_canonical_type();
13945
13946 type_base_sptr canonical = type_base::get_canonical_type_for(t);
13947 maybe_adjust_canonical_type(canonical, t);
13948
13949 t->priv_->canonical_type = canonical;
13950 t->priv_->naked_canonical_type = canonical.get();
13951
13952 if (class_decl_sptr cl = is_class_type(t))
13953 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
13954 if ((canonical = d->get_canonical_type()))
13955 {
13956 d->priv_->canonical_type = canonical;
13957 d->priv_->naked_canonical_type = canonical.get();
13958 }
13959
13960 if (canonical)
13961 if (decl_base_sptr d = is_decl_slow(canonical))
13962 {
13963 scope_decl *scope = d->get_scope();
13964 // Add the canonical type to the set of canonical types
13965 // belonging to its scope.
13966 if (scope)
13967 {
13968 if (is_type(scope))
13969 // The scope in question is itself a type (e.g, a class
13970 // or union). Let's call that type ST. We want to add
13971 // 'canonical' to the set of canonical types belonging
13972 // to ST.
13973 if (type_base_sptr c = is_type(scope)->get_canonical_type())
13974 // We want to add 'canonical' to set of canonical
13975 // types belonging to the canonical type of ST. That
13976 // way, just looking at the canonical type of ST is
13977 // enough to get the types that belong to the scope of
13978 // the class of equivalence of ST.
13979 scope = is_scope_decl(is_decl(c)).get();
13980 scope->get_canonical_types().insert(canonical);
13981 }
13982 // else, if the type doesn't have a scope, it's not meant to be
13983 // emitted. This can be the case for the result of the
13984 // function strip_typedef, for instance.
13985 }
13986
13987 t->on_canonical_type_set();
13988 return canonical;
13989 }
13990
13991
13992 /// Set the definition of this declaration-only @ref decl_base.
13993 ///
13994 /// @param d the new definition to set.
13995 void
set_definition_of_declaration(const decl_base_sptr & d)13996 decl_base::set_definition_of_declaration(const decl_base_sptr& d)
13997 {
13998 ABG_ASSERT(get_is_declaration_only());
13999 priv_->definition_of_declaration_ = d;
14000 if (type_base *t = is_type(this))
14001 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
14002 t->priv_->canonical_type = canonical_type;
14003
14004 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
14005 }
14006
14007 /// The constructor of @ref type_base.
14008 ///
14009 /// @param s the size of the type, in bits.
14010 ///
14011 /// @param a the alignment of the type, in bits.
type_base(const environment * e,size_t s,size_t a)14012 type_base::type_base(const environment* e, size_t s, size_t a)
14013 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
14014 priv_(new priv(s, a))
14015 {}
14016
14017 /// Getter of the canonical type of the current instance of @ref
14018 /// type_base.
14019 ///
14020 /// @return a smart pointer to the canonical type of the current
14021 /// intance of @ref type_base, or an empty smart pointer if the
14022 /// current instance of @ref type_base doesn't have any canonical
14023 /// type.
14024 type_base_sptr
get_canonical_type() const14025 type_base::get_canonical_type() const
14026 {return priv_->canonical_type.lock();}
14027
14028 /// Getter of the canonical type pointer.
14029 ///
14030 /// Note that this function doesn't return a smart pointer, but rather
14031 /// the underlying pointer managed by the smart pointer. So it's as
14032 /// fast as possible. This getter is to be used in code paths that
14033 /// are proven to be performance hot spots; especially, when comparing
14034 /// sensitive types like class, function, pointers and reference
14035 /// types. Those are compared extremely frequently and thus, their
14036 /// accessing the canonical type must be fast.
14037 ///
14038 /// @return the canonical type pointer, not managed by a smart
14039 /// pointer.
14040 type_base*
get_naked_canonical_type() const14041 type_base::get_naked_canonical_type() const
14042 {return priv_->naked_canonical_type;}
14043
14044 /// Get the pretty representation of the current type.
14045 ///
14046 /// The pretty representation is retrieved from a cache. If the cache
14047 /// is empty, this function computes the pretty representation, put it
14048 /// in the cache and returns it.
14049 ///
14050 /// Note that if the type is *NOT* canonicalized, the pretty
14051 /// representation is never cached.
14052 ///
14053 /// @param internal if true, then the pretty representation is to be
14054 /// used for purpuses that are internal to the libabigail library
14055 /// itself. If you don't know what this means, then you probably
14056 /// should set this parameter to "false".
14057 const interned_string&
get_cached_pretty_representation(bool internal) const14058 type_base::get_cached_pretty_representation(bool internal) const
14059 {
14060 if (internal)
14061 {
14062 if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
14063 {
14064 string r = ir::get_pretty_representation(this, internal);
14065 priv_->internal_cached_repr_ = get_environment()->intern(r);
14066 }
14067 return priv_->internal_cached_repr_;
14068 }
14069
14070 if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
14071 {
14072 string r = ir::get_pretty_representation(this, internal);
14073 priv_->cached_repr_ = get_environment()->intern(r);
14074 }
14075
14076 return priv_->cached_repr_;
14077 }
14078
14079 /// Compares two instances of @ref type_base.
14080 ///
14081 /// If the two intances are different, set a bitfield to give some
14082 /// insight about the kind of differences there are.
14083 ///
14084 /// @param l the first artifact of the comparison.
14085 ///
14086 /// @param r the second artifact of the comparison.
14087 ///
14088 /// @param k a pointer to a bitfield that gives information about the
14089 /// kind of changes there are between @p l and @p r. This one is set
14090 /// iff @p is non-null and if the function returns false.
14091 ///
14092 /// Please note that setting k to a non-null value does have a
14093 /// negative performance impact because even if @p l and @p r are not
14094 /// equal, the function keeps up the comparison in order to determine
14095 /// the different kinds of ways in which they are different.
14096 ///
14097 /// @return true if @p l equals @p r, false otherwise.
14098 bool
equals(const type_base & l,const type_base & r,change_kind * k)14099 equals(const type_base& l, const type_base& r, change_kind* k)
14100 {
14101 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
14102 && l.get_alignment_in_bits() == r.get_alignment_in_bits());
14103 if (!result)
14104 if (k)
14105 *k |= LOCAL_TYPE_CHANGE_KIND;
14106 ABG_RETURN(result);
14107 }
14108
14109 /// Return true iff both type declarations are equal.
14110 ///
14111 /// Note that this doesn't test if the scopes of both types are equal.
14112 bool
operator ==(const type_base & other) const14113 type_base::operator==(const type_base& other) const
14114 {return equals(*this, other, 0);}
14115
14116 /// Inequality operator.
14117 ///
14118 ///@param other the instance of @ref type_base to compare the current
14119 /// instance against.
14120 ///
14121 /// @return true iff the current instance is different from @p other.
14122 bool
operator !=(const type_base & other) const14123 type_base::operator!=(const type_base& other) const
14124 {return !operator==(other);}
14125
14126 /// Setter for the size of the type.
14127 ///
14128 /// @param s the new size -- in bits.
14129 void
set_size_in_bits(size_t s)14130 type_base::set_size_in_bits(size_t s)
14131 {priv_->size_in_bits = s;}
14132
14133 /// Getter for the size of the type.
14134 ///
14135 /// @return the size in bits of the type.
14136 size_t
get_size_in_bits() const14137 type_base::get_size_in_bits() const
14138 {return priv_->size_in_bits;}
14139
14140 /// Setter for the alignment of the type.
14141 ///
14142 /// @param a the new alignment -- in bits.
14143 void
set_alignment_in_bits(size_t a)14144 type_base::set_alignment_in_bits(size_t a)
14145 {priv_->alignment_in_bits = a;}
14146
14147 /// Getter for the alignment of the type.
14148 ///
14149 /// @return the alignment of the type in bits.
14150 size_t
get_alignment_in_bits() const14151 type_base::get_alignment_in_bits() const
14152 {return priv_->alignment_in_bits;}
14153
14154 /// Default implementation of traversal for types. This function does
14155 /// nothing. It must be implemented by every single new type that is
14156 /// written.
14157 ///
14158 /// Please look at e.g, class_decl::traverse() for an example of how
14159 /// to implement this.
14160 ///
14161 /// @param v the visitor used to visit the type.
14162 bool
traverse(ir_node_visitor & v)14163 type_base::traverse(ir_node_visitor& v)
14164 {
14165 if (v.type_node_has_been_visited(this))
14166 return true;
14167
14168 v.visit_begin(this);
14169 bool result = v.visit_end(this);
14170 v.mark_type_node_as_visited(this);
14171
14172 return result;
14173 }
14174
~type_base()14175 type_base::~type_base()
14176 {delete priv_;}
14177
14178 // </type_base definitions>
14179
14180 // <integral_type definitions>
14181
14182 /// Bitwise OR operator for integral_type::modifiers_type.
14183 ///
14184 /// @param l the left-hand side operand.
14185 ///
14186 /// @param r the right-hand side operand.
14187 ///
14188 /// @return the result of the bitwise OR.
14189 integral_type::modifiers_type
operator |(integral_type::modifiers_type l,integral_type::modifiers_type r)14190 operator|(integral_type::modifiers_type l, integral_type::modifiers_type r)
14191 {
14192 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
14193 |static_cast<unsigned>(r));
14194 }
14195
14196 /// Bitwise AND operator for integral_type::modifiers_type.
14197 ///
14198 /// @param l the left-hand side operand.
14199 ///
14200 /// @param r the right-hand side operand.
14201 ///
14202 /// @return the result of the bitwise AND.
14203 integral_type::modifiers_type
operator &(integral_type::modifiers_type l,integral_type::modifiers_type r)14204 operator&(integral_type::modifiers_type l, integral_type::modifiers_type r)
14205 {
14206 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
14207 &static_cast<unsigned>(r));
14208 }
14209
14210 /// Bitwise |= operator for integral_type::modifiers_type.
14211 ///
14212 /// @param l the left-hand side operand.
14213 ///
14214 /// @param r the right-hand side operand.
14215 ///
14216 /// @return the result of the bitwise |=.
14217 integral_type::modifiers_type&
operator |=(integral_type::modifiers_type & l,integral_type::modifiers_type r)14218 operator|=(integral_type::modifiers_type& l, integral_type::modifiers_type r)
14219 {
14220 l = l | r;
14221 return l;
14222 }
14223
14224 /// Parse a word containing one integral type modifier.
14225 ///
14226 /// A word is considered to be a string of characters that doesn't
14227 /// contain any white space.
14228 ///
14229 /// @param word the word to parse. It is considered to be a string of
14230 /// characters that doesn't contain any white space.
14231 ///
14232 /// @param modifiers out parameter. It's set by this function to the
14233 /// parsed modifier iff the function returned true.
14234 ///
14235 /// @return true iff @word was successfully parsed.
14236 static bool
parse_integral_type_modifier(const string & word,integral_type::modifiers_type & modifiers)14237 parse_integral_type_modifier(const string& word,
14238 integral_type::modifiers_type &modifiers)
14239 {
14240 if (word == "signed")
14241 modifiers |= integral_type::SIGNED_MODIFIER;
14242 else if (word == "unsigned")
14243 modifiers |= integral_type::UNSIGNED_MODIFIER;
14244 else if (word == "short")
14245 modifiers |= integral_type::SHORT_MODIFIER;
14246 else if (word == "long")
14247 modifiers |= integral_type::LONG_MODIFIER;
14248 else if (word == "long long")
14249 modifiers |= integral_type::LONG_LONG_MODIFIER;
14250 else
14251 return false;
14252
14253 return true;
14254 }
14255
14256 /// Parse a base type of an integral type from a string.
14257 ///
14258 /// @param type_name the type name to parse.
14259 ///
14260 /// @param base out parameter. This is set to the resulting base type
14261 /// parsed, iff the function returned true.
14262 ///
14263 /// @return true iff the function could successfully parse the base
14264 /// type.
14265 static bool
parse_base_integral_type(const string & type_name,integral_type::base_type & base)14266 parse_base_integral_type(const string& type_name,
14267 integral_type::base_type& base)
14268 {
14269 if (type_name == "int")
14270 base = integral_type::INT_BASE_TYPE;
14271 else if (type_name == "char")
14272 base = integral_type::CHAR_BASE_TYPE;
14273 else if (type_name == "bool" || type_name == "_Bool")
14274 base = integral_type::BOOL_BASE_TYPE;
14275 else if (type_name == "double")
14276 base = integral_type::DOUBLE_BASE_TYPE;
14277 else if (type_name =="float")
14278 base = integral_type::FLOAT_BASE_TYPE;
14279 else if (type_name == "char16_t")
14280 base = integral_type::CHAR16_T_BASE_TYPE;
14281 else if (type_name == "char32_t")
14282 base = integral_type::CHAR32_T_BASE_TYPE;
14283 else if (type_name == "wchar_t")
14284 base = integral_type::WCHAR_T_BASE_TYPE;
14285 else
14286 return false;
14287
14288 return true;
14289 }
14290
14291 /// Parse an integral type from a string.
14292 ///
14293 /// @param type_name the string containing the integral type to parse.
14294 ///
14295 /// @param base out parameter. Is set by this function to the base
14296 /// type of the integral type, iff the function returned true.
14297 ///
14298 /// @param modifiers out parameter If set by this function to the
14299 /// modifier of the integral type, iff the function returned true.
14300 ///
14301 /// @return true iff the function could parse an integral type from @p
14302 /// type_name.
14303 static bool
parse_integral_type(const string & type_name,integral_type::base_type & base,integral_type::modifiers_type & modifiers)14304 parse_integral_type(const string& type_name,
14305 integral_type::base_type& base,
14306 integral_type::modifiers_type& modifiers)
14307 {
14308 string input = type_name;
14309 string::size_type len = input.length();
14310 string::size_type cur_pos = 0, prev_pos = 0;
14311 string cur_word, prev_word;
14312 bool ok = false;
14313
14314 while (cur_pos < len)
14315 {
14316 prev_pos = cur_pos;
14317 cur_pos = input.find(' ', prev_pos);
14318 prev_word = cur_word;
14319 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
14320
14321 if (cur_pos < len && isspace(input[cur_pos]))
14322 do
14323 ++cur_pos;
14324 while (cur_pos < len && isspace(input[cur_pos]));
14325
14326 if (cur_pos < len
14327 && cur_word == "long"
14328 && prev_word != "long")
14329 {
14330 prev_pos = cur_pos;
14331 cur_pos = input.find(' ', prev_pos);
14332 string saved_prev_word = prev_word;
14333 prev_word = cur_word;
14334 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
14335 if (cur_word == "long")
14336 cur_word = "long long";
14337 else
14338 {
14339 cur_pos = prev_pos;
14340 cur_word = prev_word;
14341 prev_word = saved_prev_word;
14342 }
14343 }
14344
14345 if (!parse_integral_type_modifier(cur_word, modifiers))
14346 {
14347 if (!parse_base_integral_type(cur_word, base))
14348 return false;
14349 else
14350 ok = true;
14351 }
14352 else
14353 ok = true;
14354 }
14355
14356 return ok;
14357 }
14358
14359 /// Parse an integral type from a string.
14360 ///
14361 /// @param str the string containing the integral type to parse.
14362 ///
14363 ///@param type the resulting @ref integral_type. Is set to the result
14364 ///of the parse, iff the function returns true.
14365 ///
14366 /// @return true iff the function could parse an integral type from @p
14367 /// str.
14368 bool
parse_integral_type(const string & str,integral_type & type)14369 parse_integral_type(const string& str, integral_type& type)
14370 {
14371 return false; // Disable all integral type name interpretation.
14372 integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
14373 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
14374
14375 if (!parse_integral_type(str, base_type, modifiers))
14376 return false;
14377
14378 // So this is an integral type.
14379 integral_type int_type(base_type, modifiers);
14380 type = int_type;
14381 return true;
14382 }
14383
14384 /// Default constructor of the @ref integral_type.
integral_type()14385 integral_type::integral_type()
14386 : base_(INT_BASE_TYPE),
14387 modifiers_(NO_MODIFIER)
14388 {}
14389
14390 /// Constructor of the @ref integral_type.
14391 ///
14392 /// @param b the base type of the integral type.
14393 ///
14394 /// @param m the modifiers of the integral type.
integral_type(base_type b,modifiers_type m)14395 integral_type::integral_type(base_type b, modifiers_type m)
14396 : base_(b), modifiers_(m)
14397 {}
14398
14399 /// Constructor of the @ref integral_type.
14400 ///
14401 /// @param the name of the integral type to parse to initialize the
14402 /// current instance of @ref integral_type.
integral_type(const string & type_name)14403 integral_type::integral_type(const string& type_name)
14404 : base_(INT_BASE_TYPE),
14405 modifiers_(NO_MODIFIER)
14406 {
14407 bool could_parse = parse_integral_type(type_name, base_, modifiers_);
14408 ABG_ASSERT(could_parse);
14409 }
14410
14411 /// Getter of the base type of the @ref integral_type.
14412 ///
14413 /// @return the base type of the @ref integral_type.
14414 integral_type::base_type
get_base_type() const14415 integral_type::get_base_type() const
14416 {return base_;}
14417
14418 /// Getter of the modifiers bitmap of the @ref integral_type.
14419 ///
14420 /// @return the modifiers bitmap of the @ref integral_type.
14421 integral_type::modifiers_type
get_modifiers() const14422 integral_type::get_modifiers() const
14423 {return modifiers_;}
14424
14425 /// Equality operator for the @ref integral_type.
14426 ///
14427 /// @param other the other integral type to compare against.
14428 ///
14429 /// @return true iff @p other equals the current instance of @ref
14430 /// integral_type.
14431 bool
operator ==(const integral_type & other) const14432 integral_type::operator==(const integral_type&other) const
14433 {return base_ == other.base_ && modifiers_ == other.modifiers_;}
14434
14435 /// Return the string representation of the current instance of @ref
14436 /// integral_type.
14437 ///
14438 /// @return the string representation of the current instance of @ref
14439 /// integral_type.
14440 string
to_string() const14441 integral_type::to_string() const
14442 {
14443 string result;
14444
14445 // Look at modifiers ...
14446 if (modifiers_ & SIGNED_MODIFIER)
14447 result += "signed ";
14448 if (modifiers_ & UNSIGNED_MODIFIER)
14449 result += "unsigned ";
14450 if (modifiers_ & SHORT_MODIFIER)
14451 result += "short ";
14452 if (modifiers_ & LONG_MODIFIER)
14453 result += "long ";
14454 if (modifiers_ & LONG_LONG_MODIFIER)
14455 result += "long long ";
14456
14457 // ... and look at base types.
14458 if (base_ == INT_BASE_TYPE)
14459 result += "int";
14460 else if (base_ == CHAR_BASE_TYPE)
14461 result += "char";
14462 else if (base_ == BOOL_BASE_TYPE)
14463 result += "bool";
14464 else if (base_ == DOUBLE_BASE_TYPE)
14465 result += "double";
14466 else if (base_ == FLOAT_BASE_TYPE)
14467 result += "float";
14468 else if (base_ == CHAR16_T_BASE_TYPE)
14469 result += "char16_t";
14470 else if (base_ == CHAR32_T_BASE_TYPE)
14471 result += "char32_t";
14472 else if (base_ == WCHAR_T_BASE_TYPE)
14473 result += "wchar_t";
14474
14475 return result;
14476 }
14477
14478 /// Convert the current instance of @ref integral_type into its string
14479 /// representation.
14480 ///
14481 /// @return the string representation of the current instance of @ref
14482 /// integral_type.
operator string() const14483 integral_type::operator string() const
14484 {return to_string();}
14485
14486 // </integral_type definitions>
14487
14488 //<type_decl definitions>
14489
14490 /// Constructor.
14491 ///
14492 /// @param env the environment we are operating from.
14493 ///
14494 /// @param name the name of the type declaration.
14495 ///
14496 /// @param size_in_bits the size of the current type_decl, in bits.
14497 ///
14498 /// @param alignment_in_bits the alignment of the current typ, in
14499 /// bits.
14500 ///
14501 /// @param locus the source location of the current type declaration.
14502 ///
14503 /// @param linkage_name the linkage_name of the current type declaration.
14504 ///
14505 /// @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)14506 type_decl::type_decl(const environment* env,
14507 const string& name,
14508 size_t size_in_bits,
14509 size_t alignment_in_bits,
14510 const location& locus,
14511 const string& linkage_name,
14512 visibility vis)
14513
14514 : type_or_decl_base(env,
14515 BASIC_TYPE
14516 | ABSTRACT_TYPE_BASE
14517 | ABSTRACT_DECL_BASE),
14518 decl_base(env, name, locus, linkage_name, vis),
14519 type_base(env, size_in_bits, alignment_in_bits)
14520 {
14521 runtime_type_instance(this);
14522
14523 integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
14524 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
14525 integral_type int_type(base_type, modifiers);
14526 if (parse_integral_type(name, int_type))
14527 {
14528 // Convert the integral_type into its canonical string
14529 // representation.
14530 string integral_type_name = int_type;
14531
14532 // Set the name of this type_decl to the canonical string
14533 // representation above
14534 set_name(integral_type_name);
14535 set_qualified_name(get_name());
14536
14537 if (!get_linkage_name().empty())
14538 set_linkage_name(integral_type_name);
14539 }
14540 }
14541
14542 /// Compares two instances of @ref type_decl.
14543 ///
14544 /// If the two intances are different, set a bitfield to give some
14545 /// insight about the kind of differences there are.
14546 ///
14547 /// @param l the first artifact of the comparison.
14548 ///
14549 /// @param r the second artifact of the comparison.
14550 ///
14551 /// @param k a pointer to a bitfield that gives information about the
14552 /// kind of changes there are between @p l and @p r. This one is set
14553 /// iff @p k is non-null and the function returns false.
14554 ///
14555 /// Please note that setting k to a non-null value does have a
14556 /// negative performance impact because even if @p l and @p r are not
14557 /// equal, the function keeps up the comparison in order to determine
14558 /// the different kinds of ways in which they are different.
14559 ///
14560 /// @return true if @p l equals @p r, false otherwise.
14561 bool
equals(const type_decl & l,const type_decl & r,change_kind * k)14562 equals(const type_decl& l, const type_decl& r, change_kind* k)
14563 {
14564 bool result = equals(static_cast<const decl_base&>(l),
14565 static_cast<const decl_base&>(r),
14566 k);
14567 if (!k && !result)
14568 ABG_RETURN_FALSE;
14569
14570 result &= equals(static_cast<const type_base&>(l),
14571 static_cast<const type_base&>(r),
14572 k);
14573 ABG_RETURN(result);
14574 }
14575
14576 /// Return true if both types equals.
14577 ///
14578 /// This operator re-uses the overload that takes a decl_base.
14579 ///
14580 /// Note that this does not check the scopes of any of the types.
14581 ///
14582 /// @param o the other type_decl to check agains.
14583 bool
operator ==(const type_base & o) const14584 type_decl::operator==(const type_base& o) const
14585 {
14586 const decl_base* other = dynamic_cast<const decl_base*>(&o);
14587 if (!other)
14588 return false;
14589 return *this == *other;
14590 }
14591
14592 /// Return true if both types equals.
14593 ///
14594 /// Note that this does not check the scopes of any of the types.
14595 ///
14596 /// @param o the other type_decl to check against.
14597 bool
operator ==(const decl_base & o) const14598 type_decl::operator==(const decl_base& o) const
14599 {
14600 const type_decl* other = dynamic_cast<const type_decl*>(&o);
14601 if (!other)
14602 return false;
14603 return try_canonical_compare(this, other);
14604 }
14605
14606 /// Return true if both types equals.
14607 ///
14608 /// Note that this does not check the scopes of any of the types.
14609 ///
14610 /// @param o the other type_decl to check against.
14611 ///
14612 /// @return true iff the current isntance equals @p o
14613 bool
operator ==(const type_decl & o) const14614 type_decl::operator==(const type_decl& o) const
14615 {
14616 const decl_base& other = o;
14617 return *this == other;
14618 }
14619
14620 /// Inequality operator.
14621 ///
14622 /// @param o the other type to compare against.
14623 ///
14624 /// @return true iff the current instance is different from @p o.
14625 bool
operator !=(const type_decl & o) const14626 type_decl::operator!=(const type_decl& o) const
14627 {return !operator==(o);}
14628
14629 /// Equality operator for @ref type_decl_sptr.
14630 ///
14631 /// @param l the first operand to compare.
14632 ///
14633 /// @param r the second operand to compare.
14634 ///
14635 /// @return true iff @p l equals @p r.
14636 bool
operator ==(const type_decl_sptr & l,const type_decl_sptr & r)14637 operator==(const type_decl_sptr& l, const type_decl_sptr& r)
14638 {
14639 if (!!l != !!r)
14640 return false;
14641 if (l.get() == r.get())
14642 return true;
14643 return *l == *r;
14644 }
14645
14646 /// Inequality operator for @ref type_decl_sptr.
14647 ///
14648 /// @param l the first operand to compare.
14649 ///
14650 /// @param r the second operand to compare.
14651 ///
14652 /// @return true iff @p l is different from @p r.
14653 bool
operator !=(const type_decl_sptr & l,const type_decl_sptr & r)14654 operator!=(const type_decl_sptr& l, const type_decl_sptr& r)
14655 {return !operator==(l, r);}
14656
14657 /// Get the pretty representation of the current instance of @ref
14658 /// type_decl.
14659 ///
14660 /// @param internal set to true if the call is intended to get a
14661 /// representation of the decl (or type) for the purpose of canonical
14662 /// type comparison. This is mainly used in the function
14663 /// type_base::get_canonical_type_for().
14664 ///
14665 /// In other words if the argument for this parameter is true then the
14666 /// call is meant for internal use (for technical use inside the
14667 /// library itself), false otherwise. If you don't know what this is
14668 /// for, then set it to false.
14669 ///
14670 /// @param qualified_name if true, names emitted in the pretty
14671 /// representation are fully qualified.
14672 ///
14673 /// @return the pretty representatin of the @ref type_decl.
14674 string
get_pretty_representation(bool internal,bool qualified_name) const14675 type_decl::get_pretty_representation(bool internal,
14676 bool qualified_name) const
14677 {
14678 if (qualified_name)
14679 return get_qualified_name(internal);
14680 return get_name();
14681 }
14682
14683 /// This implements the ir_traversable_base::traverse pure virtual
14684 /// function.
14685 ///
14686 /// @param v the visitor used on the current instance.
14687 ///
14688 /// @return true if the entire IR node tree got traversed, false
14689 /// otherwise.
14690 bool
traverse(ir_node_visitor & v)14691 type_decl::traverse(ir_node_visitor& v)
14692 {
14693 if (v.type_node_has_been_visited(this))
14694 return true;
14695
14696 v.visit_begin(this);
14697 bool result = v.visit_end(this);
14698 v.mark_type_node_as_visited(this);
14699
14700 return result;
14701 }
14702
~type_decl()14703 type_decl::~type_decl()
14704 {}
14705 //</type_decl definitions>
14706
14707 // <scope_type_decl definitions>
14708
14709 /// Constructor.
14710 ///
14711 /// @param env the environment we are operating from.
14712 ///
14713 /// @param name the name of the type.
14714 ///
14715 /// @param size_in_bits the size of the type, in bits.
14716 ///
14717 /// @param alignment_in_bits the alignment of the type, in bits.
14718 ///
14719 /// @param locus the source location where the type is defined.
14720 ///
14721 /// @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)14722 scope_type_decl::scope_type_decl(const environment* env,
14723 const string& name,
14724 size_t size_in_bits,
14725 size_t alignment_in_bits,
14726 const location& locus,
14727 visibility vis)
14728 : type_or_decl_base(env,
14729 ABSTRACT_SCOPE_TYPE_DECL
14730 | ABSTRACT_TYPE_BASE
14731 | ABSTRACT_DECL_BASE),
14732 decl_base(env, name, locus, "", vis),
14733 type_base(env, size_in_bits, alignment_in_bits),
14734 scope_decl(env, name, locus)
14735 {}
14736
14737 /// Compares two instances of @ref scope_type_decl.
14738 ///
14739 /// If the two intances are different, set a bitfield to give some
14740 /// insight about the kind of differences there are.
14741 ///
14742 /// @param l the first artifact of the comparison.
14743 ///
14744 /// @param r the second artifact of the comparison.
14745 ///
14746 /// @param k a pointer to a bitfield that gives information about the
14747 /// kind of changes there are between @p l and @p r. This one is set
14748 /// iff @p k is non-null and the function returns false.
14749 ///
14750 /// Please note that setting k to a non-null value does have a
14751 /// negative performance impact because even if @p l and @p r are not
14752 /// equal, the function keeps up the comparison in order to determine
14753 /// the different kinds of ways in which they are different.
14754 ///
14755 /// @return true if @p l equals @p r, false otherwise.
14756 bool
equals(const scope_type_decl & l,const scope_type_decl & r,change_kind * k)14757 equals(const scope_type_decl& l, const scope_type_decl& r, change_kind* k)
14758 {
14759 bool result = equals(static_cast<const scope_decl&>(l),
14760 static_cast<const scope_decl&>(r),
14761 k);
14762
14763 if (!k && !result)
14764 ABG_RETURN_FALSE;
14765
14766 result &= equals(static_cast<const type_base&>(l),
14767 static_cast<const type_base&>(r),
14768 k);
14769
14770 ABG_RETURN(result);
14771 }
14772
14773 /// Equality operator between two scope_type_decl.
14774 ///
14775 /// Note that this function does not consider the scope of the scope
14776 /// types themselves.
14777 ///
14778 /// @return true iff both scope types are equal.
14779 bool
operator ==(const decl_base & o) const14780 scope_type_decl::operator==(const decl_base& o) const
14781 {
14782 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
14783 if (!other)
14784 return false;
14785 return try_canonical_compare(this, other);
14786 }
14787
14788 /// Equality operator between two scope_type_decl.
14789 ///
14790 /// This re-uses the equality operator that takes a decl_base.
14791 ///
14792 /// @param o the other scope_type_decl to compare against.
14793 ///
14794 /// @return true iff both scope types are equal.
14795 bool
operator ==(const type_base & o) const14796 scope_type_decl::operator==(const type_base& o) const
14797 {
14798 const decl_base* other = dynamic_cast<const decl_base*>(&o);
14799 if (!other)
14800 return false;
14801
14802 return *this == *other;
14803 }
14804
14805 /// Traverses an instance of @ref scope_type_decl, visiting all the
14806 /// sub-types and decls that it might contain.
14807 ///
14808 /// @param v the visitor that is used to visit every IR sub-node of
14809 /// the current node.
14810 ///
14811 /// @return true if either
14812 /// - all the children nodes of the current IR node were traversed
14813 /// and the calling code should keep going with the traversing.
14814 /// - or the current IR node is already being traversed.
14815 /// Otherwise, returning false means that the calling code should not
14816 /// keep traversing the tree.
14817 bool
traverse(ir_node_visitor & v)14818 scope_type_decl::traverse(ir_node_visitor& v)
14819 {
14820 if (visiting())
14821 return true;
14822
14823 if (v.type_node_has_been_visited(this))
14824 return true;
14825
14826 if (v.visit_begin(this))
14827 {
14828 visiting(true);
14829 for (scope_decl::declarations::const_iterator i =
14830 get_member_decls().begin();
14831 i != get_member_decls ().end();
14832 ++i)
14833 if (!(*i)->traverse(v))
14834 break;
14835 visiting(false);
14836 }
14837
14838 bool result = v.visit_end(this);
14839 v.mark_type_node_as_visited(this);
14840
14841 return result;
14842 }
14843
~scope_type_decl()14844 scope_type_decl::~scope_type_decl()
14845 {}
14846 // </scope_type_decl definitions>
14847
14848 // <namespace_decl>
14849
14850 /// Constructor.
14851 ///
14852 /// @param the environment we are operatin from.
14853 ///
14854 /// @param name the name of the namespace.
14855 ///
14856 /// @param locus the source location where the namespace is defined.
14857 ///
14858 /// @param vis the visibility of the namespace.
namespace_decl(const environment * env,const string & name,const location & locus,visibility vis)14859 namespace_decl::namespace_decl(const environment* env,
14860 const string& name,
14861 const location& locus,
14862 visibility vis)
14863 // We need to call the constructor of decl_base directly here
14864 // because it is virtually inherited by scope_decl. Note that we
14865 // just implicitely call the default constructor for scope_decl
14866 // here, as what we really want is to initialize the decl_base
14867 // subobject. Wow, virtual inheritance is useful, but setting it
14868 // up is ugly.
14869 : type_or_decl_base(env,
14870 NAMESPACE_DECL
14871 | ABSTRACT_DECL_BASE
14872 | ABSTRACT_SCOPE_DECL),
14873 decl_base(env, name, locus, "", vis),
14874 scope_decl(env, name, locus)
14875 {
14876 runtime_type_instance(this);
14877 }
14878
14879 /// Build and return a copy of the pretty representation of the
14880 /// namespace.
14881 ///
14882 /// @param internal set to true if the call is intended to get a
14883 /// representation of the decl (or type) for the purpose of canonical
14884 /// type comparison. This is mainly used in the function
14885 /// type_base::get_canonical_type_for().
14886 ///
14887 /// In other words if the argument for this parameter is true then the
14888 /// call is meant for internal use (for technical use inside the
14889 /// library itself), false otherwise. If you don't know what this is
14890 /// for, then set it to false.
14891 ///
14892 /// @param qualified_name if true, names emitted in the pretty
14893 /// representation are fully qualified.
14894 ///
14895 /// @return a copy of the pretty representation of the namespace.
14896 string
get_pretty_representation(bool internal,bool qualified_name) const14897 namespace_decl::get_pretty_representation(bool internal,
14898 bool qualified_name) const
14899 {
14900 string r =
14901 "namespace " + scope_decl::get_pretty_representation(internal,
14902 qualified_name);
14903 return r;
14904 }
14905
14906 /// Return true iff both namespaces and their members are equal.
14907 ///
14908 /// Note that this function does not check if the scope of these
14909 /// namespaces are equal.
14910 bool
operator ==(const decl_base & o) const14911 namespace_decl::operator==(const decl_base& o) const
14912 {
14913 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
14914 if (!other)
14915 return false;
14916 return scope_decl::operator==(*other);
14917 }
14918
14919 /// Test if the current namespace_decl is empty or contains empty
14920 /// namespaces itself.
14921 ///
14922 /// @return true iff the current namespace_decl is empty or contains
14923 /// empty itself.
14924 bool
is_empty_or_has_empty_sub_namespaces() const14925 namespace_decl::is_empty_or_has_empty_sub_namespaces() const
14926 {
14927 if (is_empty())
14928 return true;
14929
14930 for (declarations::const_iterator i = get_member_decls().begin();
14931 i != get_member_decls().end();
14932 ++i)
14933 {
14934 if (!is_namespace(*i))
14935 return false;
14936
14937 namespace_decl_sptr ns = is_namespace(*i);
14938 ABG_ASSERT(ns);
14939
14940 if (!ns->is_empty_or_has_empty_sub_namespaces())
14941 return false;
14942 }
14943
14944 return true;
14945 }
14946
14947 /// This implements the ir_traversable_base::traverse pure virtual
14948 /// function.
14949 ///
14950 /// @param v the visitor used on the current instance and on its
14951 /// member nodes.
14952 ///
14953 /// @return true if the entire IR node tree got traversed, false
14954 /// otherwise.
14955 bool
traverse(ir_node_visitor & v)14956 namespace_decl::traverse(ir_node_visitor& v)
14957 {
14958 if (visiting())
14959 return true;
14960
14961 if (v.visit_begin(this))
14962 {
14963 visiting(true);
14964 scope_decl::declarations::const_iterator i;
14965 for (i = get_member_decls().begin();
14966 i != get_member_decls ().end();
14967 ++i)
14968 {
14969 ir_traversable_base_sptr t =
14970 dynamic_pointer_cast<ir_traversable_base>(*i);
14971 if (t)
14972 if (!t->traverse (v))
14973 break;
14974 }
14975 visiting(false);
14976 }
14977 return v.visit_end(this);
14978 }
14979
~namespace_decl()14980 namespace_decl::~namespace_decl()
14981 {
14982 }
14983
14984 // </namespace_decl>
14985
14986 // <qualified_type_def>
14987
14988 /// Type of the private data of qualified_type_def.
14989 class qualified_type_def::priv
14990 {
14991 friend class qualified_type_def;
14992
14993 qualified_type_def::CV cv_quals_;
14994 // Before the type is canonicalized, this is used as a temporary
14995 // internal name.
14996 interned_string temporary_internal_name_;
14997 // Once the type is canonicalized, this is used as the internal
14998 // name.
14999 interned_string internal_name_;
15000 weak_ptr<type_base> underlying_type_;
15001
priv()15002 priv()
15003 : cv_quals_(CV_NONE)
15004 {}
15005
priv(qualified_type_def::CV quals,type_base_sptr t)15006 priv(qualified_type_def::CV quals,
15007 type_base_sptr t)
15008 : cv_quals_(quals),
15009 underlying_type_(t)
15010 {}
15011
priv(qualified_type_def::CV quals)15012 priv(qualified_type_def::CV quals)
15013 : cv_quals_(quals)
15014 {}
15015 };// end class qualified_type_def::priv
15016
15017 /// Build the name of the current instance of qualified type.
15018 ///
15019 /// @param fully_qualified if true, build a fully qualified name.
15020 ///
15021 /// @param internal set to true if the call is intended for an
15022 /// internal use (for technical use inside the library itself), false
15023 /// otherwise. If you don't know what this is for, then set it to
15024 /// false.
15025 ///
15026 /// @return a copy of the newly-built name.
15027 string
build_name(bool fully_qualified,bool internal) const15028 qualified_type_def::build_name(bool fully_qualified, bool internal) const
15029 {
15030 type_base_sptr t = get_underlying_type();
15031 if (!t)
15032 // The qualified type might temporarily have no underlying type,
15033 // especially during the construction of the type, while the
15034 // underlying type is not yet constructed. In that case, let's do
15035 // like if the underlying type is the 'void' type.
15036 t = get_environment()->get_void_type();
15037
15038 return get_name_of_qualified_type(t, get_cv_quals(),
15039 fully_qualified,
15040 internal);
15041 }
15042
15043 /// This function is automatically invoked whenever an instance of
15044 /// this type is canonicalized.
15045 ///
15046 /// It's an overload of the virtual type_base::on_canonical_type_set.
15047 ///
15048 /// We put here what is thus meant to be executed only at the point of
15049 /// type canonicalization.
15050 void
on_canonical_type_set()15051 qualified_type_def::on_canonical_type_set()
15052 {clear_qualified_name();}
15053
15054 /// Constructor of the qualified_type_def
15055 ///
15056 /// @param type the underlying type
15057 ///
15058 /// @param quals a bitfield representing the const/volatile qualifiers
15059 ///
15060 /// @param locus the location of the qualified type definition
qualified_type_def(type_base_sptr type,CV quals,const location & locus)15061 qualified_type_def::qualified_type_def(type_base_sptr type,
15062 CV quals,
15063 const location& locus)
15064 : type_or_decl_base(type->get_environment(),
15065 QUALIFIED_TYPE
15066 | ABSTRACT_TYPE_BASE
15067 | ABSTRACT_DECL_BASE),
15068 type_base(type->get_environment(), type->get_size_in_bits(),
15069 type->get_alignment_in_bits()),
15070 decl_base(type->get_environment(), "", locus, "",
15071 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
15072 priv_(new priv(quals, type))
15073 {
15074 runtime_type_instance(this);
15075 interned_string name = type->get_environment()->intern(build_name(false));
15076 set_name(name);
15077 }
15078
15079 /// Constructor of the qualified_type_def
15080 ///
15081 /// @param env the environment of the type.
15082 ///
15083 /// @param quals a bitfield representing the const/volatile qualifiers
15084 ///
15085 /// @param locus the location of the qualified type definition
qualified_type_def(environment * env,CV quals,const location & locus)15086 qualified_type_def::qualified_type_def(environment* env,
15087 CV quals,
15088 const location& locus)
15089 : type_or_decl_base(env,
15090 QUALIFIED_TYPE
15091 | ABSTRACT_TYPE_BASE
15092 | ABSTRACT_DECL_BASE),
15093 type_base(env, /*size_in_bits=*/0,
15094 /*alignment_in_bits=*/0),
15095 decl_base(env, "", locus, ""),
15096 priv_(new priv(quals))
15097 {
15098 runtime_type_instance(this);
15099 // We don't yet have an underlying type. So for naming purpose,
15100 // let's temporarily pretend the underlying type is 'void'.
15101 interned_string name = env->intern("void");
15102 set_name(name);
15103 }
15104
15105 /// Get the size of the qualified type def.
15106 ///
15107 /// This is an overload for type_base::get_size_in_bits().
15108 ///
15109 /// @return the size of the qualified type.
15110 size_t
get_size_in_bits() const15111 qualified_type_def::get_size_in_bits() const
15112 {
15113 size_t s = 0;
15114 if (type_base_sptr ut = get_underlying_type())
15115 {
15116 // We do have the underlying type properly set, so let's make
15117 // the size of the qualified type match the size of its
15118 // underlying type.
15119 s = ut->get_size_in_bits();
15120 if (s != type_base::get_size_in_bits())
15121 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
15122 }
15123 return type_base::get_size_in_bits();
15124 }
15125
15126 /// Compares two instances of @ref qualified_type_def.
15127 ///
15128 /// If the two intances are different, set a bitfield to give some
15129 /// insight about the kind of differences there are.
15130 ///
15131 /// @param l the first artifact of the comparison.
15132 ///
15133 /// @param r the second artifact of the comparison.
15134 ///
15135 /// @param k a pointer to a bitfield that gives information about the
15136 /// kind of changes there are between @p l and @p r. This one is set
15137 /// iff @p k is non-null and the function returns false.
15138 ///
15139 /// Please note that setting k to a non-null value does have a
15140 /// negative performance impact because even if @p l and @p r are not
15141 /// equal, the function keeps up the comparison in order to determine
15142 /// the different kinds of ways in which they are different.
15143 ///
15144 /// @return true if @p l equals @p r, false otherwise.
15145 bool
equals(const qualified_type_def & l,const qualified_type_def & r,change_kind * k)15146 equals(const qualified_type_def& l, const qualified_type_def& r, change_kind* k)
15147 {
15148 bool result = true;
15149 if (l.get_cv_quals() != r.get_cv_quals())
15150 {
15151 result = false;
15152 if (k)
15153 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
15154 else
15155 ABG_RETURN_FALSE;
15156 }
15157
15158 if (l.get_underlying_type() != r.get_underlying_type())
15159 {
15160 result = false;
15161 if (k)
15162 {
15163 if (!types_have_similar_structure(l.get_underlying_type().get(),
15164 r.get_underlying_type().get()))
15165 // Underlying type changes in which the structure of the
15166 // type changed are considered local changes to the
15167 // qualified type.
15168 *k |= LOCAL_TYPE_CHANGE_KIND;
15169 else
15170 *k |= SUBTYPE_CHANGE_KIND;
15171 }
15172 else
15173 // okay strictly speaking this is not necessary, but I am
15174 // putting it here to maintenance; that is, so that adding
15175 // subsequent clauses needed to compare two qualified types
15176 // later still works.
15177 ABG_RETURN_FALSE;
15178 }
15179
15180 ABG_RETURN(result);
15181 }
15182
15183 /// Equality operator for qualified types.
15184 ///
15185 /// Note that this function does not check for equality of the scopes.
15186 ///
15187 ///@param o the other qualified type to compare against.
15188 ///
15189 /// @return true iff both qualified types are equal.
15190 bool
operator ==(const decl_base & o) const15191 qualified_type_def::operator==(const decl_base& o) const
15192 {
15193 const qualified_type_def* other =
15194 dynamic_cast<const qualified_type_def*>(&o);
15195 if (!other)
15196 return false;
15197 return try_canonical_compare(this, other);
15198 }
15199
15200 /// Equality operator for qualified types.
15201 ///
15202 /// Note that this function does not check for equality of the scopes.
15203 /// Also, this re-uses the equality operator above that takes a
15204 /// decl_base.
15205 ///
15206 ///@param o the other qualified type to compare against.
15207 ///
15208 /// @return true iff both qualified types are equal.
15209 bool
operator ==(const type_base & o) const15210 qualified_type_def::operator==(const type_base& o) const
15211 {
15212 const decl_base* other = dynamic_cast<const decl_base*>(&o);
15213 if (!other)
15214 return false;
15215 return *this == *other;
15216 }
15217
15218 /// Equality operator for qualified types.
15219 ///
15220 /// Note that this function does not check for equality of the scopes.
15221 /// Also, this re-uses the equality operator above that takes a
15222 /// decl_base.
15223 ///
15224 ///@param o the other qualified type to compare against.
15225 ///
15226 /// @return true iff both qualified types are equal.
15227 bool
operator ==(const qualified_type_def & o) const15228 qualified_type_def::operator==(const qualified_type_def& o) const
15229 {
15230 const decl_base* other = dynamic_cast<const decl_base*>(&o);
15231 if (!other)
15232 return false;
15233 return *this == *other;
15234 }
15235
15236 /// Implementation for the virtual qualified name builder for @ref
15237 /// qualified_type_def.
15238 ///
15239 /// @param qualified_name the output parameter to hold the resulting
15240 /// qualified name.
15241 ///
15242 /// @param internal set to true if the call is intended for an
15243 /// internal use (for technical use inside the library itself), false
15244 /// otherwise. If you don't know what this is for, then set it to
15245 /// false.
15246 void
get_qualified_name(interned_string & qualified_name,bool internal) const15247 qualified_type_def::get_qualified_name(interned_string& qualified_name,
15248 bool internal) const
15249 {qualified_name = get_qualified_name(internal);}
15250
15251 /// Implementation of the virtual qualified name builder/getter.
15252 ///
15253 /// @param internal set to true if the call is intended for an
15254 /// internal use (for technical use inside the library itself), false
15255 /// otherwise. If you don't know what this is for, then set it to
15256 /// false.
15257 ///
15258 /// @return the resulting qualified name.
15259 const interned_string&
get_qualified_name(bool internal) const15260 qualified_type_def::get_qualified_name(bool internal) const
15261 {
15262 const environment* env = get_environment();
15263 ABG_ASSERT(env);
15264
15265 if (!get_canonical_type())
15266 {
15267 // The type hasn't been canonicalized yet. We want to return a
15268 // temporary name that is not cached because the structure of
15269 // this type (and so its name) can change until its
15270 // canonicalized.
15271 if (internal)
15272 {
15273 // We are asked to return a temporary *internal* name.
15274 // Lets compute it and return a reference to where it's
15275 // stored.
15276 priv_->temporary_internal_name_ =
15277 env->intern(build_name(true, /*internal=*/true));
15278 return priv_->temporary_internal_name_;
15279 }
15280 else
15281 {
15282 // We are asked to return a temporary non-internal name.
15283 set_temporary_qualified_name
15284 (env->intern(build_name(true, /*internal=*/false)));
15285 return peek_temporary_qualified_name();
15286 }
15287 }
15288 else
15289 {
15290 // The type has already been canonicalized. We want to return
15291 // the definitive name and cache it.
15292 if (internal)
15293 {
15294 if (priv_->internal_name_.empty())
15295 priv_->internal_name_ =
15296 env->intern(build_name(/*qualified=*/true,
15297 /*internal=*/true));
15298 return priv_->internal_name_;
15299 }
15300 else
15301 {
15302 if (peek_qualified_name().empty())
15303 set_qualified_name
15304 (env->intern(build_name(/*qualified=*/true,
15305 /*internal=*/false)));
15306 return peek_qualified_name();
15307 }
15308 }
15309 }
15310
15311 /// This implements the ir_traversable_base::traverse pure virtual
15312 /// function.
15313 ///
15314 /// @param v the visitor used on the current instance.
15315 ///
15316 /// @return true if the entire IR node tree got traversed, false
15317 /// otherwise.
15318 bool
traverse(ir_node_visitor & v)15319 qualified_type_def::traverse(ir_node_visitor& v)
15320 {
15321 if (v.type_node_has_been_visited(this))
15322 return true;
15323
15324 if (visiting())
15325 return true;
15326
15327 if (v.visit_begin(this))
15328 {
15329 visiting(true);
15330 if (type_base_sptr t = get_underlying_type())
15331 t->traverse(v);
15332 visiting(false);
15333 }
15334 bool result = v.visit_end(this);
15335 v.mark_type_node_as_visited(this);
15336 return result;
15337 }
15338
~qualified_type_def()15339 qualified_type_def::~qualified_type_def()
15340 {
15341 }
15342
15343 /// Getter of the const/volatile qualifier bit field
15344 qualified_type_def::CV
get_cv_quals() const15345 qualified_type_def::get_cv_quals() const
15346 {return priv_->cv_quals_;}
15347
15348 /// Setter of the const/value qualifiers bit field
15349 void
set_cv_quals(CV cv_quals)15350 qualified_type_def::set_cv_quals(CV cv_quals)
15351 {priv_->cv_quals_ = cv_quals;}
15352
15353 /// Compute and return the string prefix or suffix representing the
15354 /// qualifiers hold by the current instance of @ref
15355 /// qualified_type_def.
15356 ///
15357 /// @return the newly-built cv string.
15358 string
get_cv_quals_string_prefix() const15359 qualified_type_def::get_cv_quals_string_prefix() const
15360 {return get_string_representation_of_cv_quals(priv_->cv_quals_);}
15361
15362 /// Getter of the underlying type
15363 type_base_sptr
get_underlying_type() const15364 qualified_type_def::get_underlying_type() const
15365 {return priv_->underlying_type_.lock();}
15366
15367 /// Setter of the underlying type.
15368 ///
15369 /// @param t the new underlying type.
15370 void
set_underlying_type(const type_base_sptr & t)15371 qualified_type_def::set_underlying_type(const type_base_sptr& t)
15372 {
15373 ABG_ASSERT(t);
15374 priv_->underlying_type_ = t;
15375 // Now we need to update other properties that depend on the new underlying type.
15376 set_size_in_bits(t->get_size_in_bits());
15377 set_alignment_in_bits(t->get_alignment_in_bits());
15378 interned_string name = get_environment()->intern(build_name(false));
15379 set_name(name);
15380 if (scope_decl* s = get_scope())
15381 {
15382 // Now that the name has been updated, we need to update the
15383 // lookup maps accordingly.
15384 scope_decl::declarations::iterator i;
15385 if (s->find_iterator_for_member(this, i))
15386 maybe_update_types_lookup_map(*i);
15387 else
15388 ABG_ASSERT_NOT_REACHED;
15389 }
15390 }
15391
15392 /// Non-member equality operator for @ref qualified_type_def
15393 ///
15394 /// @param l the left-hand side of the equality operator
15395 ///
15396 /// @param r the right-hand side of the equality operator
15397 ///
15398 /// @return true iff @p l and @p r equals.
15399 bool
operator ==(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)15400 operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
15401 {
15402 if (l.get() == r.get())
15403 return true;
15404 if (!!l != !!r)
15405 return false;
15406
15407 return *l == *r;
15408 }
15409
15410 /// Non-member inequality operator for @ref qualified_type_def
15411 ///
15412 /// @param l the left-hand side of the equality operator
15413 ///
15414 /// @param r the right-hand side of the equality operator
15415 ///
15416 /// @return true iff @p l and @p r equals.
15417 bool
operator !=(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)15418 operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
15419 {return ! operator==(l, r);}
15420
15421 /// Overloaded bitwise OR operator for cv qualifiers.
15422 qualified_type_def::CV
operator |(qualified_type_def::CV lhs,qualified_type_def::CV rhs)15423 operator|(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
15424 {
15425 return static_cast<qualified_type_def::CV>
15426 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
15427 }
15428
15429 /// Overloaded bitwise |= operator for cv qualifiers.
15430 qualified_type_def::CV&
operator |=(qualified_type_def::CV & l,qualified_type_def::CV r)15431 operator|=(qualified_type_def::CV& l, qualified_type_def::CV r)
15432 {
15433 l = l | r;
15434 return l;
15435 }
15436
15437 /// Overloaded bitwise AND operator for CV qualifiers.
15438 qualified_type_def::CV
operator &(qualified_type_def::CV lhs,qualified_type_def::CV rhs)15439 operator&(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
15440 {
15441 return static_cast<qualified_type_def::CV>
15442 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
15443 }
15444
15445 /// Overloaded bitwise inverting operator for CV qualifiers.
15446 qualified_type_def::CV
operator ~(qualified_type_def::CV q)15447 operator~(qualified_type_def::CV q)
15448 {return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
15449
15450 /// Streaming operator for qualified_type_decl::CV
15451 ///
15452 /// @param o the output stream to serialize the cv qualifier to.
15453 ///
15454 /// @param cv the cv qualifier to serialize.
15455 ///
15456 /// @return the output stream used.
15457 std::ostream&
operator <<(std::ostream & o,qualified_type_def::CV cv)15458 operator<<(std::ostream& o, qualified_type_def::CV cv)
15459 {
15460 string str;
15461
15462 switch (cv)
15463 {
15464 case qualified_type_def::CV_NONE:
15465 str = "none";
15466 break;
15467 case qualified_type_def::CV_CONST:
15468 str = "const";
15469 break;
15470 case qualified_type_def::CV_VOLATILE:
15471 str = "volatile";
15472 break;
15473 case qualified_type_def::CV_RESTRICT:
15474 str = "restrict";
15475 break;
15476 }
15477
15478 o << str;
15479 return o;
15480 }
15481
15482 // </qualified_type_def>
15483
15484 //<pointer_type_def definitions>
15485
15486 /// Private data structure of the @ref pointer_type_def.
15487 struct pointer_type_def::priv
15488 {
15489 type_base_wptr pointed_to_type_;
15490 type_base* naked_pointed_to_type_;
15491 interned_string internal_qualified_name_;
15492 interned_string temp_internal_qualified_name_;
15493
privabigail::ir::pointer_type_def::priv15494 priv(const type_base_sptr& t)
15495 : pointed_to_type_(type_or_void(t, 0)),
15496 naked_pointed_to_type_(t.get())
15497 {}
15498
privabigail::ir::pointer_type_def::priv15499 priv()
15500 : naked_pointed_to_type_()
15501 {}
15502 }; //end struct pointer_type_def
15503
15504 /// This function is automatically invoked whenever an instance of
15505 /// this type is canonicalized.
15506 ///
15507 /// It's an overload of the virtual type_base::on_canonical_type_set.
15508 ///
15509 /// We put here what is thus meant to be executed only at the point of
15510 /// type canonicalization.
15511 void
on_canonical_type_set()15512 pointer_type_def::on_canonical_type_set()
15513 {clear_qualified_name();}
15514
15515
15516 ///Constructor of @ref pointer_type_def.
15517 ///
15518 /// @param pointed_to the pointed-to type.
15519 ///
15520 /// @param size_in_bits the size of the type, in bits.
15521 ///
15522 /// @param align_in_bits the alignment of the type, in bits.
15523 ///
15524 /// @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)15525 pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
15526 size_t size_in_bits,
15527 size_t align_in_bits,
15528 const location& locus)
15529 : type_or_decl_base(pointed_to->get_environment(),
15530 POINTER_TYPE
15531 | ABSTRACT_TYPE_BASE
15532 | ABSTRACT_DECL_BASE),
15533 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
15534 decl_base(pointed_to->get_environment(), "", locus, ""),
15535 priv_(new priv(pointed_to))
15536 {
15537 runtime_type_instance(this);
15538 try
15539 {
15540 ABG_ASSERT(pointed_to);
15541 const environment* env = pointed_to->get_environment();
15542 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
15543 string name = (pto ? pto->get_name() : string("void")) + "*";
15544 set_name(env->intern(name));
15545 if (pto)
15546 set_visibility(pto->get_visibility());
15547 }
15548 catch (...)
15549 {}
15550 }
15551
15552 ///Constructor of @ref pointer_type_def.
15553 ///
15554 /// @param env the environment of the type.
15555 ///
15556 /// @param size_in_bits the size of the type, in bits.
15557 ///
15558 /// @param align_in_bits the alignment of the type, in bits.
15559 ///
15560 /// @param locus the source location where the type was defined.
pointer_type_def(environment * env,size_t size_in_bits,size_t alignment_in_bits,const location & locus)15561 pointer_type_def::pointer_type_def(environment* env, size_t size_in_bits,
15562 size_t alignment_in_bits,
15563 const location& locus)
15564 : type_or_decl_base(env,
15565 POINTER_TYPE
15566 | ABSTRACT_TYPE_BASE
15567 | ABSTRACT_DECL_BASE),
15568 type_base(env, size_in_bits, alignment_in_bits),
15569 decl_base(env, "", locus, ""),
15570 priv_(new priv())
15571 {
15572 runtime_type_instance(this);
15573 string name = string("void") + "*";
15574 set_name(env->intern(name));
15575 }
15576
15577 /// Set the pointed-to type of the pointer.
15578 ///
15579 /// @param t the new pointed-to type.
15580 void
set_pointed_to_type(const type_base_sptr & t)15581 pointer_type_def::set_pointed_to_type(const type_base_sptr& t)
15582 {
15583 ABG_ASSERT(t);
15584 priv_->pointed_to_type_ = t;
15585 priv_->naked_pointed_to_type_ = t.get();
15586
15587 try
15588 {
15589 const environment* env = t->get_environment();
15590 ABG_ASSERT(get_environment() == env);
15591 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
15592 string name = (pto ? pto->get_name() : string("void")) + "*";
15593 set_name(env->intern(name));
15594 if (pto)
15595 set_visibility(pto->get_visibility());
15596 }
15597 catch (...)
15598 {}
15599 }
15600
15601 /// Compares two instances of @ref pointer_type_def.
15602 ///
15603 /// If the two intances are different, set a bitfield to give some
15604 /// insight about the kind of differences there are.
15605 ///
15606 /// @param l the first artifact of the comparison.
15607 ///
15608 /// @param r the second artifact of the comparison.
15609 ///
15610 /// @param k a pointer to a bitfield that gives information about the
15611 /// kind of changes there are between @p l and @p r. This one is set
15612 /// iff @p k is non-null and the function returns false.
15613 ///
15614 /// Please note that setting k to a non-null value does have a
15615 /// negative performance impact because even if @p l and @p r are not
15616 /// equal, the function keeps up the comparison in order to determine
15617 /// the different kinds of ways in which they are different.
15618 ///
15619 /// @return true if @p l equals @p r, false otherwise.
15620 bool
equals(const pointer_type_def & l,const pointer_type_def & r,change_kind * k)15621 equals(const pointer_type_def& l, const pointer_type_def& r, change_kind* k)
15622 {
15623 bool result = l.get_pointed_to_type() == r.get_pointed_to_type();
15624 if (!result)
15625 if (k)
15626 {
15627 if (!types_have_similar_structure(&l, &r))
15628 // pointed-to type changes in which the structure of the
15629 // type changed are considered local changes to the pointer
15630 // type.
15631 *k |= LOCAL_TYPE_CHANGE_KIND;
15632 *k |= SUBTYPE_CHANGE_KIND;
15633 }
15634
15635 ABG_RETURN(result);
15636 }
15637
15638 /// Return true iff both instances of pointer_type_def are equal.
15639 ///
15640 /// Note that this function does not check for the scopes of the this
15641 /// types.
15642 bool
operator ==(const decl_base & o) const15643 pointer_type_def::operator==(const decl_base& o) const
15644 {
15645 const pointer_type_def* other = is_pointer_type(&o);
15646 if (!other)
15647 return false;
15648 return try_canonical_compare(this, other);
15649 }
15650
15651 /// Return true iff both instances of pointer_type_def are equal.
15652 ///
15653 /// Note that this function does not check for the scopes of the
15654 /// types.
15655 ///
15656 /// @param other the other type to compare against.
15657 ///
15658 /// @return true iff @p other equals the current instance.
15659 bool
operator ==(const type_base & other) const15660 pointer_type_def::operator==(const type_base& other) const
15661 {
15662 const decl_base* o = is_decl(&other);
15663 if (!o)
15664 return false;
15665 return *this == *o;
15666 }
15667
15668 /// Return true iff both instances of pointer_type_def are equal.
15669 ///
15670 /// Note that this function does not check for the scopes of the
15671 /// types.
15672 ///
15673 /// @param other the other type to compare against.
15674 ///
15675 /// @return true iff @p other equals the current instance.
15676 bool
operator ==(const pointer_type_def & other) const15677 pointer_type_def::operator==(const pointer_type_def& other) const
15678 {
15679 const decl_base& o = other;
15680 return *this == o;
15681 }
15682
15683 /// Getter of the pointed-to type.
15684 ///
15685 /// @return the pointed-to type.
15686 const type_base_sptr
get_pointed_to_type() const15687 pointer_type_def::get_pointed_to_type() const
15688 {return priv_->pointed_to_type_.lock();}
15689
15690 /// Getter of a naked pointer to the pointed-to type.
15691 ///
15692 /// @return a naked pointed to the pointed-to type.
15693 type_base*
get_naked_pointed_to_type() const15694 pointer_type_def::get_naked_pointed_to_type() const
15695 {return priv_->naked_pointed_to_type_;}
15696
15697 /// Build and return the qualified name of the current instance of
15698 /// @ref pointer_type_def.
15699 ///
15700 /// @param qn output parameter. The resulting qualified name.
15701 ///
15702 /// @param internal set to true if the call is intended for an
15703 /// internal use (for technical use inside the library itself), false
15704 /// otherwise. If you don't know what this is for, then set it to
15705 /// false.
15706 void
get_qualified_name(interned_string & qn,bool internal) const15707 pointer_type_def::get_qualified_name(interned_string& qn, bool internal) const
15708 {qn = get_qualified_name(internal);}
15709
15710 /// Build, cache and return the qualified name of the current instance
15711 /// of @ref pointer_type_def. Subsequent invocations of this function
15712 /// return the cached value.
15713 ///
15714 /// Note that this function should work even if the underlying type is
15715 /// momentarily empty.
15716 ///
15717 /// @param internal set to true if the call is intended for an
15718 /// internal use (for technical use inside the library itself), false
15719 /// otherwise. If you don't know what this is for, then set it to
15720 /// false.
15721 ///
15722 /// @return the resulting qualified name.
15723 const interned_string&
get_qualified_name(bool internal) const15724 pointer_type_def::get_qualified_name(bool internal) const
15725 {
15726 type_base* pointed_to_type = get_naked_pointed_to_type();
15727
15728 if (internal)
15729 {
15730 if (get_canonical_type())
15731 {
15732 if (priv_->internal_qualified_name_.empty())
15733 if (pointed_to_type)
15734 priv_->internal_qualified_name_ =
15735 get_name_of_pointer_to_type(*pointed_to_type,
15736 /*qualified_name=*/true,
15737 /*internal=*/true);
15738 return priv_->internal_qualified_name_;
15739 }
15740 else
15741 {
15742 // As the type hasn't yet been canonicalized, its structure
15743 // (and so its name) can change. So let's invalidate the
15744 // cache where we store its name at each invocation of this
15745 // function.
15746 if (pointed_to_type)
15747 priv_->temp_internal_qualified_name_ =
15748 get_name_of_pointer_to_type(*pointed_to_type,
15749 /*qualified_name=*/true,
15750 /*internal=*/true);
15751 return priv_->temp_internal_qualified_name_;
15752 }
15753 }
15754 else
15755 {
15756 if (get_naked_canonical_type())
15757 {
15758 if (decl_base::peek_qualified_name().empty())
15759 set_qualified_name
15760 (get_name_of_pointer_to_type(*pointed_to_type,
15761 /*qualified_name=*/true,
15762 /*internal=*/false));
15763 return decl_base::peek_qualified_name();
15764 }
15765 else
15766 {
15767 // As the type hasn't yet been canonicalized, its structure
15768 // (and so its name) can change. So let's invalidate the
15769 // cache where we store its name at each invocation of this
15770 // function.
15771 if (pointed_to_type)
15772 set_qualified_name
15773 (get_name_of_pointer_to_type(*pointed_to_type,
15774 /*qualified_name=*/true,
15775 /*internal=*/false));
15776 return decl_base::peek_qualified_name();
15777 }
15778 }
15779 }
15780
15781 /// This implements the ir_traversable_base::traverse pure virtual
15782 /// function.
15783 ///
15784 /// @param v the visitor used on the current instance.
15785 ///
15786 /// @return true if the entire IR node tree got traversed, false
15787 /// otherwise.
15788 bool
traverse(ir_node_visitor & v)15789 pointer_type_def::traverse(ir_node_visitor& v)
15790 {
15791 if (v.type_node_has_been_visited(this))
15792 return true;
15793
15794 if (visiting())
15795 return true;
15796
15797 if (v.visit_begin(this))
15798 {
15799 visiting(true);
15800 if (type_base_sptr t = get_pointed_to_type())
15801 t->traverse(v);
15802 visiting(false);
15803 }
15804
15805 bool result = v.visit_end(this);
15806 v.mark_type_node_as_visited(this);
15807 return result;
15808 }
15809
~pointer_type_def()15810 pointer_type_def::~pointer_type_def()
15811 {}
15812
15813 /// Turn equality of shared_ptr of @ref pointer_type_def into a deep
15814 /// equality; that is, make it compare the pointed to objects too.
15815 ///
15816 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
15817 /// of the equality.
15818 ///
15819 /// @param r the shared_ptr of @ref pointer_type_def on
15820 /// right-hand-side of the equality.
15821 ///
15822 /// @return true if the @ref pointer_type_def pointed to by the
15823 /// shared_ptrs are equal, false otherwise.
15824 bool
operator ==(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)15825 operator==(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
15826 {
15827 if (l.get() == r.get())
15828 return true;
15829 if (!!l != !!r)
15830 return false;
15831
15832 return *l == *r;
15833 }
15834
15835 /// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
15836 /// equality; that is, make it compare the pointed to objects too.
15837 ///
15838 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
15839 /// of the equality.
15840 ///
15841 /// @param r the shared_ptr of @ref pointer_type_def on
15842 /// right-hand-side of the equality.
15843 ///
15844 /// @return true iff the @ref pointer_type_def pointed to by the
15845 /// shared_ptrs are different.
15846 bool
operator !=(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)15847 operator!=(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
15848 {return !operator==(l, r);}
15849
15850 // </pointer_type_def definitions>
15851
15852 // <reference_type_def definitions>
15853
15854 /// This function is automatically invoked whenever an instance of
15855 /// this type is canonicalized.
15856 ///
15857 /// It's an overload of the virtual type_base::on_canonical_type_set.
15858 ///
15859 /// We put here what is thus meant to be executed only at the point of
15860 /// type canonicalization.
15861 void
on_canonical_type_set()15862 reference_type_def::on_canonical_type_set()
15863 {clear_qualified_name();}
15864
15865 /// Constructor of the reference_type_def type.
15866 ///
15867 /// @param pointed_to the pointed to type.
15868 ///
15869 /// @param lvalue wether the reference is an lvalue reference. If
15870 /// false, the reference is an rvalue one.
15871 ///
15872 /// @param size_in_bits the size of the type, in bits.
15873 ///
15874 /// @param align_in_bits the alignment of the type, in bits.
15875 ///
15876 /// @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)15877 reference_type_def::reference_type_def(const type_base_sptr pointed_to,
15878 bool lvalue,
15879 size_t size_in_bits,
15880 size_t align_in_bits,
15881 const location& locus)
15882 : type_or_decl_base(pointed_to->get_environment(),
15883 REFERENCE_TYPE
15884 | ABSTRACT_TYPE_BASE
15885 | ABSTRACT_DECL_BASE),
15886 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
15887 decl_base(pointed_to->get_environment(), "", locus, ""),
15888 is_lvalue_(lvalue)
15889 {
15890 runtime_type_instance(this);
15891
15892 try
15893 {
15894 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
15895 string name;
15896 if (pto)
15897 {
15898 set_visibility(pto->get_visibility());
15899 name = string(pto->get_name()) + "&";
15900 }
15901 else
15902 name = string(get_type_name(is_function_type(pointed_to),
15903 /*qualified_name=*/true)) + "&";
15904
15905 if (!is_lvalue())
15906 name += "&";
15907 environment* env = pointed_to->get_environment();
15908 ABG_ASSERT(env);
15909 set_name(env->intern(name));
15910
15911 pointed_to_type_ = type_base_wptr(type_or_void(pointed_to, 0));
15912 }
15913 catch (...)
15914 {}
15915 }
15916
15917 /// Constructor of the reference_type_def type.
15918 ///
15919 /// This one creates a type that has no pointed-to type, temporarily.
15920 /// This is useful for cases where the underlying type is not yet
15921 /// available. It can be set later using
15922 /// reference_type_def::set_pointed_to_type().
15923 ///
15924 /// @param env the environment of the type.
15925 ///
15926 /// @param lvalue wether the reference is an lvalue reference. If
15927 /// false, the reference is an rvalue one.
15928 ///
15929 /// @param size_in_bits the size of the type, in bits.
15930 ///
15931 /// @param align_in_bits the alignment of the type, in bits.
15932 ///
15933 /// @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)15934 reference_type_def::reference_type_def(const environment* env, bool lvalue,
15935 size_t size_in_bits,
15936 size_t alignment_in_bits,
15937 const location& locus)
15938 : type_or_decl_base(env,
15939 REFERENCE_TYPE
15940 | ABSTRACT_TYPE_BASE
15941 | ABSTRACT_DECL_BASE),
15942 type_base(env, size_in_bits, alignment_in_bits),
15943 decl_base(env, "", locus, ""),
15944 is_lvalue_(lvalue)
15945 {
15946 runtime_type_instance(this);
15947 string name = "void&";
15948 if (!is_lvalue())
15949 name += "&";
15950 ABG_ASSERT(env);
15951 set_name(env->intern(name));
15952 pointed_to_type_ = type_base_wptr(env->get_void_type());
15953 }
15954
15955 /// Setter of the pointed_to type of the current reference type.
15956 ///
15957 /// @param pointed_to the new pointed to type.
15958 void
set_pointed_to_type(type_base_sptr & pointed_to_type)15959 reference_type_def::set_pointed_to_type(type_base_sptr& pointed_to_type)
15960 {
15961 ABG_ASSERT(pointed_to_type);
15962 pointed_to_type_ = pointed_to_type;
15963
15964 decl_base_sptr pto;
15965 try
15966 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
15967 catch (...)
15968 {}
15969
15970 if (pto)
15971 {
15972 set_visibility(pto->get_visibility());
15973 string name = string(pto->get_name()) + "&";
15974 if (!is_lvalue())
15975 name += "&";
15976 environment* env = pto->get_environment();
15977 ABG_ASSERT(env && env == get_environment());
15978 set_name(env->intern(name));
15979 }
15980 }
15981
15982 /// Compares two instances of @ref reference_type_def.
15983 ///
15984 /// If the two intances are different, set a bitfield to give some
15985 /// insight about the kind of differences there are.
15986 ///
15987 /// @param l the first artifact of the comparison.
15988 ///
15989 /// @param r the second artifact of the comparison.
15990 ///
15991 /// @param k a pointer to a bitfield that gives information about the
15992 /// kind of changes there are between @p l and @p r. This one is set
15993 /// iff @p k is non-null and the function returns false.
15994 ///
15995 /// Please note that setting k to a non-null value does have a
15996 /// negative performance impact because even if @p l and @p r are not
15997 /// equal, the function keeps up the comparison in order to determine
15998 /// the different kinds of ways in which they are different.
15999 ///
16000 /// @return true if @p l equals @p r, false otherwise.
16001 bool
equals(const reference_type_def & l,const reference_type_def & r,change_kind * k)16002 equals(const reference_type_def& l, const reference_type_def& r, change_kind* k)
16003 {
16004 if (l.is_lvalue() != r.is_lvalue())
16005 {
16006 if (k)
16007 *k |= LOCAL_TYPE_CHANGE_KIND;
16008 ABG_RETURN_FALSE;
16009 }
16010
16011 // Compare the pointed-to-types modulo the typedefs they might have
16012 bool result = (l.get_pointed_to_type() == r.get_pointed_to_type());
16013 if (!result)
16014 if (k)
16015 {
16016 if (!types_have_similar_structure(&l, &r))
16017 *k |= LOCAL_TYPE_CHANGE_KIND;
16018 *k |= SUBTYPE_CHANGE_KIND;
16019 }
16020 ABG_RETURN(result);
16021 }
16022
16023 /// Equality operator of the @ref reference_type_def type.
16024 ///
16025 /// @param o the other instance of @ref reference_type_def to compare
16026 /// against.
16027 ///
16028 /// @return true iff the two instances are equal.
16029 bool
operator ==(const decl_base & o) const16030 reference_type_def::operator==(const decl_base& o) const
16031 {
16032 const reference_type_def* other =
16033 dynamic_cast<const reference_type_def*>(&o);
16034 if (!other)
16035 return false;
16036 return try_canonical_compare(this, other);
16037 }
16038
16039 /// Equality operator of the @ref reference_type_def type.
16040 ///
16041 /// @param o the other instance of @ref reference_type_def to compare
16042 /// against.
16043 ///
16044 /// @return true iff the two instances are equal.
16045 bool
operator ==(const type_base & o) const16046 reference_type_def::operator==(const type_base& o) const
16047 {
16048 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16049 if (!other)
16050 return false;
16051 return *this == *other;
16052 }
16053
16054 /// Equality operator of the @ref reference_type_def type.
16055 ///
16056 /// @param o the other instance of @ref reference_type_def to compare
16057 /// against.
16058 ///
16059 /// @return true iff the two instances are equal.
16060 bool
operator ==(const reference_type_def & o) const16061 reference_type_def::operator==(const reference_type_def& o) const
16062 {
16063 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16064 if (!other)
16065 return false;
16066 return *this == *other;
16067 }
16068
16069 type_base_sptr
get_pointed_to_type() const16070 reference_type_def::get_pointed_to_type() const
16071 {return pointed_to_type_.lock();}
16072
16073 bool
is_lvalue() const16074 reference_type_def::is_lvalue() const
16075 {return is_lvalue_;}
16076
16077 /// Build and return the qualified name of the current instance of the
16078 /// @ref reference_type_def.
16079 ///
16080 /// @param qn output parameter. Is set to the newly-built qualified
16081 /// name of the current instance of @ref reference_type_def.
16082 ///
16083 /// @param internal set to true if the call is intended for an
16084 /// internal use (for technical use inside the library itself), false
16085 /// otherwise. If you don't know what this is for, then set it to
16086 /// false.
16087 void
get_qualified_name(interned_string & qn,bool internal) const16088 reference_type_def::get_qualified_name(interned_string& qn, bool internal) const
16089 {qn = get_qualified_name(internal);}
16090
16091 /// Build, cache and return the qualified name of the current instance
16092 /// of the @ref reference_type_def. Subsequent invocations of this
16093 /// function return the cached value.
16094 ///
16095 /// @param internal set to true if the call is intended for an
16096 /// internal use (for technical use inside the library itself), false
16097 /// otherwise. If you don't know what this is for, then set it to
16098 /// false.
16099 ///
16100 /// @return the newly-built qualified name of the current instance of
16101 /// @ref reference_type_def.
16102 const interned_string&
get_qualified_name(bool internal) const16103 reference_type_def::get_qualified_name(bool internal) const
16104 {
16105 if (peek_qualified_name().empty()
16106 || !get_canonical_type())
16107 set_qualified_name(get_name_of_reference_to_type(*get_pointed_to_type(),
16108 is_lvalue(),
16109 /*qualified_name=*/true,
16110 internal));
16111 return peek_qualified_name();
16112 }
16113
16114 /// This implements the ir_traversable_base::traverse pure virtual
16115 /// function.
16116 ///
16117 /// @param v the visitor used on the current instance.
16118 ///
16119 /// @return true if the entire IR node tree got traversed, false
16120 /// otherwise.
16121 bool
traverse(ir_node_visitor & v)16122 reference_type_def::traverse(ir_node_visitor& v)
16123 {
16124 if (v.type_node_has_been_visited(this))
16125 return true;
16126
16127 if (visiting())
16128 return true;
16129
16130 if (v.visit_begin(this))
16131 {
16132 visiting(true);
16133 if (type_base_sptr t = get_pointed_to_type())
16134 t->traverse(v);
16135 visiting(false);
16136 }
16137
16138 bool result = v.visit_end(this);
16139 v.mark_type_node_as_visited(this);
16140 return result;
16141 }
16142
~reference_type_def()16143 reference_type_def::~reference_type_def()
16144 {}
16145
16146 /// Turn equality of shared_ptr of @ref reference_type_def into a deep
16147 /// equality; that is, make it compare the pointed to objects too.
16148 ///
16149 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
16150 /// of the equality.
16151 ///
16152 /// @param r the shared_ptr of @ref reference_type_def on
16153 /// right-hand-side of the equality.
16154 ///
16155 /// @return true if the @ref reference_type_def pointed to by the
16156 /// shared_ptrs are equal, false otherwise.
16157 bool
operator ==(const reference_type_def_sptr & l,const reference_type_def_sptr & r)16158 operator==(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
16159 {
16160 if (l.get() == r.get())
16161 return true;
16162 if (!!l != !!r)
16163 return false;
16164
16165 return *l == *r;
16166 }
16167
16168 /// Turn inequality of shared_ptr of @ref reference_type_def into a deep
16169 /// equality; that is, make it compare the pointed to objects too.
16170 ///
16171 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
16172 /// of the equality.
16173 ///
16174 /// @param r the shared_ptr of @ref reference_type_def on
16175 /// right-hand-side of the equality.
16176 ///
16177 /// @return true iff the @ref reference_type_def pointed to by the
16178 /// shared_ptrs are different.
16179 bool
operator !=(const reference_type_def_sptr & l,const reference_type_def_sptr & r)16180 operator!=(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
16181 {return !operator==(l, r);}
16182
16183 // </reference_type_def definitions>
16184
16185 // <array_type_def definitions>
16186
16187 // <array_type_def::subrange_type>
16188 array_type_def::subrange_type::~subrange_type() = default;
16189
16190 // <array_type_def::subrante_type::bound_value>
16191
16192 /// Default constructor of the @ref
16193 /// array_type_def::subrange_type::bound_value class.
16194 ///
16195 /// Constructs an unsigned bound_value of value zero.
bound_value()16196 array_type_def::subrange_type::bound_value::bound_value()
16197 : s_(UNSIGNED_SIGNEDNESS)
16198 {
16199 v_.unsigned_ = 0;
16200 }
16201
16202 /// Initialize an unsigned bound_value with a given value.
16203 ///
16204 /// @param v the initial bound value.
bound_value(uint64_t v)16205 array_type_def::subrange_type::bound_value::bound_value(uint64_t v)
16206 : s_(UNSIGNED_SIGNEDNESS)
16207 {
16208 v_.unsigned_ = v;
16209 }
16210
16211 /// Initialize a signed bound_value with a given value.
16212 ///
16213 /// @param v the initial bound value.
bound_value(int64_t v)16214 array_type_def::subrange_type::bound_value::bound_value(int64_t v)
16215 : s_(SIGNED_SIGNEDNESS)
16216 {
16217 v_.signed_ = v;
16218 }
16219
16220 /// Getter of the signedness (unsigned VS signed) of the bound value.
16221 ///
16222 /// @return the signedness of the bound value.
16223 enum array_type_def::subrange_type::bound_value::signedness
get_signedness() const16224 array_type_def::subrange_type::bound_value::get_signedness() const
16225 {return s_;}
16226
16227 /// Setter of the signedness (unsigned VS signed) of the bound value.
16228 ///
16229 /// @param s the new signedness of the bound value.
16230 void
set_signedness(enum signedness s)16231 array_type_def::subrange_type::bound_value::set_signedness(enum signedness s)
16232 { s_ = s;}
16233
16234 /// Getter of the bound value as a signed value.
16235 ///
16236 /// @return the bound value as signed.
16237 int64_t
get_signed_value() const16238 array_type_def::subrange_type::bound_value::get_signed_value() const
16239 {return v_.signed_;
16240 }
16241
16242 /// Getter of the bound value as an unsigned value.
16243 ///
16244 /// @return the bound value as unsigned.
16245 uint64_t
get_unsigned_value()16246 array_type_def::subrange_type::bound_value::get_unsigned_value()
16247 {return v_.unsigned_;}
16248
16249 /// Setter of the bound value as unsigned.
16250 ///
16251 /// @param v the new unsigned value.
16252 void
set_unsigned(uint64_t v)16253 array_type_def::subrange_type::bound_value::set_unsigned(uint64_t v)
16254 {
16255 s_ = UNSIGNED_SIGNEDNESS;
16256 v_.unsigned_ = v;
16257 }
16258
16259 /// Setter of the bound value as signed.
16260 ///
16261 /// @param v the new signed value.
16262 void
set_signed(int64_t v)16263 array_type_def::subrange_type::bound_value::set_signed(int64_t v)
16264 {
16265 s_ = SIGNED_SIGNEDNESS;
16266 v_.signed_ = v;
16267 }
16268
16269 /// Equality operator of the bound value.
16270 ///
16271 /// @param v the other bound value to compare with.
16272 ///
16273 /// @return true iff the current bound value equals @p v.
16274 bool
operator ==(const bound_value & v) const16275 array_type_def::subrange_type::bound_value::operator==(const bound_value& v) const
16276 {
16277 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
16278 }
16279
16280 // </array_type_def::subrante_type::bound_value>
16281
16282 struct array_type_def::subrange_type::priv
16283 {
16284 bound_value lower_bound_;
16285 bound_value upper_bound_;
16286 type_base_wptr underlying_type_;
16287 translation_unit::language language_;
16288 bool infinite_;
16289
privabigail::ir::array_type_def::subrange_type::priv16290 priv(bound_value ub,
16291 translation_unit::language l = translation_unit::LANG_C11)
16292 : upper_bound_(ub), language_(l), infinite_(false)
16293 {}
16294
privabigail::ir::array_type_def::subrange_type::priv16295 priv(bound_value lb, bound_value ub,
16296 translation_unit::language l = translation_unit::LANG_C11)
16297 : lower_bound_(lb), upper_bound_(ub),
16298 language_(l), infinite_(false)
16299 {}
16300
privabigail::ir::array_type_def::subrange_type::priv16301 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
16302 translation_unit::language l = translation_unit::LANG_C11)
16303 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
16304 language_(l), infinite_(false)
16305 {}
16306 };
16307
16308 /// Constructor of an array_type_def::subrange_type type.
16309 ///
16310 /// @param env the environment this type was created from.
16311 ///
16312 /// @param name the name of the subrange type.
16313 ///
16314 /// @param lower_bound the lower bound of the array. This is
16315 /// generally zero (at least for C and C++).
16316 ///
16317 /// @param upper_bound the upper bound of the array.
16318 ///
16319 /// @param underlying_type the underlying type of the subrange type.
16320 ///
16321 /// @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)16322 array_type_def::subrange_type::subrange_type(const environment* env,
16323 const string& name,
16324 bound_value lower_bound,
16325 bound_value upper_bound,
16326 const type_base_sptr& utype,
16327 const location& loc,
16328 translation_unit::language l)
16329 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
16330 type_base(env,
16331 upper_bound.get_unsigned_value()
16332 - lower_bound.get_unsigned_value(),
16333 0),
16334 decl_base(env, name, loc, ""),
16335 priv_(new priv(lower_bound, upper_bound, utype, l))
16336 {
16337 runtime_type_instance(this);
16338 }
16339
16340 /// Constructor of the array_type_def::subrange_type type.
16341 ///
16342 /// @param env the environment this type is being created in.
16343 ///
16344 /// @param name the name of the subrange type.
16345 ///
16346 /// @param lower_bound the lower bound of the array. This is
16347 /// generally zero (at least for C and C++).
16348 ///
16349 /// @param upper_bound the upper bound of the array.
16350 ///
16351 /// @param loc the source location where the type is defined.
16352 ///
16353 /// @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)16354 array_type_def::subrange_type::subrange_type(const environment* env,
16355 const string& name,
16356 bound_value lower_bound,
16357 bound_value upper_bound,
16358 const location& loc,
16359 translation_unit::language l)
16360 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
16361 type_base(env,
16362 upper_bound.get_unsigned_value()
16363 - lower_bound.get_unsigned_value(), 0),
16364 decl_base(env, name, loc, ""),
16365 priv_(new priv(lower_bound, upper_bound, l))
16366 {
16367 runtime_type_instance(this);
16368 }
16369
16370 /// Constructor of the array_type_def::subrange_type type.
16371 ///
16372 /// @param env the environment this type is being created from.
16373 ///
16374 /// @param name of the name of type.
16375 ///
16376 /// @param upper_bound the upper bound of the array. The lower bound
16377 /// is considered to be zero.
16378 ///
16379 /// @param loc the source location of the type.
16380 ///
16381 /// @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)16382 array_type_def::subrange_type::subrange_type(const environment* env,
16383 const string& name,
16384 bound_value upper_bound,
16385 const location& loc,
16386 translation_unit::language l)
16387 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
16388 type_base(env, upper_bound.get_unsigned_value(), 0),
16389 decl_base(env, name, loc, ""),
16390 priv_(new priv(upper_bound, l))
16391 {
16392 runtime_type_instance(this);
16393 }
16394
16395 /// Getter of the underlying type of the subrange, that is, the type
16396 /// that defines the range.
16397 ///
16398 /// @return the underlying type.
16399 type_base_sptr
get_underlying_type() const16400 array_type_def::subrange_type::get_underlying_type() const
16401 {return priv_->underlying_type_.lock();}
16402
16403 /// Setter of the underlying type of the subrange, that is, the type
16404 /// that defines the range.
16405 ///
16406 /// @param u the new underlying type.
16407 void
set_underlying_type(const type_base_sptr & u)16408 array_type_def::subrange_type::set_underlying_type(const type_base_sptr &u)
16409 {
16410 ABG_ASSERT(priv_->underlying_type_.expired());
16411 priv_->underlying_type_ = u;
16412 }
16413
16414 /// Getter of the upper bound of the subrange type.
16415 ///
16416 /// @return the upper bound of the subrange type.
16417 int64_t
get_upper_bound() const16418 array_type_def::subrange_type::get_upper_bound() const
16419 {return priv_->upper_bound_.get_signed_value();}
16420
16421 /// Getter of the lower bound of the subrange type.
16422 ///
16423 /// @return the lower bound of the subrange type.
16424 int64_t
get_lower_bound() const16425 array_type_def::subrange_type::get_lower_bound() const
16426 {return priv_->lower_bound_.get_signed_value();}
16427
16428 /// Setter of the upper bound of the subrange type.
16429 ///
16430 /// @param ub the new value of the upper bound.
16431 void
set_upper_bound(int64_t ub)16432 array_type_def::subrange_type::set_upper_bound(int64_t ub)
16433 {priv_->upper_bound_ = ub;}
16434
16435 /// Setter of the lower bound.
16436 ///
16437 /// @param lb the new value of the lower bound.
16438 void
set_lower_bound(int64_t lb)16439 array_type_def::subrange_type::set_lower_bound(int64_t lb)
16440 {priv_->lower_bound_ = lb;}
16441
16442 /// Getter of the length of the subrange type.
16443 ///
16444 /// Note that a length of zero means the array has an infinite (or
16445 /// rather a non-known) size.
16446 ///
16447 /// @return the length of the subrange type.
16448 uint64_t
get_length() const16449 array_type_def::subrange_type::get_length() const
16450 {
16451 if (is_infinite())
16452 return 0;
16453
16454 ABG_ASSERT(get_upper_bound() >= get_lower_bound());
16455 return get_upper_bound() - get_lower_bound() + 1;
16456 }
16457
16458 /// Test if the length of the subrange type is infinite.
16459 ///
16460 /// @return true iff the length of the subrange type is infinite.
16461 bool
is_infinite() const16462 array_type_def::subrange_type::is_infinite() const
16463 {return priv_->infinite_;}
16464
16465 /// Set the infinite-ness status of the subrange type.
16466 ///
16467 /// @param f true iff the length of the subrange type should be set to
16468 /// being infinite.
16469 void
is_infinite(bool f)16470 array_type_def::subrange_type::is_infinite(bool f)
16471 {priv_->infinite_ = f;}
16472
16473 /// Getter of the language that generated this type.
16474 ///
16475 /// @return the language of this type.
16476 translation_unit::language
get_language() const16477 array_type_def::subrange_type::get_language() const
16478 {return priv_->language_;}
16479
16480 /// Return a string representation of the sub range.
16481 ///
16482 /// @return the string representation of the sub range.
16483 string
as_string() const16484 array_type_def::subrange_type::as_string() const
16485 {
16486 std::ostringstream o;
16487
16488 if (is_ada_language(get_language()))
16489 {
16490 type_base_sptr underlying_type = get_underlying_type();
16491 if (underlying_type)
16492 o << ir::get_pretty_representation(underlying_type, false) << " ";
16493 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
16494 }
16495 else if (is_infinite())
16496 o << "[]";
16497 else
16498 o << "[" << get_length() << "]";
16499
16500 return o.str();
16501 }
16502
16503 /// Return a string representation of a vector of subranges
16504 ///
16505 /// @return the string representation of a vector of sub ranges.
16506 string
vector_as_string(const vector<subrange_sptr> & v)16507 array_type_def::subrange_type::vector_as_string(const vector<subrange_sptr>& v)
16508 {
16509 if (v.empty())
16510 return "[]";
16511
16512 string r;
16513 for (vector<subrange_sptr>::const_iterator i = v.begin();
16514 i != v.end();
16515 ++i)
16516 r += (*i)->as_string();
16517
16518 return r;
16519 }
16520
16521 /// Compares two isntances of @ref array_type_def::subrange_type.
16522 ///
16523 /// If the two intances are different, set a bitfield to give some
16524 /// insight about the kind of differences there are.
16525 ///
16526 /// @param l the first artifact of the comparison.
16527 ///
16528 /// @param r the second artifact of the comparison.
16529 ///
16530 /// @param k a pointer to a bitfield that gives information about the
16531 /// kind of changes there are between @p l and @p r. This one is set
16532 /// iff @p k is non-null and the function returns false.
16533 ///
16534 /// Please note that setting k to a non-null value does have a
16535 /// negative performance impact because even if @p l and @p r are not
16536 /// equal, the function keeps up the comparison in order to determine
16537 /// the different kinds of ways in which they are different.
16538 ///
16539 /// @return true if @p l equals @p r, false otherwise.
16540 bool
equals(const array_type_def::subrange_type & l,const array_type_def::subrange_type & r,change_kind * k)16541 equals(const array_type_def::subrange_type& l,
16542 const array_type_def::subrange_type& r,
16543 change_kind* k)
16544 {
16545 bool result = true;
16546
16547 if (l.get_lower_bound() != r.get_lower_bound()
16548 || l.get_upper_bound() != r.get_upper_bound()
16549 || l.get_name() != r.get_name())
16550 {
16551 result = false;
16552 if (k)
16553 *k |= LOCAL_TYPE_CHANGE_KIND;
16554 else
16555 ABG_RETURN(result);
16556 }
16557
16558 #if 0
16559 // If we enable this, we need to update the reporting code too, to
16560 // report changes about range underlying types too.
16561 if (l.get_underlying_type() != r.get_underlying_type())
16562 {
16563 result = false;
16564 if (k)
16565 {
16566 if (!types_have_similar_structure(l.get_underlying_type().get(),
16567 r.get_underlying_type().get()))
16568 *k |= LOCAL_TYPE_CHANGE_KIND;
16569 else
16570 *k |= SUBTYPE_CHANGE_KIND;
16571 }
16572 else
16573 ABG_RETURN(result);
16574 }
16575 #endif
16576 ABG_RETURN(result);
16577 }
16578
16579 /// Equality operator.
16580 ///
16581 /// @param o the other subrange to test against.
16582 ///
16583 /// @return true iff @p o equals the current instance of
16584 /// array_type_def::subrange_type.
16585 bool
operator ==(const decl_base & o) const16586 array_type_def::subrange_type::operator==(const decl_base& o) const
16587 {
16588 const subrange_type* other =
16589 dynamic_cast<const subrange_type*>(&o);
16590 if (!other)
16591 return false;
16592 return try_canonical_compare(this, other);
16593 }
16594
16595 /// Equality operator.
16596 ///
16597 /// @param o the other subrange to test against.
16598 ///
16599 /// @return true iff @p o equals the current instance of
16600 /// array_type_def::subrange_type.
16601 bool
operator ==(const type_base & o) const16602 array_type_def::subrange_type::operator==(const type_base& o) const
16603 {
16604 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16605 if (!other)
16606 return false;
16607 return *this == *other;
16608 }
16609
16610 /// Equality operator.
16611 ///
16612 /// @param o the other subrange to test against.
16613 ///
16614 /// @return true iff @p o equals the current instance of
16615 /// array_type_def::subrange_type.
16616 bool
operator ==(const subrange_type & o) const16617 array_type_def::subrange_type::operator==(const subrange_type& o) const
16618 {
16619 const type_base &t = o;
16620 return operator==(t);
16621 }
16622
16623 /// Inequality operator.
16624 ///
16625 /// @param o the other subrange to test against.
16626 ///
16627 /// @return true iff @p o is different from the current instance of
16628 /// array_type_def::subrange_type.
16629 bool
operator !=(const subrange_type & o) const16630 array_type_def::subrange_type::operator!=(const subrange_type& o) const
16631 {return !operator==(o);}
16632
16633 /// Build a pretty representation for an
16634 /// array_type_def::subrange_type.
16635 ///
16636 /// @param internal set to true if the call is intended to get a
16637 /// representation of the decl (or type) for the purpose of canonical
16638 /// type comparison. This is mainly used in the function
16639 /// type_base::get_canonical_type_for().
16640 ///
16641 /// In other words if the argument for this parameter is true then the
16642 /// call is meant for internal use (for technical use inside the
16643 /// library itself), false otherwise. If you don't know what this is
16644 /// for, then set it to false.
16645 ///
16646 /// @return a copy of the pretty representation of the current
16647 /// instance of typedef_decl.
16648 string
get_pretty_representation(bool,bool) const16649 array_type_def::subrange_type::get_pretty_representation(bool, bool) const
16650 {
16651 string name = get_name();
16652 string repr;
16653
16654 if (name.empty())
16655 repr += "<anonymous range>";
16656 else
16657 repr += "<range " + get_name() + ">";
16658 repr += as_string();
16659
16660 return repr;
16661 }
16662
16663 /// This implements the ir_traversable_base::traverse pure virtual
16664 /// function.
16665 ///
16666 /// @param v the visitor used on the current instance.
16667 ///
16668 /// @return true if the entire IR node tree got traversed, false
16669 /// otherwise.
16670 bool
traverse(ir_node_visitor & v)16671 array_type_def::subrange_type::traverse(ir_node_visitor& v)
16672 {
16673 if (v.type_node_has_been_visited(this))
16674 return true;
16675
16676 if (v.visit_begin(this))
16677 {
16678 visiting(true);
16679 if (type_base_sptr u = get_underlying_type())
16680 u->traverse(v);
16681 visiting(false);
16682 }
16683
16684 bool result = v.visit_end(this);
16685 v.mark_type_node_as_visited(this);
16686 return result;
16687 }
16688
16689 // </array_type_def::subrange_type>
16690
16691 struct array_type_def::priv
16692 {
16693 type_base_wptr element_type_;
16694 subranges_type subranges_;
16695 interned_string temp_internal_qualified_name_;
16696 interned_string internal_qualified_name_;
16697
privabigail::ir::array_type_def::priv16698 priv(type_base_sptr t)
16699 : element_type_(t)
16700 {}
16701
privabigail::ir::array_type_def::priv16702 priv(type_base_sptr t, subranges_type subs)
16703 : element_type_(t), subranges_(subs)
16704 {}
16705
privabigail::ir::array_type_def::priv16706 priv()
16707 {}
16708 };
16709
16710 /// Constructor for the type array_type_def
16711 ///
16712 /// Note how the constructor expects a vector of subrange
16713 /// objects. Parsing of the array information always entails
16714 /// parsing the subrange info as well, thus the class subrange_type
16715 /// is defined inside class array_type_def and also parsed
16716 /// simultaneously.
16717 ///
16718 /// @param e_type the type of the elements contained in the array
16719 ///
16720 /// @param subs a vector of the array's subranges(dimensions)
16721 ///
16722 /// @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)16723 array_type_def::array_type_def(const type_base_sptr e_type,
16724 const std::vector<subrange_sptr>& subs,
16725 const location& locus)
16726 : type_or_decl_base(e_type->get_environment(),
16727 ARRAY_TYPE
16728 | ABSTRACT_TYPE_BASE
16729 | ABSTRACT_DECL_BASE),
16730 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
16731 decl_base(e_type->get_environment(), locus),
16732 priv_(new priv(e_type))
16733 {
16734 runtime_type_instance(this);
16735 append_subranges(subs);
16736 }
16737
16738 /// Constructor for the type array_type_def
16739 ///
16740 /// This constructor builds a temporary array that has no element type
16741 /// associated. Later when the element type is available, it be set
16742 /// with the array_type_def::set_element_type() member function.
16743 ///
16744 /// Note how the constructor expects a vector of subrange
16745 /// objects. Parsing of the array information always entails
16746 /// parsing the subrange info as well, thus the class subrange_type
16747 /// is defined inside class array_type_def and also parsed
16748 /// simultaneously.
16749 ///
16750 /// @param env the environment of the array type.
16751 ///
16752 /// @param subs a vector of the array's subranges(dimensions)
16753 ///
16754 /// @param locus the source location of the array type definition.
array_type_def(environment * env,const std::vector<subrange_sptr> & subs,const location & locus)16755 array_type_def::array_type_def(environment* env,
16756 const std::vector<subrange_sptr>& subs,
16757 const location& locus)
16758 : type_or_decl_base(env,
16759 ARRAY_TYPE
16760 | ABSTRACT_TYPE_BASE
16761 | ABSTRACT_DECL_BASE),
16762 type_base(env, 0, 0),
16763 decl_base(env, locus),
16764 priv_(new priv)
16765 {
16766 runtime_type_instance(this);
16767 append_subranges(subs);
16768 }
16769
16770 /// Update the size of the array.
16771 ///
16772 /// This function computes the size of the array and sets it using
16773 /// type_base::set_size_in_bits().
16774 void
update_size()16775 array_type_def::update_size()
16776 {
16777 type_base_sptr e = priv_->element_type_.lock();
16778 if (e)
16779 {
16780 size_t s = e->get_size_in_bits();
16781 if (s)
16782 {
16783 for (const auto &sub : get_subranges())
16784 s *= sub->get_length();
16785
16786 const environment* env = e->get_environment();
16787 ABG_ASSERT(env);
16788 set_size_in_bits(s);
16789 }
16790 set_alignment_in_bits(e->get_alignment_in_bits());
16791 }
16792 }
16793
16794 string
get_subrange_representation() const16795 array_type_def::get_subrange_representation() const
16796 {
16797 string r = subrange_type::vector_as_string(get_subranges());
16798 return r;
16799 }
16800
16801 /// Get the string representation of an @ref array_type_def.
16802 ///
16803 /// @param a the array type to consider.
16804 ///
16805 /// @param internal set to true if the call is intended for an
16806 /// internal use (for technical use inside the library itself), false
16807 /// otherwise. If you don't know what this is for, then set it to
16808 /// false.
16809 static string
get_type_representation(const array_type_def & a,bool internal)16810 get_type_representation(const array_type_def& a, bool internal)
16811 {
16812 type_base_sptr e_type = a.get_element_type();
16813 decl_base_sptr d = get_type_declaration(e_type);
16814 string r;
16815
16816 if (is_ada_language(a.get_language()))
16817 {
16818 std::ostringstream o;
16819 o << "array ("
16820 << a.get_subrange_representation()
16821 << ") of "
16822 << e_type ? e_type->get_pretty_representation(internal):string("void");
16823 }
16824 else
16825 {
16826 if (internal)
16827 r = (e_type
16828 ? get_type_name(e_type,
16829 /*qualified=*/true,
16830 /*internal=*/true)
16831 : string("void"))
16832 + a.get_subrange_representation();
16833 else
16834 r = (e_type
16835 ? get_type_name(e_type, /*qualified=*/false, /*internal=*/false)
16836 : string("void"))
16837 + a.get_subrange_representation();
16838 }
16839
16840 return r;
16841 }
16842
16843 /// Get the pretty representation of the current instance of @ref
16844 /// array_type_def.
16845 ///
16846 /// @param internal set to true if the call is intended to get a
16847 /// representation of the decl (or type) for the purpose of canonical
16848 /// type comparison. This is mainly used in the function
16849 /// type_base::get_canonical_type_for().
16850 ///
16851 /// In other words if the argument for this parameter is true then the
16852 /// call is meant for internal use (for technical use inside the
16853 /// library itself), false otherwise. If you don't know what this is
16854 /// for, then set it to false.
16855 /// @param internal set to true if the call is intended for an
16856 /// internal use (for technical use inside the library itself), false
16857 /// otherwise. If you don't know what this is for, then set it to
16858 /// false.
16859 ///
16860 /// @return the pretty representation of the ABI artifact.
16861 string
get_pretty_representation(bool internal,bool) const16862 array_type_def::get_pretty_representation(bool internal,
16863 bool /*qualified_name*/) const
16864 {return get_type_representation(*this, internal);}
16865
16866 /// Compares two instances of @ref array_type_def.
16867 ///
16868 /// If the two intances are different, set a bitfield to give some
16869 /// insight about the kind of differences there are.
16870 ///
16871 /// @param l the first artifact of the comparison.
16872 ///
16873 /// @param r the second artifact of the comparison.
16874 ///
16875 /// @param k a pointer to a bitfield that gives information about the
16876 /// kind of changes there are between @p l and @p r. This one is set
16877 /// iff @p k is non-null and the function returns false.
16878 ///
16879 /// Please note that setting k to a non-null value does have a
16880 /// negative performance impact because even if @p l and @p r are not
16881 /// equal, the function keeps up the comparison in order to determine
16882 /// the different kinds of ways in which they are different.
16883 ///
16884 /// @return true if @p l equals @p r, false otherwise.
16885 bool
equals(const array_type_def & l,const array_type_def & r,change_kind * k)16886 equals(const array_type_def& l, const array_type_def& r, change_kind* k)
16887 {
16888 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
16889 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
16890
16891 bool result = true;
16892 if (this_subs.size() != other_subs.size())
16893 {
16894 result = false;
16895 if (k)
16896 *k |= LOCAL_TYPE_CHANGE_KIND;
16897 else
16898 ABG_RETURN_FALSE;
16899 }
16900
16901 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
16902 for (i = this_subs.begin(), j = other_subs.begin();
16903 i != this_subs.end() && j != other_subs.end();
16904 ++i, ++j)
16905 if (**i != **j)
16906 {
16907 result = false;
16908 if (k)
16909 {
16910 *k |= LOCAL_TYPE_CHANGE_KIND;
16911 break;
16912 }
16913 else
16914 ABG_RETURN_FALSE;
16915 }
16916
16917 // Compare the element types modulo the typedefs they might have
16918 if (l.get_element_type() != r.get_element_type())
16919 {
16920 result = false;
16921 if (k)
16922 *k |= SUBTYPE_CHANGE_KIND;
16923 else
16924 ABG_RETURN_FALSE;
16925 }
16926
16927 ABG_RETURN(result);
16928 }
16929
16930 /// Test if two variables are equals modulo CV qualifiers.
16931 ///
16932 /// @param l the first array of the comparison.
16933 ///
16934 /// @param r the second array of the comparison.
16935 ///
16936 /// @return true iff @p l equals @p r or, if they are different, the
16937 /// difference between the too is just a matter of CV qualifiers.
16938 bool
equals_modulo_cv_qualifier(const array_type_def * l,const array_type_def * r)16939 equals_modulo_cv_qualifier(const array_type_def* l, const array_type_def* r)
16940 {
16941 if (l == r)
16942 return true;
16943
16944 if (!l || !r)
16945 ABG_RETURN_FALSE;
16946
16947 l = is_array_type(peel_qualified_or_typedef_type(l));
16948 r = is_array_type(peel_qualified_or_typedef_type(r));
16949
16950 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
16951 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
16952
16953 if (this_subs.size() != other_subs.size())
16954 ABG_RETURN_FALSE;
16955
16956 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
16957 for (i = this_subs.begin(), j = other_subs.begin();
16958 i != this_subs.end() && j != other_subs.end();
16959 ++i, ++j)
16960 if (**i != **j)
16961 ABG_RETURN_FALSE;
16962
16963 type_base *first_element_type =
16964 peel_qualified_or_typedef_type(l->get_element_type().get());
16965 type_base *second_element_type =
16966 peel_qualified_or_typedef_type(r->get_element_type().get());
16967
16968 if (*first_element_type != *second_element_type)
16969 ABG_RETURN_FALSE;
16970
16971 return true;
16972 }
16973
16974 /// Get the language of the array.
16975 ///
16976 /// @return the language of the array.
16977 translation_unit::language
get_language() const16978 array_type_def::get_language() const
16979 {
16980 const std::vector<subrange_sptr>& subranges =
16981 get_subranges();
16982
16983 if (subranges.empty())
16984 return translation_unit::LANG_C11;
16985 return subranges.front()->get_language();
16986 }
16987
16988 bool
operator ==(const decl_base & o) const16989 array_type_def::operator==(const decl_base& o) const
16990 {
16991 const array_type_def* other =
16992 dynamic_cast<const array_type_def*>(&o);
16993 if (!other)
16994 return false;
16995 return try_canonical_compare(this, other);
16996 }
16997
16998 bool
operator ==(const type_base & o) const16999 array_type_def::operator==(const type_base& o) const
17000 {
17001 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17002 if (!other)
17003 return false;
17004 return *this == *other;
17005 }
17006
17007 /// Getter of the type of an array element.
17008 ///
17009 /// @return the type of an array element.
17010 const type_base_sptr
get_element_type() const17011 array_type_def::get_element_type() const
17012 {return priv_->element_type_.lock();}
17013
17014 /// Setter of the type of array element.
17015 ///
17016 /// Beware that after using this function, one might want to
17017 /// re-compute the canonical type of the array, if one has already
17018 /// been computed.
17019 ///
17020 /// The intended use of this method is to permit in-place adjustment
17021 /// of the element type's qualifiers. In particular, the size of the
17022 /// element type should not be changed.
17023 ///
17024 /// @param element_type the new element type to set.
17025 void
set_element_type(const type_base_sptr & element_type)17026 array_type_def::set_element_type(const type_base_sptr& element_type)
17027 {
17028 priv_->element_type_ = element_type;
17029 update_size();
17030 set_name(get_environment()->intern(get_pretty_representation()));
17031 }
17032
17033 /// Append subranges from the vector @param subs to the current
17034 /// vector of subranges.
17035 void
append_subranges(const std::vector<subrange_sptr> & subs)17036 array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
17037 {
17038
17039 for (const auto &sub : subs)
17040 priv_->subranges_.push_back(sub);
17041
17042 update_size();
17043 set_name(get_environment()->intern(get_pretty_representation()));
17044 }
17045
17046 /// @return true if one of the sub-ranges of the array is infinite, or
17047 /// if the array has no sub-range at all, also meaning that the size
17048 /// of the array is infinite.
17049 bool
is_infinite() const17050 array_type_def::is_infinite() const
17051 {
17052 if (priv_->subranges_.empty())
17053 return true;
17054
17055 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
17056 priv_->subranges_.begin();
17057 i != priv_->subranges_.end();
17058 ++i)
17059 if ((*i)->is_infinite())
17060 return true;
17061
17062 return false;
17063 }
17064
17065 int
get_dimension_count() const17066 array_type_def::get_dimension_count() const
17067 {return priv_->subranges_.size();}
17068
17069 /// Build and return the qualified name of the current instance of the
17070 /// @ref array_type_def.
17071 ///
17072 /// @param qn output parameter. Is set to the newly-built qualified
17073 /// name of the current instance of @ref array_type_def.
17074 ///
17075 /// @param internal set to true if the call is intended for an
17076 /// internal use (for technical use inside the library itself), false
17077 /// otherwise. If you don't know what this is for, then set it to
17078 /// false.
17079 void
get_qualified_name(interned_string & qn,bool internal) const17080 array_type_def::get_qualified_name(interned_string& qn, bool internal) const
17081 {qn = get_qualified_name(internal);}
17082
17083 /// Compute the qualified name of the array.
17084 ///
17085 /// @param internal set to true if the call is intended for an
17086 /// internal use (for technical use inside the library itself), false
17087 /// otherwise. If you don't know what this is for, then set it to
17088 /// false.
17089 ///
17090 /// @return the resulting qualified name.
17091 const interned_string&
get_qualified_name(bool internal) const17092 array_type_def::get_qualified_name(bool internal) const
17093 {
17094 const environment* env = get_environment();
17095 ABG_ASSERT(env);
17096
17097 if (internal)
17098 {
17099 if (get_canonical_type())
17100 {
17101 if (priv_->internal_qualified_name_.empty())
17102 priv_->internal_qualified_name_ =
17103 env->intern(get_type_representation(*this, /*internal=*/true));
17104 return priv_->internal_qualified_name_;
17105 }
17106 else
17107 {
17108 priv_->temp_internal_qualified_name_ =
17109 env->intern(get_type_representation(*this, /*internal=*/true));
17110 return priv_->temp_internal_qualified_name_;
17111 }
17112 }
17113 else
17114 {
17115 if (get_canonical_type())
17116 {
17117 if (decl_base::peek_qualified_name().empty())
17118 set_qualified_name(env->intern(get_type_representation
17119 (*this, /*internal=*/false)));
17120 return decl_base::peek_qualified_name();
17121 }
17122 else
17123 {
17124 set_temporary_qualified_name(env->intern(get_type_representation
17125 (*this,
17126 /*internal=*/false)));
17127 return decl_base::peek_temporary_qualified_name();
17128 }
17129 }
17130 }
17131
17132 /// This implements the ir_traversable_base::traverse pure virtual
17133 /// function.
17134 ///
17135 /// @param v the visitor used on the current instance.
17136 ///
17137 /// @return true if the entire IR node tree got traversed, false
17138 /// otherwise.
17139 bool
traverse(ir_node_visitor & v)17140 array_type_def::traverse(ir_node_visitor& v)
17141 {
17142 if (v.type_node_has_been_visited(this))
17143 return true;
17144
17145 if (visiting())
17146 return true;
17147
17148 if (v.visit_begin(this))
17149 {
17150 visiting(true);
17151 if (type_base_sptr t = get_element_type())
17152 t->traverse(v);
17153 visiting(false);
17154 }
17155
17156 bool result = v.visit_end(this);
17157 v.mark_type_node_as_visited(this);
17158 return result;
17159 }
17160
17161 const location&
get_location() const17162 array_type_def::get_location() const
17163 {return decl_base::get_location();}
17164
17165 /// Get the array's subranges
17166 const std::vector<array_type_def::subrange_sptr>&
get_subranges() const17167 array_type_def::get_subranges() const
17168 {return priv_->subranges_;}
17169
~array_type_def()17170 array_type_def::~array_type_def()
17171 {}
17172
17173 // </array_type_def definitions>
17174
17175 // <enum_type_decl definitions>
17176
17177 class enum_type_decl::priv
17178 {
17179 type_base_sptr underlying_type_;
17180 enumerators enumerators_;
17181
17182 friend class enum_type_decl;
17183
17184 priv();
17185
17186 public:
priv(type_base_sptr underlying_type,enumerators & enumerators)17187 priv(type_base_sptr underlying_type,
17188 enumerators& enumerators)
17189 : underlying_type_(underlying_type),
17190 enumerators_(enumerators)
17191 {}
17192 }; // end class enum_type_decl::priv
17193
17194 /// Constructor.
17195 ///
17196 /// @param name the name of the type declaration.
17197 ///
17198 /// @param locus the source location where the type was defined.
17199 ///
17200 /// @param underlying_type the underlying type of the enum.
17201 ///
17202 /// @param enums the enumerators of this enum type.
17203 ///
17204 /// @param linkage_name the linkage name of the enum.
17205 ///
17206 /// @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)17207 enum_type_decl::enum_type_decl(const string& name,
17208 const location& locus,
17209 type_base_sptr underlying_type,
17210 enumerators& enums,
17211 const string& linkage_name,
17212 visibility vis)
17213 : type_or_decl_base(underlying_type->get_environment(),
17214 ENUM_TYPE
17215 | ABSTRACT_TYPE_BASE
17216 | ABSTRACT_DECL_BASE),
17217 type_base(underlying_type->get_environment(),
17218 underlying_type->get_size_in_bits(),
17219 underlying_type->get_alignment_in_bits()),
17220 decl_base(underlying_type->get_environment(),
17221 name, locus, linkage_name, vis),
17222 priv_(new priv(underlying_type, enums))
17223 {
17224 runtime_type_instance(this);
17225 for (enumerators::iterator e = get_enumerators().begin();
17226 e != get_enumerators().end();
17227 ++e)
17228 e->set_enum_type(this);
17229 }
17230
17231 /// Return the underlying type of the enum.
17232 type_base_sptr
get_underlying_type() const17233 enum_type_decl::get_underlying_type() const
17234 {return priv_->underlying_type_;}
17235
17236 /// @return the list of enumerators of the enum.
17237 const enum_type_decl::enumerators&
get_enumerators() const17238 enum_type_decl::get_enumerators() const
17239 {return priv_->enumerators_;}
17240
17241 /// @return the list of enumerators of the enum.
17242 enum_type_decl::enumerators&
get_enumerators()17243 enum_type_decl::get_enumerators()
17244 {return priv_->enumerators_;}
17245
17246 /// Get the pretty representation of the current instance of @ref
17247 /// enum_type_decl.
17248 ///
17249 /// @param internal set to true if the call is intended to get a
17250 /// representation of the decl (or type) for the purpose of canonical
17251 /// type comparison. This is mainly used in the function
17252 /// type_base::get_canonical_type_for().
17253 ///
17254 /// In other words if the argument for this parameter is true then the
17255 /// call is meant for internal use (for technical use inside the
17256 /// library itself), false otherwise. If you don't know what this is
17257 /// for, then set it to false.
17258 ///
17259 /// @param qualified_name if true, names emitted in the pretty
17260 /// representation are fully qualified.
17261 ///
17262 /// @return the pretty representation of the enum type.
17263 string
get_pretty_representation(bool internal,bool qualified_name) const17264 enum_type_decl::get_pretty_representation(bool internal,
17265 bool qualified_name) const
17266 {
17267 string r = "enum ";
17268
17269 if (internal && get_is_anonymous())
17270 r += get_type_name(this, qualified_name, /*internal=*/true);
17271 else
17272 r += decl_base::get_pretty_representation(internal,
17273 qualified_name);
17274 return r;
17275 }
17276
17277 /// This implements the ir_traversable_base::traverse pure virtual
17278 /// function.
17279 ///
17280 /// @param v the visitor used on the current instance.
17281 ///
17282 /// @return true if the entire IR node tree got traversed, false
17283 /// otherwise.
17284 bool
traverse(ir_node_visitor & v)17285 enum_type_decl::traverse(ir_node_visitor &v)
17286 {
17287 if (v.type_node_has_been_visited(this))
17288 return true;
17289
17290 if (visiting())
17291 return true;
17292
17293 if (v.visit_begin(this))
17294 {
17295 visiting(true);
17296 if (type_base_sptr t = get_underlying_type())
17297 t->traverse(v);
17298 visiting(false);
17299 }
17300
17301 bool result = v.visit_end(this);
17302 v.mark_type_node_as_visited(this);
17303 return result;
17304 }
17305
17306 /// Destructor for the enum type declaration.
~enum_type_decl()17307 enum_type_decl::~enum_type_decl()
17308 {}
17309
17310 /// Test if two enums differ, but not by a name change.
17311 ///
17312 /// @param l the first enum to consider.
17313 ///
17314 /// @param r the second enum to consider.
17315 ///
17316 /// @return true iff @p l differs from @p r by anything but a name
17317 /// change.
17318 bool
enum_has_non_name_change(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)17319 enum_has_non_name_change(const enum_type_decl& l,
17320 const enum_type_decl& r,
17321 change_kind* k)
17322 {
17323 bool result = false;
17324 if (*l.get_underlying_type() != *r.get_underlying_type())
17325 {
17326 result = true;
17327 if (k)
17328 *k |= SUBTYPE_CHANGE_KIND;
17329 else
17330 return true;
17331 }
17332
17333 enum_type_decl::enumerators::const_iterator i, j;
17334 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
17335 i != l.get_enumerators().end() && j != r.get_enumerators().end();
17336 ++i, ++j)
17337 if (*i != *j)
17338 {
17339 result = true;
17340 if (k)
17341 {
17342 *k |= LOCAL_TYPE_CHANGE_KIND;
17343 break;
17344 }
17345 else
17346 return true;
17347 }
17348
17349 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
17350 {
17351 result = true;
17352 if (k)
17353 *k |= LOCAL_TYPE_CHANGE_KIND;
17354 else
17355 return true;
17356 }
17357
17358 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
17359 interned_string qn_r = l.get_environment()->intern(r.get_qualified_name());
17360 interned_string qn_l = l.get_environment()->intern(l.get_qualified_name());
17361 string n_l = l.get_name();
17362 string n_r = r.get_name();
17363 local_r.set_qualified_name(qn_l);
17364 local_r.set_name(n_l);
17365
17366 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
17367 {
17368 result = true;
17369 if (k)
17370 {
17371 if (!l.decl_base::operator==(r))
17372 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
17373 if (!l.type_base::operator==(r))
17374 *k |= LOCAL_TYPE_CHANGE_KIND;
17375 }
17376 else
17377 {
17378 local_r.set_name(n_r);
17379 local_r.set_qualified_name(qn_r);
17380 return true;
17381 }
17382 }
17383 local_r.set_qualified_name(qn_r);
17384 local_r.set_name(n_r);
17385
17386 return result;
17387 }
17388
17389 /// Test if a given enumerator is found present in an enum.
17390 ///
17391 /// This is a subroutine of the equals function for enums.
17392 ///
17393 /// @param enr the enumerator to consider.
17394 ///
17395 /// @param enom the enum to consider.
17396 ///
17397 /// @return true iff the enumerator @p enr is present in the enum @p
17398 /// enom.
17399 static bool
is_enumerator_present_in_enum(const enum_type_decl::enumerator & enr,const enum_type_decl & enom)17400 is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr,
17401 const enum_type_decl &enom)
17402 {
17403 for (const auto &e : enom.get_enumerators())
17404 if (e == enr)
17405 return true;
17406 return false;
17407 }
17408
17409 /// Check if two enumerators values are equal.
17410 ///
17411 /// This function doesn't check if the names of the enumerators are
17412 /// equal or not.
17413 ///
17414 /// @param enr the first enumerator to consider.
17415 ///
17416 /// @param enl the second enumerator to consider.
17417 ///
17418 /// @return true iff @p enr has the same value as @p enl.
17419 static bool
enumerators_values_are_equal(const enum_type_decl::enumerator & enr,const enum_type_decl::enumerator & enl)17420 enumerators_values_are_equal(const enum_type_decl::enumerator &enr,
17421 const enum_type_decl::enumerator &enl)
17422 {return enr.get_value() == enl.get_value();}
17423
17424 /// Detect if a given enumerator value is present in an enum.
17425 ///
17426 /// This function looks inside the enumerators of a given enum and
17427 /// detect if the enum contains at least one enumerator or a given
17428 /// value. The function also detects if the enumerator value we are
17429 /// looking at is present in the enum with a different name. An
17430 /// enumerator with the same value but with a different name is named
17431 /// a "redundant enumerator". The function returns the set of
17432 /// enumerators that are redundant with the value we are looking at.
17433 ///
17434 /// @param enr the enumerator to consider.
17435 ///
17436 /// @param enom the enum to consider.
17437 ///
17438 /// @param redundant_enrs if the function returns true, then this
17439 /// vector is filled with enumerators that are redundant with the
17440 /// value of @p enr.
17441 ///
17442 /// @return true iff the function detects that @p enom contains
17443 /// enumerators with the same value as @p enr.
17444 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)17445 is_enumerator_value_present_in_enum(const enum_type_decl::enumerator &enr,
17446 const enum_type_decl &enom,
17447 vector<enum_type_decl::enumerator>& redundant_enrs)
17448 {
17449 bool found = false;
17450 for (const auto &e : enom.get_enumerators())
17451 if (enumerators_values_are_equal(e, enr))
17452 {
17453 found = true;
17454 if (e != enr)
17455 redundant_enrs.push_back(e);
17456 }
17457
17458 return found;
17459 }
17460
17461 /// Check if an enumerator value is redundant in a given enum.
17462 ///
17463 /// Given an enumerator value, this function detects if an enum
17464 /// contains at least one enumerator with the the same value but with
17465 /// a different name.
17466 ///
17467 /// @param enr the enumerator to consider.
17468 ///
17469 /// @param enom the enum to consider.
17470 ///
17471 /// @return true iff @p enr is a redundant enumerator in enom.
17472 static bool
is_enumerator_value_redundant(const enum_type_decl::enumerator & enr,const enum_type_decl & enom)17473 is_enumerator_value_redundant(const enum_type_decl::enumerator &enr,
17474 const enum_type_decl &enom)
17475 {
17476 vector<enum_type_decl::enumerator> redundant_enrs;
17477 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
17478 {
17479 if (!redundant_enrs.empty())
17480 return true;
17481 }
17482 return false;
17483 }
17484
17485 /// Compares two instances of @ref enum_type_decl.
17486 ///
17487 /// If the two intances are different, set a bitfield to give some
17488 /// insight about the kind of differences there are.
17489 ///
17490 /// @param l the first artifact of the comparison.
17491 ///
17492 /// @param r the second artifact of the comparison.
17493 ///
17494 /// @param k a pointer to a bitfield that gives information about the
17495 /// kind of changes there are between @p l and @p r. This one is set
17496 /// iff @p k is non-null and the function returns false.
17497 ///
17498 /// Please note that setting k to a non-null value does have a
17499 /// negative performance impact because even if @p l and @p r are not
17500 /// equal, the function keeps up the comparison in order to determine
17501 /// the different kinds of ways in which they are different.
17502 ///
17503 /// @return true if @p l equals @p r, false otherwise.
17504 bool
equals(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)17505 equals(const enum_type_decl& l, const enum_type_decl& r, change_kind* k)
17506 {
17507 bool result = true;
17508 if (*l.get_underlying_type() != *r.get_underlying_type())
17509 {
17510 result = false;
17511 if (k)
17512 *k |= SUBTYPE_CHANGE_KIND;
17513 else
17514 ABG_RETURN_FALSE;
17515 }
17516
17517 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
17518 {
17519 result = false;
17520 if (k)
17521 {
17522 if (!l.decl_base::operator==(r))
17523 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
17524 if (!l.type_base::operator==(r))
17525 *k |= LOCAL_TYPE_CHANGE_KIND;
17526 }
17527 else
17528 ABG_RETURN_FALSE;
17529 }
17530
17531 // Now compare the enumerators. Note that the order of declaration
17532 // of enumerators should not matter in the comparison.
17533 //
17534 // Also if an enumerator value is redundant, that shouldn't impact
17535 // the comparison.
17536 //
17537 // In that case, note that the two enums below are considered equal:
17538 //
17539 // enum foo
17540 // {
17541 // e0 = 0;
17542 // e1 = 1;
17543 // e2 = 2;
17544 // };
17545 //
17546 // enum foo
17547 // {
17548 // e0 = 0;
17549 // e1 = 1;
17550 // e2 = 2;
17551 // e_added = 1; // <-- this value is redundant with the value
17552 // // of the enumerator e1.
17553 // };
17554 //
17555 // These two enums are considered equal.
17556
17557 for(const auto &e : l.get_enumerators())
17558 if (!is_enumerator_present_in_enum(e, r)
17559 && !is_enumerator_value_redundant(e, r))
17560 {
17561 result = false;
17562 if (k)
17563 {
17564 *k |= LOCAL_TYPE_CHANGE_KIND;
17565 break;
17566 }
17567 else
17568 ABG_RETURN_FALSE;
17569 }
17570
17571 for(const auto &e : r.get_enumerators())
17572 if (!is_enumerator_present_in_enum(e, l)
17573 && !is_enumerator_value_redundant(e, r))
17574 {
17575 result = false;
17576 if (k)
17577 {
17578 *k |= LOCAL_TYPE_CHANGE_KIND;
17579 break;
17580 }
17581 else
17582 ABG_RETURN_FALSE;
17583 }
17584
17585 ABG_RETURN(result);
17586 }
17587
17588 /// Equality operator.
17589 ///
17590 /// @param o the other enum to test against.
17591 ///
17592 /// @return true iff @p o equals the current instance of enum type
17593 /// decl.
17594 bool
operator ==(const decl_base & o) const17595 enum_type_decl::operator==(const decl_base& o) const
17596 {
17597 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
17598 if (!op)
17599 return false;
17600 return try_canonical_compare(this, op);
17601 }
17602
17603 /// Equality operator.
17604 ///
17605 /// @param o the other enum to test against.
17606 ///
17607 /// @return true iff @p o is equals the current instance of enum type
17608 /// decl.
17609 bool
operator ==(const type_base & o) const17610 enum_type_decl::operator==(const type_base& o) const
17611 {
17612 const decl_base* other = dynamic_cast<const decl_base*>(&o);
17613 if (!other)
17614 return false;
17615 return *this == *other;
17616 }
17617
17618 /// Equality operator for @ref enum_type_decl_sptr.
17619 ///
17620 /// @param l the first operand to compare.
17621 ///
17622 /// @param r the second operand to compare.
17623 ///
17624 /// @return true iff @p l equals @p r.
17625 bool
operator ==(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)17626 operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
17627 {
17628 if (!!l != !!r)
17629 return false;
17630 if (l.get() == r.get())
17631 return true;
17632 decl_base_sptr o = r;
17633 return *l == *o;
17634 }
17635
17636 /// Inequality operator for @ref enum_type_decl_sptr.
17637 ///
17638 /// @param l the first operand to compare.
17639 ///
17640 /// @param r the second operand to compare.
17641 ///
17642 /// @return true iff @p l equals @p r.
17643 bool
operator !=(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)17644 operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
17645 {return !operator==(l, r);}
17646
17647 /// The type of the private data of an @ref
17648 /// enum_type_decl::enumerator.
17649 class enum_type_decl::enumerator::priv
17650 {
17651 const environment* env_;
17652 interned_string name_;
17653 int64_t value_;
17654 interned_string qualified_name_;
17655 enum_type_decl* enum_type_;
17656
17657 friend class enum_type_decl::enumerator;
17658
17659 public:
17660
priv()17661 priv()
17662 : env_(),
17663 enum_type_()
17664 {}
17665
priv(const environment * env,const string & name,int64_t value,enum_type_decl * e=0)17666 priv(const environment* env,
17667 const string& name,
17668 int64_t value,
17669 enum_type_decl* e = 0)
17670 : env_(env),
17671 name_(env ? env->intern(name) : interned_string()),
17672 value_(value),
17673 enum_type_(e)
17674 {}
17675 }; // end class enum_type_def::enumerator::priv
17676
17677 /// Default constructor of the @ref enum_type_decl::enumerator type.
enumerator()17678 enum_type_decl::enumerator::enumerator()
17679 : priv_(new priv)
17680 {}
17681
17682 enum_type_decl::enumerator::~enumerator() = default;
17683
17684
17685 /// Constructor of the @ref enum_type_decl::enumerator type.
17686 ///
17687 /// @param env the environment we are operating from.
17688 ///
17689 /// @param name the name of the enumerator.
17690 ///
17691 /// @param value the value of the enumerator.
enumerator(const environment * env,const string & name,int64_t value)17692 enum_type_decl::enumerator::enumerator(const environment* env,
17693 const string& name,
17694 int64_t value)
17695 : priv_(new priv(env, name, value))
17696 {}
17697
17698 /// Copy constructor of the @ref enum_type_decl::enumerator type.
17699 ///
17700 /// @param other enumerator to copy.
enumerator(const enumerator & other)17701 enum_type_decl::enumerator::enumerator(const enumerator& other)
17702 : priv_(new priv(other.get_environment(),
17703 other.get_name(),
17704 other.get_value(),
17705 other.get_enum_type()))
17706 {}
17707
17708 /// Assignment operator of the @ref enum_type_decl::enumerator type.
17709 ///
17710 /// @param o
17711 enum_type_decl::enumerator&
operator =(const enumerator & o)17712 enum_type_decl::enumerator::operator=(const enumerator& o)
17713 {
17714 priv_->env_ = o.get_environment();
17715 priv_->name_ = o.get_name();
17716 priv_->value_ = o.get_value();
17717 priv_->enum_type_ = o.get_enum_type();
17718 return *this;
17719 }
17720 /// Equality operator
17721 ///
17722 /// @param other the enumerator to compare to the current
17723 /// instance of enum_type_decl::enumerator.
17724 ///
17725 /// @return true if @p other equals the current instance of
17726 /// enum_type_decl::enumerator.
17727 bool
operator ==(const enumerator & other) const17728 enum_type_decl::enumerator::operator==(const enumerator& other) const
17729 {
17730 bool names_equal = true;
17731 names_equal = (get_name() == other.get_name());
17732 return names_equal && (get_value() == other.get_value());
17733 }
17734
17735 /// Inequality operator.
17736 ///
17737 /// @param other the other instance to compare against.
17738 ///
17739 /// @return true iff @p other is different from the current instance.
17740 bool
operator !=(const enumerator & other) const17741 enum_type_decl::enumerator::operator!=(const enumerator& other) const
17742 {return !operator==(other);}
17743
17744 /// Getter of the environment of this enumerator.
17745 ///
17746 /// @return the environment of this enumerator.
17747 const environment*
get_environment() const17748 enum_type_decl::enumerator::get_environment() const
17749 {return priv_->env_;}
17750
17751 /// Getter for the name of the current instance of
17752 /// enum_type_decl::enumerator.
17753 ///
17754 /// @return a reference to the name of the current instance of
17755 /// enum_type_decl::enumerator.
17756 const interned_string&
get_name() const17757 enum_type_decl::enumerator::get_name() const
17758 {return priv_->name_;}
17759
17760 /// Getter for the qualified name of the current instance of
17761 /// enum_type_decl::enumerator. The first invocation of the method
17762 /// builds the qualified name, caches it and return a reference to the
17763 /// cached qualified name. Subsequent invocations just return the
17764 /// cached value.
17765 ///
17766 /// @param internal set to true if the call is intended for an
17767 /// internal use (for technical use inside the library itself), false
17768 /// otherwise. If you don't know what this is for, then set it to
17769 /// false.
17770 ///
17771 /// @return the qualified name of the current instance of
17772 /// enum_type_decl::enumerator.
17773 const interned_string&
get_qualified_name(bool internal) const17774 enum_type_decl::enumerator::get_qualified_name(bool internal) const
17775 {
17776 if (priv_->qualified_name_.empty())
17777 {
17778 const environment* env = priv_->enum_type_->get_environment();
17779 ABG_ASSERT(env);
17780 priv_->qualified_name_ =
17781 env->intern(get_enum_type()->get_qualified_name(internal)
17782 + "::"
17783 + get_name());
17784 }
17785 return priv_->qualified_name_;
17786 }
17787
17788 /// Setter for the name of @ref enum_type_decl::enumerator.
17789 ///
17790 /// @param n the new name.
17791 void
set_name(const string & n)17792 enum_type_decl::enumerator::set_name(const string& n)
17793 {
17794 const environment* env = get_environment();
17795 ABG_ASSERT(env);
17796 priv_->name_ = env->intern(n);
17797 }
17798
17799 /// Getter for the value of @ref enum_type_decl::enumerator.
17800 ///
17801 /// @return the value of the current instance of
17802 /// enum_type_decl::enumerator.
17803 int64_t
get_value() const17804 enum_type_decl::enumerator::get_value() const
17805 {return priv_->value_;}
17806
17807 /// Setter for the value of @ref enum_type_decl::enumerator.
17808 ///
17809 /// @param v the new value of the enum_type_decl::enumerator.
17810 void
set_value(int64_t v)17811 enum_type_decl::enumerator::set_value(int64_t v)
17812 {priv_->value_= v;}
17813
17814 /// Getter for the enum type that this enumerator is for.
17815 ///
17816 /// @return the enum type that this enumerator is for.
17817 enum_type_decl*
get_enum_type() const17818 enum_type_decl::enumerator::get_enum_type() const
17819 {return priv_->enum_type_;}
17820
17821 /// Setter for the enum type that this enumerator is for.
17822 ///
17823 /// @param e the new enum type.
17824 void
set_enum_type(enum_type_decl * e)17825 enum_type_decl::enumerator::set_enum_type(enum_type_decl* e)
17826 {priv_->enum_type_ = e;}
17827 // </enum_type_decl definitions>
17828
17829 // <typedef_decl definitions>
17830
17831 /// Private data structure of the @ref typedef_decl.
17832 struct typedef_decl::priv
17833 {
17834 type_base_wptr underlying_type_;
17835 string internal_qualified_name_;
17836 string temp_internal_qualified_name_;
17837
privabigail::ir::typedef_decl::priv17838 priv(const type_base_sptr& t)
17839 : underlying_type_(t)
17840 {}
17841 }; // end struct typedef_decl::priv
17842
17843 /// Constructor of the typedef_decl type.
17844 ///
17845 /// @param name the name of the typedef.
17846 ///
17847 /// @param underlying_type the underlying type of the typedef.
17848 ///
17849 /// @param locus the source location of the typedef declaration.
17850 ///
17851 /// @param linkage_name the mangled name of the typedef.
17852 ///
17853 /// @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)17854 typedef_decl::typedef_decl(const string& name,
17855 const type_base_sptr underlying_type,
17856 const location& locus,
17857 const string& linkage_name,
17858 visibility vis)
17859 : type_or_decl_base(underlying_type->get_environment(),
17860 TYPEDEF_TYPE
17861 | ABSTRACT_TYPE_BASE
17862 | ABSTRACT_DECL_BASE),
17863 type_base(underlying_type->get_environment(),
17864 underlying_type->get_size_in_bits(),
17865 underlying_type->get_alignment_in_bits()),
17866 decl_base(underlying_type->get_environment(),
17867 name, locus, linkage_name, vis),
17868 priv_(new priv(underlying_type))
17869 {
17870 runtime_type_instance(this);
17871 }
17872
17873 /// Constructor of the typedef_decl type.
17874 ///
17875 /// @param name the name of the typedef.
17876 ///
17877 /// @param env the environment of the current typedef.
17878 ///
17879 /// @param locus the source location of the typedef declaration.
17880 ///
17881 /// @param mangled_name the mangled name of the typedef.
17882 ///
17883 /// @param vis the visibility of the typedef type.
typedef_decl(const string & name,environment * env,const location & locus,const string & mangled_name,visibility vis)17884 typedef_decl::typedef_decl(const string& name,
17885 environment* env,
17886 const location& locus,
17887 const string& mangled_name,
17888 visibility vis)
17889 : type_or_decl_base(env,
17890 TYPEDEF_TYPE
17891 | ABSTRACT_TYPE_BASE
17892 | ABSTRACT_DECL_BASE),
17893 type_base(env, /*size_in_bits=*/0,
17894 /*alignment_in_bits=*/0),
17895 decl_base(env, name, locus, mangled_name, vis),
17896 priv_(new priv(nullptr))
17897 {
17898 runtime_type_instance(this);
17899 }
17900
17901 /// Return the size of the typedef.
17902 ///
17903 /// This function looks at the size of the underlying type and ensures
17904 /// that it's the same as the size of the typedef.
17905 ///
17906 /// @return the size of the typedef.
17907 size_t
get_size_in_bits() const17908 typedef_decl::get_size_in_bits() const
17909 {
17910 if (!get_underlying_type())
17911 return 0;
17912 size_t s = get_underlying_type()->get_size_in_bits();
17913 if (s != type_base::get_size_in_bits())
17914 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
17915 return type_base::get_size_in_bits();
17916 }
17917
17918 /// Return the alignment of the typedef.
17919 ///
17920 /// This function looks at the alignment of the underlying type and
17921 /// ensures that it's the same as the alignment of the typedef.
17922 ///
17923 /// @return the size of the typedef.
17924 size_t
get_alignment_in_bits() const17925 typedef_decl::get_alignment_in_bits() const
17926 {
17927 if (!get_underlying_type())
17928 return 0;
17929 size_t s = get_underlying_type()->get_alignment_in_bits();
17930 if (s != type_base::get_alignment_in_bits())
17931 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
17932 return type_base::get_alignment_in_bits();
17933 }
17934
17935 /// Compares two instances of @ref typedef_decl.
17936 ///
17937 /// If the two intances are different, set a bitfield to give some
17938 /// insight about the kind of differences there are.
17939 ///
17940 /// @param l the first artifact of the comparison.
17941 ///
17942 /// @param r the second artifact of the comparison.
17943 ///
17944 /// @param k a pointer to a bitfield that gives information about the
17945 /// kind of changes there are between @p l and @p r. This one is set
17946 /// iff @p k is non-null and the function returns false.
17947 ///
17948 /// Please note that setting k to a non-null value does have a
17949 /// negative performance impact because even if @p l and @p r are not
17950 /// equal, the function keeps up the comparison in order to determine
17951 /// the different kinds of ways in which they are different.
17952 ///
17953 /// @return true if @p l equals @p r, false otherwise.
17954 bool
equals(const typedef_decl & l,const typedef_decl & r,change_kind * k)17955 equals(const typedef_decl& l, const typedef_decl& r, change_kind* k)
17956 {
17957 bool result = true;
17958 if (!equals(static_cast<const decl_base&>(l),
17959 static_cast<const decl_base&>(r),
17960 k))
17961 {
17962 result = false;
17963 if (k)
17964 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
17965 else
17966 ABG_RETURN_FALSE;
17967 }
17968
17969 if (*l.get_underlying_type() != *r.get_underlying_type())
17970 {
17971 // Changes to the underlying type of a typedef are considered
17972 // local, a bit like for pointers.
17973 result = false;
17974 if (k)
17975 *k |= LOCAL_TYPE_CHANGE_KIND;
17976 else
17977 ABG_RETURN_FALSE;
17978 }
17979
17980 ABG_RETURN(result);
17981 }
17982
17983 /// Equality operator
17984 ///
17985 /// @param o the other typedef_decl to test against.
17986 bool
operator ==(const decl_base & o) const17987 typedef_decl::operator==(const decl_base& o) const
17988 {
17989 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
17990 if (!other)
17991 return false;
17992 return try_canonical_compare(this, other);
17993 }
17994
17995 /// Equality operator
17996 ///
17997 /// @param o the other typedef_decl to test against.
17998 ///
17999 /// @return true if the current instance of @ref typedef_decl equals
18000 /// @p o.
18001 bool
operator ==(const type_base & o) const18002 typedef_decl::operator==(const type_base& o) const
18003 {
18004 const decl_base* other = dynamic_cast<const decl_base*>(&o);
18005 if (!other)
18006 return false;
18007 return *this == *other;
18008 }
18009
18010 /// Build a pretty representation for a typedef_decl.
18011 ///
18012 /// @param internal set to true if the call is intended to get a
18013 /// representation of the decl (or type) for the purpose of canonical
18014 /// type comparison. This is mainly used in the function
18015 /// type_base::get_canonical_type_for().
18016 ///
18017 /// In other words if the argument for this parameter is true then the
18018 /// call is meant for internal use (for technical use inside the
18019 /// library itself), false otherwise. If you don't know what this is
18020 /// for, then set it to false.
18021
18022 /// @param qualified_name if true, names emitted in the pretty
18023 /// representation are fully qualified.
18024 ///
18025 /// @return a copy of the pretty representation of the current
18026 /// instance of typedef_decl.
18027 string
get_pretty_representation(bool internal,bool qualified_name) const18028 typedef_decl::get_pretty_representation(bool internal,
18029 bool qualified_name) const
18030 {
18031
18032 string result = "typedef ";
18033 if (qualified_name)
18034 result += get_qualified_name(internal);
18035 else
18036 result += get_name();
18037
18038 return result;
18039 }
18040
18041 /// Getter of the underlying type of the typedef.
18042 ///
18043 /// @return the underlying_type.
18044 type_base_sptr
get_underlying_type() const18045 typedef_decl::get_underlying_type() const
18046 {return priv_->underlying_type_.lock();}
18047
18048 /// Setter ofthe underlying type of the typedef.
18049 ///
18050 /// @param t the new underlying type of the typedef.
18051 void
set_underlying_type(const type_base_sptr & t)18052 typedef_decl::set_underlying_type(const type_base_sptr& t)
18053 {
18054 priv_->underlying_type_ = t;
18055 set_size_in_bits(t->get_size_in_bits());
18056 set_alignment_in_bits(t->get_alignment_in_bits());
18057 }
18058
18059 /// This implements the ir_traversable_base::traverse pure virtual
18060 /// function.
18061 ///
18062 /// @param v the visitor used on the current instance.
18063 ///
18064 /// @return true if the entire IR node tree got traversed, false
18065 /// otherwise.
18066 bool
traverse(ir_node_visitor & v)18067 typedef_decl::traverse(ir_node_visitor& v)
18068 {
18069 if (v.type_node_has_been_visited(this))
18070 return true;
18071
18072 if (visiting())
18073 return true;
18074
18075 if (v.visit_begin(this))
18076 {
18077 visiting(true);
18078 if (type_base_sptr t = get_underlying_type())
18079 t->traverse(v);
18080 visiting(false);
18081 }
18082
18083 bool result = v.visit_end(this);
18084 v.mark_type_node_as_visited(this);
18085 return result;
18086 }
18087
~typedef_decl()18088 typedef_decl::~typedef_decl()
18089 {}
18090 // </typedef_decl definitions>
18091
18092 // <var_decl definitions>
18093
18094 struct var_decl::priv
18095 {
18096 type_base_wptr type_;
18097 type_base* naked_type_;
18098 decl_base::binding binding_;
18099 elf_symbol_sptr symbol_;
18100 interned_string id_;
18101
privabigail::ir::var_decl::priv18102 priv()
18103 : naked_type_(),
18104 binding_(decl_base::BINDING_GLOBAL)
18105 {}
18106
privabigail::ir::var_decl::priv18107 priv(type_base_sptr t,
18108 decl_base::binding b)
18109 : type_(t),
18110 naked_type_(t.get()),
18111 binding_(b)
18112 {}
18113 }; // end struct var_decl::priv
18114
18115 /// Constructor of the @ref var_decl type.
18116 ///
18117 /// @param name the name of the variable declaration
18118 ///
18119 /// @param type the type of the variable declaration
18120 ///
18121 /// @param locus the source location where the variable was defined.
18122 ///
18123 /// @param linkage_name the linkage name of the variable.
18124 ///
18125 /// @param vis the visibility of of the variable.
18126 ///
18127 /// @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)18128 var_decl::var_decl(const string& name,
18129 type_base_sptr type,
18130 const location& locus,
18131 const string& linkage_name,
18132 visibility vis,
18133 binding bind)
18134 : type_or_decl_base(type->get_environment(),
18135 VAR_DECL | ABSTRACT_DECL_BASE),
18136 decl_base(type->get_environment(), name, locus, linkage_name, vis),
18137 priv_(new priv(type, bind))
18138 {
18139 runtime_type_instance(this);
18140 }
18141
18142 /// Getter of the type of the variable.
18143 ///
18144 /// @return the type of the variable.
18145 const type_base_sptr
get_type() const18146 var_decl::get_type() const
18147 {return priv_->type_.lock();}
18148
18149 /// Getter of the type of the variable.
18150 ///
18151 /// This getter returns a bare pointer, as opposed to a smart pointer.
18152 /// It's to be used on performance sensitive code paths identified by
18153 /// careful profiling.
18154 ///
18155 /// @return the type of the variable, as a bare pointer.
18156 const type_base*
get_naked_type() const18157 var_decl::get_naked_type() const
18158 {return priv_->naked_type_;}
18159
18160 /// Getter of the binding of the variable.
18161 ///
18162 /// @return the biding of the variable.
18163 decl_base::binding
get_binding() const18164 var_decl::get_binding() const
18165 {return priv_->binding_;}
18166
18167 /// Setter of the binding of the variable.
18168 ///
18169 /// @param b the new binding value.
18170 void
set_binding(decl_base::binding b)18171 var_decl::set_binding(decl_base::binding b)
18172 {priv_->binding_ = b;}
18173
18174 /// Sets the underlying ELF symbol for the current variable.
18175 ///
18176 /// And underlyin$g ELF symbol for the current variable might exist
18177 /// only if the corpus that this variable originates from was
18178 /// constructed from an ELF binary file.
18179 ///
18180 /// Note that comparing two variables that have underlying ELF symbols
18181 /// involves comparing their underlying elf symbols. The decl name
18182 /// for the variable thus becomes irrelevant in the comparison.
18183 ///
18184 /// @param sym the new ELF symbol for this variable decl.
18185 void
set_symbol(const elf_symbol_sptr & sym)18186 var_decl::set_symbol(const elf_symbol_sptr& sym)
18187 {
18188 priv_->symbol_ = sym;
18189 // The variable id cache that depends on the symbol must be
18190 // invalidated because the symbol changed.
18191 priv_->id_ = get_environment()->intern("");
18192 }
18193
18194 /// Gets the the underlying ELF symbol for the current variable,
18195 /// that was set using var_decl::set_symbol(). Please read the
18196 /// documentation for that member function for more information about
18197 /// "underlying ELF symbols".
18198 ///
18199 /// @return sym the underlying ELF symbol for this variable decl, if
18200 /// one exists.
18201 const elf_symbol_sptr&
get_symbol() const18202 var_decl::get_symbol() const
18203 {return priv_->symbol_;}
18204
18205 /// Create a new var_decl that is a clone of the current one.
18206 ///
18207 /// @return the cloned var_decl.
18208 var_decl_sptr
clone() const18209 var_decl::clone() const
18210 {
18211 var_decl_sptr v(new var_decl(get_name(),
18212 get_type(),
18213 get_location(),
18214 get_linkage_name(),
18215 get_visibility(),
18216 get_binding()));
18217
18218 v->set_symbol(get_symbol());
18219
18220 if (is_member_decl(*this))
18221 {
18222 class_decl* scope = dynamic_cast<class_decl*>(get_scope());
18223 scope->add_data_member(v, get_member_access_specifier(*this),
18224 get_data_member_is_laid_out(*this),
18225 get_member_is_static(*this),
18226 get_data_member_offset(*this));
18227 }
18228 else
18229 add_decl_to_scope(v, get_scope());
18230
18231 return v;
18232 }
18233 /// Setter of the scope of the current var_decl.
18234 ///
18235 /// Note that the decl won't hold a reference on the scope. It's
18236 /// rather the scope that holds a reference on its members.
18237 ///
18238 /// @param scope the new scope.
18239 void
set_scope(scope_decl * scope)18240 var_decl::set_scope(scope_decl* scope)
18241 {
18242 if (!get_context_rel())
18243 set_context_rel(new dm_context_rel(scope));
18244 else
18245 get_context_rel()->set_scope(scope);
18246 }
18247
18248 /// Compares two instances of @ref var_decl.
18249 ///
18250 /// If the two intances are different, set a bitfield to give some
18251 /// insight about the kind of differences there are.
18252 ///
18253 /// @param l the first artifact of the comparison.
18254 ///
18255 /// @param r the second artifact of the comparison.
18256 ///
18257 /// @param k a pointer to a bitfield that gives information about the
18258 /// kind of changes there are between @p l and @p r. This one is set
18259 /// iff @p k is non-null and the function returns false.
18260 ///
18261 /// Please note that setting k to a non-null value does have a
18262 /// negative performance impact because even if @p l and @p r are not
18263 /// equal, the function keeps up the comparison in order to determine
18264 /// the different kinds of ways in which they are different.
18265 ///
18266 /// @return true if @p l equals @p r, false otherwise.
18267 bool
equals(const var_decl & l,const var_decl & r,change_kind * k)18268 equals(const var_decl& l, const var_decl& r, change_kind* k)
18269 {
18270 bool result = true;
18271
18272 // First test types of variables. This should be fast because in
18273 // the general case, most types should be canonicalized.
18274 if (*l.get_naked_type() != *r.get_naked_type())
18275 {
18276 result = false;
18277 if (k)
18278 {
18279 if (!types_have_similar_structure(l.get_naked_type(),
18280 r.get_naked_type()))
18281 *k |= (LOCAL_TYPE_CHANGE_KIND);
18282 else
18283 *k |= SUBTYPE_CHANGE_KIND;
18284 }
18285 else
18286 ABG_RETURN_FALSE;
18287 }
18288
18289 // If there are underlying elf symbols for these variables,
18290 // compare them. And then compare the other parts.
18291 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
18292 if (!!s0 != !!s1)
18293 {
18294 result = false;
18295 if (k)
18296 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18297 else
18298 ABG_RETURN_FALSE;
18299 }
18300 else if (s0 && s0 != s1)
18301 {
18302 result = false;
18303 if (k)
18304 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18305 else
18306 ABG_RETURN_FALSE;
18307 }
18308 bool symbols_are_equal = (s0 && s1 && result);
18309
18310 if (symbols_are_equal)
18311 {
18312 // The variables have underlying elf symbols that are equal, so
18313 // now, let's compare the decl_base part of the variables w/o
18314 // considering their decl names.
18315 const environment* env = l.get_environment();
18316 const interned_string n1 = l.get_qualified_name(), n2 = r.get_qualified_name();
18317 const_cast<var_decl&>(l).set_qualified_name(env->intern(""));
18318 const_cast<var_decl&>(r).set_qualified_name(env->intern(""));
18319 bool decl_bases_different = !l.decl_base::operator==(r);
18320 const_cast<var_decl&>(l).set_qualified_name(n1);
18321 const_cast<var_decl&>(r).set_qualified_name(n2);
18322
18323 if (decl_bases_different)
18324 {
18325 result = false;
18326 if (k)
18327 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18328 else
18329 ABG_RETURN_FALSE;
18330 }
18331 }
18332 else
18333 if (!l.decl_base::operator==(r))
18334 {
18335 result = false;
18336 if (k)
18337 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18338 else
18339 ABG_RETURN_FALSE;
18340 }
18341
18342 const dm_context_rel* c0 =
18343 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
18344 const dm_context_rel* c1 =
18345 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
18346 ABG_ASSERT(c0 && c1);
18347
18348 if (*c0 != *c1)
18349 {
18350 result = false;
18351 if (k)
18352 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18353 else
18354 ABG_RETURN_FALSE;
18355 }
18356
18357 ABG_RETURN(result);
18358 }
18359
18360 /// Comparison operator of @ref var_decl.
18361 ///
18362 /// @param o the instance of @ref var_decl to compare against.
18363 ///
18364 /// @return true iff the current instance of @ref var_decl equals @p o.
18365 bool
operator ==(const decl_base & o) const18366 var_decl::operator==(const decl_base& o) const
18367 {
18368 const var_decl* other = dynamic_cast<const var_decl*>(&o);
18369 if (!other)
18370 return false;
18371
18372 return equals(*this, *other, 0);
18373 }
18374
18375 /// Return an ID that tries to uniquely identify the variable inside a
18376 /// program or a library.
18377 ///
18378 /// So if the variable has an underlying elf symbol, the ID is the
18379 /// concatenation of the symbol name and its version. Otherwise, the
18380 /// ID is the linkage name if its non-null. Otherwise, it's the
18381 /// pretty representation of the variable.
18382 ///
18383 /// @return the ID.
18384 interned_string
get_id() const18385 var_decl::get_id() const
18386 {
18387 if (priv_->id_.empty())
18388 {
18389 string repr = get_name();
18390 string sym_str;
18391 if (elf_symbol_sptr s = get_symbol())
18392 sym_str = s->get_id_string();
18393 else if (!get_linkage_name().empty())
18394 sym_str = get_linkage_name();
18395 const environment* env = get_type()->get_environment();
18396 ABG_ASSERT(env);
18397 priv_->id_ = env->intern(repr);
18398 if (!sym_str.empty())
18399 priv_->id_ = env->intern(priv_->id_ + "{" + sym_str + "}");
18400 }
18401 return priv_->id_;
18402 }
18403
18404 /// Return the hash value for the current instance.
18405 ///
18406 /// @return the hash value.
18407 size_t
get_hash() const18408 var_decl::get_hash() const
18409 {
18410 var_decl::hash hash_var;
18411 return hash_var(this);
18412 }
18413
18414 /// Get the qualified name of a given variable or data member.
18415 ///
18416 ///
18417 /// Note that if the current instance of @ref var_decl is an anonymous
18418 /// data member, then the qualified name is actually the flat
18419 /// representation (the definition) of the type of the anonymous data
18420 /// member. We chose the flat representation because otherwise, the
18421 /// name of an *anonymous* data member is empty, by construction, e.g:
18422 ///
18423 /// struct foo {
18424 /// int a;
18425 /// union {
18426 /// char b;
18427 /// char c;
18428 /// }; // <---- this data member is anonymous.
18429 /// int d;
18430 /// }
18431 ///
18432 /// The string returned for the anonymous member here is going to be:
18433 ///
18434 /// "union {char b; char c}"
18435 ///
18436 /// @param internal if true then this is for a purpose to the library,
18437 /// otherwise, it's for being displayed to users.
18438 ///
18439 /// @return the resulting qualified name.
18440 const interned_string&
get_qualified_name(bool internal) const18441 var_decl::get_qualified_name(bool internal) const
18442 {
18443 if (is_anonymous_data_member(this)
18444 && decl_base::get_qualified_name().empty())
18445 {
18446 // Display the anonymous data member in a way that makes sense.
18447 string r = get_pretty_representation(internal);
18448 set_qualified_name(get_environment()->intern(r));
18449 }
18450
18451 return decl_base::get_qualified_name(internal);
18452 }
18453
18454 /// Build and return the pretty representation of this variable.
18455 ///
18456 /// @param internal set to true if the call is intended to get a
18457 /// representation of the decl (or type) for the purpose of canonical
18458 /// type comparison. This is mainly used in the function
18459 /// type_base::get_canonical_type_for().
18460 ///
18461 /// In other words if the argument for this parameter is true then the
18462 /// call is meant for internal use (for technical use inside the
18463 /// library itself), false otherwise. If you don't know what this is
18464 /// for, then set it to false.
18465 ///
18466 /// @param qualified_name if true, names emitted in the pretty
18467 /// representation are fully qualified.
18468 ///
18469 /// @return a copy of the pretty representation of this variable.
18470 string
get_pretty_representation(bool internal,bool qualified_name) const18471 var_decl::get_pretty_representation(bool internal, bool qualified_name) const
18472 {
18473 string result;
18474
18475 if (is_member_decl(this) && get_member_is_static(this))
18476 result = "static ";
18477
18478 // Detect if the current instance of var_decl is a member of
18479 // an anonymous class or union.
18480 bool member_of_anonymous_class = false;
18481 if (class_or_union* scope = is_at_class_scope(this))
18482 if (scope->get_is_anonymous())
18483 member_of_anonymous_class = true;
18484
18485 if (array_type_def_sptr t = is_array_type(get_type()))
18486 {
18487 string name;
18488 if (member_of_anonymous_class || !qualified_name)
18489 name = get_name();
18490 else
18491 name = get_qualified_name(internal);
18492
18493 type_base_sptr et = t->get_element_type();
18494 ABG_ASSERT(et);
18495 decl_base_sptr decl = get_type_declaration(et);
18496 ABG_ASSERT(decl);
18497 result += decl->get_qualified_name(internal)
18498 + " " + name + t->get_subrange_representation();
18499 }
18500 else
18501 {
18502 if (/*The current var_decl is to be used as an anonymous data
18503 member. */
18504 get_name().empty())
18505 {
18506 // Display the anonymous data member in a way that
18507 // makes sense.
18508 result +=
18509 get_class_or_union_flat_representation
18510 (is_class_or_union_type(get_type()),
18511 "", /*one_line=*/true, internal);
18512 }
18513 else if (data_member_has_anonymous_type(this))
18514 {
18515 result += get_class_or_union_flat_representation
18516 (is_class_or_union_type(get_type()),
18517 "", /*one_line=*/true, internal);
18518 result += " ";
18519 if (member_of_anonymous_class || !qualified_name)
18520 // It doesn't make sense to name the member of an
18521 // anonymous class or union like:
18522 // "__anonymous__::data_member_name". So let's just use
18523 // its non-qualified name.
18524 result += get_name();
18525 else
18526 result += get_qualified_name(internal);
18527 }
18528 else
18529 {
18530 result +=
18531 get_type_declaration(get_type())->get_qualified_name(internal)
18532 + " ";
18533
18534 if (member_of_anonymous_class || !qualified_name)
18535 // It doesn't make sense to name the member of an
18536 // anonymous class or union like:
18537 // "__anonymous__::data_member_name". So let's just use
18538 // its non-qualified name.
18539 result += get_name();
18540 else
18541 result += get_qualified_name(internal);
18542 }
18543 }
18544 return result;
18545 }
18546
18547 /// Get a name that is valid even for an anonymous data member.
18548 ///
18549 /// If the current @ref var_decl is an anonymous data member, then
18550 /// return its pretty representation. As of now, that pretty
18551 /// representation is actually its flat representation as returned by
18552 /// get_class_or_union_flat_representation().
18553 ///
18554 /// Otherwise, just return the name of the current @ref var_decl.
18555 ///
18556 /// @param qualified if true, return the qualified name. This doesn't
18557 /// have an effet if the current @ref var_decl represents an anonymous
18558 /// data member.
18559 string
get_anon_dm_reliable_name(bool qualified) const18560 var_decl::get_anon_dm_reliable_name(bool qualified) const
18561 {
18562 string name;
18563 if (is_anonymous_data_member(this))
18564 // This function is used in the comparison engine to determine
18565 // which anonymous data member was deleted. So it's not involved
18566 // in type comparison or canonicalization. We don't want to use
18567 // the 'internal' version of the pretty presentation.
18568 name = get_pretty_representation(/*internal=*/false, qualified);
18569 else
18570 name = get_name();
18571
18572 return name;
18573 }
18574
18575 /// This implements the ir_traversable_base::traverse pure virtual
18576 /// function.
18577 ///
18578 /// @param v the visitor used on the current instance.
18579 ///
18580 /// @return true if the entire IR node tree got traversed, false
18581 /// otherwise.
18582 bool
traverse(ir_node_visitor & v)18583 var_decl::traverse(ir_node_visitor& v)
18584 {
18585 if (visiting())
18586 return true;
18587
18588 if (v.visit_begin(this))
18589 {
18590 visiting(true);
18591 if (type_base_sptr t = get_type())
18592 t->traverse(v);
18593 visiting(false);
18594 }
18595 return v.visit_end(this);
18596 }
18597
~var_decl()18598 var_decl::~var_decl()
18599 {}
18600
18601 // </var_decl definitions>
18602
18603 // <function_type>
18604
18605 /// The type of the private data of the @ref function_type type.
18606 struct function_type::priv
18607 {
18608 parameters parms_;
18609 type_base_wptr return_type_;
18610 interned_string cached_name_;
18611 interned_string internal_cached_name_;
18612 interned_string temp_internal_cached_name_;
18613
privabigail::ir::function_type::priv18614 priv()
18615 {}
18616
privabigail::ir::function_type::priv18617 priv(const parameters& parms,
18618 type_base_sptr return_type)
18619 : parms_(parms),
18620 return_type_(return_type)
18621 {}
18622
privabigail::ir::function_type::priv18623 priv(type_base_sptr return_type)
18624 : return_type_(return_type)
18625 {}
18626
18627 /// Mark a given @ref function_type as being compared.
18628 ///
18629 /// @param type the @ref function_type to mark as being compared.
18630 void
mark_as_being_comparedabigail::ir::function_type::priv18631 mark_as_being_compared(const function_type& type) const
18632 {
18633 const environment* env = type.get_environment();
18634 ABG_ASSERT(env);
18635 env->priv_->fn_types_being_compared_.insert(&type);
18636 }
18637
18638 /// If a given @ref function_type was marked as being compared, this
18639 /// function unmarks it.
18640 ///
18641 /// @param type the @ref function_type to mark as *NOT* being
18642 /// compared.
18643 void
unmark_as_being_comparedabigail::ir::function_type::priv18644 unmark_as_being_compared(const function_type& type) const
18645 {
18646 const environment* env = type.get_environment();
18647 ABG_ASSERT(env);
18648 env->priv_->fn_types_being_compared_.erase(&type);
18649 }
18650
18651 /// Tests if a @ref function_type is currently being compared.
18652 ///
18653 /// @param type the function type to take into account.
18654 ///
18655 /// @return true if @p type is being compared.
18656 bool
comparison_startedabigail::ir::function_type::priv18657 comparison_started(const function_type& type) const
18658 {
18659 const environment* env = type.get_environment();
18660 ABG_ASSERT(env);
18661 return env->priv_->fn_types_being_compared_.count(&type);
18662 }
18663 };// end struc function_type::priv
18664
18665 /// This function is automatically invoked whenever an instance of
18666 /// this type is canonicalized.
18667 ///
18668 /// It's an overload of the virtual type_base::on_canonical_type_set.
18669 ///
18670 /// We put here what is thus meant to be executed only at the point of
18671 /// type canonicalization.
18672 void
on_canonical_type_set()18673 function_type::on_canonical_type_set()
18674 {
18675 priv_->cached_name_.clear();
18676 priv_->internal_cached_name_.clear();
18677 }
18678
18679 /// The most straightforward constructor for the function_type class.
18680 ///
18681 /// @param return_type the return type of the function type.
18682 ///
18683 /// @param parms the list of parameters of the function type.
18684 /// Stricto sensu, we just need a list of types; we are using a list
18685 /// of parameters (where each parameter also carries the name of the
18686 /// parameter and its source location) to try and provide better
18687 /// diagnostics whenever it makes sense. If it appears that this
18688 /// wasts too many resources, we can fall back to taking just a
18689 /// vector of types here.
18690 ///
18691 /// @param size_in_bits the size of this type, in bits.
18692 ///
18693 /// @param alignment_in_bits the alignment of this type, in bits.
18694 ///
18695 /// @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)18696 function_type::function_type(type_base_sptr return_type,
18697 const parameters& parms,
18698 size_t size_in_bits,
18699 size_t alignment_in_bits)
18700 : type_or_decl_base(return_type->get_environment(),
18701 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
18702 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
18703 priv_(new priv(parms, return_type))
18704 {
18705 runtime_type_instance(this);
18706
18707 for (parameters::size_type i = 0, j = 1;
18708 i < priv_->parms_.size();
18709 ++i, ++j)
18710 {
18711 if (i == 0 && priv_->parms_[i]->get_is_artificial())
18712 // If the first parameter is artificial, then it certainly
18713 // means that this is a member function, and the first
18714 // parameter is the implicit this pointer. In that case, set
18715 // the index of that implicit parameter to zero. Otherwise,
18716 // the index of the first parameter starts at one.
18717 j = 0;
18718 priv_->parms_[i]->set_index(j);
18719 }
18720 }
18721
18722 /// A constructor for a function_type that takes no parameters.
18723 ///
18724 /// @param return_type the return type of this function_type.
18725 ///
18726 /// @param size_in_bits the size of this type, in bits.
18727 ///
18728 /// @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)18729 function_type::function_type(type_base_sptr return_type,
18730 size_t size_in_bits, size_t alignment_in_bits)
18731 : type_or_decl_base(return_type->get_environment(),
18732 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
18733 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
18734 priv_(new priv(return_type))
18735 {
18736 runtime_type_instance(this);
18737 }
18738
18739 /// A constructor for a function_type that takes no parameter and
18740 /// that has no return_type yet. These missing parts can (and must)
18741 /// be added later.
18742 ///
18743 /// @param env the environment we are operating from.
18744 ///
18745 /// @param size_in_bits the size of this type, in bits.
18746 ///
18747 /// @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)18748 function_type::function_type(const environment* env,
18749 size_t size_in_bits,
18750 size_t alignment_in_bits)
18751 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
18752 type_base(env, size_in_bits, alignment_in_bits),
18753 priv_(new priv)
18754 {
18755 runtime_type_instance(this);
18756 }
18757
18758 /// Getter for the return type of the current instance of @ref
18759 /// function_type.
18760 ///
18761 /// @return the return type.
18762 type_base_sptr
get_return_type() const18763 function_type::get_return_type() const
18764 {return priv_->return_type_.lock();}
18765
18766 /// Setter of the return type of the current instance of @ref
18767 /// function_type.
18768 ///
18769 /// @param t the new return type to set.
18770 void
set_return_type(type_base_sptr t)18771 function_type::set_return_type(type_base_sptr t)
18772 {priv_->return_type_ = t;}
18773
18774 /// Getter for the set of parameters of the current intance of @ref
18775 /// function_type.
18776 ///
18777 /// @return the parameters of the current instance of @ref
18778 /// function_type.
18779 const function_decl::parameters&
get_parameters() const18780 function_type::get_parameters() const
18781 {return priv_->parms_;}
18782
18783 /// Get the Ith parameter of the vector of parameters of the current
18784 /// instance of @ref function_type.
18785 ///
18786 /// Note that the first parameter is at index 0. That parameter is
18787 /// the first parameter that comes after the possible implicit "this"
18788 /// parameter, when the current instance @ref function_type is for a
18789 /// member function. Otherwise, if the current instance of @ref
18790 /// function_type is for a non-member function, the parameter at index
18791 /// 0 is the first parameter of the function.
18792 ///
18793 ///
18794 /// @param i the index of the parameter to return. If i is greater
18795 /// than the index of the last parameter, then this function returns
18796 /// an empty parameter (smart) pointer.
18797 ///
18798 /// @return the @p i th parameter that is not implicit.
18799 const function_decl::parameter_sptr
get_parm_at_index_from_first_non_implicit_parm(size_t i) const18800 function_type::get_parm_at_index_from_first_non_implicit_parm(size_t i) const
18801 {
18802 parameter_sptr result;
18803 if (dynamic_cast<const method_type*>(this))
18804 {
18805 if (i + 1 < get_parameters().size())
18806 result = get_parameters()[i + 1];
18807 }
18808 else
18809 {
18810 if (i < get_parameters().size())
18811 result = get_parameters()[i];
18812 }
18813 return result;
18814 }
18815
18816 /// Setter for the parameters of the current instance of @ref
18817 /// function_type.
18818 ///
18819 /// @param p the new vector of parameters to set.
18820 void
set_parameters(const parameters & p)18821 function_type::set_parameters(const parameters &p)
18822 {
18823 priv_->parms_ = p;
18824 for (parameters::size_type i = 0, j = 1;
18825 i < priv_->parms_.size();
18826 ++i, ++j)
18827 {
18828 if (i == 0 && priv_->parms_[i]->get_is_artificial())
18829 // If the first parameter is artificial, then it certainly
18830 // means that this is a member function, and the first
18831 // parameter is the implicit this pointer. In that case, set
18832 // the index of that implicit parameter to zero. Otherwise,
18833 // the index of the first parameter starts at one.
18834 j = 0;
18835 priv_->parms_[i]->set_index(j);
18836 }
18837 }
18838
18839 /// Append a new parameter to the vector of parameters of the current
18840 /// instance of @ref function_type.
18841 ///
18842 /// @param parm the parameter to append.
18843 void
append_parameter(parameter_sptr parm)18844 function_type::append_parameter(parameter_sptr parm)
18845 {
18846 parm->set_index(priv_->parms_.size());
18847 priv_->parms_.push_back(parm);
18848 }
18849
18850 /// Test if the current instance of @ref function_type is for a
18851 /// variadic function.
18852 ///
18853 /// A variadic function is a function that takes a variable number of
18854 /// arguments.
18855 ///
18856 /// @return true iff the current instance of @ref function_type is for
18857 /// a variadic function.
18858 bool
is_variadic() const18859 function_type::is_variadic() const
18860 {
18861 return (!priv_->parms_.empty()
18862 && priv_->parms_.back()->get_variadic_marker());
18863 }
18864
18865 /// Compare two function types.
18866 ///
18867 /// In case these function types are actually method types, this
18868 /// function avoids comparing two parameters (of the function types)
18869 /// if the types of the parameters are actually the types of the
18870 /// classes of the method types. This prevents infinite recursion
18871 /// during the comparison of two classes that are structurally
18872 /// identical.
18873 ///
18874 /// This is a subroutine of the equality operator of function_type.
18875 ///
18876 /// @param lhs the first function type to consider
18877 ///
18878 /// @param rhs the second function type to consider
18879 ///
18880 /// @param k a pointer to a bitfield set by the function to give
18881 /// information about the kind of changes carried by @p lhs and @p
18882 /// rhs. It is set iff @p k is non-null and the function returns
18883 /// false.
18884 ///
18885 /// Please note that setting k to a non-null value does have a
18886 /// negative performance impact because even if @p l and @p r are not
18887 /// equal, the function keeps up the comparison in order to determine
18888 /// the different kinds of ways in which they are different.
18889 ///
18890 ///@return true if lhs == rhs, false otherwise.
18891 bool
equals(const function_type & l,const function_type & r,change_kind * k)18892 equals(const function_type& l,
18893 const function_type& r,
18894 change_kind* k)
18895 {
18896 #define RETURN(value) return return_comparison_result(l, r, value)
18897
18898 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
18899 mark_types_as_being_compared(l, r);
18900
18901 bool result = true;
18902
18903 if (!l.type_base::operator==(r))
18904 {
18905 result = false;
18906 if (k)
18907 *k |= LOCAL_TYPE_CHANGE_KIND;
18908 else
18909 RETURN(result);
18910 }
18911
18912 class_or_union* l_class = 0, *r_class = 0;
18913 if (const method_type* m = dynamic_cast<const method_type*>(&l))
18914 l_class = m->get_class_type().get();
18915
18916 if (const method_type* m = dynamic_cast<const method_type*>(&r))
18917 r_class = m->get_class_type().get();
18918
18919 // Compare the names of the class of the method
18920
18921 if (!!l_class != !!r_class)
18922 {
18923 result = false;
18924 if (k)
18925 *k |= LOCAL_TYPE_CHANGE_KIND;
18926 else
18927 RETURN(result);
18928 }
18929 else if (l_class
18930 && (l_class->get_qualified_name()
18931 != r_class->get_qualified_name()))
18932 {
18933 result = false;
18934 if (k)
18935 *k |= LOCAL_TYPE_CHANGE_KIND;
18936 else
18937 RETURN(result);
18938 }
18939
18940 // Then compare the return type; Beware if it's t's a class type
18941 // that is the same as the method class name; we can recurse for
18942 // ever in that case.
18943
18944 decl_base* l_return_type_decl =
18945 get_type_declaration(l.get_return_type()).get();
18946 decl_base* r_return_type_decl =
18947 get_type_declaration(r.get_return_type()).get();
18948 bool compare_result_types = true;
18949 string l_rt_name = l_return_type_decl
18950 ? l_return_type_decl->get_qualified_name()
18951 : string();
18952 string r_rt_name = r_return_type_decl
18953 ? r_return_type_decl->get_qualified_name()
18954 : string();
18955
18956 if ((l_class && (l_class->get_qualified_name() == l_rt_name))
18957 ||
18958 (r_class && (r_class->get_qualified_name() == r_rt_name)))
18959 compare_result_types = false;
18960
18961 if (compare_result_types)
18962 {
18963 if (l.get_return_type() != r.get_return_type())
18964 {
18965 result = false;
18966 if (k)
18967 {
18968 if (!types_have_similar_structure(l.get_return_type(),
18969 r.get_return_type()))
18970 *k |= LOCAL_TYPE_CHANGE_KIND;
18971 else
18972 *k |= SUBTYPE_CHANGE_KIND;
18973 }
18974 else
18975 RETURN(result);
18976 }
18977 }
18978 else
18979 if (l_rt_name != r_rt_name)
18980 {
18981 result = false;
18982 if (k)
18983 *k |= SUBTYPE_CHANGE_KIND;
18984 else
18985 RETURN(result);
18986 }
18987
18988 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
18989 for (i = l.get_first_parm(), j = r.get_first_parm();
18990 i != l.get_parameters().end() && j != r.get_parameters().end();
18991 ++i, ++j)
18992 {
18993 if (**i != **j)
18994 {
18995 result = false;
18996 if (k)
18997 {
18998 if (!types_have_similar_structure((*i)->get_type(),
18999 (*j)->get_type()))
19000 *k |= LOCAL_TYPE_CHANGE_KIND;
19001 else
19002 *k |= SUBTYPE_CHANGE_KIND;
19003 }
19004 else
19005 RETURN(result);
19006 }
19007 }
19008
19009 if ((i != l.get_parameters().end()
19010 || j != r.get_parameters().end()))
19011 {
19012 result = false;
19013 if (k)
19014 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19015 else
19016 RETURN(result);
19017 }
19018
19019 RETURN(result);
19020 #undef RETURN
19021 }
19022
19023 /// Get the first parameter of the function.
19024 ///
19025 /// If the function is a non-static member function, the parameter
19026 /// returned is the first one following the implicit 'this' parameter.
19027 ///
19028 /// @return the first non implicit parameter of the function.
19029 function_type::parameters::const_iterator
get_first_non_implicit_parm() const19030 function_type::get_first_non_implicit_parm() const
19031 {
19032 if (get_parameters().empty())
19033 return get_parameters().end();
19034
19035 bool is_method = dynamic_cast<const method_type*>(this);
19036
19037 parameters::const_iterator i = get_parameters().begin();
19038
19039 if (is_method)
19040 ++i;
19041
19042 return i;
19043 }
19044
19045 /// Get the first parameter of the function.
19046 ///
19047 /// Note that if the function is a non-static member function, the
19048 /// parameter returned is the implicit 'this' parameter.
19049 ///
19050 /// @return the first parameter of the function.
19051 function_type::parameters::const_iterator
get_first_parm() const19052 function_type::get_first_parm() const
19053 {return get_parameters().begin();}
19054
19055 /// Get the name of the current @ref function_type.
19056 ///
19057 /// The name is retrieved from a cache. If the cache is empty, this
19058 /// function computes the name of the type, stores it in the cache and
19059 /// returns it. Subsequent invocation of the function are going to
19060 /// just hit the cache.
19061 ///
19062 /// Note that if the type is *NOT* canonicalized then function type
19063 /// name is never cached.
19064 ///
19065 /// @param internal if true then it means the function type name is
19066 /// going to be used for purposes that are internal to libabigail
19067 /// itself. If you don't know what this is then you probably should
19068 /// set this parameter to 'false'.
19069 ///
19070 /// @return the name of the function type.
19071 const interned_string&
get_cached_name(bool internal) const19072 function_type::get_cached_name(bool internal) const
19073 {
19074 if (internal)
19075 {
19076 if (get_naked_canonical_type())
19077 {
19078 if (priv_->internal_cached_name_.empty())
19079 priv_->internal_cached_name_ =
19080 get_function_type_name(this, /*internal=*/true);
19081 return priv_->internal_cached_name_;
19082 }
19083 else
19084 {
19085 priv_->temp_internal_cached_name_ =
19086 get_function_type_name(this,
19087 /*internal=*/true);
19088 return priv_->temp_internal_cached_name_;
19089 }
19090 }
19091 else
19092 {
19093 if (get_naked_canonical_type())
19094 {
19095 if (priv_->cached_name_.empty())
19096 priv_->cached_name_ =
19097 get_function_type_name(this, /*internal=*/false);
19098 return priv_->cached_name_;
19099 }
19100 else
19101 {
19102 priv_->cached_name_ =
19103 get_function_type_name(this, /*internal=*/false);
19104 return priv_->cached_name_;
19105 }
19106 }
19107 }
19108
19109 /// Equality operator for function_type.
19110 ///
19111 /// @param o the other function_type to compare against.
19112 ///
19113 /// @return true iff the two function_type are equal.
19114 bool
operator ==(const type_base & other) const19115 function_type::operator==(const type_base& other) const
19116 {
19117 const function_type* o = dynamic_cast<const function_type*>(&other);
19118 if (!o)
19119 return false;
19120 return try_canonical_compare(this, o);
19121 }
19122
19123 /// Return a copy of the pretty representation of the current @ref
19124 /// function_type.
19125 ///
19126 /// @param internal set to true if the call is intended to get a
19127 /// representation of the decl (or type) for the purpose of canonical
19128 /// type comparison. This is mainly used in the function
19129 /// type_base::get_canonical_type_for().
19130 ///
19131 /// In other words if the argument for this parameter is true then the
19132 /// call is meant for internal use (for technical use inside the
19133 /// library itself), false otherwise. If you don't know what this is
19134 /// for, then set it to false.
19135 ///
19136 /// @return a copy of the pretty representation of the current @ref
19137 /// function_type.
19138 string
get_pretty_representation(bool internal,bool) const19139 function_type::get_pretty_representation(bool internal,
19140 bool /*qualified_name*/) const
19141 {return ir::get_pretty_representation(this, internal);}
19142
19143 /// Traverses an instance of @ref function_type, visiting all the
19144 /// sub-types and decls that it might contain.
19145 ///
19146 /// @param v the visitor that is used to visit every IR sub-node of
19147 /// the current node.
19148 ///
19149 /// @return true if either
19150 /// - all the children nodes of the current IR node were traversed
19151 /// and the calling code should keep going with the traversing.
19152 /// - or the current IR node is already being traversed.
19153 /// Otherwise, returning false means that the calling code should not
19154 /// keep traversing the tree.
19155 bool
traverse(ir_node_visitor & v)19156 function_type::traverse(ir_node_visitor& v)
19157 {
19158 // TODO: should we allow the walker to avoid visiting function type
19159 // twice? I think that if we do, then ir_node_visitor needs an
19160 // option to specifically disallow this feature for function types.
19161
19162 if (visiting())
19163 return true;
19164
19165 if (v.visit_begin(this))
19166 {
19167 visiting(true);
19168 bool keep_going = true;
19169
19170 if (type_base_sptr t = get_return_type())
19171 {
19172 if (!t->traverse(v))
19173 keep_going = false;
19174 }
19175
19176 if (keep_going)
19177 for (parameters::const_iterator i = get_parameters().begin();
19178 i != get_parameters().end();
19179 ++i)
19180 if (type_base_sptr parm_type = (*i)->get_type())
19181 if (!parm_type->traverse(v))
19182 break;
19183
19184 visiting(false);
19185 }
19186 return v.visit_end(this);
19187 }
19188
~function_type()19189 function_type::~function_type()
19190 {}
19191 // </function_type>
19192
19193 // <method_type>
19194
19195 struct method_type::priv
19196 {
19197 class_or_union_wptr class_type_;
19198 bool is_const;
19199
privabigail::ir::method_type::priv19200 priv()
19201 : is_const()
19202 {}
19203 }; // end struct method_type::priv
19204
19205 /// Constructor for instances of method_type.
19206 ///
19207 /// Instances of method_decl must be of type method_type.
19208 ///
19209 /// @param return_type the type of the return value of the method.
19210 ///
19211 /// @param class_type the base type of the method type. That is, the
19212 /// type of the class the method belongs to.
19213 ///
19214 /// @param p the vector of the parameters of the method.
19215 ///
19216 /// @param is_const whether this method type is for a const method.
19217 /// Note that const-ness is a property of the method *type* and of the
19218 /// relationship between a method *declaration* and its scope.
19219 ///
19220 /// @param size_in_bits the size of an instance of method_type,
19221 /// expressed in bits.
19222 ///
19223 /// @param alignment_in_bits the alignment of an instance of
19224 /// 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)19225 method_type::method_type (type_base_sptr return_type,
19226 class_or_union_sptr class_type,
19227 const std::vector<function_decl::parameter_sptr>& p,
19228 bool is_const,
19229 size_t size_in_bits,
19230 size_t alignment_in_bits)
19231 : type_or_decl_base(class_type->get_environment(),
19232 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
19233 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
19234 function_type(return_type, p, size_in_bits, alignment_in_bits),
19235 priv_(new priv)
19236 {
19237 runtime_type_instance(this);
19238 set_class_type(class_type);
19239 set_is_const(is_const);
19240 }
19241
19242 /// Constructor of instances of method_type.
19243 ///
19244 ///Instances of method_decl must be of type method_type.
19245 ///
19246 /// @param return_type the type of the return value of the method.
19247 ///
19248 /// @param class_type the type of the class the method belongs to.
19249 /// The actual (dynamic) type of class_type must be a pointer
19250 /// class_type. We are setting it to pointer to type_base here to
19251 /// help client code that is compiled without rtti and thus cannot
19252 /// perform dynamic casts.
19253 ///
19254 /// @param p the vector of the parameters of the method type.
19255 ///
19256 /// @param is_const whether this method type is for a const method.
19257 /// Note that const-ness is a property of the method *type* and of the
19258 /// relationship between a method *declaration* and its scope.
19259 ///
19260 /// @param size_in_bits the size of an instance of method_type,
19261 /// expressed in bits.
19262 ///
19263 /// @param alignment_in_bits the alignment of an instance of
19264 /// 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)19265 method_type::method_type(type_base_sptr return_type,
19266 type_base_sptr class_type,
19267 const std::vector<function_decl::parameter_sptr>& p,
19268 bool is_const,
19269 size_t size_in_bits,
19270 size_t alignment_in_bits)
19271 : type_or_decl_base(class_type->get_environment(),
19272 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
19273 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
19274 function_type(return_type, p, size_in_bits, alignment_in_bits),
19275 priv_(new priv)
19276 {
19277 runtime_type_instance(this);
19278 set_class_type(is_class_type(class_type));
19279 set_is_const(is_const);
19280 }
19281
19282 /// Constructor of the qualified_type_def
19283 ///
19284 /// @param env the environment we are operating from.
19285 ///
19286 /// @param size_in_bits the size of the type, expressed in bits.
19287 ///
19288 /// @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)19289 method_type::method_type(const environment* env,
19290 size_t size_in_bits,
19291 size_t alignment_in_bits)
19292 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
19293 type_base(env, size_in_bits, alignment_in_bits),
19294 function_type(env, size_in_bits, alignment_in_bits),
19295 priv_(new priv)
19296 {
19297 runtime_type_instance(this);
19298 }
19299
19300 /// Constructor of instances of method_type.
19301 ///
19302 /// When constructed with this constructor, and instane of method_type
19303 /// must set a return type using method_type::set_return_type
19304 ///
19305 /// @param class_typ the base type of the method type. That is, the
19306 /// type of the class (or union) the method belongs to.
19307 ///
19308 /// @param size_in_bits the size of an instance of method_type,
19309 /// expressed in bits.
19310 ///
19311 /// @param alignment_in_bits the alignment of an instance of
19312 /// 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)19313 method_type::method_type(class_or_union_sptr class_type,
19314 bool is_const,
19315 size_t size_in_bits,
19316 size_t alignment_in_bits)
19317 : type_or_decl_base(class_type->get_environment(),
19318 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
19319 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
19320 function_type(class_type->get_environment(),
19321 size_in_bits,
19322 alignment_in_bits),
19323 priv_(new priv)
19324 {
19325 runtime_type_instance(this);
19326 set_class_type(class_type);
19327 set_is_const(is_const);
19328 }
19329
19330 /// Get the class type this method belongs to.
19331 ///
19332 /// @return the class type.
19333 class_or_union_sptr
get_class_type() const19334 method_type::get_class_type() const
19335 {return class_or_union_sptr(priv_->class_type_);}
19336
19337 /// Sets the class type of the current instance of method_type.
19338 ///
19339 /// The class type is the type of the class the method belongs to.
19340 ///
19341 /// @param t the new class type to set.
19342 void
set_class_type(const class_or_union_sptr & t)19343 method_type::set_class_type(const class_or_union_sptr& t)
19344 {
19345 if (!t)
19346 return;
19347
19348 priv_->class_type_ = t;
19349 }
19350
19351 /// Return a copy of the pretty representation of the current @ref
19352 /// method_type.
19353 ///
19354 /// @param internal set to true if the call is intended to get a
19355 /// representation of the decl (or type) for the purpose of canonical
19356 /// type comparison. This is mainly used in the function
19357 /// type_base::get_canonical_type_for().
19358 ///
19359 /// In other words if the argument for this parameter is true then the
19360 /// call is meant for internal use (for technical use inside the
19361 /// library itself), false otherwise. If you don't know what this is
19362 /// for, then set it to false.
19363 ///
19364 /// @return a copy of the pretty representation of the current @ref
19365 /// method_type.
19366 string
get_pretty_representation(bool internal,bool) const19367 method_type::get_pretty_representation(bool internal,
19368 bool /*qualified_name*/) const
19369 {return ir::get_pretty_representation(*this, internal);}
19370
19371 /// Setter of the "is-const" property of @ref method_type.
19372 ///
19373 /// @param the new value of the "is-const" property.
19374 void
set_is_const(bool f)19375 method_type::set_is_const(bool f)
19376 {priv_->is_const = f;}
19377
19378 /// Getter of the "is-const" property of @ref method_type.
19379 ///
19380 /// @return true iff the "is-const" property was set.
19381 bool
get_is_const() const19382 method_type::get_is_const() const
19383 {return priv_->is_const;}
19384
19385 /// The destructor of method_type
~method_type()19386 method_type::~method_type()
19387 {}
19388
19389 // </method_type>
19390
19391 // <function_decl definitions>
19392
19393 struct function_decl::priv
19394 {
19395 bool declared_inline_;
19396 decl_base::binding binding_;
19397 function_type_wptr type_;
19398 function_type* naked_type_;
19399 elf_symbol_sptr symbol_;
19400 interned_string id_;
19401
privabigail::ir::function_decl::priv19402 priv()
19403 : declared_inline_(false),
19404 binding_(decl_base::BINDING_GLOBAL),
19405 naked_type_()
19406 {}
19407
privabigail::ir::function_decl::priv19408 priv(function_type_sptr t,
19409 bool declared_inline,
19410 decl_base::binding binding)
19411 : declared_inline_(declared_inline),
19412 binding_(binding),
19413 type_(t),
19414 naked_type_(t.get())
19415 {}
19416
privabigail::ir::function_decl::priv19417 priv(function_type_sptr t,
19418 bool declared_inline,
19419 decl_base::binding binding,
19420 elf_symbol_sptr s)
19421 : declared_inline_(declared_inline),
19422 binding_(binding),
19423 type_(t),
19424 naked_type_(t.get()),
19425 symbol_(s)
19426 {}
19427 }; // end sruct function_decl::priv
19428
19429 /// Constructor of the @ref function_decl.
19430 ///
19431 /// @param name the name of the function.
19432 ///
19433 /// @param function_type the type of the function.
19434 ///
19435 /// @param declared_inline wether the function is declared inline.
19436 ///
19437 /// @param locus the source location of the function.
19438 ///
19439 /// @param mangled_name the linkage name of the function.
19440 ///
19441 /// @param vis the visibility of the function.
19442 ///
19443 /// @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)19444 function_decl::function_decl(const string& name,
19445 function_type_sptr function_type,
19446 bool declared_inline,
19447 const location& locus,
19448 const string& mangled_name,
19449 visibility vis,
19450 binding bind)
19451 : type_or_decl_base(function_type->get_environment(),
19452 FUNCTION_DECL | ABSTRACT_DECL_BASE),
19453 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
19454 priv_(new priv(function_type, declared_inline, bind))
19455 {
19456 runtime_type_instance(this);
19457 }
19458
19459 /// Constructor of the function_decl type.
19460 ///
19461 /// This flavour of constructor is for when the pointer to the
19462 /// instance of function_type that the client code has is presented as
19463 /// a pointer to type_base. In that case, this constructor saves the
19464 /// client code from doing a dynamic_cast to get the function_type
19465 /// pointer.
19466 ///
19467 /// @param name the name of the function declaration.
19468 ///
19469 /// @param fn_type the type of the function declaration. The dynamic
19470 /// type of this parameter should be 'pointer to function_type'
19471 ///
19472 /// @param declared_inline whether this function was declared inline
19473 ///
19474 /// @param locus the source location of the function declaration.
19475 ///
19476 /// @param linkage_name the mangled name of the function declaration.
19477 ///
19478 /// @param vis the visibility of the function declaration.
19479 ///
19480 /// @param bind the kind of the binding of the function
19481 /// 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)19482 function_decl::function_decl(const string& name,
19483 type_base_sptr fn_type,
19484 bool declared_inline,
19485 const location& locus,
19486 const string& linkage_name,
19487 visibility vis,
19488 binding bind)
19489 : type_or_decl_base(fn_type->get_environment(),
19490 FUNCTION_DECL | ABSTRACT_DECL_BASE),
19491 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
19492 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
19493 declared_inline,
19494 bind))
19495 {
19496 runtime_type_instance(this);
19497 }
19498
19499 /// Get the pretty representation of the current instance of @ref function_decl.
19500 ///
19501 /// @param internal set to true if the call is intended to get a
19502 /// representation of the decl (or type) for the purpose of canonical
19503 /// type comparison. This is mainly used in the function
19504 /// type_base::get_canonical_type_for().
19505 ///
19506 /// In other words if the argument for this parameter is true then the
19507 /// call is meant for internal use (for technical use inside the
19508 /// library itself), false otherwise. If you don't know what this is
19509 /// for, then set it to false.
19510 ///
19511 /// @return the pretty representation for a function.
19512 string
get_pretty_representation(bool internal,bool) const19513 function_decl::get_pretty_representation(bool internal,
19514 bool /*qualified_name*/) const
19515 {
19516 const method_decl* mem_fn =
19517 dynamic_cast<const method_decl*>(this);
19518
19519 string result = mem_fn ? "method ": "function ";
19520
19521 if (mem_fn
19522 && is_member_function(mem_fn)
19523 && get_member_function_is_virtual(mem_fn))
19524 result += "virtual ";
19525
19526 decl_base_sptr type;
19527 if ((mem_fn
19528 && is_member_function(mem_fn)
19529 && (get_member_function_is_dtor(*mem_fn)
19530 || get_member_function_is_ctor(*mem_fn))))
19531 /*cdtors do not have return types. */;
19532 else
19533 type = mem_fn
19534 ? get_type_declaration(mem_fn->get_type()->get_return_type())
19535 : get_type_declaration(get_type()->get_return_type());
19536
19537 if (type)
19538 result += type->get_qualified_name(internal) + " ";
19539
19540 result += get_pretty_representation_of_declarator(internal);
19541
19542 return result;
19543 }
19544
19545 /// Compute and return the pretty representation for the part of the
19546 /// function declaration that starts at the declarator. That is, the
19547 /// return type and the other specifiers of the beginning of the
19548 /// function's declaration ar omitted.
19549 ///
19550 /// @param internal set to true if the call is intended to get a
19551 /// representation of the decl (or type) for the purpose of canonical
19552 /// type comparison. This is mainly used in the function
19553 /// type_base::get_canonical_type_for().
19554 ///
19555 /// In other words if the argument for this parameter is true then the
19556 /// call is meant for internal use (for technical use inside the
19557 /// library itself), false otherwise. If you don't know what this is
19558 /// for, then set it to false.
19559 ///
19560 /// @return the pretty representation for the part of the function
19561 /// declaration that starts at the declarator.
19562 string
get_pretty_representation_of_declarator(bool internal) const19563 function_decl::get_pretty_representation_of_declarator (bool internal) const
19564 {
19565 const method_decl* mem_fn =
19566 dynamic_cast<const method_decl*>(this);
19567
19568 string result;
19569
19570 if (mem_fn)
19571 {
19572 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
19573 + "::" + mem_fn->get_name();
19574 }
19575 else
19576 result += get_qualified_name();
19577
19578 result += "(";
19579
19580 parameters::const_iterator i = get_parameters().begin(),
19581 end = get_parameters().end();
19582
19583 // Skip the first parameter if this is a method.
19584 if (mem_fn && i != end)
19585 ++i;
19586 parameter_sptr parm;
19587 parameter_sptr first_parm;
19588 if (i != end)
19589 first_parm = *i;
19590 for (; i != end; ++i)
19591 {
19592 parm = *i;
19593 if (parm.get() != first_parm.get())
19594 result += ", ";
19595 if (parm->get_variadic_marker()
19596 || get_environment()->is_variadic_parameter_type(parm->get_type()))
19597 result += "...";
19598 else
19599 {
19600 decl_base_sptr type_decl = get_type_declaration(parm->get_type());
19601 result += type_decl->get_qualified_name(internal);
19602 }
19603 }
19604 result += ")";
19605
19606 if (mem_fn
19607 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
19608 || is_method_type(mem_fn->get_type())->get_is_const()))
19609 result += " const";
19610
19611 return result;
19612 }
19613
19614 /// Getter for the first non-implicit parameter of a function decl.
19615 ///
19616 /// If the function is a non-static member function, the parameter
19617 /// returned is the first one following the implicit 'this' parameter.
19618 ///
19619 /// @return the first non implicit parm.
19620 function_decl::parameters::const_iterator
get_first_non_implicit_parm() const19621 function_decl::get_first_non_implicit_parm() const
19622 {
19623 if (get_parameters().empty())
19624 return get_parameters().end();
19625
19626 bool is_method = dynamic_cast<const method_decl*>(this);
19627
19628 parameters::const_iterator i = get_parameters().begin();
19629 if (is_method)
19630 ++i;
19631
19632 return i;
19633 }
19634
19635 /// Return the type of the current instance of @ref function_decl.
19636 ///
19637 /// It's either a function_type or method_type.
19638 /// @return the type of the current instance of @ref function_decl.
19639 const shared_ptr<function_type>
get_type() const19640 function_decl::get_type() const
19641 {return priv_->type_.lock();}
19642
19643 /// Fast getter of the type of the current instance of @ref function_decl.
19644 ///
19645 /// Note that this function returns the underlying pointer managed by
19646 /// the smart pointer returned by function_decl::get_type(). It's
19647 /// faster than function_decl::get_type(). This getter is to be used
19648 /// in code paths that are proven to be performance hot spots;
19649 /// especially (for instance) when comparing function types. Those
19650 /// are compared extremely frequently when libabigail is used to
19651 /// handle huge binaries with a lot of functions.
19652 ///
19653 /// @return the type of the current instance of @ref function_decl.
19654 const function_type*
get_naked_type() const19655 function_decl::get_naked_type() const
19656 {return priv_->naked_type_;}
19657
19658 void
set_type(const function_type_sptr & fn_type)19659 function_decl::set_type(const function_type_sptr& fn_type)
19660 {
19661 priv_->type_ = fn_type;
19662 priv_->naked_type_ = fn_type.get();
19663 }
19664
19665 /// This sets the underlying ELF symbol for the current function decl.
19666 ///
19667 /// And underlyin$g ELF symbol for the current function decl might
19668 /// exist only if the corpus that this function decl originates from
19669 /// was constructed from an ELF binary file.
19670 ///
19671 /// Note that comparing two function decls that have underlying ELF
19672 /// symbols involves comparing their underlying elf symbols. The decl
19673 /// name for the function thus becomes irrelevant in the comparison.
19674 ///
19675 /// @param sym the new ELF symbol for this function decl.
19676 void
set_symbol(const elf_symbol_sptr & sym)19677 function_decl::set_symbol(const elf_symbol_sptr& sym)
19678 {
19679 priv_->symbol_ = sym;
19680 // The function id cache that depends on the symbol must be
19681 // invalidated because the symbol changed.
19682 priv_->id_ = get_environment()->intern("");
19683 }
19684
19685 /// Gets the the underlying ELF symbol for the current variable,
19686 /// that was set using function_decl::set_symbol(). Please read the
19687 /// documentation for that member function for more information about
19688 /// "underlying ELF symbols".
19689 ///
19690 /// @return sym the underlying ELF symbol for this function decl, if
19691 /// one exists.
19692 const elf_symbol_sptr&
get_symbol() const19693 function_decl::get_symbol() const
19694 {return priv_->symbol_;}
19695
19696 bool
is_declared_inline() const19697 function_decl::is_declared_inline() const
19698 {return priv_->declared_inline_;}
19699
19700 decl_base::binding
get_binding() const19701 function_decl::get_binding() const
19702 {return priv_->binding_;}
19703
19704 /// @return the return type of the current instance of function_decl.
19705 const shared_ptr<type_base>
get_return_type() const19706 function_decl::get_return_type() const
19707 {return get_type()->get_return_type();}
19708
19709 /// @return the parameters of the function.
19710 const std::vector<shared_ptr<function_decl::parameter> >&
get_parameters() const19711 function_decl::get_parameters() const
19712 {return get_type()->get_parameters();}
19713
19714 /// Append a parameter to the type of this function.
19715 ///
19716 /// @param parm the parameter to append.
19717 void
append_parameter(shared_ptr<parameter> parm)19718 function_decl::append_parameter(shared_ptr<parameter> parm)
19719 {get_type()->append_parameter(parm);}
19720
19721 /// Append a vector of parameters to the type of this function.
19722 ///
19723 /// @param parms the vector of parameters to append.
19724 void
append_parameters(std::vector<shared_ptr<parameter>> & parms)19725 function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
19726 {
19727 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
19728 i != parms.end();
19729 ++i)
19730 get_type()->append_parameter(*i);
19731 }
19732
19733 /// Create a new instance of function_decl that is a clone of the
19734 /// current one.
19735 ///
19736 /// @return the new clone.
19737 function_decl_sptr
clone() const19738 function_decl::clone() const
19739 {
19740 function_decl_sptr f;
19741 if (is_member_function(*this))
19742 {
19743 method_decl_sptr
19744 m(new method_decl(get_name(),
19745 get_type(),
19746 is_declared_inline(),
19747 get_location(),
19748 get_linkage_name(),
19749 get_visibility(),
19750 get_binding()));
19751 class_or_union* scope = is_class_or_union_type(get_scope());
19752 ABG_ASSERT(scope);
19753 scope->add_member_function(m, get_member_access_specifier(*this),
19754 get_member_function_is_virtual(*this),
19755 get_member_function_vtable_offset(*this),
19756 get_member_is_static(*this),
19757 get_member_function_is_ctor(*this),
19758 get_member_function_is_dtor(*this),
19759 get_member_function_is_const(*this));
19760 f = m;
19761 }
19762 else
19763 {
19764 f.reset(new function_decl(get_name(),
19765 get_type(),
19766 is_declared_inline(),
19767 get_location(),
19768 get_linkage_name(),
19769 get_visibility(),
19770 get_binding()));
19771 add_decl_to_scope(f, get_scope());
19772 }
19773 f->set_symbol(get_symbol());
19774
19775 return f;
19776 }
19777
19778 /// Compares two instances of @ref function_decl.
19779 ///
19780 /// If the two intances are different, set a bitfield to give some
19781 /// insight about the kind of differences there are.
19782 ///
19783 /// @param l the first artifact of the comparison.
19784 ///
19785 /// @param r the second artifact of the comparison.
19786 ///
19787 /// @param k a pointer to a bitfield that gives information about the
19788 /// kind of changes there are between @p l and @p r. This one is set
19789 /// iff @p k is non-null and the function returns false.
19790 ///
19791 /// Please note that setting k to a non-null value does have a
19792 /// negative performance impact because even if @p l and @p r are not
19793 /// equal, the function keeps up the comparison in order to determine
19794 /// the different kinds of ways in which they are different.
19795 ///
19796 /// @return true if @p l equals @p r, false otherwise.
19797 bool
equals(const function_decl & l,const function_decl & r,change_kind * k)19798 equals(const function_decl& l, const function_decl& r, change_kind* k)
19799 {
19800 bool result = true;
19801
19802 // Compare function types
19803 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
19804 if (t0 == t1 || *t0 == *t1)
19805 ; // the types are equal, let's move on to compare the other
19806 // properties of the functions.
19807 else
19808 {
19809 result = false;
19810 if (k)
19811 {
19812 if (!types_have_similar_structure(t0, t1))
19813 *k |= LOCAL_TYPE_CHANGE_KIND;
19814 else
19815 *k |= SUBTYPE_CHANGE_KIND;
19816 }
19817 else
19818 ABG_RETURN_FALSE;
19819 }
19820
19821 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
19822 if (!!s0 != !!s1)
19823 {
19824 result = false;
19825 if (k)
19826 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19827 else
19828 ABG_RETURN_FALSE;
19829 }
19830 else if (s0 && s0 != s1)
19831 {
19832 if (!elf_symbols_alias(s0, s1))
19833 {
19834 result = false;
19835 if (k)
19836 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19837 else
19838 ABG_RETURN_FALSE;
19839 }
19840 }
19841 bool symbols_are_equal = (s0 && s1 && result);
19842
19843 if (symbols_are_equal)
19844 {
19845 // The functions have underlying elf symbols that are equal,
19846 // so now, let's compare the decl_base part of the functions
19847 // w/o considering their decl names.
19848 interned_string n1 = l.get_name(), n2 = r.get_name();
19849 interned_string ln1 = l.get_linkage_name(), ln2 = r.get_linkage_name();
19850 const_cast<function_decl&>(l).set_name("");
19851 const_cast<function_decl&>(l).set_linkage_name("");
19852 const_cast<function_decl&>(r).set_name("");
19853 const_cast<function_decl&>(r).set_linkage_name("");
19854
19855 bool decl_bases_different = !l.decl_base::operator==(r);
19856
19857 const_cast<function_decl&>(l).set_name(n1);
19858 const_cast<function_decl&>(l).set_linkage_name(ln1);
19859 const_cast<function_decl&>(r).set_name(n2);
19860 const_cast<function_decl&>(r).set_linkage_name(ln2);
19861
19862 if (decl_bases_different)
19863 {
19864 result = false;
19865 if (k)
19866 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19867 else
19868 ABG_RETURN_FALSE;
19869 }
19870 }
19871 else
19872 if (!l.decl_base::operator==(r))
19873 {
19874 result = false;
19875 if (k)
19876 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19877 else
19878 ABG_RETURN_FALSE;
19879 }
19880
19881 // Compare the remaining properties
19882 if (l.is_declared_inline() != r.is_declared_inline()
19883 || l.get_binding() != r.get_binding())
19884 {
19885 result = false;
19886 if (k)
19887 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19888 else
19889 ABG_RETURN_FALSE;
19890 }
19891
19892 if (is_member_function(l) != is_member_function(r))
19893 {
19894 result = false;
19895 if (k)
19896 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19897 else
19898 ABG_RETURN_FALSE;
19899 }
19900
19901 if (is_member_function(l) && is_member_function(r))
19902 {
19903 if (!((get_member_function_is_ctor(l)
19904 == get_member_function_is_ctor(r))
19905 && (get_member_function_is_dtor(l)
19906 == get_member_function_is_dtor(r))
19907 && (get_member_is_static(l)
19908 == get_member_is_static(r))
19909 && (get_member_function_is_const(l)
19910 == get_member_function_is_const(r))
19911 && (get_member_function_is_virtual(l)
19912 == get_member_function_is_virtual(r))
19913 && (get_member_function_vtable_offset(l)
19914 == get_member_function_vtable_offset(r))))
19915 {
19916 result = false;
19917 if (k)
19918 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19919 else
19920 ABG_RETURN_FALSE;
19921 }
19922 }
19923
19924 ABG_RETURN(result);
19925 }
19926
19927 /// Comparison operator for @ref function_decl.
19928 ///
19929 /// @param other the other instance of @ref function_decl to compare
19930 /// against.
19931 ///
19932 /// @return true iff the current instance of @ref function_decl equals
19933 /// @p other.
19934 bool
operator ==(const decl_base & other) const19935 function_decl::operator==(const decl_base& other) const
19936 {
19937 const function_decl* o = dynamic_cast<const function_decl*>(&other);
19938 if (!o)
19939 return false;
19940 return equals(*this, *o, 0);
19941 }
19942
19943 /// Return true iff the function takes a variable number of
19944 /// parameters.
19945 ///
19946 /// @return true if the function taks a variable number
19947 /// of parameters.
19948 bool
is_variadic() const19949 function_decl::is_variadic() const
19950 {
19951 return (!get_parameters().empty()
19952 && get_parameters().back()->get_variadic_marker());
19953 }
19954
19955 /// The virtual implementation of 'get_hash' for a function_decl.
19956 ///
19957 /// This allows decl_base::get_hash to work for function_decls.
19958 ///
19959 /// @return the hash value for function decl.
19960 size_t
get_hash() const19961 function_decl::get_hash() const
19962 {
19963 function_decl::hash hash_fn;
19964 return hash_fn(*this);
19965 }
19966
19967 /// Return an ID that tries to uniquely identify the function inside a
19968 /// program or a library.
19969 ///
19970 /// So if the function has an underlying elf symbol, the ID is the
19971 /// concatenation of the symbol name and its version. Otherwise, the
19972 /// ID is the linkage name if its non-null. Otherwise, it's the
19973 /// pretty representation of the function.
19974 ///
19975 /// @return the ID.
19976 interned_string
get_id() const19977 function_decl::get_id() const
19978 {
19979 if (priv_->id_.empty())
19980 {
19981 const environment* env = get_type()->get_environment();
19982 if (elf_symbol_sptr s = get_symbol())
19983 {
19984 if (s->has_aliases())
19985 // The symbol has several aliases, so let's use a scheme
19986 // that allows all aliased functions to have different
19987 // IDs.
19988 priv_->id_ = env->intern(get_name() + "/" + s->get_id_string());
19989 else
19990 // Let's use the full symbol name with its version as ID.
19991 priv_->id_ = env->intern(s->get_id_string());
19992 }
19993 else if (!get_linkage_name().empty())
19994 priv_->id_= env->intern(get_linkage_name());
19995 else
19996 priv_->id_ = env->intern(get_pretty_representation());
19997 }
19998 return priv_->id_;
19999 }
20000
20001 /// Test if two function declarations are aliases.
20002 ///
20003 /// Two functions declarations are aliases if their symbols are
20004 /// aliases, in the ELF sense.
20005 ///
20006 /// @param f1 the first function to consider.
20007 ///
20008 /// @param f2 the second function to consider.
20009 ///
20010 /// @return true iff @p f1 is an alias of @p f2
20011 bool
function_decls_alias(const function_decl & f1,const function_decl & f2)20012 function_decls_alias(const function_decl& f1, const function_decl& f2)
20013 {
20014 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
20015
20016 if (!s1 || !s2)
20017 return false;
20018
20019 return elf_symbols_alias(s1, s2);
20020 }
20021
20022 /// This implements the ir_traversable_base::traverse pure virtual
20023 /// function.
20024 ///
20025 /// @param v the visitor used on the current instance.
20026 ///
20027 /// @return true if the entire IR node tree got traversed, false
20028 /// otherwise.
20029 bool
traverse(ir_node_visitor & v)20030 function_decl::traverse(ir_node_visitor& v)
20031 {
20032 if (visiting())
20033 return true;
20034
20035 if (v.visit_begin(this))
20036 {
20037 visiting(true);
20038 if (type_base_sptr t = get_type())
20039 t->traverse(v);
20040 visiting(false);
20041 }
20042 return v.visit_end(this);
20043 }
20044
20045 /// Destructor of the @ref function_decl type.
~function_decl()20046 function_decl::~function_decl()
20047 {delete priv_;}
20048
20049 /// A deep comparison operator for a shared pointer to @ref function_decl
20050 ///
20051 /// This function compares to shared pointers to @ref function_decl by
20052 /// looking at the pointed-to instances of @ref function_dec
20053 /// comparing them too. If the two pointed-to objects are equal then
20054 /// this function returns true.
20055 ///
20056 /// @param l the left-hand side argument of the equality operator.
20057 ///
20058 /// @param r the right-hand side argument of the equality operator.
20059 ///
20060 /// @return true iff @p l equals @p r.
20061 bool
operator ==(const function_decl_sptr & l,const function_decl_sptr & r)20062 operator==(const function_decl_sptr& l, const function_decl_sptr& r)
20063 {
20064 if (l.get() == r.get())
20065 return true;
20066 if (!!l != !!r)
20067 return false;
20068
20069 return *l == *r;
20070 }
20071
20072 /// A deep inequality operator for smart pointers to functions.
20073 ///
20074 /// @param l the left-hand side argument of the inequality operator.
20075 ///
20076 /// @pram r the right-hand side argument of the inequality operator.
20077 ///
20078 /// @return true iff @p is not equal to @p r.
20079 bool
operator !=(const function_decl_sptr & l,const function_decl_sptr & r)20080 operator!=(const function_decl_sptr& l, const function_decl_sptr& r)
20081 {return !operator==(l, r);}
20082
20083 // <function_decl definitions>
20084
20085 // <function_decl::parameter definitions>
20086
20087 struct function_decl::parameter::priv
20088 {
20089 type_base_wptr type_;
20090 unsigned index_;
20091 bool variadic_marker_;
20092
privabigail::ir::function_decl::parameter::priv20093 priv()
20094 : index_(),
20095 variadic_marker_()
20096 {}
20097
privabigail::ir::function_decl::parameter::priv20098 priv(type_base_sptr type,
20099 unsigned index,
20100 bool variadic_marker)
20101 : type_(type),
20102 index_(index),
20103 variadic_marker_(variadic_marker)
20104 {}
20105 };// end struct function_decl::parameter::priv
20106
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic)20107 function_decl::parameter::parameter(const type_base_sptr type,
20108 unsigned index,
20109 const string& name,
20110 const location& loc,
20111 bool is_variadic)
20112 : type_or_decl_base(type->get_environment(),
20113 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
20114 decl_base(type->get_environment(), name, loc),
20115 priv_(new priv(type, index, is_variadic))
20116 {
20117 runtime_type_instance(this);
20118 }
20119
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic,bool is_artificial)20120 function_decl::parameter::parameter(const type_base_sptr type,
20121 unsigned index,
20122 const string& name,
20123 const location& loc,
20124 bool is_variadic,
20125 bool is_artificial)
20126 : type_or_decl_base(type->get_environment(),
20127 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
20128 decl_base(type->get_environment(), name, loc),
20129 priv_(new priv(type, index, is_variadic))
20130 {
20131 runtime_type_instance(this);
20132 set_is_artificial(is_artificial);
20133 }
20134
parameter(const type_base_sptr type,const string & name,const location & loc,bool is_variadic,bool is_artificial)20135 function_decl::parameter::parameter(const type_base_sptr type,
20136 const string& name,
20137 const location& loc,
20138 bool is_variadic,
20139 bool is_artificial)
20140 : type_or_decl_base(type->get_environment(),
20141 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
20142 decl_base(type->get_environment(), name, loc),
20143 priv_(new priv(type, 0, is_variadic))
20144 {
20145 runtime_type_instance(this);
20146 set_is_artificial(is_artificial);
20147 }
20148
parameter(const type_base_sptr type,unsigned index,bool variad)20149 function_decl::parameter::parameter(const type_base_sptr type,
20150 unsigned index,
20151 bool variad)
20152 : type_or_decl_base(type->get_environment(),
20153 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
20154 decl_base(type->get_environment(), "", location()),
20155 priv_(new priv(type, index, variad))
20156 {
20157 runtime_type_instance(this);
20158 }
20159
20160 function_decl::parameter::~parameter() = default;
20161
20162 const type_base_sptr
get_type() const20163 function_decl::parameter::get_type()const
20164 {return priv_->type_.lock();}
20165
20166 /// @return a copy of the type name of the parameter.
20167 interned_string
get_type_name() const20168 function_decl::parameter::get_type_name() const
20169 {
20170 const environment* env = get_environment();
20171 ABG_ASSERT(env);
20172
20173 type_base_sptr t = get_type();
20174 string str;
20175 if (get_variadic_marker() || env->is_variadic_parameter_type(t))
20176 str = "...";
20177 else
20178 {
20179 ABG_ASSERT(t);
20180 str = abigail::ir::get_type_name(t);
20181 }
20182 return env->intern(str);
20183 }
20184
20185 /// @return a copy of the pretty representation of the type of the
20186 /// parameter.
20187 const string
get_type_pretty_representation() const20188 function_decl::parameter::get_type_pretty_representation() const
20189 {
20190 type_base_sptr t = get_type();
20191 string str;
20192 if (get_variadic_marker()
20193 || get_environment()->is_variadic_parameter_type(t))
20194 str = "...";
20195 else
20196 {
20197 ABG_ASSERT(t);
20198 str += get_type_declaration(t)->get_pretty_representation();
20199 }
20200 return str;
20201 }
20202
20203 /// Get a name uniquely identifying the parameter in the function.
20204 ///
20205 ///@return the unique parm name id.
20206 interned_string
get_name_id() const20207 function_decl::parameter::get_name_id() const
20208 {
20209 const environment* env = get_environment();
20210 ABG_ASSERT(env);
20211
20212 std::ostringstream o;
20213 o << "parameter-" << get_index();
20214
20215 return env->intern(o.str());
20216 }
20217
20218 unsigned
get_index() const20219 function_decl::parameter::get_index() const
20220 {return priv_->index_;}
20221
20222 void
set_index(unsigned i)20223 function_decl::parameter::set_index(unsigned i)
20224 {priv_->index_ = i;}
20225
20226
20227 bool
get_variadic_marker() const20228 function_decl::parameter::get_variadic_marker() const
20229 {return priv_->variadic_marker_;}
20230
20231 /// Compares two instances of @ref function_decl::parameter.
20232 ///
20233 /// If the two intances are different, set a bitfield to give some
20234 /// insight about the kind of differences there are.
20235 ///
20236 /// @param l the first artifact of the comparison.
20237 ///
20238 /// @param r the second artifact of the comparison.
20239 ///
20240 /// @param k a pointer to a bitfield that gives information about the
20241 /// kind of changes there are between @p l and @p r. This one is set
20242 /// iff @p k is non-null and the function returns false.
20243 ///
20244 /// Please note that setting k to a non-null value does have a
20245 /// negative performance impact because even if @p l and @p r are not
20246 /// equal, the function keeps up the comparison in order to determine
20247 /// the different kinds of ways in which they are different.
20248 ///
20249 /// @return true if @p l equals @p r, false otherwise.
20250 bool
equals(const function_decl::parameter & l,const function_decl::parameter & r,change_kind * k)20251 equals(const function_decl::parameter& l,
20252 const function_decl::parameter& r,
20253 change_kind* k)
20254 {
20255 bool result = true;
20256
20257 if ((l.get_variadic_marker() != r.get_variadic_marker())
20258 || (l.get_index() != r.get_index())
20259 || (!!l.get_type() != !!r.get_type()))
20260 {
20261 result = false;
20262 if (k)
20263 {
20264 if (l.get_index() != r.get_index())
20265 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20266 if (l.get_variadic_marker() != r.get_variadic_marker()
20267 || !!l.get_type() != !!r.get_type())
20268 *k |= LOCAL_TYPE_CHANGE_KIND;
20269 }
20270 else
20271 ABG_RETURN_FALSE;
20272 }
20273
20274 type_base_sptr l_type = l.get_type();
20275 type_base_sptr r_type = r.get_type();
20276 if (l_type != r_type)
20277 {
20278 result = false;
20279 if (k)
20280 {
20281 if (!types_have_similar_structure(l_type, r_type))
20282 *k |= LOCAL_TYPE_CHANGE_KIND;
20283 else
20284 *k |= SUBTYPE_CHANGE_KIND;
20285 }
20286 else
20287 ABG_RETURN_FALSE;
20288 }
20289
20290 ABG_RETURN(result);
20291 }
20292
20293 bool
operator ==(const parameter & o) const20294 function_decl::parameter::operator==(const parameter& o) const
20295 {return equals(*this, o, 0);}
20296
20297 bool
operator ==(const decl_base & o) const20298 function_decl::parameter::operator==(const decl_base& o) const
20299 {
20300 const function_decl::parameter* p =
20301 dynamic_cast<const function_decl::parameter*>(&o);
20302 if (!p)
20303 return false;
20304 return function_decl::parameter::operator==(*p);
20305 }
20306
20307 /// Non-member equality operator for @ref function_decl::parameter.
20308 ///
20309 /// @param l the left-hand side of the equality operator
20310 ///
20311 /// @param r the right-hand side of the equality operator
20312 ///
20313 /// @return true iff @p l and @p r equals.
20314 bool
operator ==(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)20315 operator==(const function_decl::parameter_sptr& l,
20316 const function_decl::parameter_sptr& r)
20317 {
20318 if (!!l != !!r)
20319 return false;
20320 if (!l)
20321 return true;
20322 return *l == *r;
20323 }
20324
20325 /// Non-member inequality operator for @ref function_decl::parameter.
20326 ///
20327 /// @param l the left-hand side of the equality operator
20328 ///
20329 /// @param r the right-hand side of the equality operator
20330 ///
20331 /// @return true iff @p l and @p r different.
20332 bool
operator !=(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)20333 operator!=(const function_decl::parameter_sptr& l,
20334 const function_decl::parameter_sptr& r)
20335 {return !operator==(l, r);}
20336
20337 /// Traverse the diff sub-tree under the current instance
20338 /// function_decl.
20339 ///
20340 /// @param v the visitor to invoke on each diff node of the sub-tree.
20341 ///
20342 /// @return true if the traversing has to keep going on, false
20343 /// otherwise.
20344 bool
traverse(ir_node_visitor & v)20345 function_decl::parameter::traverse(ir_node_visitor& v)
20346 {
20347 if (visiting())
20348 return true;
20349
20350 if (v.visit_begin(this))
20351 {
20352 visiting(true);
20353 if (type_base_sptr t = get_type())
20354 t->traverse(v);
20355 visiting(false);
20356 }
20357 return v.visit_end(this);
20358 }
20359
20360 /// Get the hash of a decl. If the hash hasn't been computed yet,
20361 /// compute it ans store its value; otherwise, just return the hash.
20362 ///
20363 /// @return the hash of the decl.
20364 size_t
get_hash() const20365 function_decl::parameter::get_hash() const
20366 {
20367 function_decl::parameter::hash hash_fn_parm;
20368 return hash_fn_parm(this);
20369 }
20370
20371 /// Compute the qualified name of the parameter.
20372 ///
20373 /// @param internal set to true if the call is intended for an
20374 /// internal use (for technical use inside the library itself), false
20375 /// otherwise. If you don't know what this is for, then set it to
20376 /// false.
20377 ///
20378 /// @param qn the resulting qualified name.
20379 void
get_qualified_name(interned_string & qualified_name,bool) const20380 function_decl::parameter::get_qualified_name(interned_string& qualified_name,
20381 bool /*internal*/) const
20382 {qualified_name = get_name();}
20383
20384 /// Compute and return a copy of the pretty representation of the
20385 /// current function parameter.
20386 ///
20387 /// @param internal set to true if the call is intended to get a
20388 /// representation of the decl (or type) for the purpose of canonical
20389 /// type comparison. This is mainly used in the function
20390 /// type_base::get_canonical_type_for().
20391 ///
20392 /// In other words if the argument for this parameter is true then the
20393 /// call is meant for internal use (for technical use inside the
20394 /// library itself), false otherwise. If you don't know what this is
20395 /// for, then set it to false.
20396 ///
20397 /// @return a copy of the textual representation of the current
20398 /// function parameter.
20399 string
get_pretty_representation(bool internal,bool) const20400 function_decl::parameter::get_pretty_representation(bool internal,
20401 bool /*qualified_name*/) const
20402 {
20403 const environment* env = get_environment();
20404 ABG_ASSERT(env);
20405
20406 string type_repr;
20407 type_base_sptr t = get_type();
20408 if (!t)
20409 type_repr = "void";
20410 else if (env->is_variadic_parameter_type(t))
20411 type_repr = "...";
20412 else
20413 type_repr = ir::get_pretty_representation(t, internal);
20414
20415 string result = type_repr;
20416 string parm_name = get_name_id();
20417
20418 if (!parm_name.empty())
20419 result += " " + parm_name;
20420
20421 return result;
20422 }
20423
20424 // </function_decl::parameter definitions>
20425
20426 // <class_or_union definitions>
20427
20428 /// A Constructor for instances of @ref class_or_union
20429 ///
20430 /// @param env the environment we are operating from.
20431 ///
20432 /// @param name the identifier of the class.
20433 ///
20434 /// @param size_in_bits the size of an instance of @ref
20435 /// class_or_union, expressed in bits
20436 ///
20437 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
20438 /// expressed in bits.
20439 ///
20440 /// @param locus the source location of declaration point this class.
20441 ///
20442 /// @param vis the visibility of instances of @ref class_or_union.
20443 ///
20444 /// @param mem_types the vector of member types of this instance of
20445 /// @ref class_or_union.
20446 ///
20447 /// @param data_members the vector of data members of this instance of
20448 /// @ref class_or_union.
20449 ///
20450 /// @param member_fns the vector of member functions of this instance
20451 /// 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)20452 class_or_union::class_or_union(const environment* env, const string& name,
20453 size_t size_in_bits, size_t align_in_bits,
20454 const location& locus, visibility vis,
20455 member_types& mem_types,
20456 data_members& data_members,
20457 member_functions& member_fns)
20458 : type_or_decl_base(env,
20459 ABSTRACT_TYPE_BASE
20460 | ABSTRACT_DECL_BASE
20461 | ABSTRACT_SCOPE_TYPE_DECL
20462 | ABSTRACT_SCOPE_DECL),
20463 decl_base(env, name, locus, name, vis),
20464 type_base(env, size_in_bits, align_in_bits),
20465 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
20466 priv_(new priv(mem_types, data_members, member_fns))
20467 {
20468 for (member_types::iterator i = mem_types.begin();
20469 i != mem_types.end();
20470 ++i)
20471 if (!has_scope(get_type_declaration(*i)))
20472 add_decl_to_scope(get_type_declaration(*i), this);
20473
20474 for (data_members::iterator i = data_members.begin();
20475 i != data_members.end();
20476 ++i)
20477 if (!has_scope(*i))
20478 add_decl_to_scope(*i, this);
20479
20480 for (member_functions::iterator i = member_fns.begin();
20481 i != member_fns.end();
20482 ++i)
20483 if (!has_scope(static_pointer_cast<decl_base>(*i)))
20484 add_decl_to_scope(*i, this);
20485 }
20486
20487 /// A constructor for instances of @ref class_or_union.
20488 ///
20489 /// @param env the environment we are operating from.
20490 ///
20491 /// @param name the name of the class.
20492 ///
20493 /// @param size_in_bits the size of an instance of @ref
20494 /// class_or_union, expressed in bits
20495 ///
20496 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
20497 /// expressed in bits.
20498 ///
20499 /// @param locus the source location of declaration point this class.
20500 ///
20501 /// @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)20502 class_or_union::class_or_union(const environment* env, const string& name,
20503 size_t size_in_bits, size_t align_in_bits,
20504 const location& locus, visibility vis)
20505 : type_or_decl_base(env,
20506 ABSTRACT_TYPE_BASE
20507 | ABSTRACT_DECL_BASE
20508 | ABSTRACT_SCOPE_TYPE_DECL
20509 | ABSTRACT_SCOPE_DECL),
20510 decl_base(env, name, locus, name, vis),
20511 type_base(env, size_in_bits, align_in_bits),
20512 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
20513 priv_(new priv)
20514 {}
20515
20516 /// Constructor of the @ref class_or_union type.
20517 ///
20518 /// @param env the @ref environment we are operating from.
20519 ///
20520 /// @param name the name of the @ref class_or_union.
20521 ///
20522 /// @param is_declaration_only a boolean saying whether the instance
20523 /// represents a declaration only, or not.
class_or_union(const environment * env,const string & name,bool is_declaration_only)20524 class_or_union::class_or_union(const environment* env, const string& name,
20525 bool is_declaration_only)
20526 : type_or_decl_base(env,
20527 ABSTRACT_TYPE_BASE
20528 | ABSTRACT_DECL_BASE
20529 | ABSTRACT_SCOPE_TYPE_DECL
20530 | ABSTRACT_SCOPE_DECL),
20531 decl_base(env, name, location(), name),
20532 type_base(env, 0, 0),
20533 scope_type_decl(env, name, 0, 0, location()),
20534 priv_(new priv)
20535 {
20536 set_is_declaration_only(is_declaration_only);
20537 }
20538
20539 /// This implements the ir_traversable_base::traverse pure virtual
20540 /// function.
20541 ///
20542 /// @param v the visitor used on the member nodes of the translation
20543 /// unit during the traversal.
20544 ///
20545 /// @return true if the entire IR node tree got traversed, false
20546 /// otherwise.
20547 bool
traverse(ir_node_visitor & v)20548 class_or_union::traverse(ir_node_visitor& v)
20549 {
20550 if (v.type_node_has_been_visited(this))
20551 return true;
20552
20553 if (visiting())
20554 return true;
20555
20556 if (v.visit_begin(this))
20557 {
20558 visiting(true);
20559 bool stop = false;
20560
20561 if (!stop)
20562 for (data_members::const_iterator i = get_data_members().begin();
20563 i != get_data_members().end();
20564 ++i)
20565 if (!(*i)->traverse(v))
20566 {
20567 stop = true;
20568 break;
20569 }
20570
20571 if (!stop)
20572 for (member_functions::const_iterator i= get_member_functions().begin();
20573 i != get_member_functions().end();
20574 ++i)
20575 if (!(*i)->traverse(v))
20576 {
20577 stop = true;
20578 break;
20579 }
20580
20581 if (!stop)
20582 for (member_types::const_iterator i = get_member_types().begin();
20583 i != get_member_types().end();
20584 ++i)
20585 if (!(*i)->traverse(v))
20586 {
20587 stop = true;
20588 break;
20589 }
20590
20591 if (!stop)
20592 for (member_function_templates::const_iterator i =
20593 get_member_function_templates().begin();
20594 i != get_member_function_templates().end();
20595 ++i)
20596 if (!(*i)->traverse(v))
20597 {
20598 stop = true;
20599 break;
20600 }
20601
20602 if (!stop)
20603 for (member_class_templates::const_iterator i =
20604 get_member_class_templates().begin();
20605 i != get_member_class_templates().end();
20606 ++i)
20607 if (!(*i)->traverse(v))
20608 {
20609 stop = true;
20610 break;
20611 }
20612 visiting(false);
20613 }
20614
20615 bool result = v.visit_end(this);
20616 v.mark_type_node_as_visited(this);
20617 return result;
20618 }
20619
20620 /// Destrcutor of the @ref class_or_union type.
~class_or_union()20621 class_or_union::~class_or_union()
20622 {delete priv_;}
20623
20624 /// Add a member declaration to the current instance of class_or_union.
20625 /// The member declaration can be either a member type, data member,
20626 /// member function, or member template.
20627 ///
20628 /// @param d the member declaration to add.
20629 decl_base_sptr
add_member_decl(const decl_base_sptr & d)20630 class_or_union::add_member_decl(const decl_base_sptr& d)
20631 {return insert_member_decl(d, get_member_decls().end());}
20632
20633 /// Remove a given decl from the current @ref class_or_union scope.
20634 ///
20635 /// Note that only type declarations are supported by this method for
20636 /// now. Support for the other kinds of declaration is left as an
20637 /// exercise for the interested reader of the code.
20638 ///
20639 /// @param decl the declaration to remove from this @ref
20640 /// class_or_union scope.
20641 void
remove_member_decl(decl_base_sptr decl)20642 class_or_union::remove_member_decl(decl_base_sptr decl)
20643 {
20644 type_base_sptr t = is_type(decl);
20645
20646 // For now we want to support just removing types from classes. For
20647 // other kinds of IR node, we need more work.
20648 ABG_ASSERT(t);
20649
20650 remove_member_type(t);
20651 }
20652
20653 /// Fixup the members of the type of an anonymous data member.
20654 ///
20655 /// Walk all data members of (the type of) a given anonymous data
20656 /// member and set a particular property of the relationship between
20657 /// each data member and its containing type.
20658 ///
20659 /// That property records the fact that the data member belongs to the
20660 /// anonymous data member we consider.
20661 ///
20662 /// In the future, if there are other properties of this relationship
20663 /// to set in this manner, they ought to be added here.
20664 ///
20665 /// @param anon_dm the anonymous data member to consider.
20666 void
maybe_fixup_members_of_anon_data_member(var_decl_sptr & anon_dm)20667 class_or_union::maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm)
20668 {
20669 class_or_union * anon_dm_type =
20670 anonymous_data_member_to_class_or_union(anon_dm.get());
20671 if (!anon_dm_type)
20672 return;
20673
20674 for (class_or_union::data_members::const_iterator it =
20675 anon_dm_type->get_non_static_data_members().begin();
20676 it != anon_dm_type->get_non_static_data_members().end();
20677 ++it)
20678 {
20679 dm_context_rel *rel =
20680 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
20681 ABG_ASSERT(rel);
20682 rel->set_anonymous_data_member(anon_dm.get());
20683 }
20684 }
20685
20686 /// Insert a member type.
20687 ///
20688 /// @param t the type to insert in the @ref class_or_union type.
20689 ///
20690 /// @param an iterator right before which @p t has to be inserted.
20691 void
insert_member_type(type_base_sptr t,declarations::iterator before)20692 class_or_union::insert_member_type(type_base_sptr t,
20693 declarations::iterator before)
20694 {
20695 decl_base_sptr d = get_type_declaration(t);
20696 ABG_ASSERT(d);
20697 ABG_ASSERT(!has_scope(d));
20698
20699 priv_->member_types_.push_back(t);
20700 scope_decl::insert_member_decl(d, before);
20701 }
20702
20703 /// Add a member type to the current instance of class_or_union.
20704 ///
20705 /// @param t the member type to add. It must not have been added to a
20706 /// scope, otherwise this will violate an ABG_ASSERTion.
20707 void
add_member_type(type_base_sptr t)20708 class_or_union::add_member_type(type_base_sptr t)
20709 {insert_member_type(t, get_member_decls().end());}
20710
20711 /// Add a member type to the current instance of class_or_union.
20712 ///
20713 /// @param t the type to be added as a member type to the current
20714 /// instance of class_or_union. An instance of class_or_union::member_type
20715 /// will be created out of @p t and and added to the the class.
20716 ///
20717 /// @param a the access specifier for the member type to be created.
20718 type_base_sptr
add_member_type(type_base_sptr t,access_specifier a)20719 class_or_union::add_member_type(type_base_sptr t, access_specifier a)
20720 {
20721 decl_base_sptr d = get_type_declaration(t);
20722 ABG_ASSERT(d);
20723 ABG_ASSERT(!is_member_decl(d));
20724 add_member_type(t);
20725 set_member_access_specifier(d, a);
20726 return t;
20727 }
20728
20729 /// Remove a member type from the current @ref class_or_union scope.
20730 ///
20731 /// @param t the type to remove.
20732 void
remove_member_type(type_base_sptr t)20733 class_or_union::remove_member_type(type_base_sptr t)
20734 {
20735 for (member_types::iterator i = priv_->member_types_.begin();
20736 i != priv_->member_types_.end();
20737 ++i)
20738 {
20739 if (*((*i)) == *t)
20740 {
20741 priv_->member_types_.erase(i);
20742 return;
20743 }
20744 }
20745 }
20746
20747 /// Getter of the alignment of the @ref class_or_union type.
20748 ///
20749 /// If this @ref class_or_union is a declaration of a definition that
20750 /// is elsewhere, then the size of the definition is returned.
20751 ///
20752 /// @return the alignment of the @ref class_or_union type.
20753 size_t
get_alignment_in_bits() const20754 class_or_union::get_alignment_in_bits() const
20755 {
20756 if (get_is_declaration_only() && get_definition_of_declaration())
20757 return is_class_or_union_type
20758 (get_definition_of_declaration())->get_alignment_in_bits();
20759
20760 return type_base::get_alignment_in_bits();
20761 }
20762
20763 /// Setter of the alignment of the class type.
20764 ///
20765 /// If this class is a declaration of a definition that is elsewhere,
20766 /// then the new alignment is set to the definition.
20767 ///
20768 /// @param s the new alignment.
20769 void
set_alignment_in_bits(size_t a)20770 class_or_union::set_alignment_in_bits(size_t a)
20771 {
20772 if (get_is_declaration_only() && get_definition_of_declaration())
20773 is_class_or_union_type
20774 (get_definition_of_declaration()) ->set_alignment_in_bits(a);
20775 else
20776 type_base::set_alignment_in_bits(a);
20777 }
20778
20779 /// Setter of the size of the @ref class_or_union type.
20780 ///
20781 /// If this @ref class_or_union is a declaration of a definition that
20782 /// is elsewhere, then the new size is set to the definition.
20783 ///
20784 /// @param s the new size.
20785 void
set_size_in_bits(size_t s)20786 class_or_union::set_size_in_bits(size_t s)
20787 {
20788 if (get_is_declaration_only() && get_definition_of_declaration())
20789 is_class_or_union_type
20790 (get_definition_of_declaration())->set_size_in_bits(s);
20791 else
20792 type_base::set_size_in_bits(s);
20793 }
20794
20795 /// Getter of the size of the @ref class_or_union type.
20796 ///
20797 /// If this @ref class_or_union is a declaration of a definition that
20798 /// is elsewhere, then the size of the definition is returned.
20799 ///
20800 /// @return the size of the @ref class_or_union type.
20801 size_t
get_size_in_bits() const20802 class_or_union::get_size_in_bits() const
20803 {
20804 if (get_is_declaration_only() && get_definition_of_declaration())
20805 return is_class_or_union_type
20806 (get_definition_of_declaration())->get_size_in_bits();
20807
20808 return type_base::get_size_in_bits();
20809 }
20810
20811 /// Get the member types of this @ref class_or_union.
20812 ///
20813 /// @return a vector of the member types of this ref class_or_union.
20814 const class_or_union::member_types&
get_member_types() const20815 class_or_union::get_member_types() const
20816 {return priv_->member_types_;}
20817
20818 /// Get the number of anonymous member classes contained in this
20819 /// class.
20820 ///
20821 /// @return the number of anonymous member classes contained in this
20822 /// class.
20823 size_t
get_num_anonymous_member_classes() const20824 class_or_union::get_num_anonymous_member_classes() const
20825 {
20826 int result = 0;
20827 for (member_types::const_iterator it = get_member_types().begin();
20828 it != get_member_types().end();
20829 ++it)
20830 if (class_decl_sptr t = is_class_type(*it))
20831 if (t->get_is_anonymous())
20832 ++result;
20833
20834 return result;
20835 }
20836
20837 /// Get the number of anonymous member unions contained in this class.
20838 ///
20839 /// @return the number of anonymous member unions contained in this
20840 /// class.
20841 size_t
get_num_anonymous_member_unions() const20842 class_or_union::get_num_anonymous_member_unions() const
20843 {
20844 int result = 0;
20845 for (member_types::const_iterator it = get_member_types().begin();
20846 it != get_member_types().end();
20847 ++it)
20848 if (union_decl_sptr t = is_union_type(*it))
20849 if (t->get_is_anonymous())
20850 ++result;
20851
20852 return result;
20853 }
20854
20855 /// Get the number of anonymous member enums contained in this class.
20856 ///
20857 /// @return the number of anonymous member enums contained in this
20858 /// class.
20859 size_t
get_num_anonymous_member_enums() const20860 class_or_union::get_num_anonymous_member_enums() const
20861 {
20862 int result = 0;
20863 for (member_types::const_iterator it = get_member_types().begin();
20864 it != get_member_types().end();
20865 ++it)
20866 if (enum_type_decl_sptr t = is_enum_type(*it))
20867 if (t->get_is_anonymous())
20868 ++result;
20869
20870 return result;
20871 }
20872
20873 /// Find a member type of a given name, inside the current @ref
20874 /// class_or_union.
20875 ///
20876 /// @param name the name of the member type to look for.
20877 ///
20878 /// @return a pointer to the @ref type_base that represents the member
20879 /// type of name @p name, for the current class.
20880 type_base_sptr
find_member_type(const string & name) const20881 class_or_union::find_member_type(const string& name) const
20882 {
20883 for (member_types::const_iterator i = get_member_types().begin();
20884 i != get_member_types().end();
20885 ++i)
20886 if (get_type_name(*i, /*qualified*/false) == name)
20887 return *i;
20888 return type_base_sptr();
20889 }
20890
20891 /// Add a data member to the current instance of class_or_union.
20892 ///
20893 /// @param v a var_decl to add as a data member. A proper
20894 /// class_or_union::data_member is created from @p v and added to the
20895 /// class_or_union. This var_decl should not have been already added
20896 /// to a scope.
20897 ///
20898 /// @param access the access specifier for the data member.
20899 ///
20900 /// @param is_laid_out whether the data member was laid out. That is,
20901 /// if its offset has been computed. In the pattern of a class
20902 /// template for instance, this would be set to false.
20903 ///
20904 /// @param is_static whether the data memer is static.
20905 ///
20906 /// @param offset_in_bits if @p is_laid_out is true, this is the
20907 /// offset of the data member, expressed (oh, surprise) in bits.
20908 void
add_data_member(var_decl_sptr v,access_specifier access,bool is_laid_out,bool is_static,size_t offset_in_bits)20909 class_or_union::add_data_member(var_decl_sptr v, access_specifier access,
20910 bool is_laid_out, bool is_static,
20911 size_t offset_in_bits)
20912 {
20913 ABG_ASSERT(!has_scope(v));
20914
20915 priv_->data_members_.push_back(v);
20916 scope_decl::add_member_decl(v);
20917 set_data_member_is_laid_out(v, is_laid_out);
20918 set_data_member_offset(v, offset_in_bits);
20919 set_member_access_specifier(v, access);
20920 set_member_is_static(v, is_static);
20921
20922 if (!is_static)
20923 {
20924 // If this is a non-static variable, add it to the set of
20925 // non-static variables, if it's not only in there.
20926 bool is_already_in = false;
20927 for (data_members::const_iterator i =
20928 priv_->non_static_data_members_.begin();
20929 i != priv_->non_static_data_members_.end();
20930 ++i)
20931 if (*i == v)
20932 {
20933 is_already_in = true;
20934 break;
20935 }
20936 if (!is_already_in)
20937 priv_->non_static_data_members_.push_back(v);
20938 }
20939
20940 // If v is an anonymous data member, then fixup its data members.
20941 // For now, the only thing the fixup does is to make the data
20942 // members of the anonymous data member be aware of their containing
20943 // anonymous data member. That is helpful to compute the absolute
20944 // bit offset of each of the members of the anonymous data member.
20945 maybe_fixup_members_of_anon_data_member(v);
20946 }
20947
20948 /// Get the data members of this @ref class_or_union.
20949 ///
20950 /// @return a vector of the data members of this @ref class_or_union.
20951 const class_or_union::data_members&
get_data_members() const20952 class_or_union::get_data_members() const
20953 {return priv_->data_members_;}
20954
20955 /// Find a data member of a given name in the current @ref class_or_union.
20956 ///
20957 /// @param name the name of the data member to find in the current
20958 /// @ref class_or_union.
20959 ///
20960 /// @return a pointer to the @ref var_decl that represents the data
20961 /// member to find inside the current @ref class_or_union.
20962 const var_decl_sptr
find_data_member(const string & name) const20963 class_or_union::find_data_member(const string& name) const
20964 {
20965 for (data_members::const_iterator i = get_data_members().begin();
20966 i != get_data_members().end();
20967 ++i)
20968 if ((*i)->get_name() == name)
20969 return *i;
20970
20971 // We haven't found a data member with the name 'name'. Let's look
20972 // closer again, this time in our anonymous data members.
20973 for (data_members::const_iterator i = get_data_members().begin();
20974 i != get_data_members().end();
20975 ++i)
20976 if (is_anonymous_data_member(*i))
20977 {
20978 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
20979 ABG_ASSERT(type);
20980 if (var_decl_sptr data_member = type->find_data_member(name))
20981 return data_member;
20982 }
20983
20984 return var_decl_sptr();
20985 }
20986
20987 /// Find an anonymous data member in the class.
20988 ///
20989 /// @param v the anonymous data member to find.
20990 ///
20991 /// @return the anonymous data member found, or nil if none was found.
20992 const var_decl_sptr
find_anonymous_data_member(const var_decl_sptr & v) const20993 class_or_union::find_anonymous_data_member(const var_decl_sptr& v) const
20994 {
20995 if (!v->get_name().empty())
20996 return var_decl_sptr();
20997
20998 for (data_members::const_iterator it = get_non_static_data_members().begin();
20999 it != get_non_static_data_members().end();
21000 ++it)
21001 {
21002 if (is_anonymous_data_member(*it))
21003 if ((*it)->get_pretty_representation(/*internal=*/false, true)
21004 == v->get_pretty_representation(/*internal=*/false, true))
21005 return *it;
21006 }
21007
21008 return var_decl_sptr();
21009 }
21010
21011 /// Find a given data member.
21012 ///
21013 /// This function takes a @ref var_decl as an argument. If it has a
21014 /// non-empty name, then it tries to find a data member which has the
21015 /// same name as the argument.
21016 ///
21017 /// If it has an empty name, then the @ref var_decl is considered as
21018 /// an anonymous data member. In that case, this function tries to
21019 /// find an anonymous data member which type equals that of the @ref
21020 /// var_decl argument.
21021 ///
21022 /// @param v this carries either the name of the data member we need
21023 /// to look for, or the type of the anonymous data member we are
21024 /// looking for.
21025 const var_decl_sptr
find_data_member(const var_decl_sptr & v) const21026 class_or_union::find_data_member(const var_decl_sptr& v) const
21027 {
21028 if (!v)
21029 return var_decl_sptr();
21030
21031 if (v->get_name().empty())
21032 return find_anonymous_data_member(v);
21033
21034 return find_data_member(v->get_name());
21035 }
21036
21037
21038 /// Get the non-static data memebers of this @ref class_or_union.
21039 ///
21040 /// @return a vector of the non-static data members of this @ref
21041 /// class_or_union.
21042 const class_or_union::data_members&
get_non_static_data_members() const21043 class_or_union::get_non_static_data_members() const
21044 {return priv_->non_static_data_members_;}
21045
21046 /// Add a member function.
21047 ///
21048 /// @param f the new member function to add.
21049 ///
21050 /// @param a the access specifier to use for the new member function.
21051 ///
21052 /// @param is_static whether the new member function is static.
21053 ///
21054 /// @param is_ctor whether the new member function is a constructor.
21055 ///
21056 /// @param is_dtor whether the new member function is a destructor.
21057 ///
21058 /// @param is_const whether the new member function is const.
21059 void
add_member_function(method_decl_sptr f,access_specifier a,bool is_static,bool is_ctor,bool is_dtor,bool is_const)21060 class_or_union::add_member_function(method_decl_sptr f,
21061 access_specifier a,
21062 bool is_static, bool is_ctor,
21063 bool is_dtor, bool is_const)
21064 {
21065 ABG_ASSERT(!has_scope(f));
21066
21067 scope_decl::add_member_decl(f);
21068
21069 set_member_function_is_ctor(f, is_ctor);
21070 set_member_function_is_dtor(f, is_dtor);
21071 set_member_access_specifier(f, a);
21072 set_member_is_static(f, is_static);
21073 set_member_function_is_const(f, is_const);
21074
21075 priv_->member_functions_.push_back(f);
21076
21077 // Update the map of linkage name -> member functions. It's useful,
21078 // so that class_or_union::find_member_function() can function.
21079 if (!f->get_linkage_name().empty())
21080 priv_->mem_fns_map_[f->get_linkage_name()] = f;
21081 }
21082
21083 /// Get the member functions of this @ref class_or_union.
21084 ///
21085 /// @return a vector of the member functions of this @ref
21086 /// class_or_union.
21087 const class_or_union::member_functions&
get_member_functions() const21088 class_or_union::get_member_functions() const
21089 {return priv_->member_functions_;}
21090
21091 /// Find a method, using its linkage name as a key.
21092 ///
21093 /// @param linkage_name the linkage name of the method to find.
21094 ///
21095 /// @return the method found, or nil if none was found.
21096 const method_decl*
find_member_function(const string & linkage_name) const21097 class_or_union::find_member_function(const string& linkage_name) const
21098 {
21099 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
21100 }
21101
21102 /// Find a method, using its linkage name as a key.
21103 ///
21104 /// @param linkage_name the linkage name of the method to find.
21105 ///
21106 /// @return the method found, or nil if none was found.
21107 method_decl*
find_member_function(const string & linkage_name)21108 class_or_union::find_member_function(const string& linkage_name)
21109 {
21110 string_mem_fn_sptr_map_type::const_iterator i =
21111 priv_->mem_fns_map_.find(linkage_name);
21112 if (i == priv_->mem_fns_map_.end())
21113 return 0;
21114 return i->second.get();
21115 }
21116
21117 /// Find a method, using its linkage name as a key.
21118 ///
21119 /// @param linkage_name the linkage name of the method to find.
21120 ///
21121 /// @return the method found, or nil if none was found.
21122 method_decl_sptr
find_member_function_sptr(const string & linkage_name)21123 class_or_union::find_member_function_sptr(const string& linkage_name)
21124 {
21125 string_mem_fn_sptr_map_type::const_iterator i =
21126 priv_->mem_fns_map_.find(linkage_name);
21127 if (i == priv_->mem_fns_map_.end())
21128 return 0;
21129 return i->second;
21130 }
21131
21132 /// Find a method (member function) using its signature (pretty
21133 /// representation) as a key.
21134 ///
21135 /// @param s the signature of the method.
21136 ///
21137 /// @return the method found, or nil if none was found.
21138 const method_decl*
find_member_function_from_signature(const string & s) const21139 class_or_union::find_member_function_from_signature(const string& s) const
21140 {
21141 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
21142 }
21143
21144 /// Find a method (member function) using its signature (pretty
21145 /// representation) as a key.
21146 ///
21147 /// @param s the signature of the method.
21148 ///
21149 /// @return the method found, or nil if none was found.
21150 method_decl*
find_member_function_from_signature(const string & s)21151 class_or_union::find_member_function_from_signature(const string& s)
21152 {
21153 string_mem_fn_ptr_map_type::const_iterator i =
21154 priv_->signature_2_mem_fn_map_.find(s);
21155 if (i == priv_->signature_2_mem_fn_map_.end())
21156 return 0;
21157 return i->second;
21158 }
21159
21160 /// Get the member function templates of this class.
21161 ///
21162 /// @return a vector of the member function templates of this class.
21163 const member_function_templates&
get_member_function_templates() const21164 class_or_union::get_member_function_templates() const
21165 {return priv_->member_function_templates_;}
21166
21167 /// Get the member class templates of this class.
21168 ///
21169 /// @return a vector of the member class templates of this class.
21170 const member_class_templates&
get_member_class_templates() const21171 class_or_union::get_member_class_templates() const
21172 {return priv_->member_class_templates_;}
21173
21174 /// Append a member function template to the @ref class_or_union.
21175 ///
21176 /// @param m the member function template to append.
21177 void
add_member_function_template(member_function_template_sptr m)21178 class_or_union::add_member_function_template(member_function_template_sptr m)
21179 {
21180 decl_base* c = m->as_function_tdecl()->get_scope();
21181 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
21182 /// error message or something like a structured error.
21183 priv_->member_function_templates_.push_back(m);
21184 if (!c)
21185 scope_decl::add_member_decl(m->as_function_tdecl());
21186 }
21187
21188 /// Append a member class template to the @ref class_or_union.
21189 ///
21190 /// @param m the member function template to append.
21191 void
add_member_class_template(member_class_template_sptr m)21192 class_or_union::add_member_class_template(member_class_template_sptr m)
21193 {
21194 decl_base* c = m->as_class_tdecl()->get_scope();
21195 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
21196 /// error message or something like a structured error.
21197 m->set_scope(this);
21198 priv_->member_class_templates_.push_back(m);
21199 if (!c)
21200 scope_decl::add_member_decl(m->as_class_tdecl());
21201 }
21202
21203 ///@return true iff the current instance has no member.
21204 bool
has_no_member() const21205 class_or_union::has_no_member() const
21206 {
21207 return (priv_->member_types_.empty()
21208 && priv_->data_members_.empty()
21209 && priv_->member_functions_.empty()
21210 && priv_->member_function_templates_.empty()
21211 && priv_->member_class_templates_.empty());
21212 }
21213
21214 /// Insert a data member to this @ref class_or_union type.
21215 ///
21216 /// @param d the data member to insert.
21217 ///
21218 /// @param before an iterator to the point before which to insert the
21219 /// the data member, in the coontainer that contains all the data
21220 /// members.
21221 decl_base_sptr
insert_member_decl(decl_base_sptr d,declarations::iterator before)21222 class_or_union::insert_member_decl(decl_base_sptr d,
21223 declarations::iterator before)
21224 {
21225 if (type_base_sptr t = dynamic_pointer_cast<type_base>(d))
21226 insert_member_type(t, before);
21227 else if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
21228 {
21229 add_data_member(v, public_access,
21230 /*is_laid_out=*/false,
21231 /*is_static=*/true,
21232 /*offset_in_bits=*/0);
21233 d = v;
21234 }
21235 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
21236 add_member_function(f, public_access,
21237 /*is_static=*/false,
21238 /*is_ctor=*/false,
21239 /*is_dtor=*/false,
21240 /*is_const=*/false);
21241 else if (member_function_template_sptr f =
21242 dynamic_pointer_cast<member_function_template>(d))
21243 add_member_function_template(f);
21244 else if (member_class_template_sptr c =
21245 dynamic_pointer_cast<member_class_template>(d))
21246 add_member_class_template(c);
21247 else
21248 scope_decl::add_member_decl(d);
21249
21250 return d;
21251 }
21252
21253 /// Equality operator.
21254 ///
21255 /// @param other the other @ref class_or_union to compare against.
21256 ///
21257 /// @return true iff @p other equals the current @ref class_or_union.
21258 bool
operator ==(const decl_base & other) const21259 class_or_union::operator==(const decl_base& other) const
21260 {
21261 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
21262 if (!op)
21263 return false;
21264
21265 // If this is a decl-only type (and thus with no canonical type),
21266 // use the canonical type of the definition, if any.
21267 const class_or_union *l = 0;
21268 if (get_is_declaration_only())
21269 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
21270 if (l == 0)
21271 l = this;
21272
21273 // Likewise for the other class.
21274 const class_or_union *r = 0;
21275 if (op->get_is_declaration_only())
21276 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
21277 if (r == 0)
21278 r = op;
21279
21280 return try_canonical_compare(l, r);
21281 }
21282
21283 /// Equality operator.
21284 ///
21285 /// @param other the other @ref class_or_union to compare against.
21286 ///
21287 /// @return true iff @p other equals the current @ref class_or_union.
21288 bool
operator ==(const type_base & other) const21289 class_or_union::operator==(const type_base& other) const
21290 {
21291 const decl_base* o = dynamic_cast<const decl_base*>(&other);
21292 if (!o)
21293 return false;
21294 return *this == *o;
21295 }
21296
21297 /// Equality operator.
21298 ///
21299 /// @param other the other @ref class_or_union to compare against.
21300 ///
21301 /// @return true iff @p other equals the current @ref class_or_union.
21302 bool
operator ==(const class_or_union & other) const21303 class_or_union::operator==(const class_or_union& other) const
21304 {
21305 const decl_base& o = other;
21306 return class_or_union::operator==(o);
21307 }
21308
21309 /// Compares two instances of @ref class_or_union.
21310 ///
21311 /// If the two intances are different, set a bitfield to give some
21312 /// insight about the kind of differences there are.
21313 ///
21314 /// @param l the first artifact of the comparison.
21315 ///
21316 /// @param r the second artifact of the comparison.
21317 ///
21318 /// @param k a pointer to a bitfield that gives information about the
21319 /// kind of changes there are between @p l and @p r. This one is set
21320 /// iff it's non-null and if the function returns false.
21321 ///
21322 /// Please note that setting k to a non-null value does have a
21323 /// negative performance impact because even if @p l and @p r are not
21324 /// equal, the function keeps up the comparison in order to determine
21325 /// the different kinds of ways in which they are different.
21326 ///
21327 /// @return true if @p l equals @p r, false otherwise.
21328 bool
equals(const class_or_union & l,const class_or_union & r,change_kind * k)21329 equals(const class_or_union& l, const class_or_union& r, change_kind* k)
21330 {
21331 #define RETURN(value) return return_comparison_result(l, r, value);
21332
21333 // if one of the classes is declaration-only, look through it to
21334 // get its definition.
21335 bool l_is_decl_only = l.get_is_declaration_only();
21336 bool r_is_decl_only = r.get_is_declaration_only();
21337 if (l_is_decl_only || r_is_decl_only)
21338 {
21339 const class_or_union* def1 = l_is_decl_only
21340 ? is_class_or_union_type(l.get_naked_definition_of_declaration())
21341 : &l;
21342
21343 const class_or_union* def2 = r_is_decl_only
21344 ? is_class_or_union_type(r.get_naked_definition_of_declaration())
21345 : &r;
21346
21347 if (!def1 || !def2)
21348 {
21349 if (!l.get_is_anonymous()
21350 && !r.get_is_anonymous()
21351 && l_is_decl_only && r_is_decl_only
21352 && comparison::filtering::is_decl_only_class_with_size_change(l, r))
21353 // The two decl-only classes differ from their size. A
21354 // true decl-only class should not have a size property to
21355 // begin with. This comes from a DWARF oddity and can
21356 // results in a false positive, so let's not consider that
21357 // change.
21358 return true;
21359
21360 if ((l.get_environment()->decl_only_class_equals_definition()
21361 || ((odr_is_relevant(l) && !def1)
21362 || (odr_is_relevant(r) && !def2)))
21363 && !is_anonymous_or_typedef_named(l)
21364 && !is_anonymous_or_typedef_named(r))
21365 {
21366 const interned_string& q1 = l.get_scoped_name();
21367 const interned_string& q2 = r.get_scoped_name();
21368 if (q1 == q2)
21369 // Not using RETURN(true) here, because that causes
21370 // performance issues. We don't need to do
21371 // l.priv_->unmark_as_being_compared({l,r}) here because
21372 // we haven't marked l or r as being compared yet, and
21373 // doing so has a peformance cost that shows up on
21374 // performance profiles for *big* libraries.
21375 return true;
21376 else
21377 {
21378 if (k)
21379 *k |= LOCAL_TYPE_CHANGE_KIND;
21380 // Not using RETURN(true) here, because that causes
21381 // performance issues. We don't need to do
21382 // l.priv_->unmark_as_being_compared({l,r}) here because
21383 // we haven't marked l or r as being compared yet, and
21384 // doing so has a peformance cost that shows up on
21385 // performance profiles for *big* libraries.
21386 ABG_RETURN_FALSE;
21387 }
21388 }
21389 else // A decl-only class is considered different from a
21390 // class definition of the same name.
21391 {
21392 if (!!def1 != !!def2)
21393 {
21394 if (k)
21395 *k |= LOCAL_TYPE_CHANGE_KIND;
21396 ABG_RETURN_FALSE;
21397 }
21398
21399 // both definitions are empty
21400 if (!(l.decl_base::operator==(r)
21401 && l.type_base::operator==(r)))
21402 {
21403 if (k)
21404 *k |= LOCAL_TYPE_CHANGE_KIND;
21405 ABG_RETURN_FALSE;
21406 }
21407
21408 return true;
21409 }
21410 }
21411
21412 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
21413
21414 mark_types_as_being_compared(l, r);
21415
21416 bool val = *def1 == *def2;
21417 if (!val)
21418 if (k)
21419 *k |= LOCAL_TYPE_CHANGE_KIND;
21420 RETURN(val);
21421 }
21422
21423 // No need to go further if the classes have different names or
21424 // different size / alignment.
21425 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
21426 {
21427 if (k)
21428 *k |= LOCAL_TYPE_CHANGE_KIND;
21429 ABG_RETURN_FALSE;
21430 }
21431
21432 if (types_defined_same_linux_kernel_corpus_public(l, r))
21433 return true;
21434
21435 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r);
21436
21437 mark_types_as_being_compared(l, r);
21438
21439 bool result = true;
21440
21441 //compare data_members
21442 {
21443 if (l.get_non_static_data_members().size()
21444 != r.get_non_static_data_members().size())
21445 {
21446 result = false;
21447 if (k)
21448 *k |= LOCAL_TYPE_CHANGE_KIND;
21449 else
21450 RETURN(result);
21451 }
21452
21453 for (class_or_union::data_members::const_iterator
21454 d0 = l.get_non_static_data_members().begin(),
21455 d1 = r.get_non_static_data_members().begin();
21456 (d0 != l.get_non_static_data_members().end()
21457 && d1 != r.get_non_static_data_members().end());
21458 ++d0, ++d1)
21459 if (**d0 != **d1)
21460 {
21461 result = false;
21462 if (k)
21463 {
21464 // Report any representation change as being local.
21465 if (!types_have_similar_structure((*d0)->get_type(),
21466 (*d1)->get_type())
21467 || (*d0)->get_type() == (*d1)->get_type())
21468 *k |= LOCAL_TYPE_CHANGE_KIND;
21469 else
21470 *k |= SUBTYPE_CHANGE_KIND;
21471 }
21472 else
21473 RETURN(result);
21474 }
21475 }
21476
21477 // Do not compare member functions. DWARF does not necessarily
21478 // all the member functions, be they virtual or not, in all
21479 // translation units. So we cannot have a clear view of them, per
21480 // class
21481
21482 // compare member function templates
21483 {
21484 if (l.get_member_function_templates().size()
21485 != r.get_member_function_templates().size())
21486 {
21487 result = false;
21488 if (k)
21489 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21490 else
21491 RETURN(result);
21492 }
21493
21494 for (member_function_templates::const_iterator
21495 fn_tmpl_it0 = l.get_member_function_templates().begin(),
21496 fn_tmpl_it1 = r.get_member_function_templates().begin();
21497 fn_tmpl_it0 != l.get_member_function_templates().end()
21498 && fn_tmpl_it1 != r.get_member_function_templates().end();
21499 ++fn_tmpl_it0, ++fn_tmpl_it1)
21500 if (**fn_tmpl_it0 != **fn_tmpl_it1)
21501 {
21502 result = false;
21503 if (k)
21504 {
21505 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21506 break;
21507 }
21508 else
21509 RETURN(result);
21510 }
21511 }
21512
21513 // compare member class templates
21514 {
21515 if (l.get_member_class_templates().size()
21516 != r.get_member_class_templates().size())
21517 {
21518 result = false;
21519 if (k)
21520 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21521 else
21522 RETURN(result);
21523 }
21524
21525 for (member_class_templates::const_iterator
21526 cl_tmpl_it0 = l.get_member_class_templates().begin(),
21527 cl_tmpl_it1 = r.get_member_class_templates().begin();
21528 cl_tmpl_it0 != l.get_member_class_templates().end()
21529 && cl_tmpl_it1 != r.get_member_class_templates().end();
21530 ++cl_tmpl_it0, ++cl_tmpl_it1)
21531 if (**cl_tmpl_it0 != **cl_tmpl_it1)
21532 {
21533 result = false;
21534 if (k)
21535 {
21536 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21537 break;
21538 }
21539 else
21540 RETURN(result);
21541 }
21542 }
21543
21544 RETURN(result);
21545 #undef RETURN
21546 }
21547
21548
21549 /// Copy a method of a @ref class_or_union into a new @ref
21550 /// class_or_union.
21551 ///
21552 /// @param t the @ref class_or_union into which the method is to be copied.
21553 ///
21554 /// @param method the method to copy into @p t.
21555 ///
21556 /// @return the resulting newly copied method.
21557 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl_sptr & method)21558 copy_member_function(const class_or_union_sptr& t,
21559 const method_decl_sptr& method)
21560 {return copy_member_function(t, method.get());}
21561
21562
21563 /// Copy a method of a @ref class_or_union into a new @ref
21564 /// class_or_union.
21565 ///
21566 /// @param t the @ref class_or_union into which the method is to be copied.
21567 ///
21568 /// @param method the method to copy into @p t.
21569 ///
21570 /// @return the resulting newly copied method.
21571 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl * method)21572 copy_member_function(const class_or_union_sptr& t, const method_decl* method)
21573 {
21574 ABG_ASSERT(t);
21575 ABG_ASSERT(method);
21576
21577 method_type_sptr old_type = method->get_type();
21578 ABG_ASSERT(old_type);
21579 method_type_sptr new_type(new method_type(old_type->get_return_type(),
21580 t,
21581 old_type->get_parameters(),
21582 old_type->get_is_const(),
21583 old_type->get_size_in_bits(),
21584 old_type->get_alignment_in_bits()));
21585 new_type->set_environment(t->get_environment());
21586 keep_type_alive(new_type);
21587
21588 method_decl_sptr
21589 new_method(new method_decl(method->get_name(),
21590 new_type,
21591 method->is_declared_inline(),
21592 method->get_location(),
21593 method->get_linkage_name(),
21594 method->get_visibility(),
21595 method->get_binding()));
21596 new_method->set_symbol(method->get_symbol());
21597
21598 if (class_decl_sptr class_type = is_class_type(t))
21599 class_type->add_member_function(new_method,
21600 get_member_access_specifier(*method),
21601 get_member_function_is_virtual(*method),
21602 get_member_function_vtable_offset(*method),
21603 get_member_is_static(*method),
21604 get_member_function_is_ctor(*method),
21605 get_member_function_is_dtor(*method),
21606 get_member_function_is_const(*method));
21607 else
21608 t->add_member_function(new_method,
21609 get_member_access_specifier(*method),
21610 get_member_is_static(*method),
21611 get_member_function_is_ctor(*method),
21612 get_member_function_is_dtor(*method),
21613 get_member_function_is_const(*method));
21614 return new_method;
21615 }
21616
21617 // </class_or_union definitions>
21618
21619 /// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
21620 /// @{
21621 ///
21622 /// This optimization is also known as "canonical type propagation".
21623 ///
21624 /// During the canonicalization of a type T (which doesn't yet have a
21625 /// canonical type), T is compared structurally (member-wise) against
21626 /// a type C which already has a canonical type. The comparison
21627 /// expression is C == T.
21628 ///
21629 /// During that structural comparison, if a subtype of C (which also
21630 /// already has a canonical type) is structurally compared to a
21631 /// subtype of T (which doesn't yet have a canonical type) and if they
21632 /// are equal, then we can deduce that the canonical type of the
21633 /// subtype of C is the canonical type of the subtype of C.
21634 ///
21635 /// Thus, we can canonicalize the sub-type of the T, during the
21636 /// canonicalization of T itself. That canonicalization of the
21637 /// sub-type of T is what we call the "on-the-fly canonicalization".
21638 /// It's on the fly because it happens during a comparison -- which
21639 /// itself happens during the canonicalization of T.
21640 ///
21641 /// For now this on-the-fly canonicalization only happens when
21642 /// comparing @ref class_decl and @ref function_type.
21643 ///
21644 /// Note however that there is a case when a type is *NOT* eligible to
21645 /// this canonical type propagation optimization.
21646 ///
21647 /// The reason why a type is deemed NON-eligible to the canonical type
21648 /// propagation optimization is that it "depends" on recursively
21649 /// present type. Let me explain.
21650 ///
21651 /// Suppose we have a type T that has sub-types named ST0 and ST1.
21652 /// Suppose ST1 itself has a sub-type that is T itself. In this case,
21653 /// we say that T is a recursive type, because it has T (itself) as
21654 /// one of its sub-types:
21655 ///
21656 /// T
21657 /// +-- ST0
21658 /// |
21659 /// +-- ST1
21660 /// | +
21661 /// | |
21662 /// | +-- T
21663 /// |
21664 /// +-- ST2
21665 ///
21666 /// ST1 is said to "depend" on T because it has T as a sub-type. But
21667 /// because T is recursive, then ST1 is said to depend on a recursive
21668 /// type. Notice however that ST0 does not depend on any recursive
21669 /// type.
21670 ///
21671 /// Now suppose we are comparing T to a type T' that has the same
21672 /// structure with sub-types ST0', ST1' and ST2'. During the
21673 /// comparison of ST1 against ST1', their sub-type T is compared
21674 /// against T'. Because T (resp. T') is a recursive type that is
21675 /// already being compared, the comparison of T against T' (as a
21676 /// subtypes of ST1 and ST1') returns true, meaning they are
21677 /// considered equal. This is done so that we don't enter an infinite
21678 /// recursion.
21679 ///
21680 /// That means ST1 is also deemed equal to ST1'. If we are in the
21681 /// course of the canonicalization of T' and thus if T (as well as as
21682 /// all of its sub-types) is already canonicalized, then the canonical
21683 /// type propagation optimization will make us propagate the canonical
21684 /// type of ST1 onto ST1'. So the canonical type of ST1' will be
21685 /// equal to the canonical type of ST1 as a result of that
21686 /// optmization.
21687 ///
21688 /// But then, later down the road, when ST2 is compared against ST2',
21689 /// let's suppose that we find out that they are different. Meaning
21690 /// that ST2 != ST2'. This means that T != T', i.e, the
21691 /// canonicalization of T' failed for now. But most importantly, it
21692 /// means that the propagation of the canonical type of ST1 to ST1'
21693 /// must now be invalidated. Meaning, ST1' must now be considered as
21694 /// not having any canonical type.
21695 ///
21696 /// In other words, during type canonicalization, if ST1' depends on a
21697 /// recursive type T', its propagated canonical type must be
21698 /// invalidated (set to nullptr) if T' appears to be different from T,
21699 /// a.k.a, the canonicalization of T' temporarily failed.
21700 ///
21701 /// This means that any sub-type that depends on recursive types and
21702 /// that has been the target of the canonical type propagation
21703 /// optimization must be tracked. If the dependant recursive type
21704 /// fails its canonicalization, then the sub-type being compared must
21705 /// have its propagated canonical type cleared. In other words, its
21706 /// propagated canonical type must be cancelled.
21707 ///
21708 /// @}
21709
21710
21711 /// If on-the-fly canonicalization is turned on, then this function
21712 /// sets the canonical type of its second parameter to the canonical
21713 /// type of the first parameter.
21714 ///
21715 /// @param lhs_type the type which canonical type to propagate.
21716 ///
21717 /// @param rhs_type the type which canonical type to set.
21718 static bool
maybe_propagate_canonical_type(const type_base & lhs_type,const type_base & rhs_type)21719 maybe_propagate_canonical_type(const type_base& lhs_type,
21720 const type_base& rhs_type)
21721 {
21722 if (const environment *env = lhs_type.get_environment())
21723 if (env->do_on_the_fly_canonicalization())
21724 if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
21725 if (!rhs_type.get_canonical_type())
21726 if (env->priv_->propagate_ct(lhs_type, rhs_type))
21727 return true;
21728 return false;
21729 }
21730
21731 // <class_decl definitions>
21732
21733 static void
21734 sort_virtual_member_functions(class_decl::member_functions& mem_fns);
21735
21736 /// The private data for the class_decl type.
21737 struct class_decl::priv
21738 {
21739 base_specs bases_;
21740 unordered_map<string, base_spec_sptr> bases_map_;
21741 member_functions virtual_mem_fns_;
21742 virtual_mem_fn_map_type virtual_mem_fns_map_;
21743 bool is_struct_;
21744
privabigail::ir::class_decl::priv21745 priv()
21746 : is_struct_(false)
21747 {}
21748
privabigail::ir::class_decl::priv21749 priv(bool is_struct, class_decl::base_specs& bases)
21750 : bases_(bases),
21751 is_struct_(is_struct)
21752 {
21753 }
21754
privabigail::ir::class_decl::priv21755 priv(bool is_struct)
21756 : is_struct_(is_struct)
21757 {}
21758 };// end struct class_decl::priv
21759
21760 /// A Constructor for instances of \ref class_decl
21761 ///
21762 /// @param env the environment we are operating from.
21763 ///
21764 /// @param name the identifier of the class.
21765 ///
21766 /// @param size_in_bits the size of an instance of class_decl, expressed
21767 /// in bits
21768 ///
21769 /// @param align_in_bits the alignment of an instance of class_decl,
21770 /// expressed in bits.
21771 ///
21772 /// @param locus the source location of declaration point this class.
21773 ///
21774 /// @param vis the visibility of instances of class_decl.
21775 ///
21776 /// @param bases the vector of base classes for this instance of class_decl.
21777 ///
21778 /// @param mbrs the vector of member types of this instance of
21779 /// class_decl.
21780 ///
21781 /// @param data_mbrs the vector of data members of this instance of
21782 /// class_decl.
21783 ///
21784 /// @param mbr_fns the vector of member functions of this instance of
21785 /// 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)21786 class_decl::class_decl(const environment* env, const string& name,
21787 size_t size_in_bits, size_t align_in_bits,
21788 bool is_struct, const location& locus,
21789 visibility vis, base_specs& bases,
21790 member_types& mbr_types,
21791 data_members& data_mbrs,
21792 member_functions& mbr_fns)
21793 : type_or_decl_base(env,
21794 CLASS_TYPE
21795 | ABSTRACT_TYPE_BASE
21796 | ABSTRACT_DECL_BASE
21797 | ABSTRACT_SCOPE_TYPE_DECL
21798 | ABSTRACT_SCOPE_DECL),
21799 decl_base(env, name, locus, name, vis),
21800 type_base(env, size_in_bits, align_in_bits),
21801 class_or_union(env, name, size_in_bits, align_in_bits,
21802 locus, vis, mbr_types, data_mbrs, mbr_fns),
21803 priv_(new priv(is_struct, bases))
21804 {
21805 runtime_type_instance(this);
21806 }
21807
21808 /// A Constructor for instances of @ref class_decl
21809 ///
21810 /// @param env the environment we are operating from.
21811 ///
21812 /// @param name the identifier of the class.
21813 ///
21814 /// @param size_in_bits the size of an instance of class_decl, expressed
21815 /// in bits
21816 ///
21817 /// @param align_in_bits the alignment of an instance of class_decl,
21818 /// expressed in bits.
21819 ///
21820 /// @param locus the source location of declaration point this class.
21821 ///
21822 /// @param vis the visibility of instances of class_decl.
21823 ///
21824 /// @param bases the vector of base classes for this instance of class_decl.
21825 ///
21826 /// @param mbrs the vector of member types of this instance of
21827 /// class_decl.
21828 ///
21829 /// @param data_mbrs the vector of data members of this instance of
21830 /// class_decl.
21831 ///
21832 /// @param mbr_fns the vector of member functions of this instance of
21833 /// class_decl.
21834 ///
21835 /// @param is_anonymous whether the newly created instance is
21836 /// 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)21837 class_decl::class_decl(const environment* env, const string& name,
21838 size_t size_in_bits, size_t align_in_bits,
21839 bool is_struct, const location& locus,
21840 visibility vis, base_specs& bases,
21841 member_types& mbr_types, data_members& data_mbrs,
21842 member_functions& mbr_fns, bool is_anonymous)
21843 : type_or_decl_base(env,
21844 CLASS_TYPE
21845 | ABSTRACT_TYPE_BASE
21846 | ABSTRACT_DECL_BASE
21847 | ABSTRACT_SCOPE_TYPE_DECL
21848 | ABSTRACT_SCOPE_DECL),
21849 decl_base(env, name, locus,
21850 // If the class is anonymous then by default it won't
21851 // have a linkage name. Also, the anonymous class does
21852 // have an internal-only unique name that is generally
21853 // not taken into account when comparing classes; such a
21854 // unique internal-only name, when used as a linkage
21855 // name might introduce spurious comparison false
21856 // negatives.
21857 /*linkage_name=*/is_anonymous ? string() : name,
21858 vis),
21859 type_base(env, size_in_bits, align_in_bits),
21860 class_or_union(env, name, size_in_bits, align_in_bits,
21861 locus, vis, mbr_types, data_mbrs, mbr_fns),
21862 priv_(new priv(is_struct, bases))
21863 {
21864 runtime_type_instance(this);
21865 set_is_anonymous(is_anonymous);
21866 }
21867
21868 /// A constructor for instances of class_decl.
21869 ///
21870 /// @param env the environment we are operating from.
21871 ///
21872 /// @param name the name of the class.
21873 ///
21874 /// @param size_in_bits the size of an instance of class_decl, expressed
21875 /// in bits
21876 ///
21877 /// @param align_in_bits the alignment of an instance of class_decl,
21878 /// expressed in bits.
21879 ///
21880 /// @param locus the source location of declaration point this class.
21881 ///
21882 /// @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)21883 class_decl::class_decl(const environment* env, const string& name,
21884 size_t size_in_bits, size_t align_in_bits,
21885 bool is_struct, const location& locus,
21886 visibility vis)
21887 : type_or_decl_base(env,
21888 CLASS_TYPE
21889 | ABSTRACT_TYPE_BASE
21890 | ABSTRACT_DECL_BASE
21891 | ABSTRACT_SCOPE_TYPE_DECL
21892 | ABSTRACT_SCOPE_DECL),
21893 decl_base(env, name, locus, name, vis),
21894 type_base(env, size_in_bits, align_in_bits),
21895 class_or_union(env, name, size_in_bits, align_in_bits,
21896 locus, vis),
21897 priv_(new priv(is_struct))
21898 {
21899 runtime_type_instance(this);
21900 }
21901
21902 /// A constructor for instances of @ref class_decl.
21903 ///
21904 /// @param env the environment we are operating from.
21905 ///
21906 /// @param name the name of the class.
21907 ///
21908 /// @param size_in_bits the size of an instance of class_decl, expressed
21909 /// in bits
21910 ///
21911 /// @param align_in_bits the alignment of an instance of class_decl,
21912 /// expressed in bits.
21913 ///
21914 /// @param locus the source location of declaration point this class.
21915 ///
21916 /// @param vis the visibility of instances of class_decl.
21917 ///
21918 /// @param is_anonymous whether the newly created instance is
21919 /// 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)21920 class_decl:: class_decl(const environment* env, const string& name,
21921 size_t size_in_bits, size_t align_in_bits,
21922 bool is_struct, const location& locus,
21923 visibility vis, bool is_anonymous)
21924 : type_or_decl_base(env,
21925 CLASS_TYPE
21926 | ABSTRACT_TYPE_BASE
21927 | ABSTRACT_DECL_BASE
21928 | ABSTRACT_SCOPE_TYPE_DECL
21929 | ABSTRACT_SCOPE_DECL),
21930 decl_base(env, name, locus,
21931 // If the class is anonymous then by default it won't
21932 // have a linkage name. Also, the anonymous class does
21933 // have an internal-only unique name that is generally
21934 // not taken into account when comparing classes; such a
21935 // unique internal-only name, when used as a linkage
21936 // name might introduce spurious comparison false
21937 // negatives.
21938 /*linkage_name=*/ is_anonymous ? string() : name,
21939 vis),
21940 type_base(env, size_in_bits, align_in_bits),
21941 class_or_union(env, name, size_in_bits, align_in_bits,
21942 locus, vis),
21943 priv_(new priv(is_struct))
21944 {
21945 runtime_type_instance(this);
21946 set_is_anonymous(is_anonymous);
21947 }
21948
21949 /// A constuctor for instances of class_decl that represent a
21950 /// declaration without definition.
21951 ///
21952 /// @param env the environment we are operating from.
21953 ///
21954 /// @param name the name of the class.
21955 ///
21956 /// @param is_declaration_only a boolean saying whether the instance
21957 /// represents a declaration only, or not.
class_decl(const environment * env,const string & name,bool is_struct,bool is_declaration_only)21958 class_decl::class_decl(const environment* env, const string& name,
21959 bool is_struct, bool is_declaration_only)
21960 : type_or_decl_base(env,
21961 CLASS_TYPE
21962 | ABSTRACT_TYPE_BASE
21963 | ABSTRACT_DECL_BASE
21964 | ABSTRACT_SCOPE_TYPE_DECL
21965 | ABSTRACT_SCOPE_DECL),
21966 decl_base(env, name, location(), name),
21967 type_base(env, 0, 0),
21968 class_or_union(env, name, is_declaration_only),
21969 priv_(new priv(is_struct))
21970 {
21971 runtime_type_instance(this);
21972 }
21973
21974 /// This method is invoked automatically right after the current
21975 /// instance of @ref class_decl has been canonicalized.
21976 ///
21977 /// Currently, the only thing it does is to sort the virtual member
21978 /// functions vector.
21979 void
on_canonical_type_set()21980 class_decl::on_canonical_type_set()
21981 {
21982 sort_virtual_mem_fns();
21983
21984 for (class_decl::virtual_mem_fn_map_type::iterator i =
21985 priv_->virtual_mem_fns_map_.begin();
21986 i != priv_->virtual_mem_fns_map_.end();
21987 ++i)
21988 sort_virtual_member_functions(i->second);
21989 }
21990
21991 /// Set the "is-struct" flag of the class.
21992 ///
21993 /// @param f the new value of the flag.
21994 void
is_struct(bool f)21995 class_decl::is_struct(bool f)
21996 {priv_->is_struct_ = f;}
21997
21998 /// Test if the class is a struct.
21999 ///
22000 /// @return true iff the class is a struct.
22001 bool
is_struct() const22002 class_decl::is_struct() const
22003 {return priv_->is_struct_;}
22004
22005 /// Add a base specifier to this class.
22006 ///
22007 /// @param b the new base specifier.
22008 void
add_base_specifier(base_spec_sptr b)22009 class_decl::add_base_specifier(base_spec_sptr b)
22010 {
22011 ABG_ASSERT(get_environment());
22012 ABG_ASSERT(b->get_environment() == get_environment());
22013 priv_->bases_.push_back(b);
22014 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
22015 if (const environment* env = get_environment())
22016 b->set_environment(env);
22017 }
22018
22019 /// Get the base specifiers for this class.
22020 ///
22021 /// @return a vector of the base specifiers.
22022 const class_decl::base_specs&
get_base_specifiers() const22023 class_decl::get_base_specifiers() const
22024 {return priv_->bases_;}
22025
22026 /// Find a base class of a given qualified name for the current class.
22027 ///
22028 /// @param qualified_name the qualified name of the base class to look for.
22029 ///
22030 /// @return a pointer to the @ref class_decl that represents the base
22031 /// class of name @p qualified_name, if found.
22032 class_decl_sptr
find_base_class(const string & qualified_name) const22033 class_decl::find_base_class(const string& qualified_name) const
22034 {
22035 unordered_map<string, base_spec_sptr>::iterator i =
22036 priv_->bases_map_.find(qualified_name);
22037
22038 if (i != priv_->bases_map_.end())
22039 return i->second->get_base_class();
22040
22041 return class_decl_sptr();
22042 }
22043
22044 /// Get the virtual member functions of this class.
22045 ///
22046 /// @param return a vector of the virtual member functions of this
22047 /// class.
22048 const class_decl::member_functions&
get_virtual_mem_fns() const22049 class_decl::get_virtual_mem_fns() const
22050 {return priv_->virtual_mem_fns_;}
22051
22052 /// Get the map that associates a virtual table offset to the virtual
22053 /// member functions with that virtual table offset.
22054 ///
22055 /// Usually, there should be a 1:1 mapping between a given vtable
22056 /// offset and virtual member functions of that vtable offset. But
22057 /// because of some implementation details, there can be several C++
22058 /// destructor functions that are *generated* by compilers, for a
22059 /// given destructor that is defined in the source code. If the
22060 /// destructor is virtual then those generated functions have some
22061 /// DWARF attributes in common with the constructor that the user
22062 /// actually defined in its source code. Among those attributes are
22063 /// the vtable offset of the destructor.
22064 ///
22065 /// @return the map that associates a virtual table offset to the
22066 /// virtual member functions with that virtual table offset.
22067 const class_decl::virtual_mem_fn_map_type&
get_virtual_mem_fns_map() const22068 class_decl::get_virtual_mem_fns_map() const
22069 {return priv_->virtual_mem_fns_map_;}
22070
22071 /// Sort the virtual member functions by their virtual index.
22072 void
sort_virtual_mem_fns()22073 class_decl::sort_virtual_mem_fns()
22074 {sort_virtual_member_functions(priv_->virtual_mem_fns_);}
22075
22076 /// Getter of the pretty representation of the current instance of
22077 /// @ref class_decl.
22078 ///
22079 /// @param internal set to true if the call is intended to get a
22080 /// representation of the decl (or type) for the purpose of canonical
22081 /// type comparison. This is mainly used in the function
22082 /// type_base::get_canonical_type_for().
22083 ///
22084 /// In other words if the argument for this parameter is true then the
22085 /// call is meant for internal use (for technical use inside the
22086 /// library itself), false otherwise. If you don't know what this is
22087 /// for, then set it to false.
22088 ///
22089 /// @param qualified_name if true, names emitted in the pretty
22090 /// representation are fully qualified.
22091 ///
22092 /// @return the pretty representaion for a class_decl.
22093 string
get_pretty_representation(bool internal,bool qualified_name) const22094 class_decl::get_pretty_representation(bool internal,
22095 bool qualified_name) const
22096 {
22097 string cl = "class ";
22098 if (!internal && is_struct())
22099 cl = "struct ";
22100
22101 // When computing the pretty representation for internal purposes,
22102 // if an anonymous class is named by a typedef, then consider that
22103 // it has a name, which is the typedef name.
22104 if (get_is_anonymous())
22105 {
22106 if (internal)
22107 return cl + get_type_name(this, qualified_name, /*internal=*/true);
22108 return get_class_or_union_flat_representation(this, "",
22109 /*one_line=*/true,
22110 internal);
22111
22112 }
22113
22114 string result = cl;
22115 if (qualified_name)
22116 result += get_qualified_name(internal);
22117 else
22118 result += get_name();
22119
22120 return result;
22121 }
22122
22123 decl_base_sptr
insert_member_decl(decl_base_sptr d,declarations::iterator before)22124 class_decl::insert_member_decl(decl_base_sptr d,
22125 declarations::iterator before)
22126 {
22127 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
22128 add_member_function(f, public_access,
22129 /*is_virtual=*/false,
22130 /*vtable_offset=*/0,
22131 /*is_static=*/false,
22132 /*is_ctor=*/false,
22133 /*is_dtor=*/false,
22134 /*is_const=*/false);
22135 else
22136 d = class_or_union::insert_member_decl(d, before);
22137
22138 return d;
22139 }
22140
22141 /// The private data structure of class_decl::base_spec.
22142 struct class_decl::base_spec::priv
22143 {
22144 class_decl_wptr base_class_;
22145 long offset_in_bits_;
22146 bool is_virtual_;
22147
privabigail::ir::class_decl::base_spec::priv22148 priv(const class_decl_sptr& cl,
22149 long offset_in_bits,
22150 bool is_virtual)
22151 : base_class_(cl),
22152 offset_in_bits_(offset_in_bits),
22153 is_virtual_(is_virtual)
22154 {}
22155 };
22156
22157 /// Constructor for base_spec instances.
22158 ///
22159 /// @param base the base class to consider
22160 ///
22161 /// @param a the access specifier of the base class.
22162 ///
22163 /// @param offset_in_bits if positive or null, represents the offset
22164 /// of the base in the layout of its containing type.. If negative,
22165 /// means that the current base is not laid out in its containing type.
22166 ///
22167 /// @param is_virtual if true, means that the current base class is
22168 /// virtual in it's containing type.
base_spec(const class_decl_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)22169 class_decl::base_spec::base_spec(const class_decl_sptr& base,
22170 access_specifier a,
22171 long offset_in_bits,
22172 bool is_virtual)
22173 : type_or_decl_base(base->get_environment(),
22174 ABSTRACT_DECL_BASE),
22175 decl_base(base->get_environment(), base->get_name(), base->get_location(),
22176 base->get_linkage_name(), base->get_visibility()),
22177 member_base(a),
22178 priv_(new priv(base, offset_in_bits, is_virtual))
22179 {
22180 runtime_type_instance(this);
22181 }
22182
22183 /// Get the base class referred to by the current base class
22184 /// specifier.
22185 ///
22186 /// @return the base class.
22187 class_decl_sptr
get_base_class() const22188 class_decl::base_spec::get_base_class() const
22189 {return priv_->base_class_.lock();}
22190
22191 /// Getter of the "is-virtual" proprerty of the base class specifier.
22192 ///
22193 /// @return true iff this specifies a virtual base class.
22194 bool
get_is_virtual() const22195 class_decl::base_spec::get_is_virtual() const
22196 {return priv_->is_virtual_;}
22197
22198 /// Getter of the offset of the base.
22199 ///
22200 /// @return the offset of the base.
22201 long
get_offset_in_bits() const22202 class_decl::base_spec::get_offset_in_bits() const
22203 {return priv_->offset_in_bits_;}
22204
22205 /// Calculate the hash value for a class_decl::base_spec.
22206 ///
22207 /// @return the hash value.
22208 size_t
get_hash() const22209 class_decl::base_spec::get_hash() const
22210 {
22211 base_spec::hash h;
22212 return h(*this);
22213 }
22214
22215 /// Traverses an instance of @ref class_decl::base_spec, visiting all
22216 /// the sub-types and decls that it might contain.
22217 ///
22218 /// @param v the visitor that is used to visit every IR sub-node of
22219 /// the current node.
22220 ///
22221 /// @return true if either
22222 /// - all the children nodes of the current IR node were traversed
22223 /// and the calling code should keep going with the traversing.
22224 /// - or the current IR node is already being traversed.
22225 /// Otherwise, returning false means that the calling code should not
22226 /// keep traversing the tree.
22227 bool
traverse(ir_node_visitor & v)22228 class_decl::base_spec::traverse(ir_node_visitor& v)
22229 {
22230 if (visiting())
22231 return true;
22232
22233 if (v.visit_begin(this))
22234 {
22235 visiting(true);
22236 get_base_class()->traverse(v);
22237 visiting(false);
22238 }
22239
22240 return v.visit_end(this);
22241 }
22242
22243 /// Constructor for base_spec instances.
22244 ///
22245 /// Note that this constructor is for clients that don't support RTTI
22246 /// and that have a base class of type_base, but of dynamic type
22247 /// class_decl.
22248 ///
22249 /// @param base the base class to consider. Must be a pointer to an
22250 /// instance of class_decl
22251 ///
22252 /// @param a the access specifier of the base class.
22253 ///
22254 /// @param offset_in_bits if positive or null, represents the offset
22255 /// of the base in the layout of its containing type.. If negative,
22256 /// means that the current base is not laid out in its containing type.
22257 ///
22258 /// @param is_virtual if true, means that the current base class is
22259 /// virtual in it's containing type.
base_spec(const type_base_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)22260 class_decl::base_spec::base_spec(const type_base_sptr& base,
22261 access_specifier a,
22262 long offset_in_bits,
22263 bool is_virtual)
22264 : type_or_decl_base(base->get_environment(),
22265 ABSTRACT_DECL_BASE),
22266 decl_base(base->get_environment(), get_type_declaration(base)->get_name(),
22267 get_type_declaration(base)->get_location(),
22268 get_type_declaration(base)->get_linkage_name(),
22269 get_type_declaration(base)->get_visibility()),
22270 member_base(a),
22271 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
22272 offset_in_bits,
22273 is_virtual))
22274 {
22275 runtime_type_instance(this);
22276 }
22277
22278 class_decl::base_spec::~base_spec() = default;
22279
22280 /// Compares two instances of @ref class_decl::base_spec.
22281 ///
22282 /// If the two intances are different, set a bitfield to give some
22283 /// insight about the kind of differences there are.
22284 ///
22285 /// @param l the first artifact of the comparison.
22286 ///
22287 /// @param r the second artifact of the comparison.
22288 ///
22289 /// @param k a pointer to a bitfield that gives information about the
22290 /// kind of changes there are between @p l and @p r. This one is set
22291 /// iff @p k is non-null and the function returns false.
22292 ///
22293 /// Please note that setting k to a non-null value does have a
22294 /// negative performance impact because even if @p l and @p r are not
22295 /// equal, the function keeps up the comparison in order to determine
22296 /// the different kinds of ways in which they are different.
22297 ///
22298 /// @return true if @p l equals @p r, false otherwise.
22299 bool
equals(const class_decl::base_spec & l,const class_decl::base_spec & r,change_kind * k)22300 equals(const class_decl::base_spec& l,
22301 const class_decl::base_spec& r,
22302 change_kind* k)
22303 {
22304 if (!l.member_base::operator==(r))
22305 {
22306 if (k)
22307 *k |= LOCAL_TYPE_CHANGE_KIND;
22308 ABG_RETURN_FALSE;
22309 }
22310
22311 return (*l.get_base_class() == *r.get_base_class());
22312 }
22313
22314 /// Comparison operator for @ref class_decl::base_spec.
22315 ///
22316 /// @param other the instance of @ref class_decl::base_spec to compare
22317 /// against.
22318 ///
22319 /// @return true if the current instance of @ref class_decl::base_spec
22320 /// equals @p other.
22321 bool
operator ==(const decl_base & other) const22322 class_decl::base_spec::operator==(const decl_base& other) const
22323 {
22324 const class_decl::base_spec* o =
22325 dynamic_cast<const class_decl::base_spec*>(&other);
22326
22327 if (!o)
22328 return false;
22329
22330 return equals(*this, *o, 0);
22331 }
22332
22333 /// Comparison operator for @ref class_decl::base_spec.
22334 ///
22335 /// @param other the instance of @ref class_decl::base_spec to compare
22336 /// against.
22337 ///
22338 /// @return true if the current instance of @ref class_decl::base_spec
22339 /// equals @p other.
22340 bool
operator ==(const member_base & other) const22341 class_decl::base_spec::operator==(const member_base& other) const
22342 {
22343 const class_decl::base_spec* o =
22344 dynamic_cast<const class_decl::base_spec*>(&other);
22345 if (!o)
22346 return false;
22347
22348 return operator==(static_cast<const decl_base&>(*o));
22349 }
22350
~mem_fn_context_rel()22351 mem_fn_context_rel::~mem_fn_context_rel()
22352 {
22353 }
22354
22355 /// A constructor for instances of method_decl.
22356 ///
22357 /// @param name the name of the method.
22358 ///
22359 /// @param type the type of the method.
22360 ///
22361 /// @param declared_inline whether the method was
22362 /// declared inline or not.
22363 ///
22364 /// @param locus the source location of the method.
22365 ///
22366 /// @param linkage_name the mangled name of the method.
22367 ///
22368 /// @param vis the visibility of the method.
22369 ///
22370 /// @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)22371 method_decl::method_decl(const string& name,
22372 method_type_sptr type,
22373 bool declared_inline,
22374 const location& locus,
22375 const string& linkage_name,
22376 visibility vis,
22377 binding bind)
22378 : type_or_decl_base(type->get_environment(),
22379 METHOD_DECL
22380 | ABSTRACT_DECL_BASE
22381 |FUNCTION_DECL),
22382 decl_base(type->get_environment(), name, locus, linkage_name, vis),
22383 function_decl(name, static_pointer_cast<function_type>(type),
22384 declared_inline, locus, linkage_name, vis, bind)
22385 {
22386 runtime_type_instance(this);
22387 set_context_rel(new mem_fn_context_rel(0));
22388 set_member_function_is_const(*this, type->get_is_const());
22389 }
22390
22391 /// A constructor for instances of method_decl.
22392 ///
22393 /// @param name the name of the method.
22394 ///
22395 /// @param type the type of the method. Must be an instance of
22396 /// method_type.
22397 ///
22398 /// @param declared_inline whether the method was
22399 /// declared inline or not.
22400 ///
22401 /// @param locus the source location of the method.
22402 ///
22403 /// @param linkage_name the mangled name of the method.
22404 ///
22405 /// @param vis the visibility of the method.
22406 ///
22407 /// @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)22408 method_decl::method_decl(const string& name,
22409 function_type_sptr type,
22410 bool declared_inline,
22411 const location& locus,
22412 const string& linkage_name,
22413 visibility vis,
22414 binding bind)
22415 : type_or_decl_base(type->get_environment(),
22416 METHOD_DECL
22417 | ABSTRACT_DECL_BASE
22418 | FUNCTION_DECL),
22419 decl_base(type->get_environment(), name, locus, linkage_name, vis),
22420 function_decl(name, static_pointer_cast<function_type>
22421 (dynamic_pointer_cast<method_type>(type)),
22422 declared_inline, locus, linkage_name, vis, bind)
22423 {
22424 runtime_type_instance(this);
22425 set_context_rel(new mem_fn_context_rel(0));
22426 }
22427
22428 /// A constructor for instances of method_decl.
22429 ///
22430 /// @param name the name of the method.
22431 ///
22432 /// @param type the type of the method. Must be an instance of
22433 /// method_type.
22434 ///
22435 /// @param declared_inline whether the method was
22436 /// declared inline or not.
22437 ///
22438 /// @param locus the source location of the method.
22439 ///
22440 /// @param linkage_name the mangled name of the method.
22441 ///
22442 /// @param vis the visibility of the method.
22443 ///
22444 /// @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)22445 method_decl::method_decl(const string& name,
22446 type_base_sptr type,
22447 bool declared_inline,
22448 const location& locus,
22449 const string& linkage_name,
22450 visibility vis,
22451 binding bind)
22452 : type_or_decl_base(type->get_environment(),
22453 METHOD_DECL
22454 | ABSTRACT_DECL_BASE
22455 | FUNCTION_DECL),
22456 decl_base(type->get_environment(), name, locus, linkage_name, vis),
22457 function_decl(name, static_pointer_cast<function_type>
22458 (dynamic_pointer_cast<method_type>(type)),
22459 declared_inline, locus, linkage_name, vis, bind)
22460 {
22461 runtime_type_instance(this);
22462 set_context_rel(new mem_fn_context_rel(0));
22463 }
22464
22465 /// Set the linkage name of the method.
22466 ///
22467 /// @param l the new linkage name of the method.
22468 void
set_linkage_name(const string & l)22469 method_decl::set_linkage_name(const string& l)
22470 {
22471 decl_base::set_linkage_name(l);
22472 // Update the linkage_name -> member function map of the containing
22473 // class declaration.
22474 if (!l.empty())
22475 {
22476 method_type_sptr t = get_type();
22477 class_or_union_sptr cl = t->get_class_type();
22478 method_decl_sptr m(this, sptr_utils::noop_deleter());
22479 cl->priv_->mem_fns_map_[l] = m;
22480 }
22481 }
22482
~method_decl()22483 method_decl::~method_decl()
22484 {}
22485
22486 const method_type_sptr
get_type() const22487 method_decl::get_type() const
22488 {
22489 method_type_sptr result;
22490 if (function_decl::get_type())
22491 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
22492 return result;
22493 }
22494
22495 /// Set the containing class of a method_decl.
22496 ///
22497 /// @param scope the new containing class_decl.
22498 void
set_scope(scope_decl * scope)22499 method_decl::set_scope(scope_decl* scope)
22500 {
22501 if (!get_context_rel())
22502 set_context_rel(new mem_fn_context_rel(scope));
22503 else
22504 get_context_rel()->set_scope(scope);
22505 }
22506
22507 /// Equality operator for @ref method_decl_sptr.
22508 ///
22509 /// This is a deep equality operator, as it compares the @ref
22510 /// method_decl that is pointed-to by the smart pointer.
22511 ///
22512 /// @param l the left-hand side argument of the equality operator.
22513 ///
22514 /// @param r the righ-hand side argument of the equality operator.
22515 ///
22516 /// @return true iff @p l equals @p r.
22517 bool
operator ==(const method_decl_sptr & l,const method_decl_sptr & r)22518 operator==(const method_decl_sptr& l, const method_decl_sptr& r)
22519 {
22520 if (l.get() == r.get())
22521 return true;
22522 if (!!l != !!r)
22523 return false;
22524
22525 return *l == *r;
22526 }
22527
22528 /// Inequality operator for @ref method_decl_sptr.
22529 ///
22530 /// This is a deep equality operator, as it compares the @ref
22531 /// method_decl that is pointed-to by the smart pointer.
22532 ///
22533 /// @param l the left-hand side argument of the equality operator.
22534 ///
22535 /// @param r the righ-hand side argument of the equality operator.
22536 ///
22537 /// @return true iff @p l differs from @p r.
22538 bool
operator !=(const method_decl_sptr & l,const method_decl_sptr & r)22539 operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
22540 {return !operator==(l, r);}
22541
22542 /// Test if a function_decl is actually a method_decl.
22543 ///
22544 ///@param d the @ref function_decl to consider.
22545 ///
22546 /// @return the method_decl sub-object of @p d if inherits
22547 /// a method_decl type.
22548 method_decl*
is_method_decl(const type_or_decl_base * d)22549 is_method_decl(const type_or_decl_base *d)
22550 {
22551 return dynamic_cast<method_decl*>
22552 (const_cast<type_or_decl_base*>(d));
22553 }
22554
22555 /// Test if a function_decl is actually a method_decl.
22556 ///
22557 ///@param d the @ref function_decl to consider.
22558 ///
22559 /// @return the method_decl sub-object of @p d if inherits
22560 /// a method_decl type.
22561 method_decl*
is_method_decl(const type_or_decl_base & d)22562 is_method_decl(const type_or_decl_base&d)
22563 {return is_method_decl(&d);}
22564
22565 /// Test if a function_decl is actually a method_decl.
22566 ///
22567 ///@param d the @ref function_decl to consider.
22568 ///
22569 /// @return the method_decl sub-object of @p d if inherits
22570 /// a method_decl type.
22571 method_decl_sptr
is_method_decl(const type_or_decl_base_sptr & d)22572 is_method_decl(const type_or_decl_base_sptr& d)
22573 {return dynamic_pointer_cast<method_decl>(d);}
22574
22575 /// A "less than" functor to sort a vector of instances of
22576 /// method_decl that are virtual.
22577 struct virtual_member_function_less_than
22578 {
22579 /// The less than operator. First, it sorts the methods by their
22580 /// vtable index. If they have the same vtable index, it sorts them
22581 /// by the name of their ELF symbol. If they don't have elf
22582 /// symbols, it sorts them by considering their pretty
22583 /// representation.
22584 ///
22585 /// Note that this method expects virtual methods.
22586 ///
22587 /// @param f the first method to consider.
22588 ///
22589 /// @param s the second method to consider.
22590 ///
22591 /// @return true if method @p is less than method @s.
22592 bool
operator ()abigail::ir::virtual_member_function_less_than22593 operator()(const method_decl& f,
22594 const method_decl& s)
22595 {
22596 ABG_ASSERT(get_member_function_is_virtual(f));
22597 ABG_ASSERT(get_member_function_is_virtual(s));
22598
22599 ssize_t f_offset = get_member_function_vtable_offset(f);
22600 ssize_t s_offset = get_member_function_vtable_offset(s);
22601 if (f_offset != s_offset) return f_offset < s_offset;
22602
22603 string fn, sn;
22604
22605 // If the functions have symbols, then compare their symbol-id
22606 // string.
22607 elf_symbol_sptr f_sym = f.get_symbol();
22608 elf_symbol_sptr s_sym = s.get_symbol();
22609 if ((!f_sym) != (!s_sym)) return !f_sym;
22610 if (f_sym && s_sym)
22611 {
22612 fn = f_sym->get_id_string();
22613 sn = s_sym->get_id_string();
22614 if (fn != sn) return fn < sn;
22615 }
22616
22617 // Try the linkage names (important for destructors).
22618 fn = f.get_linkage_name();
22619 sn = s.get_linkage_name();
22620 if (fn != sn) return fn < sn;
22621
22622 // None of the functions have symbols or linkage names that
22623 // distinguish them, so compare their pretty representation.
22624 fn = f.get_pretty_representation();
22625 sn = s.get_pretty_representation();
22626 if (fn != sn) return fn < sn;
22627
22628 /// If it's just the file paths that are different then sort them
22629 /// too.
22630 string fn_filepath, sn_filepath;
22631 unsigned line = 0, column = 0;
22632 location fn_loc = f.get_location(), sn_loc = s.get_location();
22633 if (fn_loc)
22634 fn_loc.expand(fn_filepath, line, column);
22635 if (sn_loc)
22636 sn_loc.expand(sn_filepath, line, column);
22637 return fn_filepath < sn_filepath;
22638 }
22639
22640 /// The less than operator. First, it sorts the methods by their
22641 /// vtable index. If they have the same vtable index, it sorts them
22642 /// by the name of their ELF symbol. If they don't have elf
22643 /// symbols, it sorts them by considering their pretty
22644 /// representation.
22645 ///
22646 /// Note that this method expects to take virtual methods.
22647 ///
22648 /// @param f the first method to consider.
22649 ///
22650 /// @param s the second method to consider.
22651 bool
operator ()abigail::ir::virtual_member_function_less_than22652 operator()(const method_decl_sptr f,
22653 const method_decl_sptr s)
22654 {return operator()(*f, *s);}
22655 }; // end struct virtual_member_function_less_than
22656
22657 /// Sort a vector of instances of virtual member functions.
22658 ///
22659 /// @param mem_fns the vector of member functions to sort.
22660 static void
sort_virtual_member_functions(class_decl::member_functions & mem_fns)22661 sort_virtual_member_functions(class_decl::member_functions& mem_fns)
22662 {
22663 virtual_member_function_less_than lt;
22664 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
22665 }
22666
22667 /// Add a member function to the current instance of @ref class_or_union.
22668 ///
22669 /// @param f a method_decl to add to the current class. This function
22670 /// should not have been already added to a scope.
22671 ///
22672 /// @param access the access specifier for the member function to add.
22673 ///
22674 /// @param is_virtual if this is true then it means the function @p f
22675 /// is a virtual function. That also means that the current instance
22676 /// of @ref class_or_union is actually an instance of @ref class_decl.
22677 ///
22678 /// @param vtable_offset the offset of the member function in the
22679 /// virtual table. This parameter is taken into account only if @p
22680 /// is_virtual is true.
22681 ///
22682 /// @param is_static whether the member function is static.
22683 ///
22684 /// @param is_ctor whether the member function is a constructor.
22685 ///
22686 /// @param is_dtor whether the member function is a destructor.
22687 ///
22688 /// @param is_const whether the member function is const.
22689 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)22690 class_or_union::add_member_function(method_decl_sptr f,
22691 access_specifier a,
22692 bool is_virtual,
22693 size_t vtable_offset,
22694 bool is_static, bool is_ctor,
22695 bool is_dtor, bool is_const)
22696 {
22697 add_member_function(f, a, is_static, is_ctor,
22698 is_dtor, is_const);
22699
22700 if (class_decl* klass = is_class_type(this))
22701 {
22702 set_member_function_is_virtual(f, is_virtual);
22703 if (is_virtual)
22704 {
22705 set_member_function_vtable_offset(f, vtable_offset);
22706 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
22707 }
22708 }
22709 }
22710
22711 /// When a virtual member function has seen its virtualness set by
22712 /// set_member_function_is_virtual(), this function ensures that the
22713 /// member function is added to the specific vectors and maps of
22714 /// virtual member function of its class.
22715 ///
22716 /// @param method the method to fixup.
22717 void
fixup_virtual_member_function(method_decl_sptr method)22718 fixup_virtual_member_function(method_decl_sptr method)
22719 {
22720 if (!method || !get_member_function_is_virtual(method))
22721 return;
22722
22723 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
22724
22725 class_decl::member_functions::const_iterator m;
22726 for (m = klass->priv_->virtual_mem_fns_.begin();
22727 m != klass->priv_->virtual_mem_fns_.end();
22728 ++m)
22729 if (m->get() == method.get())
22730 break;
22731 if (m == klass->priv_->virtual_mem_fns_.end())
22732 klass->priv_->virtual_mem_fns_.push_back(method);
22733
22734 // Build or udpate the map that associates a vtable offset to the
22735 // number of virtual member functions that "point" to it.
22736 ssize_t voffset = get_member_function_vtable_offset(method);
22737 if (voffset == -1)
22738 return;
22739
22740 class_decl::virtual_mem_fn_map_type::iterator i =
22741 klass->priv_->virtual_mem_fns_map_.find(voffset);
22742 if (i == klass->priv_->virtual_mem_fns_map_.end())
22743 {
22744 class_decl::member_functions virtual_mem_fns_at_voffset;
22745 virtual_mem_fns_at_voffset.push_back(method);
22746 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
22747 }
22748 else
22749 {
22750 for (m = i->second.begin() ; m != i->second.end(); ++m)
22751 if (m->get() == method.get())
22752 break;
22753 if (m == i->second.end())
22754 i->second.push_back(method);
22755 }
22756 }
22757
22758 /// Return true iff the class has no entity in its scope.
22759 bool
has_no_base_nor_member() const22760 class_decl::has_no_base_nor_member() const
22761 {return priv_->bases_.empty() && has_no_member();}
22762
22763 /// Test if the current instance of @ref class_decl has virtual member
22764 /// functions.
22765 ///
22766 /// @return true iff the current instance of @ref class_decl has
22767 /// virtual member functions.
22768 bool
has_virtual_member_functions() const22769 class_decl::has_virtual_member_functions() const
22770 {return !get_virtual_mem_fns().empty();}
22771
22772 /// Test if the current instance of @ref class_decl has at least one
22773 /// virtual base.
22774 ///
22775 /// @return true iff the current instance of @ref class_decl has a
22776 /// virtual member function.
22777 bool
has_virtual_bases() const22778 class_decl::has_virtual_bases() const
22779 {
22780 for (base_specs::const_iterator b = get_base_specifiers().begin();
22781 b != get_base_specifiers().end();
22782 ++b)
22783 if ((*b)->get_is_virtual()
22784 || (*b)->get_base_class()->has_virtual_bases())
22785 return true;
22786
22787 return false;
22788 }
22789
22790 /// Test if the current instance has a vtable.
22791 ///
22792 /// This is only valid for a C++ program.
22793 ///
22794 /// Basically this function checks if the class has either virtual
22795 /// functions, or virtual bases.
22796 bool
has_vtable() const22797 class_decl::has_vtable() const
22798 {
22799 if (has_virtual_member_functions()
22800 || has_virtual_bases())
22801 return true;
22802 return false;
22803 }
22804
22805 /// Get the highest vtable offset of all the virtual methods of the
22806 /// class.
22807 ///
22808 /// @return the highest vtable offset of all the virtual methods of
22809 /// the class.
22810 ssize_t
get_biggest_vtable_offset() const22811 class_decl::get_biggest_vtable_offset() const
22812 {
22813 ssize_t offset = -1;
22814 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
22815 get_virtual_mem_fns_map().begin();
22816 e != get_virtual_mem_fns_map().end();
22817 ++e)
22818 if (e->first > offset)
22819 offset = e->first;
22820
22821 return offset;
22822 }
22823
22824 /// Return the hash value for the current instance.
22825 ///
22826 /// @return the hash value.
22827 size_t
get_hash() const22828 class_decl::get_hash() const
22829 {
22830 class_decl::hash hash_class;
22831 return hash_class(this);
22832 }
22833
22834 /// Test if two methods are equal without taking their symbol or
22835 /// linkage name into account.
22836 ///
22837 /// @param f the first method.
22838 ///
22839 /// @param s the second method.
22840 ///
22841 /// @return true iff @p f equals @p s without taking their linkage
22842 /// name or symbol into account.
22843 static bool
methods_equal_modulo_elf_symbol(const method_decl_sptr & f,const method_decl_sptr & s)22844 methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
22845 const method_decl_sptr& s)
22846 {
22847 method_decl_sptr first = f, second = s;
22848 elf_symbol_sptr saved_first_elf_symbol =
22849 first->get_symbol();
22850 elf_symbol_sptr saved_second_elf_symbol =
22851 second->get_symbol();
22852 interned_string saved_first_linkage_name =
22853 first->get_linkage_name();
22854 interned_string saved_second_linkage_name =
22855 second->get_linkage_name();
22856
22857 first->set_symbol(elf_symbol_sptr());
22858 first->set_linkage_name("");
22859 second->set_symbol(elf_symbol_sptr());
22860 second->set_linkage_name("");
22861
22862 bool equal = *first == *second;
22863
22864 first->set_symbol(saved_first_elf_symbol);
22865 first->set_linkage_name(saved_first_linkage_name);
22866 second->set_symbol(saved_second_elf_symbol);
22867 second->set_linkage_name(saved_second_linkage_name);
22868
22869 return equal;
22870 }
22871
22872 /// Test if a given method is equivalent to at least of other method
22873 /// that is in a vector of methods.
22874 ///
22875 /// Note that "equivalent" here means being equal without taking the
22876 /// linkage name or the symbol of the methods into account.
22877 ///
22878 /// This is a sub-routine of the 'equals' function that compares @ref
22879 /// class_decl.
22880 ///
22881 /// @param method the method to compare.
22882 ///
22883 /// @param fns the vector of functions to compare @p method against.
22884 ///
22885 /// @return true iff @p is equivalent to at least one method in @p
22886 /// fns.
22887 static bool
method_matches_at_least_one_in_vector(const method_decl_sptr & method,const class_decl::member_functions & fns)22888 method_matches_at_least_one_in_vector(const method_decl_sptr& method,
22889 const class_decl::member_functions& fns)
22890 {
22891 for (class_decl::member_functions::const_iterator i = fns.begin();
22892 i != fns.end();
22893 ++i)
22894 // Note that the comparison must be done in this order: method ==
22895 // *i This is to keep the consistency of the comparison. It's
22896 // important especially when doing type canonicalization. The
22897 // already canonicalize type is the left operand, and the type
22898 // being canonicalized is the right operand. This comes from the
22899 // code in type_base::get_canonical_type_for().
22900 if (methods_equal_modulo_elf_symbol(method, *i))
22901 return true;
22902
22903 return false;
22904 }
22905
22906 /// Cancel the canonical type that was propagated.
22907 ///
22908 /// If we are in the process of comparing a type for the purpose of
22909 /// canonicalization, and if that type has been the target of the
22910 /// canonical type propagation optimization, then clear the propagated
22911 /// canonical type. See @ref OnTheFlyCanonicalization for more about
22912 /// the canonical type optimization
22913 ///
22914 /// @param t the type to consider.
22915 static bool
maybe_cancel_propagated_canonical_type(const class_or_union & t)22916 maybe_cancel_propagated_canonical_type(const class_or_union& t)
22917 {
22918 const environment* env = t.get_environment();
22919 if (env && env->do_on_the_fly_canonicalization())
22920 if (is_type(&t)->priv_->canonical_type_propagated())
22921 {
22922 is_type(&t)->priv_->clear_propagated_canonical_type();
22923 env->priv_->remove_from_types_with_non_confirmed_propagated_ct(&t);
22924 return true;
22925 }
22926 return false;
22927 }
22928
22929 /// Compares two instances of @ref class_decl.
22930 ///
22931 /// If the two intances are different, set a bitfield to give some
22932 /// insight about the kind of differences there are.
22933 ///
22934 /// @param l the first artifact of the comparison.
22935 ///
22936 /// @param r the second artifact of the comparison.
22937 ///
22938 /// @param k a pointer to a bitfield that gives information about the
22939 /// kind of changes there are between @p l and @p r. This one is set
22940 /// iff @p k is non-null and the function returns false.
22941 ///
22942 /// Please note that setting k to a non-null value does have a
22943 /// negative performance impact because even if @p l and @p r are not
22944 /// equal, the function keeps up the comparison in order to determine
22945 /// the different kinds of ways in which they are different.
22946 ///
22947 /// @return true if @p l equals @p r, false otherwise.
22948 bool
equals(const class_decl & l,const class_decl & r,change_kind * k)22949 equals(const class_decl& l, const class_decl& r, change_kind* k)
22950 {
22951 // if one of the classes is declaration-only then we take a fast
22952 // path here.
22953 if (l.get_is_declaration_only() || r.get_is_declaration_only())
22954 return equals(static_cast<const class_or_union&>(l),
22955 static_cast<const class_or_union&>(r),
22956 k);
22957
22958 RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(static_cast<const class_or_union&>(l),
22959 static_cast<const class_or_union&>(r));
22960
22961 bool result = true;
22962 if (!equals(static_cast<const class_or_union&>(l),
22963 static_cast<const class_or_union&>(r),
22964 k))
22965 {
22966 result = false;
22967 if (!k)
22968 return result;
22969 }
22970
22971 mark_types_as_being_compared(static_cast<const class_or_union&>(l),
22972 static_cast<const class_or_union&>(r));
22973
22974 #define RETURN(value) \
22975 return return_comparison_result(static_cast<const class_or_union&>(l), \
22976 static_cast<const class_or_union&>(r), \
22977 value);
22978
22979 // If comparing the class_or_union 'part' of the type led to
22980 // canonical type propagation, then cancel that because it's too
22981 // early to do that at this point. We still need to compare bases
22982 // virtual members.
22983 maybe_cancel_propagated_canonical_type(r);
22984
22985 // Compare bases.
22986 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
22987 {
22988 result = false;
22989 if (k)
22990 *k |= LOCAL_TYPE_CHANGE_KIND;
22991 else
22992 RETURN(result);
22993 }
22994
22995 for (class_decl::base_specs::const_iterator
22996 b0 = l.get_base_specifiers().begin(),
22997 b1 = r.get_base_specifiers().begin();
22998 (b0 != l.get_base_specifiers().end()
22999 && b1 != r.get_base_specifiers().end());
23000 ++b0, ++b1)
23001 if (*b0 != *b1)
23002 {
23003 result = false;
23004 if (k)
23005 {
23006 if (!types_have_similar_structure((*b0)->get_base_class().get(),
23007 (*b1)->get_base_class().get()))
23008 *k |= LOCAL_TYPE_CHANGE_KIND;
23009 else
23010 *k |= SUBTYPE_CHANGE_KIND;
23011 break;
23012 }
23013 RETURN(result);
23014 }
23015
23016 // Compare virtual member functions
23017
23018 // We look at the map that associates a given vtable offset to a
23019 // vector of virtual member functions that point to that offset.
23020 //
23021 // This is because there are cases where several functions can
23022 // point to the same virtual table offset.
23023 //
23024 // This is usually the case for virtual destructors. Even though
23025 // there can be only one virtual destructor declared in source
23026 // code, there are actually potentially up to three generated
23027 // functions for that destructor. Some of these generated
23028 // functions can be clones of other functions that are among those
23029 // generated ones. In any cases, they all have the same
23030 // properties, including the vtable offset property.
23031
23032 // So, there should be the same number of different vtable
23033 // offsets, the size of two maps must be equals.
23034 if (l.get_virtual_mem_fns_map().size()
23035 != r.get_virtual_mem_fns_map().size())
23036 {
23037 result = false;
23038 if (k)
23039 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23040 else
23041 RETURN(result);
23042 }
23043
23044 // Then, each virtual member function of a given vtable offset in
23045 // the first class type, must match an equivalent virtual member
23046 // function of a the same vtable offset in the second class type.
23047 //
23048 // By "match", I mean that the two virtual member function should
23049 // be equal if we don't take into account their symbol name or
23050 // their linkage name. This is because two destructor functions
23051 // clones (for instance) might have different linkage name, but
23052 // are still equivalent if their other properties are the same.
23053 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
23054 l.get_virtual_mem_fns_map().begin();
23055 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
23056 ++first_v_fn_entry)
23057 {
23058 unsigned voffset = first_v_fn_entry->first;
23059 const class_decl::member_functions& first_vfns =
23060 first_v_fn_entry->second;
23061
23062 const class_decl::virtual_mem_fn_map_type::const_iterator
23063 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
23064
23065 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
23066 {
23067 result = false;
23068 if (k)
23069 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
23070 RETURN(result);
23071 }
23072
23073 const class_decl::member_functions& second_vfns =
23074 second_v_fn_entry->second;
23075
23076 bool matches = false;
23077 for (class_decl::member_functions::const_iterator i =
23078 first_vfns.begin();
23079 i != first_vfns.end();
23080 ++i)
23081 if (method_matches_at_least_one_in_vector(*i, second_vfns))
23082 {
23083 matches = true;
23084 break;
23085 }
23086
23087 if (!matches)
23088 {
23089 result = false;
23090 if (k)
23091 *k |= SUBTYPE_CHANGE_KIND;
23092 else
23093 RETURN(result);
23094 }
23095 }
23096
23097 RETURN(result);
23098 #undef RETURN
23099 }
23100
23101 /// Copy a method of a class into a new class.
23102 ///
23103 /// @param klass the class into which the method is to be copied.
23104 ///
23105 /// @param method the method to copy into @p klass.
23106 ///
23107 /// @return the resulting newly copied method.
23108 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl_sptr & f)23109 copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
23110 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
23111
23112 /// Copy a method of a class into a new class.
23113 ///
23114 /// @param klass the class into which the method is to be copied.
23115 ///
23116 /// @param method the method to copy into @p klass.
23117 ///
23118 /// @return the resulting newly copied method.
23119 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl * f)23120 copy_member_function(const class_decl_sptr& clazz, const method_decl* f)
23121 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
23122
23123 /// Comparison operator for @ref class_decl.
23124 ///
23125 /// @param other the instance of @ref class_decl to compare against.
23126 ///
23127 /// @return true iff the current instance of @ref class_decl equals @p
23128 /// other.
23129 bool
operator ==(const decl_base & other) const23130 class_decl::operator==(const decl_base& other) const
23131 {
23132 const class_decl* op = is_class_type(&other);
23133 if (!op)
23134 return false;
23135
23136 // If this is a decl-only type (and thus with no canonical type),
23137 // use the canonical type of the definition, if any.
23138 const class_decl *l = 0;
23139 if (get_is_declaration_only())
23140 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
23141 if (l == 0)
23142 l = this;
23143
23144 ABG_ASSERT(l);
23145
23146 // Likewise for the other type.
23147 const class_decl *r = 0;
23148 if (op->get_is_declaration_only())
23149 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
23150 if (r == 0)
23151 r = op;
23152
23153 ABG_ASSERT(r);
23154
23155 return try_canonical_compare(l, r);
23156 }
23157
23158 /// Equality operator for class_decl.
23159 ///
23160 /// Re-uses the equality operator that takes a decl_base.
23161 ///
23162 /// @param other the other class_decl to compare against.
23163 ///
23164 /// @return true iff the current instance equals the other one.
23165 bool
operator ==(const type_base & other) const23166 class_decl::operator==(const type_base& other) const
23167 {
23168 const decl_base* o = is_decl(&other);
23169 if (!o)
23170 return false;
23171 return *this == *o;
23172 }
23173
23174 /// Comparison operator for @ref class_decl.
23175 ///
23176 /// @param other the instance of @ref class_decl to compare against.
23177 ///
23178 /// @return true iff the current instance of @ref class_decl equals @p
23179 /// other.
23180 bool
operator ==(const class_decl & other) const23181 class_decl::operator==(const class_decl& other) const
23182 {
23183 const decl_base& o = other;
23184 return *this == o;
23185 }
23186
23187 /// Turn equality of shared_ptr of class_decl into a deep equality;
23188 /// that is, make it compare the pointed to objects too.
23189 ///
23190 /// @param l the shared_ptr of class_decl on left-hand-side of the
23191 /// equality.
23192 ///
23193 /// @param r the shared_ptr of class_decl on right-hand-side of the
23194 /// equality.
23195 ///
23196 /// @return true if the class_decl pointed to by the shared_ptrs are
23197 /// equal, false otherwise.
23198 bool
operator ==(const class_decl_sptr & l,const class_decl_sptr & r)23199 operator==(const class_decl_sptr& l, const class_decl_sptr& r)
23200 {
23201 if (l.get() == r.get())
23202 return true;
23203 if (!!l != !!r)
23204 return false;
23205
23206 return *l == *r;
23207 }
23208
23209 /// Turn inequality of shared_ptr of class_decl into a deep equality;
23210 /// that is, make it compare the pointed to objects too.
23211 ///
23212 /// @param l the shared_ptr of class_decl on left-hand-side of the
23213 /// equality.
23214 ///
23215 /// @param r the shared_ptr of class_decl on right-hand-side of the
23216 /// equality.
23217 ///
23218 /// @return true if the class_decl pointed to by the shared_ptrs are
23219 /// different, false otherwise.
23220 bool
operator !=(const class_decl_sptr & l,const class_decl_sptr & r)23221 operator!=(const class_decl_sptr& l, const class_decl_sptr& r)
23222 {return !operator==(l, r);}
23223
23224 /// Turn equality of shared_ptr of class_or_union into a deep
23225 /// equality; that is, make it compare the pointed to objects too.
23226 ///
23227 /// @param l the left-hand-side operand of the operator
23228 ///
23229 /// @param r the right-hand-side operand of the operator.
23230 ///
23231 /// @return true iff @p l equals @p r.
23232 bool
operator ==(const class_or_union_sptr & l,const class_or_union_sptr & r)23233 operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
23234 {
23235 if (l.get() == r.get())
23236 return true;
23237 if (!!l != !!r)
23238 return false;
23239
23240 return *l == *r;
23241 }
23242
23243 /// Turn inequality of shared_ptr of class_or_union into a deep
23244 /// equality; that is, make it compare the pointed to objects too.
23245 ///
23246 /// @param l the left-hand-side operand of the operator
23247 ///
23248 /// @param r the right-hand-side operand of the operator.
23249 ///
23250 /// @return true iff @p l is different from @p r.
23251 bool
operator !=(const class_or_union_sptr & l,const class_or_union_sptr & r)23252 operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
23253 {return !operator==(l, r);}
23254
23255 /// This implements the ir_traversable_base::traverse pure virtual
23256 /// function.
23257 ///
23258 /// @param v the visitor used on the current instance and on its
23259 /// members.
23260 ///
23261 /// @return true if the entire IR node tree got traversed, false
23262 /// otherwise.
23263 bool
traverse(ir_node_visitor & v)23264 class_decl::traverse(ir_node_visitor& v)
23265 {
23266 if (v.type_node_has_been_visited(this))
23267 return true;
23268
23269 if (visiting())
23270 return true;
23271
23272 if (v.visit_begin(this))
23273 {
23274 visiting(true);
23275 bool stop = false;
23276
23277 for (base_specs::const_iterator i = get_base_specifiers().begin();
23278 i != get_base_specifiers().end();
23279 ++i)
23280 {
23281 if (!(*i)->traverse(v))
23282 {
23283 stop = true;
23284 break;
23285 }
23286 }
23287
23288 if (!stop)
23289 for (data_members::const_iterator i = get_data_members().begin();
23290 i != get_data_members().end();
23291 ++i)
23292 if (!(*i)->traverse(v))
23293 {
23294 stop = true;
23295 break;
23296 }
23297
23298 if (!stop)
23299 for (member_functions::const_iterator i= get_member_functions().begin();
23300 i != get_member_functions().end();
23301 ++i)
23302 if (!(*i)->traverse(v))
23303 {
23304 stop = true;
23305 break;
23306 }
23307
23308 if (!stop)
23309 for (member_types::const_iterator i = get_member_types().begin();
23310 i != get_member_types().end();
23311 ++i)
23312 if (!(*i)->traverse(v))
23313 {
23314 stop = true;
23315 break;
23316 }
23317
23318 if (!stop)
23319 for (member_function_templates::const_iterator i =
23320 get_member_function_templates().begin();
23321 i != get_member_function_templates().end();
23322 ++i)
23323 if (!(*i)->traverse(v))
23324 {
23325 stop = true;
23326 break;
23327 }
23328
23329 if (!stop)
23330 for (member_class_templates::const_iterator i =
23331 get_member_class_templates().begin();
23332 i != get_member_class_templates().end();
23333 ++i)
23334 if (!(*i)->traverse(v))
23335 {
23336 stop = true;
23337 break;
23338 }
23339 visiting(false);
23340 }
23341
23342 bool result = v.visit_end(this);
23343 v.mark_type_node_as_visited(this);
23344 return result;
23345 }
23346
23347 /// Destructor of the @ref class_decl type.
~class_decl()23348 class_decl::~class_decl()
23349 {delete priv_;}
23350
~context_rel()23351 context_rel::~context_rel()
23352 {}
23353
23354 bool
operator ==(const member_base & o) const23355 member_base::operator==(const member_base& o) const
23356 {
23357 return (get_access_specifier() == o.get_access_specifier()
23358 && get_is_static() == o.get_is_static());
23359 }
23360
23361 /// Equality operator for smart pointers to @ref
23362 /// class_decl::base_specs.
23363 ///
23364 /// This compares the pointed-to objects.
23365 ///
23366 /// @param l the first instance to consider.
23367 ///
23368 /// @param r the second instance to consider.
23369 ///
23370 /// @return true iff @p l equals @p r.
23371 bool
operator ==(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)23372 operator==(const class_decl::base_spec_sptr& l,
23373 const class_decl::base_spec_sptr& r)
23374 {
23375 if (l.get() == r.get())
23376 return true;
23377 if (!!l != !!r)
23378 return false;
23379
23380 return *l == static_cast<const decl_base&>(*r);
23381 }
23382
23383 /// Inequality operator for smart pointers to @ref
23384 /// class_decl::base_specs.
23385 ///
23386 /// This compares the pointed-to objects.
23387 ///
23388 /// @param l the first instance to consider.
23389 ///
23390 /// @param r the second instance to consider.
23391 ///
23392 /// @return true iff @p l is different from @p r.
23393 bool
operator !=(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)23394 operator!=(const class_decl::base_spec_sptr& l,
23395 const class_decl::base_spec_sptr& r)
23396 {return !operator==(l, r);}
23397
23398 /// Test if an ABI artifact is a class base specifier.
23399 ///
23400 /// @param tod the ABI artifact to consider.
23401 ///
23402 /// @return a pointer to the @ref class_decl::base_spec sub-object of
23403 /// @p tod iff it's a class base specifier.
23404 class_decl::base_spec*
is_class_base_spec(const type_or_decl_base * tod)23405 is_class_base_spec(const type_or_decl_base* tod)
23406 {
23407 return dynamic_cast<class_decl::base_spec*>
23408 (const_cast<type_or_decl_base*>(tod));
23409 }
23410
23411 /// Test if an ABI artifact is a class base specifier.
23412 ///
23413 /// @param tod the ABI artifact to consider.
23414 ///
23415 /// @return a pointer to the @ref class_decl::base_spec sub-object of
23416 /// @p tod iff it's a class base specifier.
23417 class_decl::base_spec_sptr
is_class_base_spec(type_or_decl_base_sptr tod)23418 is_class_base_spec(type_or_decl_base_sptr tod)
23419 {return dynamic_pointer_cast<class_decl::base_spec>(tod);}
23420
23421 bool
operator ==(const member_base & other) const23422 member_function_template::operator==(const member_base& other) const
23423 {
23424 try
23425 {
23426 const member_function_template& o =
23427 dynamic_cast<const member_function_template&>(other);
23428
23429 if (!(is_constructor() == o.is_constructor()
23430 && is_const() == o.is_const()
23431 && member_base::operator==(o)))
23432 return false;
23433
23434 if (function_tdecl_sptr ftdecl = as_function_tdecl())
23435 {
23436 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
23437 if (other_ftdecl)
23438 return ftdecl->function_tdecl::operator==(*other_ftdecl);
23439 }
23440 }
23441 catch(...)
23442 {}
23443 return false;
23444 }
23445
23446 /// Equality operator for smart pointers to @ref
23447 /// member_function_template. This is compares the
23448 /// pointed-to instances.
23449 ///
23450 /// @param l the first instance to consider.
23451 ///
23452 /// @param r the second instance to consider.
23453 ///
23454 /// @return true iff @p l equals @p r.
23455 bool
operator ==(const member_function_template_sptr & l,const member_function_template_sptr & r)23456 operator==(const member_function_template_sptr& l,
23457 const member_function_template_sptr& r)
23458 {
23459 if (l.get() == r.get())
23460 return true;
23461 if (!!l != !!r)
23462 return false;
23463
23464 return *l == *r;
23465 }
23466
23467 /// Inequality operator for smart pointers to @ref
23468 /// member_function_template. This is compares the pointed-to
23469 /// instances.
23470 ///
23471 /// @param l the first instance to consider.
23472 ///
23473 /// @param r the second instance to consider.
23474 ///
23475 /// @return true iff @p l equals @p r.
23476 bool
operator !=(const member_function_template_sptr & l,const member_function_template_sptr & r)23477 operator!=(const member_function_template_sptr& l,
23478 const member_function_template_sptr& r)
23479 {return !operator==(l, r);}
23480
23481 /// This implements the ir_traversable_base::traverse pure virtual
23482 /// function.
23483 ///
23484 /// @param v the visitor used on the current instance and on its
23485 /// underlying function template.
23486 ///
23487 /// @return true if the entire IR node tree got traversed, false
23488 /// otherwise.
23489 bool
traverse(ir_node_visitor & v)23490 member_function_template::traverse(ir_node_visitor& v)
23491 {
23492 if (visiting())
23493 return true;
23494
23495 if (v.visit_begin(this))
23496 {
23497 visiting(true);
23498 if (function_tdecl_sptr f = as_function_tdecl())
23499 f->traverse(v);
23500 visiting(false);
23501 }
23502 return v.visit_end(this);
23503 }
23504
23505 /// Equality operator of the the @ref member_class_template class.
23506 ///
23507 /// @param other the other @ref member_class_template to compare against.
23508 ///
23509 /// @return true iff the current instance equals @p other.
23510 bool
operator ==(const member_base & other) const23511 member_class_template::operator==(const member_base& other) const
23512 {
23513 try
23514 {
23515 const member_class_template& o =
23516 dynamic_cast<const member_class_template&>(other);
23517
23518 if (!member_base::operator==(o))
23519 return false;
23520
23521 return as_class_tdecl()->class_tdecl::operator==(o);
23522 }
23523 catch(...)
23524 {return false;}
23525 }
23526
23527 /// Comparison operator for the @ref member_class_template
23528 /// type.
23529 ///
23530 /// @param other the other instance of @ref
23531 /// member_class_template to compare against.
23532 ///
23533 /// @return true iff the two instances are equal.
23534 bool
operator ==(const member_class_template & other) const23535 member_class_template::operator==(const member_class_template& other) const
23536 {
23537 const decl_base* o = dynamic_cast<const decl_base*>(&other);
23538 return *this == *o;
23539 }
23540
23541 /// Comparison operator for the @ref member_class_template
23542 /// type.
23543 ///
23544 /// @param l the first argument of the operator.
23545 ///
23546 /// @param r the second argument of the operator.
23547 ///
23548 /// @return true iff the two instances are equal.
23549 bool
operator ==(const member_class_template_sptr & l,const member_class_template_sptr & r)23550 operator==(const member_class_template_sptr& l,
23551 const member_class_template_sptr& r)
23552 {
23553 if (l.get() == r.get())
23554 return true;
23555 if (!!l != !!r)
23556 return false;
23557
23558 return *l == *r;
23559 }
23560
23561 /// Inequality operator for the @ref member_class_template
23562 /// type.
23563 ///
23564 /// @param l the first argument of the operator.
23565 ///
23566 /// @param r the second argument of the operator.
23567 ///
23568 /// @return true iff the two instances are equal.
23569 bool
operator !=(const member_class_template_sptr & l,const member_class_template_sptr & r)23570 operator!=(const member_class_template_sptr& l,
23571 const member_class_template_sptr& r)
23572 {return !operator==(l, r);}
23573
23574 /// This implements the ir_traversable_base::traverse pure virtual
23575 /// function.
23576 ///
23577 /// @param v the visitor used on the current instance and on the class
23578 /// pattern of the template.
23579 ///
23580 /// @return true if the entire IR node tree got traversed, false
23581 /// otherwise.
23582 bool
traverse(ir_node_visitor & v)23583 member_class_template::traverse(ir_node_visitor& v)
23584 {
23585 if (visiting())
23586 return true;
23587
23588 if (v.visit_begin(this))
23589 {
23590 visiting(true);
23591 if (class_tdecl_sptr t = as_class_tdecl())
23592 t->traverse(v);
23593 visiting(false);
23594 }
23595 return v.visit_end(this);
23596 }
23597
23598 /// Streaming operator for class_decl::access_specifier.
23599 ///
23600 /// @param o the output stream to serialize the access specifier to.
23601 ///
23602 /// @param a the access specifier to serialize.
23603 ///
23604 /// @return the output stream.
23605 std::ostream&
operator <<(std::ostream & o,access_specifier a)23606 operator<<(std::ostream& o, access_specifier a)
23607 {
23608 string r;
23609
23610 switch (a)
23611 {
23612 case no_access:
23613 r = "none";
23614 break;
23615 case private_access:
23616 r = "private";
23617 break;
23618 case protected_access:
23619 r = "protected";
23620 break;
23621 case public_access:
23622 r= "public";
23623 break;
23624 };
23625 o << r;
23626 return o;
23627 }
23628
23629 /// Sets the static-ness property of a class member.
23630 ///
23631 /// @param d the class member to set the static-ness property for.
23632 /// Note that this must be a class member otherwise the function
23633 /// aborts the current process.
23634 ///
23635 /// @param s this must be true if the member is to be static, false
23636 /// otherwise.
23637 void
set_member_is_static(decl_base & d,bool s)23638 set_member_is_static(decl_base& d, bool s)
23639 {
23640 ABG_ASSERT(is_member_decl(d));
23641
23642 context_rel* c = d.get_context_rel();
23643 ABG_ASSERT(c);
23644
23645 c->set_is_static(s);
23646
23647 scope_decl* scope = d.get_scope();
23648
23649 if (class_or_union* cl = is_class_or_union_type(scope))
23650 {
23651 if (var_decl* v = is_var_decl(&d))
23652 {
23653 if (s)
23654 // remove from the non-static data members
23655 for (class_decl::data_members::iterator i =
23656 cl->priv_->non_static_data_members_.begin();
23657 i != cl->priv_->non_static_data_members_.end();
23658 ++i)
23659 {
23660 if ((*i)->get_name() == v->get_name())
23661 {
23662 cl->priv_->non_static_data_members_.erase(i);
23663 break;
23664 }
23665 }
23666 else
23667 {
23668 bool is_already_in_non_static_data_members = false;
23669 for (class_or_union::data_members::iterator i =
23670 cl->priv_->non_static_data_members_.begin();
23671 i != cl->priv_->non_static_data_members_.end();
23672 ++i)
23673 {
23674 if ((*i)->get_name() == v->get_name())
23675 {
23676 is_already_in_non_static_data_members = true;
23677 break;
23678 }
23679 }
23680 if (!is_already_in_non_static_data_members)
23681 {
23682 var_decl_sptr var;
23683 // add to non-static data members.
23684 for (class_or_union::data_members::const_iterator i =
23685 cl->priv_->data_members_.begin();
23686 i != cl->priv_->data_members_.end();
23687 ++i)
23688 {
23689 if ((*i)->get_name() == v->get_name())
23690 {
23691 var = *i;
23692 break;
23693 }
23694 }
23695 ABG_ASSERT(var);
23696 cl->priv_->non_static_data_members_.push_back(var);
23697 }
23698 }
23699 }
23700 }
23701 }
23702
23703 /// Sets the static-ness property of a class member.
23704 ///
23705 /// @param d the class member to set the static-ness property for.
23706 /// Note that this must be a class member otherwise the function
23707 /// aborts the current process.
23708 ///
23709 /// @param s this must be true if the member is to be static, false
23710 /// otherwise.
23711 void
set_member_is_static(const decl_base_sptr & d,bool s)23712 set_member_is_static(const decl_base_sptr& d, bool s)
23713 {set_member_is_static(*d, s);}
23714
23715 // </class_decl>
23716
23717 // <union_decl>
23718
23719 /// Constructor for the @ref union_decl type.
23720 ///
23721 /// @param env the @ref environment we are operating from.
23722 ///
23723 /// @param name the name of the union type.
23724 ///
23725 /// @param size_in_bits the size of the union, in bits.
23726 ///
23727 /// @param locus the location of the type.
23728 ///
23729 /// @param vis the visibility of instances of @ref union_decl.
23730 ///
23731 /// @param mbr_types the member types of the union.
23732 ///
23733 /// @param data_mbrs the data members of the union.
23734 ///
23735 /// @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)23736 union_decl::union_decl(const environment* env, const string& name,
23737 size_t size_in_bits, const location& locus,
23738 visibility vis, member_types& mbr_types,
23739 data_members& data_mbrs, member_functions& member_fns)
23740 : type_or_decl_base(env,
23741 UNION_TYPE
23742 | ABSTRACT_TYPE_BASE
23743 | ABSTRACT_DECL_BASE),
23744 decl_base(env, name, locus, name, vis),
23745 type_base(env, size_in_bits, 0),
23746 class_or_union(env, name, size_in_bits, 0,
23747 locus, vis, mbr_types, data_mbrs, member_fns)
23748 {
23749 runtime_type_instance(this);
23750 }
23751
23752 /// Constructor for the @ref union_decl type.
23753 ///
23754 /// @param env the @ref environment we are operating from.
23755 ///
23756 /// @param name the name of the union type.
23757 ///
23758 /// @param size_in_bits the size of the union, in bits.
23759 ///
23760 /// @param locus the location of the type.
23761 ///
23762 /// @param vis the visibility of instances of @ref union_decl.
23763 ///
23764 /// @param mbr_types the member types of the union.
23765 ///
23766 /// @param data_mbrs the data members of the union.
23767 ///
23768 /// @param member_fns the member functions of the union.
23769 ///
23770 /// @param is_anonymous whether the newly created instance is
23771 /// 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)23772 union_decl::union_decl(const environment* env, const string& name,
23773 size_t size_in_bits, const location& locus,
23774 visibility vis, member_types& mbr_types,
23775 data_members& data_mbrs, member_functions& member_fns,
23776 bool is_anonymous)
23777 : type_or_decl_base(env,
23778 UNION_TYPE
23779 | ABSTRACT_TYPE_BASE
23780 | ABSTRACT_DECL_BASE),
23781 decl_base(env, name, locus,
23782 // If the class is anonymous then by default it won't
23783 // have a linkage name. Also, the anonymous class does
23784 // have an internal-only unique name that is generally
23785 // not taken into account when comparing classes; such a
23786 // unique internal-only name, when used as a linkage
23787 // name might introduce spurious comparison false
23788 // negatives.
23789 /*linkage_name=*/is_anonymous ? string() : name,
23790 vis),
23791 type_base(env, size_in_bits, 0),
23792 class_or_union(env, name, size_in_bits, 0,
23793 locus, vis, mbr_types, data_mbrs, member_fns)
23794 {
23795 runtime_type_instance(this);
23796 set_is_anonymous(is_anonymous);
23797 }
23798
23799 /// Constructor for the @ref union_decl type.
23800 ///
23801 /// @param env the @ref environment we are operating from.
23802 ///
23803 /// @param name the name of the union type.
23804 ///
23805 /// @param size_in_bits the size of the union, in bits.
23806 ///
23807 /// @param locus the location of the type.
23808 ///
23809 /// @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)23810 union_decl::union_decl(const environment* env, const string& name,
23811 size_t size_in_bits, const location& locus,
23812 visibility vis)
23813 : type_or_decl_base(env,
23814 UNION_TYPE
23815 | ABSTRACT_TYPE_BASE
23816 | ABSTRACT_DECL_BASE
23817 | ABSTRACT_SCOPE_TYPE_DECL
23818 | ABSTRACT_SCOPE_DECL),
23819 decl_base(env, name, locus, name, vis),
23820 type_base(env, size_in_bits, 0),
23821 class_or_union(env, name, size_in_bits,
23822 0, locus, vis)
23823 {
23824 runtime_type_instance(this);
23825 }
23826
23827 /// Constructor for the @ref union_decl type.
23828 ///
23829 /// @param env the @ref environment we are operating from.
23830 ///
23831 /// @param name the name of the union type.
23832 ///
23833 /// @param size_in_bits the size of the union, in bits.
23834 ///
23835 /// @param locus the location of the type.
23836 ///
23837 /// @param vis the visibility of instances of @ref union_decl.
23838 ///
23839 /// @param is_anonymous whether the newly created instance is
23840 /// anonymous.
union_decl(const environment * env,const string & name,size_t size_in_bits,const location & locus,visibility vis,bool is_anonymous)23841 union_decl::union_decl(const environment* env, const string& name,
23842 size_t size_in_bits, const location& locus,
23843 visibility vis, bool is_anonymous)
23844 : type_or_decl_base(env,
23845 UNION_TYPE
23846 | ABSTRACT_TYPE_BASE
23847 | ABSTRACT_DECL_BASE
23848 | ABSTRACT_SCOPE_TYPE_DECL
23849 | ABSTRACT_SCOPE_DECL),
23850 decl_base(env, name, locus,
23851 // If the class is anonymous then by default it won't
23852 // have a linkage name. Also, the anonymous class does
23853 // have an internal-only unique name that is generally
23854 // not taken into account when comparing classes; such a
23855 // unique internal-only name, when used as a linkage
23856 // name might introduce spurious comparison false
23857 // negatives.
23858 /*linkage_name=*/is_anonymous ? string() : name,
23859 vis),
23860 type_base(env, size_in_bits, 0),
23861 class_or_union(env, name, size_in_bits,
23862 0, locus, vis)
23863 {
23864 runtime_type_instance(this);
23865 set_is_anonymous(is_anonymous);
23866 }
23867
23868 /// Constructor for the @ref union_decl type.
23869 ///
23870 /// @param env the @ref environment we are operating from.
23871 ///
23872 /// @param name the name of the union type.
23873 ///
23874 /// @param is_declaration_only a boolean saying whether the instance
23875 /// represents a declaration only, or not.
union_decl(const environment * env,const string & name,bool is_declaration_only)23876 union_decl::union_decl(const environment* env,
23877 const string& name,
23878 bool is_declaration_only)
23879 : type_or_decl_base(env,
23880 UNION_TYPE
23881 | ABSTRACT_TYPE_BASE
23882 | ABSTRACT_DECL_BASE
23883 | ABSTRACT_SCOPE_TYPE_DECL
23884 | ABSTRACT_SCOPE_DECL),
23885 decl_base(env, name, location(), name),
23886 type_base(env, 0, 0),
23887 class_or_union(env, name, is_declaration_only)
23888 {
23889 runtime_type_instance(this);
23890 }
23891
23892 /// Getter of the pretty representation of the current instance of
23893 /// @ref union_decl.
23894 ///
23895 /// @param internal set to true if the call is intended to get a
23896 /// representation of the decl (or type) for the purpose of canonical
23897 /// type comparison. This is mainly used in the function
23898 /// type_base::get_canonical_type_for().
23899 ///
23900 /// In other words if the argument for this parameter is true then the
23901 /// call is meant for internal use (for technical use inside the
23902 /// library itself), false otherwise. If you don't know what this is
23903 /// for, then set it to false.
23904 ///
23905 /// @param qualified_name if true, names emitted in the pretty
23906 /// representation are fully qualified.
23907 ///
23908 /// @return the pretty representaion for a union_decl.
23909 string
get_pretty_representation(bool internal,bool qualified_name) const23910 union_decl::get_pretty_representation(bool internal,
23911 bool qualified_name) const
23912 {
23913 string repr;
23914 if (get_is_anonymous())
23915 {
23916 if (internal)
23917 repr = string("union ") +
23918 get_type_name(this, qualified_name, /*internal=*/true);
23919 else
23920 repr = get_class_or_union_flat_representation(this, "",
23921 /*one_line=*/true,
23922 internal);
23923 }
23924 else
23925 {
23926 repr = "union ";
23927 if (qualified_name)
23928 repr += get_qualified_name(internal);
23929 else
23930 repr += get_name();
23931 }
23932
23933 return repr;
23934 }
23935
23936 /// Comparison operator for @ref union_decl.
23937 ///
23938 /// @param other the instance of @ref union_decl to compare against.
23939 ///
23940 /// @return true iff the current instance of @ref union_decl equals @p
23941 /// other.
23942 bool
operator ==(const decl_base & other) const23943 union_decl::operator==(const decl_base& other) const
23944 {
23945 const union_decl* op = dynamic_cast<const union_decl*>(&other);
23946 if (!op)
23947 return false;
23948 return try_canonical_compare(this, op);
23949 }
23950
23951 /// Equality operator for union_decl.
23952 ///
23953 /// Re-uses the equality operator that takes a decl_base.
23954 ///
23955 /// @param other the other union_decl to compare against.
23956 ///
23957 /// @return true iff the current instance equals the other one.
23958 bool
operator ==(const type_base & other) const23959 union_decl::operator==(const type_base& other) const
23960 {
23961 const decl_base *o = dynamic_cast<const decl_base*>(&other);
23962 if (!o)
23963 return false;
23964 return *this == *o;
23965 }
23966
23967 /// Comparison operator for @ref union_decl.
23968 ///
23969 /// @param other the instance of @ref union_decl to compare against.
23970 ///
23971 /// @return true iff the current instance of @ref union_decl equals @p
23972 /// other.
23973 bool
operator ==(const union_decl & other) const23974 union_decl::operator==(const union_decl& other) const
23975 {
23976 const decl_base& o = other;
23977 return *this == o;
23978 }
23979
23980 /// This implements the ir_traversable_base::traverse pure virtual
23981 /// function.
23982 ///
23983 /// @param v the visitor used on the current instance and on its
23984 /// members.
23985 ///
23986 /// @return true if the entire IR node tree got traversed, false
23987 /// otherwise.
23988 bool
traverse(ir_node_visitor & v)23989 union_decl::traverse(ir_node_visitor& v)
23990 {
23991 if (v.type_node_has_been_visited(this))
23992 return true;
23993
23994 if (visiting())
23995 return true;
23996
23997 if (v.visit_begin(this))
23998 {
23999 visiting(true);
24000 bool stop = false;
24001
24002 if (!stop)
24003 for (data_members::const_iterator i = get_data_members().begin();
24004 i != get_data_members().end();
24005 ++i)
24006 if (!(*i)->traverse(v))
24007 {
24008 stop = true;
24009 break;
24010 }
24011
24012 if (!stop)
24013 for (member_functions::const_iterator i= get_member_functions().begin();
24014 i != get_member_functions().end();
24015 ++i)
24016 if (!(*i)->traverse(v))
24017 {
24018 stop = true;
24019 break;
24020 }
24021
24022 if (!stop)
24023 for (member_types::const_iterator i = get_member_types().begin();
24024 i != get_member_types().end();
24025 ++i)
24026 if (!(*i)->traverse(v))
24027 {
24028 stop = true;
24029 break;
24030 }
24031
24032 if (!stop)
24033 for (member_function_templates::const_iterator i =
24034 get_member_function_templates().begin();
24035 i != get_member_function_templates().end();
24036 ++i)
24037 if (!(*i)->traverse(v))
24038 {
24039 stop = true;
24040 break;
24041 }
24042
24043 if (!stop)
24044 for (member_class_templates::const_iterator i =
24045 get_member_class_templates().begin();
24046 i != get_member_class_templates().end();
24047 ++i)
24048 if (!(*i)->traverse(v))
24049 {
24050 stop = true;
24051 break;
24052 }
24053 visiting(false);
24054 }
24055
24056 bool result = v.visit_end(this);
24057 v.mark_type_node_as_visited(this);
24058 return result;
24059 }
24060
24061 /// Destructor of the @ref union_decl type.
~union_decl()24062 union_decl::~union_decl()
24063 {}
24064
24065 /// Compares two instances of @ref union_decl.
24066 ///
24067 /// If the two intances are different, set a bitfield to give some
24068 /// insight about the kind of differences there are.
24069 ///
24070 /// @param l the first artifact of the comparison.
24071 ///
24072 /// @param r the second artifact of the comparison.
24073 ///
24074 /// @param k a pointer to a bitfield that gives information about the
24075 /// kind of changes there are between @p l and @p r. This one is set
24076 /// iff @p k is non-null and the function returns false.
24077 ///
24078 /// Please note that setting k to a non-null value does have a
24079 /// negative performance impact because even if @p l and @p r are not
24080 /// equal, the function keeps up the comparison in order to determine
24081 /// the different kinds of ways in which they are different.
24082 ///
24083 /// @return true if @p l equals @p r, false otherwise.
24084 bool
equals(const union_decl & l,const union_decl & r,change_kind * k)24085 equals(const union_decl& l, const union_decl& r, change_kind* k)
24086 {
24087 bool result = equals(static_cast<const class_or_union&>(l),
24088 static_cast<const class_or_union&>(r),
24089 k);
24090 ABG_RETURN(result);
24091 }
24092
24093 /// Copy a method of a @ref union_decl into a new @ref
24094 /// union_decl.
24095 ///
24096 /// @param t the @ref union_decl into which the method is to be copied.
24097 ///
24098 /// @param method the method to copy into @p t.
24099 ///
24100 /// @return the resulting newly copied method.
24101 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl_sptr & f)24102 copy_member_function(const union_decl_sptr& union_type,
24103 const method_decl_sptr& f)
24104 {return copy_member_function(union_type, f.get());}
24105
24106 /// Copy a method of a @ref union_decl into a new @ref
24107 /// union_decl.
24108 ///
24109 /// @param t the @ref union_decl into which the method is to be copied.
24110 ///
24111 /// @param method the method to copy into @p t.
24112 ///
24113 /// @return the resulting newly copied method.
24114 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl * f)24115 copy_member_function(const union_decl_sptr& union_type,
24116 const method_decl* f)
24117 {
24118 const class_or_union_sptr t = union_type;
24119 return copy_member_function(t, f);
24120 }
24121
24122 /// Turn equality of shared_ptr of union_decl into a deep equality;
24123 /// that is, make it compare the pointed to objects too.
24124 ///
24125 /// @param l the left-hand-side operand of the operator
24126 ///
24127 /// @param r the right-hand-side operand of the operator.
24128 ///
24129 /// @return true iff @p l equals @p r.
24130 bool
operator ==(const union_decl_sptr & l,const union_decl_sptr & r)24131 operator==(const union_decl_sptr& l, const union_decl_sptr& r)
24132 {
24133 if (l.get() == r.get())
24134 return true;
24135 if (!!l != !!r)
24136 return false;
24137
24138 return *l == *r;
24139 }
24140
24141 /// Turn inequality of shared_ptr of union_decl into a deep equality;
24142 /// that is, make it compare the pointed to objects too.
24143 ///
24144 /// @param l the left-hand-side operand of the operator
24145 ///
24146 /// @param r the right-hand-side operand of the operator.
24147 ///
24148 /// @return true iff @p l is different from @p r.
24149 bool
operator !=(const union_decl_sptr & l,const union_decl_sptr & r)24150 operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
24151 {return !operator==(l, r);}
24152 // </union_decl>
24153
24154 // <template_decl stuff>
24155
24156 /// Data type of the private data of the @template_decl type.
24157 class template_decl::priv
24158 {
24159 friend class template_decl;
24160
24161 std::list<template_parameter_sptr> parms_;
24162 public:
24163
priv()24164 priv()
24165 {}
24166 }; // end class template_decl::priv
24167
24168 /// Add a new template parameter to the current instance of @ref
24169 /// template_decl.
24170 ///
24171 /// @param p the new template parameter to add.
24172 void
add_template_parameter(const template_parameter_sptr p)24173 template_decl::add_template_parameter(const template_parameter_sptr p)
24174 {priv_->parms_.push_back(p);}
24175
24176 /// Get the list of template parameters of the current instance of
24177 /// @ref template_decl.
24178 ///
24179 /// @return the list of template parameters.
24180 const std::list<template_parameter_sptr>&
get_template_parameters() const24181 template_decl::get_template_parameters() const
24182 {return priv_->parms_;}
24183
24184 /// Constructor.
24185 ///
24186 /// @param env the environment we are operating from.
24187 ///
24188 /// @param name the name of the template decl.
24189 ///
24190 /// @param locus the source location where the template declaration is
24191 /// defined.
24192 ///
24193 /// @param vis the visibility of the template declaration.
template_decl(const environment * env,const string & name,const location & locus,visibility vis)24194 template_decl::template_decl(const environment* env,
24195 const string& name,
24196 const location& locus,
24197 visibility vis)
24198 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
24199 decl_base(env, name, locus, /*mangled_name=*/"", vis),
24200 priv_(new priv)
24201 {
24202 runtime_type_instance(this);
24203 }
24204
24205 /// Destructor.
~template_decl()24206 template_decl::~template_decl()
24207 {}
24208
24209 /// Equality operator.
24210 ///
24211 /// @param o the other instance to compare against.
24212 ///
24213 /// @return true iff @p equals the current instance.
24214 bool
operator ==(const template_decl & o) const24215 template_decl::operator==(const template_decl& o) const
24216 {
24217 try
24218 {
24219 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
24220 for (t0 = get_template_parameters().begin(),
24221 t1 = o.get_template_parameters().begin();
24222 (t0 != get_template_parameters().end()
24223 && t1 != o.get_template_parameters().end());
24224 ++t0, ++t1)
24225 {
24226 if (**t0 != **t1)
24227 return false;
24228 }
24229
24230 if (t0 != get_template_parameters().end()
24231 || t1 != o.get_template_parameters().end())
24232 return false;
24233
24234 return true;
24235 }
24236 catch(...)
24237 {return false;}
24238 }
24239
24240 // </template_decl stuff>
24241
24242 //<template_parameter>
24243
24244 /// The type of the private data of the @ref template_parameter type.
24245 class template_parameter::priv
24246 {
24247 friend class template_parameter;
24248
24249 unsigned index_;
24250 template_decl_wptr template_decl_;
24251 mutable bool hashing_started_;
24252 mutable bool comparison_started_;
24253
24254 priv();
24255
24256 public:
24257
priv(unsigned index,template_decl_sptr enclosing_template_decl)24258 priv(unsigned index, template_decl_sptr enclosing_template_decl)
24259 : index_(index),
24260 template_decl_(enclosing_template_decl),
24261 hashing_started_(),
24262 comparison_started_()
24263 {}
24264 }; // end class template_parameter::priv
24265
template_parameter(unsigned index,template_decl_sptr enclosing_template)24266 template_parameter::template_parameter(unsigned index,
24267 template_decl_sptr enclosing_template)
24268 : priv_(new priv(index, enclosing_template))
24269 {}
24270
24271 unsigned
get_index() const24272 template_parameter::get_index() const
24273 {return priv_->index_;}
24274
24275 const template_decl_sptr
get_enclosing_template_decl() const24276 template_parameter::get_enclosing_template_decl() const
24277 {return priv_->template_decl_.lock();}
24278
24279 bool
get_hashing_has_started() const24280 template_parameter::get_hashing_has_started() const
24281 {return priv_->hashing_started_;}
24282
24283 void
set_hashing_has_started(bool f) const24284 template_parameter::set_hashing_has_started(bool f) const
24285 {priv_->hashing_started_ = f;}
24286
24287 bool
operator ==(const template_parameter & o) const24288 template_parameter::operator==(const template_parameter& o) const
24289 {
24290 if (get_index() != o.get_index())
24291 return false;
24292
24293 if (priv_->comparison_started_)
24294 return true;
24295
24296 bool result = false;
24297
24298 // Avoid inifite loops due to the fact that comparison the enclosing
24299 // template decl might lead to comparing this very same template
24300 // parameter with another one ...
24301 priv_->comparison_started_ = true;
24302
24303 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
24304 ;
24305 else if (get_enclosing_template_decl()
24306 && (*get_enclosing_template_decl()
24307 != *o.get_enclosing_template_decl()))
24308 ;
24309 else
24310 result = true;
24311
24312 priv_->comparison_started_ = false;
24313
24314 return result;
24315 }
24316
24317 /// Inequality operator.
24318 ///
24319 /// @param other the other instance to compare against.
24320 ///
24321 /// @return true iff the other instance is different from the current
24322 /// one.
24323 bool
operator !=(const template_parameter & other) const24324 template_parameter::operator!=(const template_parameter& other) const
24325 {return !operator==(other);}
24326
24327 /// Destructor.
~template_parameter()24328 template_parameter::~template_parameter()
24329 {}
24330
24331 /// The type of the private data of the @ref type_tparameter type.
24332 class type_tparameter::priv
24333 {
24334 friend class type_tparameter;
24335 }; // end class type_tparameter::priv
24336
24337 /// Constructor of the @ref type_tparameter type.
24338 ///
24339 /// @param index the index the type template parameter.
24340 ///
24341 /// @param enclosing_tdecl the enclosing template declaration.
24342 ///
24343 /// @param name the name of the template parameter.
24344 ///
24345 /// @param locus the location of the declaration of this type template
24346 /// parameter.
type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)24347 type_tparameter::type_tparameter(unsigned index,
24348 template_decl_sptr enclosing_tdecl,
24349 const string& name,
24350 const location& locus)
24351 : type_or_decl_base(enclosing_tdecl->get_environment(),
24352 ABSTRACT_DECL_BASE
24353 | ABSTRACT_TYPE_BASE
24354 | BASIC_TYPE),
24355 decl_base(enclosing_tdecl->get_environment(), name, locus),
24356 type_base(enclosing_tdecl->get_environment(), 0, 0),
24357 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
24358 template_parameter(index, enclosing_tdecl),
24359 priv_(new priv)
24360 {
24361 runtime_type_instance(this);
24362 }
24363
24364 bool
operator ==(const type_base & other) const24365 type_tparameter::operator==(const type_base& other) const
24366 {
24367 if (!type_decl::operator==(other))
24368 return false;
24369
24370 try
24371 {
24372 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
24373 return template_parameter::operator==(o);
24374 }
24375 catch (...)
24376 {return false;}
24377 }
24378
24379 bool
operator ==(const template_parameter & other) const24380 type_tparameter::operator==(const template_parameter& other) const
24381 {
24382 try
24383 {
24384 const type_base& o = dynamic_cast<const type_base&>(other);
24385 return *this == o;
24386 }
24387 catch(...)
24388 {return false;}
24389 }
24390
24391 bool
operator ==(const type_tparameter & other) const24392 type_tparameter::operator==(const type_tparameter& other) const
24393 {return *this == static_cast<const type_base&>(other);}
24394
~type_tparameter()24395 type_tparameter::~type_tparameter()
24396 {}
24397
24398 /// The type of the private data of the @ref non_type_tparameter type.
24399 class non_type_tparameter::priv
24400 {
24401 friend class non_type_tparameter;
24402
24403 type_base_wptr type_;
24404
24405 priv();
24406
24407 public:
24408
priv(type_base_sptr type)24409 priv(type_base_sptr type)
24410 : type_(type)
24411 {}
24412 }; // end class non_type_tparameter::priv
24413
24414 /// The constructor for the @ref non_type_tparameter type.
24415 ///
24416 /// @param index the index of the template parameter.
24417 ///
24418 /// @param enclosing_tdecl the enclosing template declaration that
24419 /// holds this parameter parameter.
24420 ///
24421 /// @param name the name of the template parameter.
24422 ///
24423 /// @param type the type of the template parameter.
24424 ///
24425 /// @param locus the location of the declaration of this template
24426 /// parameter.
non_type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,type_base_sptr type,const location & locus)24427 non_type_tparameter::non_type_tparameter(unsigned index,
24428 template_decl_sptr enclosing_tdecl,
24429 const string& name,
24430 type_base_sptr type,
24431 const location& locus)
24432 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
24433 decl_base(type->get_environment(), name, locus, ""),
24434 template_parameter(index, enclosing_tdecl),
24435 priv_(new priv(type))
24436 {
24437 runtime_type_instance(this);
24438 }
24439
24440 /// Getter for the type of the template parameter.
24441 ///
24442 /// @return the type of the template parameter.
24443 const type_base_sptr
get_type() const24444 non_type_tparameter::get_type() const
24445 {return priv_->type_.lock();}
24446
24447 /// Get the hash value of the current instance.
24448 ///
24449 /// @return the hash value.
24450 size_t
get_hash() const24451 non_type_tparameter::get_hash() const
24452 {
24453 non_type_tparameter::hash hash_tparm;
24454 return hash_tparm(this);
24455 }
24456
24457 bool
operator ==(const decl_base & other) const24458 non_type_tparameter::operator==(const decl_base& other) const
24459 {
24460 if (!decl_base::operator==(other))
24461 return false;
24462
24463 try
24464 {
24465 const non_type_tparameter& o =
24466 dynamic_cast<const non_type_tparameter&>(other);
24467 return (template_parameter::operator==(o)
24468 && get_type() == o.get_type());
24469 }
24470 catch(...)
24471 {return false;}
24472 }
24473
24474 bool
operator ==(const template_parameter & other) const24475 non_type_tparameter::operator==(const template_parameter& other) const
24476 {
24477 try
24478 {
24479 const decl_base& o = dynamic_cast<const decl_base&>(other);
24480 return *this == o;
24481 }
24482 catch(...)
24483 {return false;}
24484 }
24485
~non_type_tparameter()24486 non_type_tparameter::~non_type_tparameter()
24487 {}
24488
24489 // <template_tparameter stuff>
24490
24491 /// Type of the private data of the @ref template_tparameter type.
24492 class template_tparameter::priv
24493 {
24494 }; //end class template_tparameter::priv
24495
24496 /// Constructor for the @ref template_tparameter.
24497 ///
24498 /// @param index the index of the template parameter.
24499 ///
24500 /// @param enclosing_tdecl the enclosing template declaration.
24501 ///
24502 /// @param name the name of the template parameter.
24503 ///
24504 /// @param locus the location of the declaration of the template
24505 /// parameter.
template_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)24506 template_tparameter::template_tparameter(unsigned index,
24507 template_decl_sptr enclosing_tdecl,
24508 const string& name,
24509 const location& locus)
24510 : type_or_decl_base(enclosing_tdecl->get_environment(),
24511 ABSTRACT_DECL_BASE
24512 | ABSTRACT_TYPE_BASE
24513 | BASIC_TYPE),
24514 decl_base(enclosing_tdecl->get_environment(), name, locus),
24515 type_base(enclosing_tdecl->get_environment(), 0, 0),
24516 type_decl(enclosing_tdecl->get_environment(), name,
24517 0, 0, locus, name, VISIBILITY_DEFAULT),
24518 type_tparameter(index, enclosing_tdecl, name, locus),
24519 template_decl(enclosing_tdecl->get_environment(), name, locus),
24520 priv_(new priv)
24521 {
24522 runtime_type_instance(this);
24523 }
24524
24525 bool
operator ==(const type_base & other) const24526 template_tparameter::operator==(const type_base& other) const
24527 {
24528 try
24529 {
24530 const template_tparameter& o =
24531 dynamic_cast<const template_tparameter&>(other);
24532 return (type_tparameter::operator==(o)
24533 && template_decl::operator==(o));
24534 }
24535 catch(...)
24536 {return false;}
24537 }
24538
24539 bool
operator ==(const template_parameter & o) const24540 template_tparameter::operator==(const template_parameter& o) const
24541 {
24542 try
24543 {
24544 const template_tparameter& other =
24545 dynamic_cast<const template_tparameter&>(o);
24546 return *this == static_cast<const type_base&>(other);
24547 }
24548 catch(...)
24549 {return false;}
24550 }
24551
24552 bool
operator ==(const template_decl & o) const24553 template_tparameter::operator==(const template_decl& o) const
24554 {
24555 try
24556 {
24557 const template_tparameter& other =
24558 dynamic_cast<const template_tparameter&>(o);
24559 return type_base::operator==(other);
24560 }
24561 catch(...)
24562 {return false;}
24563 }
24564
~template_tparameter()24565 template_tparameter::~template_tparameter()
24566 {}
24567
24568 // </template_tparameter stuff>
24569
24570 // <type_composition stuff>
24571
24572 /// The type of the private data of the @ref type_composition type.
24573 class type_composition::priv
24574 {
24575 friend class type_composition;
24576
24577 type_base_wptr type_;
24578
24579 // Forbid this.
24580 priv();
24581
24582 public:
24583
priv(type_base_wptr type)24584 priv(type_base_wptr type)
24585 : type_(type)
24586 {}
24587 }; //end class type_composition::priv
24588
24589 /// Constructor for the @ref type_composition type.
24590 ///
24591 /// @param index the index of the template type composition.
24592 ///
24593 /// @param tdecl the enclosing template parameter that owns the
24594 /// composition.
24595 ///
24596 /// @param t the resulting type.
type_composition(unsigned index,template_decl_sptr tdecl,type_base_sptr t)24597 type_composition::type_composition(unsigned index,
24598 template_decl_sptr tdecl,
24599 type_base_sptr t)
24600 : type_or_decl_base(tdecl->get_environment(),
24601 ABSTRACT_DECL_BASE),
24602 decl_base(tdecl->get_environment(), "", location()),
24603 template_parameter(index, tdecl),
24604 priv_(new priv(t))
24605 {
24606 runtime_type_instance(this);
24607 }
24608
24609 /// Getter for the resulting composed type.
24610 ///
24611 /// @return the composed type.
24612 const type_base_sptr
get_composed_type() const24613 type_composition::get_composed_type() const
24614 {return priv_->type_.lock();}
24615
24616 /// Setter for the resulting composed type.
24617 ///
24618 /// @param t the composed type.
24619 void
set_composed_type(type_base_sptr t)24620 type_composition::set_composed_type(type_base_sptr t)
24621 {priv_->type_ = t;}
24622
24623 /// Get the hash value for the current instance.
24624 ///
24625 /// @return the hash value.
24626 size_t
get_hash() const24627 type_composition::get_hash() const
24628 {
24629 type_composition::hash hash_type_composition;
24630 return hash_type_composition(this);
24631 }
24632
~type_composition()24633 type_composition::~type_composition()
24634 {}
24635
24636 // </type_composition stuff>
24637
24638 //</template_parameter stuff>
24639
24640 // <function_template>
24641
24642 class function_tdecl::priv
24643 {
24644 friend class function_tdecl;
24645
24646 function_decl_sptr pattern_;
24647 binding binding_;
24648
24649 priv();
24650
24651 public:
24652
priv(function_decl_sptr pattern,binding bind)24653 priv(function_decl_sptr pattern, binding bind)
24654 : pattern_(pattern), binding_(bind)
24655 {}
24656
priv(binding bind)24657 priv(binding bind)
24658 : binding_(bind)
24659 {}
24660 }; // end class function_tdecl::priv
24661
24662 /// Constructor for a function template declaration.
24663 ///
24664 /// @param env the environment we are operating from.
24665 ///
24666 /// @param locus the location of the declaration.
24667 ///
24668 /// @param vis the visibility of the declaration. This is the
24669 /// visibility the functions instantiated from this template are going
24670 /// to have.
24671 ///
24672 /// @param bind the binding of the declaration. This is the binding
24673 /// the functions instantiated from this template are going to have.
function_tdecl(const environment * env,const location & locus,visibility vis,binding bind)24674 function_tdecl::function_tdecl(const environment* env,
24675 const location& locus,
24676 visibility vis,
24677 binding bind)
24678 : type_or_decl_base(env,
24679 ABSTRACT_DECL_BASE
24680 | TEMPLATE_DECL
24681 | ABSTRACT_SCOPE_DECL),
24682 decl_base(env, "", locus, "", vis),
24683 template_decl(env, "", locus, vis),
24684 scope_decl(env, "", locus),
24685 priv_(new priv(bind))
24686 {
24687 runtime_type_instance(this);
24688 }
24689
24690 /// Constructor for a function template declaration.
24691 ///
24692 /// @param pattern the pattern of the template.
24693 ///
24694 /// @param locus the location of the declaration.
24695 ///
24696 /// @param vis the visibility of the declaration. This is the
24697 /// visibility the functions instantiated from this template are going
24698 /// to have.
24699 ///
24700 /// @param bind the binding of the declaration. This is the binding
24701 /// the functions instantiated from this template are going to have.
function_tdecl(function_decl_sptr pattern,const location & locus,visibility vis,binding bind)24702 function_tdecl::function_tdecl(function_decl_sptr pattern,
24703 const location& locus,
24704 visibility vis,
24705 binding bind)
24706 : type_or_decl_base(pattern->get_environment(),
24707 ABSTRACT_DECL_BASE
24708 | TEMPLATE_DECL
24709 | ABSTRACT_SCOPE_DECL),
24710 decl_base(pattern->get_environment(), pattern->get_name(), locus,
24711 pattern->get_name(), vis),
24712 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
24713 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
24714 priv_(new priv(pattern, bind))
24715 {
24716 runtime_type_instance(this);
24717 }
24718
24719 /// Set a new pattern to the function template.
24720 ///
24721 /// @param p the new pattern.
24722 void
set_pattern(function_decl_sptr p)24723 function_tdecl::set_pattern(function_decl_sptr p)
24724 {
24725 priv_->pattern_ = p;
24726 add_decl_to_scope(p, this);
24727 set_name(p->get_name());
24728 }
24729
24730 /// Get the pattern of the function template.
24731 ///
24732 /// @return the pattern.
24733 function_decl_sptr
get_pattern() const24734 function_tdecl::get_pattern() const
24735 {return priv_->pattern_;}
24736
24737 /// Get the binding of the function template.
24738 ///
24739 /// @return the binding
24740 decl_base::binding
get_binding() const24741 function_tdecl::get_binding() const
24742 {return priv_->binding_;}
24743
24744 /// Comparison operator for the @ref function_tdecl type.
24745 ///
24746 /// @param other the other instance of @ref function_tdecl to compare against.
24747 ///
24748 /// @return true iff the two instance are equal.
24749 bool
operator ==(const decl_base & other) const24750 function_tdecl::operator==(const decl_base& other) const
24751 {
24752 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
24753 if (o)
24754 return *this == *o;
24755 return false;
24756 }
24757
24758 /// Comparison operator for the @ref function_tdecl type.
24759 ///
24760 /// @param other the other instance of @ref function_tdecl to compare against.
24761 ///
24762 /// @return true iff the two instance are equal.
24763 bool
operator ==(const template_decl & other) const24764 function_tdecl::operator==(const template_decl& other) const
24765 {
24766 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
24767 if (o)
24768 return *this == *o;
24769 return false;
24770 }
24771
24772 /// Comparison operator for the @ref function_tdecl type.
24773 ///
24774 /// @param o the other instance of @ref function_tdecl to compare against.
24775 ///
24776 /// @return true iff the two instance are equal.
24777 bool
operator ==(const function_tdecl & o) const24778 function_tdecl::operator==(const function_tdecl& o) const
24779 {
24780 if (!(get_binding() == o.get_binding()
24781 && template_decl::operator==(o)
24782 && scope_decl::operator==(o)
24783 && !!get_pattern() == !!o.get_pattern()))
24784 return false;
24785
24786 if (get_pattern())
24787 return (*get_pattern() == *o.get_pattern());
24788
24789 return true;
24790 }
24791
24792 /// This implements the ir_traversable_base::traverse pure virtual
24793 /// function.
24794 ///
24795 /// @param v the visitor used on the current instance and on the
24796 /// function pattern of the template.
24797 ///
24798 /// @return true if the entire IR node tree got traversed, false
24799 /// otherwise.
24800 bool
traverse(ir_node_visitor & v)24801 function_tdecl::traverse(ir_node_visitor&v)
24802 {
24803 if (visiting())
24804 return true;
24805
24806 if (!v.visit_begin(this))
24807 {
24808 visiting(true);
24809 if (get_pattern())
24810 get_pattern()->traverse(v);
24811 visiting(false);
24812 }
24813 return v.visit_end(this);
24814 }
24815
~function_tdecl()24816 function_tdecl::~function_tdecl()
24817 {}
24818
24819 // </function_template>
24820
24821 // <class template>
24822
24823 /// Type of the private data of the the @ref class_tdecl type.
24824 class class_tdecl::priv
24825 {
24826 friend class class_tdecl;
24827 class_decl_sptr pattern_;
24828
24829 public:
24830
priv()24831 priv()
24832 {}
24833
priv(class_decl_sptr pattern)24834 priv(class_decl_sptr pattern)
24835 : pattern_(pattern)
24836 {}
24837 }; // end class class_tdecl::priv
24838
24839 /// Constructor for the @ref class_tdecl type.
24840 ///
24841 /// @param env the environment we are operating from.
24842 ///
24843 /// @param locus the location of the declaration of the class_tdecl
24844 /// type.
24845 ///
24846 /// @param vis the visibility of the instance of class instantiated
24847 /// from this template.
class_tdecl(const environment * env,const location & locus,visibility vis)24848 class_tdecl::class_tdecl(const environment* env,
24849 const location& locus,
24850 visibility vis)
24851 : type_or_decl_base(env,
24852 ABSTRACT_DECL_BASE
24853 | TEMPLATE_DECL
24854 | ABSTRACT_SCOPE_DECL),
24855 decl_base(env, "", locus, "", vis),
24856 template_decl(env, "", locus, vis),
24857 scope_decl(env, "", locus),
24858 priv_(new priv)
24859 {
24860 runtime_type_instance(this);
24861 }
24862
24863 /// Constructor for the @ref class_tdecl type.
24864 ///
24865 /// @param pattern The details of the class template. This must NOT be a
24866 /// null pointer. If you really this to be null, please use the
24867 /// constructor above instead.
24868 ///
24869 /// @param locus the source location of the declaration of the type.
24870 ///
24871 /// @param vis the visibility of the instances of class instantiated
24872 /// from this template.
class_tdecl(class_decl_sptr pattern,const location & locus,visibility vis)24873 class_tdecl::class_tdecl(class_decl_sptr pattern,
24874 const location& locus,
24875 visibility vis)
24876 : type_or_decl_base(pattern->get_environment(),
24877 ABSTRACT_DECL_BASE
24878 | TEMPLATE_DECL
24879 | ABSTRACT_SCOPE_DECL),
24880 decl_base(pattern->get_environment(), pattern->get_name(),
24881 locus, pattern->get_name(), vis),
24882 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
24883 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
24884 priv_(new priv(pattern))
24885 {
24886 runtime_type_instance(this);
24887 }
24888
24889 /// Setter of the pattern of the template.
24890 ///
24891 /// @param p the new template.
24892 void
set_pattern(class_decl_sptr p)24893 class_tdecl::set_pattern(class_decl_sptr p)
24894 {
24895 priv_->pattern_ = p;
24896 add_decl_to_scope(p, this);
24897 set_name(p->get_name());
24898 }
24899
24900 /// Getter of the pattern of the template.
24901 ///
24902 /// @return p the new template.
24903 class_decl_sptr
get_pattern() const24904 class_tdecl::get_pattern() const
24905 {return priv_->pattern_;}
24906
24907 bool
operator ==(const decl_base & other) const24908 class_tdecl::operator==(const decl_base& other) const
24909 {
24910 try
24911 {
24912 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
24913
24914 if (!(template_decl::operator==(o)
24915 && scope_decl::operator==(o)
24916 && !!get_pattern() == !!o.get_pattern()))
24917 return false;
24918
24919 if (!get_pattern() || !o.get_pattern())
24920 return true;
24921
24922 return get_pattern()->decl_base::operator==(*o.get_pattern());
24923 }
24924 catch(...) {}
24925 return false;
24926 }
24927
24928 bool
operator ==(const template_decl & other) const24929 class_tdecl::operator==(const template_decl& other) const
24930 {
24931 try
24932 {
24933 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
24934 return *this == static_cast<const decl_base&>(o);
24935 }
24936 catch(...)
24937 {return false;}
24938 }
24939
24940 bool
operator ==(const class_tdecl & o) const24941 class_tdecl::operator==(const class_tdecl& o) const
24942 {return *this == static_cast<const decl_base&>(o);}
24943
24944 /// This implements the ir_traversable_base::traverse pure virtual
24945 /// function.
24946 ///
24947 /// @param v the visitor used on the current instance and on the class
24948 /// pattern of the template.
24949 ///
24950 /// @return true if the entire IR node tree got traversed, false
24951 /// otherwise.
24952 bool
traverse(ir_node_visitor & v)24953 class_tdecl::traverse(ir_node_visitor&v)
24954 {
24955 if (visiting())
24956 return true;
24957
24958 if (v.visit_begin(this))
24959 {
24960 visiting(true);
24961 if (class_decl_sptr pattern = get_pattern())
24962 pattern->traverse(v);
24963 visiting(false);
24964 }
24965 return v.visit_end(this);
24966 }
24967
~class_tdecl()24968 class_tdecl::~class_tdecl()
24969 {}
24970
24971 /// This visitor checks if a given type as non-canonicalized sub
24972 /// types.
24973 class non_canonicalized_subtype_detector : public ir::ir_node_visitor
24974 {
24975 type_base* type_;
24976 type_base* has_non_canonical_type_;
24977
24978 private:
24979 non_canonicalized_subtype_detector();
24980
24981 public:
non_canonicalized_subtype_detector(type_base * type)24982 non_canonicalized_subtype_detector(type_base* type)
24983 : type_(type),
24984 has_non_canonical_type_()
24985 {}
24986
24987 /// Return true if the visitor detected that there is a
24988 /// non-canonicalized sub-type.
24989 ///
24990 /// @return true if the visitor detected that there is a
24991 /// non-canonicalized sub-type.
24992 type_base*
has_non_canonical_type() const24993 has_non_canonical_type() const
24994 {return has_non_canonical_type_;}
24995
24996 /// The intent of this visitor handler is to avoid looking into
24997 /// sub-types of member functions of the type we are traversing.
24998 bool
visit_begin(function_decl * f)24999 visit_begin(function_decl* f)
25000 {
25001 // Do not look at sub-types of non-virtual member functions.
25002 if (is_member_function(f)
25003 && get_member_function_is_virtual(*f))
25004 return false;
25005 return true;
25006 }
25007
25008 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
25009 /// the 'has_non_canonical_type' flag. And in any case, when
25010 /// visiting a sub-type, do not visit its children nodes. So this
25011 /// function only goes to the level below the level of the top-most
25012 /// type.
25013 ///
25014 /// @return true if we are at the same level as the top-most type,
25015 /// otherwise return false.
25016 bool
visit_begin(type_base * t)25017 visit_begin(type_base* t)
25018 {
25019 if (t != type_)
25020 {
25021 if (!t->get_canonical_type())
25022 // We are looking a sub-type of 'type_' which has no
25023 // canonical type. So tada! we found one! Get out right
25024 // now with the trophy.
25025 has_non_canonical_type_ = t;
25026
25027 return false;
25028 }
25029 return true;
25030 }
25031
25032 /// When we are done visiting a sub-type, if it's been flagged as
25033 /// been non-canonicalized, then stop the traversing.
25034 ///
25035 /// Otherwise, keep going.
25036 ///
25037 /// @return false iff the sub-type that has been visited is
25038 /// non-canonicalized.
25039 bool
visit_end(type_base *)25040 visit_end(type_base* )
25041 {
25042 if (has_non_canonical_type_)
25043 return false;
25044 return true;
25045 }
25046 }; //end class non_canonicalized_subtype_detector
25047
25048 /// Test if a type has sub-types that are non-canonicalized.
25049 ///
25050 /// @param t the type which sub-types to consider.
25051 ///
25052 /// @return true if a type has sub-types that are non-canonicalized.
25053 type_base*
type_has_non_canonicalized_subtype(type_base_sptr t)25054 type_has_non_canonicalized_subtype(type_base_sptr t)
25055 {
25056 if (!t)
25057 return 0;
25058
25059 non_canonicalized_subtype_detector v(t.get());
25060 t->traverse(v);
25061 return v.has_non_canonical_type();
25062 }
25063
25064 /// Tests if the change of a given type effectively comes from just
25065 /// its sub-types. That is, if the type has changed but its type name
25066 /// hasn't changed, then the change of the type mostly likely is a
25067 /// sub-type change.
25068 ///
25069 /// @param t_v1 the first version of the type.
25070 ///
25071 /// @param t_v2 the second version of the type.
25072 ///
25073 /// @return true iff the type changed and the change is about its
25074 /// sub-types.
25075 bool
type_has_sub_type_changes(const type_base_sptr t_v1,const type_base_sptr t_v2)25076 type_has_sub_type_changes(const type_base_sptr t_v1,
25077 const type_base_sptr t_v2)
25078 {
25079 type_base_sptr t1 = strip_typedef(t_v1);
25080 type_base_sptr t2 = strip_typedef(t_v2);
25081
25082 string repr1 = get_pretty_representation(t1, /*internal=*/false),
25083 repr2 = get_pretty_representation(t2, /*internal=*/false);
25084 return (t1 != t2 && repr1 == repr2);
25085 }
25086
25087 /// Make sure that the life time of a given (smart pointer to a) type
25088 /// is the same as the life time of the libabigail library.
25089 ///
25090 /// @param t the type to consider.
25091 void
keep_type_alive(type_base_sptr t)25092 keep_type_alive(type_base_sptr t)
25093 {
25094 environment* env = t->get_environment();
25095 ABG_ASSERT(env);
25096 env->priv_->extra_live_types_.push_back(t);
25097 }
25098
25099 /// Hash an ABI artifact that is either a type or a decl.
25100 ///
25101 /// This function intends to provides the fastest possible hashing for
25102 /// types and decls, while being completely correct.
25103 ///
25104 /// Note that if the artifact is a type and if it has a canonical
25105 /// type, the hash value is going to be the pointer value of the
25106 /// canonical type. Otherwise, this function computes a hash value
25107 /// for the type by recursively walking the type members. This last
25108 /// code path is possibly *very* slow and should only be used when
25109 /// only handful of types are going to be hashed.
25110 ///
25111 /// If the artifact is a decl, then a combination of the hash of its
25112 /// type and the hash of the other properties of the decl is computed.
25113 ///
25114 /// @param tod the type or decl to hash.
25115 ///
25116 /// @return the resulting hash value.
25117 size_t
hash_type_or_decl(const type_or_decl_base * tod)25118 hash_type_or_decl(const type_or_decl_base *tod)
25119 {
25120 size_t result = 0;
25121
25122 if (tod == 0)
25123 ;
25124 else if (const type_base* t = is_type(tod))
25125 result = hash_type(t);
25126 else if (const decl_base* d = is_decl(tod))
25127 {
25128 if (var_decl* v = is_var_decl(d))
25129 {
25130 ABG_ASSERT(v->get_type());
25131 size_t h = hash_type_or_decl(v->get_type());
25132 string repr = v->get_pretty_representation(/*internal=*/true);
25133 std::hash<string> hash_string;
25134 h = hashing::combine_hashes(h, hash_string(repr));
25135 result = h;
25136 }
25137 else if (function_decl* f = is_function_decl(d))
25138 {
25139 ABG_ASSERT(f->get_type());
25140 size_t h = hash_type_or_decl(f->get_type());
25141 string repr = f->get_pretty_representation(/*internal=*/true);
25142 std::hash<string> hash_string;
25143 h = hashing::combine_hashes(h, hash_string(repr));
25144 result = h;
25145 }
25146 else if (function_decl::parameter* p = is_function_parameter(d))
25147 {
25148 type_base_sptr parm_type = p->get_type();
25149 ABG_ASSERT(parm_type);
25150 std::hash<bool> hash_bool;
25151 std::hash<unsigned> hash_unsigned;
25152 size_t h = hash_type_or_decl(parm_type);
25153 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
25154 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
25155 result = h;
25156 }
25157 else if (class_decl::base_spec *bs = is_class_base_spec(d))
25158 {
25159 member_base::hash hash_member;
25160 std::hash<size_t> hash_size;
25161 std::hash<bool> hash_bool;
25162 type_base_sptr type = bs->get_base_class();
25163 size_t h = hash_type_or_decl(type);
25164 h = hashing::combine_hashes(h, hash_member(*bs));
25165 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
25166 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
25167 result = h;
25168 }
25169 else
25170 // This is a *really* *SLOW* path. If it shows up in a
25171 // performance profile, I bet it'd be a good idea to try to
25172 // avoid it altogether.
25173 result = d->get_hash();
25174 }
25175 else
25176 // We should never get here.
25177 abort();
25178 return result;
25179 }
25180
25181 /// Hash an ABI artifact that is either a type.
25182 ///
25183 /// This function intends to provides the fastest possible hashing for
25184 /// types while being completely correct.
25185 ///
25186 /// Note that if the type artifact has a canonical type, the hash
25187 /// value is going to be the pointer value of the canonical type.
25188 /// Otherwise, this function computes a hash value for the type by
25189 /// recursively walking the type members. This last code path is
25190 /// possibly *very* slow and should only be used when only handful of
25191 /// types are going to be hashed.
25192 ///
25193 /// @param t the type or decl to hash.
25194 ///
25195 /// @return the resulting hash value.
25196 size_t
hash_type(const type_base * t)25197 hash_type(const type_base *t)
25198 {return hash_as_canonical_type_or_constant(t);}
25199
25200 /// Hash an ABI artifact that is either a type of a decl.
25201 ///
25202 /// @param tod the ABI artifact to hash.
25203 ///
25204 /// @return the hash value of the ABI artifact.
25205 size_t
hash_type_or_decl(const type_or_decl_base_sptr & tod)25206 hash_type_or_decl(const type_or_decl_base_sptr& tod)
25207 {return hash_type_or_decl(tod.get());}
25208
25209 /// Test if a given type is allowed to be non canonicalized
25210 ///
25211 /// This is a subroutine of hash_as_canonical_type_or_constant.
25212 ///
25213 /// For now, the only types allowed to be non canonicalized in the
25214 /// system are decl-only class/union, the void type and variadic
25215 /// parameter types.
25216 ///
25217 /// @return true iff @p t is a one of the only types allowed to be
25218 /// non-canonicalized in the system.
25219 bool
is_non_canonicalized_type(const type_base * t)25220 is_non_canonicalized_type(const type_base *t)
25221 {
25222 if (!t)
25223 return true;
25224
25225 const environment* env = t->get_environment();
25226 return (is_declaration_only_class_or_union_type(t)
25227 || env->is_void_type(t)
25228 || env->is_variadic_parameter_type(t));
25229 }
25230
25231 /// For a given type, return its exemplar type.
25232 ///
25233 /// For a given type, its exemplar type is either its canonical type
25234 /// or the canonical type of the definition type of a given
25235 /// declaration-only type. If the neither of those two types exist,
25236 /// then the exemplar type is the given type itself.
25237 ///
25238 /// @param type the input to consider.
25239 ///
25240 /// @return the exemplar type.
25241 type_base*
get_exemplar_type(const type_base * type)25242 get_exemplar_type(const type_base* type)
25243 {
25244 if (decl_base * decl = is_decl(type))
25245 {
25246 // Make sure we get the real definition of a decl-only type.
25247 decl = look_through_decl_only(decl);
25248 type = is_type(decl);
25249 ABG_ASSERT(type);
25250 }
25251 type_base *exemplar = type->get_naked_canonical_type();
25252 if (!exemplar)
25253 {
25254 // The type has no canonical type. Let's be sure that it's one
25255 // of those rare types that are allowed to be non canonicalized
25256 // in the system.
25257 exemplar = const_cast<type_base*>(type);
25258 ABG_ASSERT(is_non_canonicalized_type(exemplar));
25259 }
25260 return exemplar;
25261 }
25262
25263 /// Test if a given type is allowed to be non canonicalized
25264 ///
25265 /// This is a subroutine of hash_as_canonical_type_or_constant.
25266 ///
25267 /// For now, the only types allowed to be non canonicalized in the
25268 /// system are decl-only class/union and the void type.
25269 ///
25270 /// @return true iff @p t is a one of the only types allowed to be
25271 /// non-canonicalized in the system.
25272 bool
is_non_canonicalized_type(const type_base_sptr & t)25273 is_non_canonicalized_type(const type_base_sptr& t)
25274 {return is_non_canonicalized_type(t.get());}
25275
25276 /// Hash a type by either returning the pointer value of its canonical
25277 /// type or by returning a constant if the type doesn't have a
25278 /// canonical type.
25279 ///
25280 /// This is a subroutine of hash_type.
25281 ///
25282 /// @param t the type to consider.
25283 ///
25284 /// @return the hash value.
25285 static size_t
hash_as_canonical_type_or_constant(const type_base * t)25286 hash_as_canonical_type_or_constant(const type_base *t)
25287 {
25288 type_base *canonical_type = 0;
25289
25290 if (t)
25291 canonical_type = t->get_naked_canonical_type();
25292
25293 if (!canonical_type)
25294 {
25295 // If the type doesn't have a canonical type, maybe it's because
25296 // it's a declaration-only type? If that's the case, let's try
25297 // to get the canonical type of the definition of this
25298 // declaration.
25299 decl_base *decl = is_decl(t);
25300 if (decl
25301 && decl->get_is_declaration_only()
25302 && decl->get_naked_definition_of_declaration())
25303 {
25304 type_base *definition =
25305 is_type(decl->get_naked_definition_of_declaration());
25306 ABG_ASSERT(definition);
25307 canonical_type = definition->get_naked_canonical_type();
25308 }
25309 }
25310
25311 if (canonical_type)
25312 return reinterpret_cast<size_t>(canonical_type);
25313
25314 // If we reached this point, it means we are seeing a
25315 // non-canonicalized type. It must be a decl-only class or a void
25316 // type, otherwise it means that for some weird reason, the type
25317 // hasn't been canonicalized. It should be!
25318 ABG_ASSERT(is_non_canonicalized_type(t));
25319
25320 return 0xDEADBABE;
25321 }
25322
25323 /// Test if the pretty representation of a given @ref function_decl is
25324 /// lexicographically less then the pretty representation of another
25325 /// @ref function_decl.
25326 ///
25327 /// @param f the first @ref function_decl to consider for comparison.
25328 ///
25329 /// @param s the second @ref function_decl to consider for comparison.
25330 ///
25331 /// @return true iff the pretty representation of @p f is
25332 /// lexicographically less than the pretty representation of @p s.
25333 bool
function_decl_is_less_than(const function_decl & f,const function_decl & s)25334 function_decl_is_less_than(const function_decl &f, const function_decl &s)
25335 {
25336 string fr = f.get_pretty_representation_of_declarator(),
25337 sr = s.get_pretty_representation_of_declarator();
25338
25339 if (fr != sr)
25340 return fr < sr;
25341
25342 fr = f.get_pretty_representation(/*internal=*/true),
25343 sr = s.get_pretty_representation(/*internal=*/true);
25344
25345 if (fr != sr)
25346 return fr < sr;
25347
25348 if (f.get_symbol())
25349 fr = f.get_symbol()->get_id_string();
25350 else if (!f.get_linkage_name().empty())
25351 fr = f.get_linkage_name();
25352
25353 if (s.get_symbol())
25354 sr = s.get_symbol()->get_id_string();
25355 else if (!s.get_linkage_name().empty())
25356 sr = s.get_linkage_name();
25357
25358 return fr < sr;
25359 }
25360
25361 /// Test if two types have similar structures, even though they are
25362 /// (or can be) different.
25363 ///
25364 /// const and volatile qualifiers are completely ignored.
25365 ///
25366 /// typedef are resolved to their definitions; their names are ignored.
25367 ///
25368 /// Two indirect types (pointers or references) have similar structure
25369 /// if their underlying types are of the same kind and have the same
25370 /// name. In the indirect types case, the size of the underlying type
25371 /// does not matter.
25372 ///
25373 /// Two direct types (i.e, non indirect) have a similar structure if
25374 /// they have the same kind, name and size. Two class types have
25375 /// similar structure if they have the same name, size, and if the
25376 /// types of their data members have similar types.
25377 ///
25378 /// @param first the first type to consider.
25379 ///
25380 /// @param second the second type to consider.
25381 ///
25382 /// @param indirect_type whether to do an indirect comparison
25383 ///
25384 /// @return true iff @p first and @p second have similar structures.
25385 bool
types_have_similar_structure(const type_base_sptr & first,const type_base_sptr & second,bool indirect_type)25386 types_have_similar_structure(const type_base_sptr& first,
25387 const type_base_sptr& second,
25388 bool indirect_type)
25389 {
25390 // This wrapper function is used during comparisons. It is called by and its
25391 // wrappee calls the main equality functions, possibly resulting in a
25392 // multiplication of the cost of comparison.
25393
25394 // This is a convenient place to add some memoisation to avoid at
25395 // least some of the duplicate calls. This is safe only if pointer
25396 // addresses are never reused.
25397 using Arguments = std::tuple<const type_base*, const type_base*, bool>;
25398
25399 struct Hasher {
25400 size_t operator()(const Arguments& arguments) const {
25401 const auto& [first, second, indirect] = arguments;
25402 size_t seed = 0;
25403 std::hash<const type_base*> h;
25404 combine_hash(seed, h(first));
25405 combine_hash(seed, h(second));
25406 combine_hash(seed, indirect);
25407 return seed;
25408 }
25409 static void combine_hash(size_t& seed, size_t hash) {
25410 seed ^= hash + 0x9e3779b97f4a7c15 + (seed << 12) + (seed >> 4);
25411 }
25412 };
25413
25414 static std::unordered_map<Arguments, abg_compat::optional<bool>, Hasher> memo;
25415
25416 const Arguments t{first.get(), second.get(), indirect_type};
25417 const auto& [it, inserted] = memo.insert({t, {}});
25418 auto& result = it->second;
25419 if (inserted)
25420 result = types_have_similar_structure(
25421 std::get<0>(t), std::get<1>(t), std::get<2>(t));
25422 else
25423 ABG_ASSERT(result.has_value());
25424 return *result;
25425 }
25426
25427 /// Test if two types have similar structures, even though they are
25428 /// (or can be) different.
25429 ///
25430 /// const and volatile qualifiers are completely ignored.
25431 ///
25432 /// typedef are resolved to their definitions; their names are ignored.
25433 ///
25434 /// Two indirect types (pointers, references or arrays) have similar
25435 /// structure if their underlying types are of the same kind and have
25436 /// the same name. In the indirect types case, the size of the
25437 /// underlying type does not matter.
25438 ///
25439 /// Two direct types (i.e, non indirect) have a similar structure if
25440 /// they have the same kind, name and size. Two class types have
25441 /// similar structure if they have the same name, size, and if the
25442 /// types of their data members have similar types.
25443 ///
25444 /// @param first the first type to consider.
25445 ///
25446 /// @param second the second type to consider.
25447 ///
25448 /// @param indirect_type if true, then consider @p first and @p
25449 /// second as being underlying types of indirect types. Meaning that
25450 /// their size does not matter.
25451 ///
25452 /// @return true iff @p first and @p second have similar structures.
25453 bool
types_have_similar_structure(const type_base * first,const type_base * second,bool indirect_type)25454 types_have_similar_structure(const type_base* first,
25455 const type_base* second,
25456 bool indirect_type)
25457 {
25458 if (!!first != !!second)
25459 return false;
25460
25461 if (!first)
25462 return false;
25463
25464 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
25465 first = peel_qualified_or_typedef_type(first);
25466 second = peel_qualified_or_typedef_type(second);
25467
25468 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
25469 // various ty2 below cannot be null.
25470 if (typeid(*first) != typeid(*second))
25471 return false;
25472
25473 // Peel off matching pointers.
25474 if (const pointer_type_def* ty1 = is_pointer_type(first))
25475 {
25476 const pointer_type_def* ty2 = is_pointer_type(second);
25477 return types_have_similar_structure(ty1->get_pointed_to_type(),
25478 ty2->get_pointed_to_type(),
25479 /*indirect_type=*/true);
25480 }
25481
25482 // Peel off matching references.
25483 if (const reference_type_def* ty1 = is_reference_type(first))
25484 {
25485 const reference_type_def* ty2 = is_reference_type(second);
25486 if (ty1->is_lvalue() != ty2->is_lvalue())
25487 return false;
25488 return types_have_similar_structure(ty1->get_pointed_to_type(),
25489 ty2->get_pointed_to_type(),
25490 /*indirect_type=*/true);
25491 }
25492
25493 if (const type_decl* ty1 = is_type_decl(first))
25494 {
25495 const type_decl* ty2 = is_type_decl(second);
25496 if (!indirect_type)
25497 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
25498 return false;
25499
25500 return ty1->get_name() == ty2->get_name();
25501 }
25502
25503 if (const enum_type_decl* ty1 = is_enum_type(first))
25504 {
25505 const enum_type_decl* ty2 = is_enum_type(second);
25506 if (!indirect_type)
25507 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
25508 return false;
25509
25510 return (get_name(ty1->get_underlying_type())
25511 == get_name(ty2->get_underlying_type()));
25512 }
25513
25514 if (const class_decl* ty1 = is_class_type(first))
25515 {
25516 const class_decl* ty2 = is_class_type(second);
25517 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
25518 && ty1->get_name() != ty2->get_name())
25519 return false;
25520
25521 if (!indirect_type)
25522 {
25523 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
25524 || (ty1->get_non_static_data_members().size()
25525 != ty2->get_non_static_data_members().size()))
25526 return false;
25527
25528 for (class_or_union::data_members::const_iterator
25529 i = ty1->get_non_static_data_members().begin(),
25530 j = ty2->get_non_static_data_members().begin();
25531 (i != ty1->get_non_static_data_members().end()
25532 && j != ty2->get_non_static_data_members().end());
25533 ++i, ++j)
25534 {
25535 var_decl_sptr dm1 = *i;
25536 var_decl_sptr dm2 = *j;
25537 if (!types_have_similar_structure(dm1->get_type().get(),
25538 dm2->get_type().get(),
25539 indirect_type))
25540 return false;
25541 }
25542 }
25543
25544 return true;
25545 }
25546
25547 if (const union_decl* ty1 = is_union_type(first))
25548 {
25549 const union_decl* ty2 = is_union_type(second);
25550 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
25551 && ty1->get_name() != ty2->get_name())
25552 return false;
25553
25554 if (!indirect_type)
25555 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
25556
25557 return true;
25558 }
25559
25560 if (const array_type_def* ty1 = is_array_type(first))
25561 {
25562 const array_type_def* ty2 = is_array_type(second);
25563 // TODO: Handle int[5][2] vs int[2][5] better.
25564 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
25565 || ty1->get_dimension_count() != ty2->get_dimension_count()
25566 || !types_have_similar_structure(ty1->get_element_type(),
25567 ty2->get_element_type(),
25568 /*indirect_type=*/true))
25569 return false;
25570
25571 return true;
25572 }
25573
25574 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
25575 {
25576 const array_type_def::subrange_type *ty2 = is_subrange_type(second);
25577 if (ty1->get_upper_bound() != ty2->get_upper_bound()
25578 || ty1->get_lower_bound() != ty2->get_lower_bound()
25579 || ty1->get_language() != ty2->get_language()
25580 || !types_have_similar_structure(ty1->get_underlying_type(),
25581 ty2->get_underlying_type(),
25582 indirect_type))
25583 return false;
25584
25585 return true;
25586 }
25587
25588 if (const function_type* ty1 = is_function_type(first))
25589 {
25590 const function_type* ty2 = is_function_type(second);
25591 if (!types_have_similar_structure(ty1->get_return_type(),
25592 ty2->get_return_type(),
25593 indirect_type))
25594 return false;
25595
25596 if (ty1->get_parameters().size() != ty2->get_parameters().size())
25597 return false;
25598
25599 for (function_type::parameters::const_iterator
25600 i = ty1->get_parameters().begin(),
25601 j = ty2->get_parameters().begin();
25602 (i != ty1->get_parameters().end()
25603 && j != ty2->get_parameters().end());
25604 ++i, ++j)
25605 if (!types_have_similar_structure((*i)->get_type(),
25606 (*j)->get_type(),
25607 indirect_type))
25608 return false;
25609
25610 return true;
25611 }
25612
25613 // All kinds of type should have been handled at this point.
25614 ABG_ASSERT_NOT_REACHED;
25615
25616 return false;
25617 }
25618
25619 /// Look for a data member of a given class, struct or union type and
25620 /// return it.
25621 ///
25622 /// The data member is designated by its name.
25623 ///
25624 /// @param type the class, struct or union type to consider.
25625 ///
25626 /// @param dm_name the name of the data member to lookup.
25627 ///
25628 /// @return the data member iff it was found in @type or NULL if no
25629 /// data member with that name was found.
25630 const var_decl*
lookup_data_member(const type_base * type,const char * dm_name)25631 lookup_data_member(const type_base* type,
25632 const char* dm_name)
25633
25634 {
25635 class_or_union *cou = is_class_or_union_type(type);
25636 if (!cou)
25637 return 0;
25638
25639 return cou->find_data_member(dm_name).get();
25640 }
25641
25642 /// Get the function parameter designated by its index.
25643 ///
25644 /// Note that the first function parameter has index 0.
25645 ///
25646 /// @param fun the function to consider.
25647 ///
25648 /// @param parm_index the index of the function parameter to get.
25649 ///
25650 /// @return the function parameter designated by its index, of NULL if
25651 /// no function parameter with that index was found.
25652 const function_decl::parameter*
get_function_parameter(const decl_base * fun,unsigned parm_index)25653 get_function_parameter(const decl_base* fun,
25654 unsigned parm_index)
25655 {
25656 function_decl* fn = is_function_decl(fun);
25657 if (!fn)
25658 return 0;
25659
25660 const function_decl::parameters &parms = fn->get_type()->get_parameters();
25661 if (parms.size() <= parm_index)
25662 return 0;
25663
25664 return parms[parm_index].get();
25665 }
25666
25667 bool
traverse(ir_node_visitor &)25668 ir_traversable_base::traverse(ir_node_visitor&)
25669 {return true;}
25670
25671 // <ir_node_visitor stuff>
25672
25673 /// The private data structure of the ir_node_visitor type.
25674 struct ir_node_visitor::priv
25675 {
25676 pointer_set visited_ir_nodes;
25677 bool allow_visiting_already_visited_type_node;
25678
privabigail::ir::ir_node_visitor::priv25679 priv()
25680 : allow_visiting_already_visited_type_node(true)
25681 {}
25682 }; // end struct ir_node_visitory::priv
25683
25684 /// Default Constructor of the ir_node_visitor type.
ir_node_visitor()25685 ir_node_visitor::ir_node_visitor()
25686 : priv_(new priv)
25687 {}
25688
25689 ir_node_visitor::~ir_node_visitor() = default;
25690
25691 /// Set if the walker using this visitor is allowed to re-visit a type
25692 /// node that was previously visited or not.
25693 ///
25694 /// @param f if true, then the walker using this visitor is allowed to
25695 /// re-visit a type node that was previously visited.
25696 void
allow_visiting_already_visited_type_node(bool f)25697 ir_node_visitor::allow_visiting_already_visited_type_node(bool f)
25698 {priv_->allow_visiting_already_visited_type_node = f;}
25699
25700 /// Get if the walker using this visitor is allowed to re-visit a type
25701 /// node that was previously visited or not.
25702 ///
25703 /// @return true iff the walker using this visitor is allowed to
25704 /// re-visit a type node that was previously visited.
25705 bool
allow_visiting_already_visited_type_node() const25706 ir_node_visitor::allow_visiting_already_visited_type_node() const
25707 {return priv_->allow_visiting_already_visited_type_node;}
25708
25709 /// Mark a given type node as having been visited.
25710 ///
25711 /// Note that for this function to work, the type node must have been
25712 /// canonicalized. Otherwise the process is aborted.
25713 ///
25714 /// @param p the type to mark as having been visited.
25715 void
mark_type_node_as_visited(type_base * p)25716 ir_node_visitor::mark_type_node_as_visited(type_base *p)
25717 {
25718 if (allow_visiting_already_visited_type_node())
25719 return;
25720
25721 if (p == 0 || type_node_has_been_visited(p))
25722 return;
25723
25724 type_base* canonical_type = p->get_naked_canonical_type();
25725 ABG_ASSERT(canonical_type);
25726
25727 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
25728 priv_->visited_ir_nodes.insert(canonical_ptr_value);
25729 }
25730
25731 /// Un-mark all visited type nodes.
25732 ///
25733 /// That is, no type node is going to be considered as having been
25734 /// visited anymore.
25735 ///
25736 /// In other words, after invoking this funciton,
25737 /// ir_node_visitor::type_node_has_been_visited() is going to return
25738 /// false on all type nodes.
25739 void
forget_visited_type_nodes()25740 ir_node_visitor::forget_visited_type_nodes()
25741 {priv_->visited_ir_nodes.clear();}
25742
25743 /// Test if a given type node has been marked as visited.
25744 ///
25745 /// @param p the type node to consider.
25746 ///
25747 /// @return true iff the type node @p p has been marked as visited by
25748 /// the function ir_node_visitor::mark_type_node_as_visited.
25749 bool
type_node_has_been_visited(type_base * p) const25750 ir_node_visitor::type_node_has_been_visited(type_base* p) const
25751 {
25752 if (allow_visiting_already_visited_type_node())
25753 return false;
25754
25755 if (p == 0)
25756 return false;
25757
25758 type_base *canonical_type = p->get_naked_canonical_type();
25759 ABG_ASSERT(canonical_type);
25760
25761 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
25762 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
25763 if (it == priv_->visited_ir_nodes.end())
25764 return false;
25765
25766 return true;
25767 }
25768
25769 bool
visit_begin(decl_base *)25770 ir_node_visitor::visit_begin(decl_base*)
25771 {return true;}
25772
25773 bool
visit_end(decl_base *)25774 ir_node_visitor::visit_end(decl_base*)
25775 {return true;}
25776
25777 bool
visit_begin(scope_decl *)25778 ir_node_visitor::visit_begin(scope_decl*)
25779 {return true;}
25780
25781 bool
visit_end(scope_decl *)25782 ir_node_visitor::visit_end(scope_decl*)
25783 {return true;}
25784
25785 bool
visit_begin(type_base *)25786 ir_node_visitor::visit_begin(type_base*)
25787 {return true;}
25788
25789 bool
visit_end(type_base *)25790 ir_node_visitor::visit_end(type_base*)
25791 {return true;}
25792
25793 bool
visit_begin(scope_type_decl * t)25794 ir_node_visitor::visit_begin(scope_type_decl* t)
25795 {return visit_begin(static_cast<type_base*>(t));}
25796
25797 bool
visit_end(scope_type_decl * t)25798 ir_node_visitor::visit_end(scope_type_decl* t)
25799 {return visit_end(static_cast<type_base*>(t));}
25800
25801 bool
visit_begin(type_decl * t)25802 ir_node_visitor::visit_begin(type_decl* t)
25803 {return visit_begin(static_cast<type_base*>(t));}
25804
25805 bool
visit_end(type_decl * t)25806 ir_node_visitor::visit_end(type_decl* t)
25807 {return visit_end(static_cast<type_base*>(t));}
25808
25809 bool
visit_begin(namespace_decl * d)25810 ir_node_visitor::visit_begin(namespace_decl* d)
25811 {return visit_begin(static_cast<decl_base*>(d));}
25812
25813 bool
visit_end(namespace_decl * d)25814 ir_node_visitor::visit_end(namespace_decl* d)
25815 {return visit_end(static_cast<decl_base*>(d));}
25816
25817 bool
visit_begin(qualified_type_def * t)25818 ir_node_visitor::visit_begin(qualified_type_def* t)
25819 {return visit_begin(static_cast<type_base*>(t));}
25820
25821 bool
visit_end(qualified_type_def * t)25822 ir_node_visitor::visit_end(qualified_type_def* t)
25823 {return visit_end(static_cast<type_base*>(t));}
25824
25825 bool
visit_begin(pointer_type_def * t)25826 ir_node_visitor::visit_begin(pointer_type_def* t)
25827 {return visit_begin(static_cast<type_base*>(t));}
25828
25829 bool
visit_end(pointer_type_def * t)25830 ir_node_visitor::visit_end(pointer_type_def* t)
25831 {return visit_end(static_cast<type_base*>(t));}
25832
25833 bool
visit_begin(reference_type_def * t)25834 ir_node_visitor::visit_begin(reference_type_def* t)
25835 {return visit_begin(static_cast<type_base*>(t));}
25836
25837 bool
visit_end(reference_type_def * t)25838 ir_node_visitor::visit_end(reference_type_def* t)
25839 {return visit_end(static_cast<type_base*>(t));}
25840
25841 bool
visit_begin(array_type_def * t)25842 ir_node_visitor::visit_begin(array_type_def* t)
25843 {return visit_begin(static_cast<type_base*>(t));}
25844
25845 bool
visit_end(array_type_def * t)25846 ir_node_visitor::visit_end(array_type_def* t)
25847 {return visit_end(static_cast<type_base*>(t));}
25848
25849 bool
visit_begin(array_type_def::subrange_type * t)25850 ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
25851 {return visit_begin(static_cast<type_base*>(t));}
25852
25853 bool
visit_end(array_type_def::subrange_type * t)25854 ir_node_visitor::visit_end(array_type_def::subrange_type* t)
25855 {return visit_end(static_cast<type_base*>(t));}
25856
25857 bool
visit_begin(enum_type_decl * t)25858 ir_node_visitor::visit_begin(enum_type_decl* t)
25859 {return visit_begin(static_cast<type_base*>(t));}
25860
25861 bool
visit_end(enum_type_decl * t)25862 ir_node_visitor::visit_end(enum_type_decl* t)
25863 {return visit_end(static_cast<type_base*>(t));}
25864
25865 bool
visit_begin(typedef_decl * t)25866 ir_node_visitor::visit_begin(typedef_decl* t)
25867 {return visit_begin(static_cast<type_base*>(t));}
25868
25869 bool
visit_end(typedef_decl * t)25870 ir_node_visitor::visit_end(typedef_decl* t)
25871 {return visit_end(static_cast<type_base*>(t));}
25872
25873 bool
visit_begin(function_type * t)25874 ir_node_visitor::visit_begin(function_type* t)
25875 {return visit_begin(static_cast<type_base*>(t));}
25876
25877 bool
visit_end(function_type * t)25878 ir_node_visitor::visit_end(function_type* t)
25879 {return visit_end(static_cast<type_base*>(t));}
25880
25881 bool
visit_begin(var_decl * d)25882 ir_node_visitor::visit_begin(var_decl* d)
25883 {return visit_begin(static_cast<decl_base*>(d));}
25884
25885 bool
visit_end(var_decl * d)25886 ir_node_visitor::visit_end(var_decl* d)
25887 {return visit_end(static_cast<decl_base*>(d));}
25888
25889 bool
visit_begin(function_decl * d)25890 ir_node_visitor::visit_begin(function_decl* d)
25891 {return visit_begin(static_cast<decl_base*>(d));}
25892
25893 bool
visit_end(function_decl * d)25894 ir_node_visitor::visit_end(function_decl* d)
25895 {return visit_end(static_cast<decl_base*>(d));}
25896
25897 bool
visit_begin(function_decl::parameter * d)25898 ir_node_visitor::visit_begin(function_decl::parameter* d)
25899 {return visit_begin(static_cast<decl_base*>(d));}
25900
25901 bool
visit_end(function_decl::parameter * d)25902 ir_node_visitor::visit_end(function_decl::parameter* d)
25903 {return visit_end(static_cast<decl_base*>(d));}
25904
25905 bool
visit_begin(function_tdecl * d)25906 ir_node_visitor::visit_begin(function_tdecl* d)
25907 {return visit_begin(static_cast<decl_base*>(d));}
25908
25909 bool
visit_end(function_tdecl * d)25910 ir_node_visitor::visit_end(function_tdecl* d)
25911 {return visit_end(static_cast<decl_base*>(d));}
25912
25913 bool
visit_begin(class_tdecl * d)25914 ir_node_visitor::visit_begin(class_tdecl* d)
25915 {return visit_begin(static_cast<decl_base*>(d));}
25916
25917 bool
visit_end(class_tdecl * d)25918 ir_node_visitor::visit_end(class_tdecl* d)
25919 {return visit_end(static_cast<decl_base*>(d));}
25920
25921 bool
visit_begin(class_or_union * t)25922 ir_node_visitor::visit_begin(class_or_union* t)
25923 {return visit_begin(static_cast<type_base*>(t));}
25924
25925 bool
visit_end(class_or_union * t)25926 ir_node_visitor::visit_end(class_or_union* t)
25927 {return visit_end(static_cast<type_base*>(t));}
25928
25929 bool
visit_begin(class_decl * t)25930 ir_node_visitor::visit_begin(class_decl* t)
25931 {return visit_begin(static_cast<type_base*>(t));}
25932
25933 bool
visit_end(class_decl * t)25934 ir_node_visitor::visit_end(class_decl* t)
25935 {return visit_end(static_cast<type_base*>(t));}
25936
25937 bool
visit_begin(union_decl * t)25938 ir_node_visitor::visit_begin(union_decl* t)
25939 {return visit_begin(static_cast<type_base*>(t));}
25940
25941 bool
visit_end(union_decl * t)25942 ir_node_visitor::visit_end(union_decl* t)
25943 {return visit_end(static_cast<type_base*>(t));}
25944
25945 bool
visit_begin(class_decl::base_spec * d)25946 ir_node_visitor::visit_begin(class_decl::base_spec* d)
25947 {return visit_begin(static_cast<decl_base*>(d));}
25948
25949 bool
visit_end(class_decl::base_spec * d)25950 ir_node_visitor::visit_end(class_decl::base_spec* d)
25951 {return visit_end(static_cast<decl_base*>(d));}
25952
25953 bool
visit_begin(member_function_template * d)25954 ir_node_visitor::visit_begin(member_function_template* d)
25955 {return visit_begin(static_cast<decl_base*>(d));}
25956
25957 bool
visit_end(member_function_template * d)25958 ir_node_visitor::visit_end(member_function_template* d)
25959 {return visit_end(static_cast<decl_base*>(d));}
25960
25961 bool
visit_begin(member_class_template * d)25962 ir_node_visitor::visit_begin(member_class_template* d)
25963 {return visit_begin(static_cast<decl_base*>(d));}
25964
25965 bool
visit_end(member_class_template * d)25966 ir_node_visitor::visit_end(member_class_template* d)
25967 {return visit_end(static_cast<decl_base*>(d));}
25968
25969 // </ir_node_visitor stuff>
25970
25971 // <debugging facilities>
25972
25973 /// Generate a different string at each invocation.
25974 ///
25975 /// @return the resulting string.
25976 static string
get_next_string()25977 get_next_string()
25978 {
25979 static __thread size_t counter;
25980 ++counter;
25981 std::ostringstream o;
25982 o << counter;
25983 return o.str();
25984 }
25985
25986 /// Convenience typedef for a hash map of pointer to function_decl and
25987 /// string.
25988 typedef unordered_map<const function_decl*, string,
25989 function_decl::hash,
25990 function_decl::ptr_equal> fns_to_str_map_type;
25991
25992 /// Return a string associated to a given function. Two functions
25993 /// that compare equal would yield the same string, as far as this
25994 /// routine is concerned. And two functions that are different would
25995 /// yield different strings.
25996 ///
25997 /// This is used to debug core diffing issues on functions. The
25998 /// sequence of strings can be given to the 'testdiff2' program that
25999 /// is in the tests/ directory of the source tree, to reproduce core
26000 /// diffing issues on string and thus ease the debugging.
26001 ///
26002 /// @param fn the function to generate a string for.
26003 ///
26004 /// @param m the function_decl* <-> string map to be used by this
26005 /// function to generate strings associated to a function.
26006 ///
26007 /// @return the resulting string.
26008 static const string&
fn_to_str(const function_decl * fn,fns_to_str_map_type & m)26009 fn_to_str(const function_decl* fn,
26010 fns_to_str_map_type& m)
26011 {
26012 fns_to_str_map_type::const_iterator i = m.find(fn);
26013 if (i != m.end())
26014 return i->second;
26015 string s = get_next_string();
26016 return m[fn]= s;
26017 }
26018
26019 /// Generate a sequence of string that matches a given sequence of
26020 /// function. In the resulting sequence, each function is "uniquely
26021 /// representated" by a string. For instance, if the same function "foo"
26022 /// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
26023 /// we don't care about the actual string) would appear at index 1 and 3.
26024 ///
26025 /// @param begin the beginning of the sequence of functions to consider.
26026 ///
26027 /// @param end the end of the sequence of functions. This points to
26028 /// one-passed-the-end of the actual sequence.
26029 ///
26030 /// @param m the function_decl* <-> string map to be used by this
26031 /// function to generate strings associated to a function.
26032 ///
26033 /// @param o the output stream where to emit the generated list of
26034 /// strings to.
26035 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)26036 fns_to_str(vector<function_decl*>::const_iterator begin,
26037 vector<function_decl*>::const_iterator end,
26038 fns_to_str_map_type& m,
26039 std::ostream& o)
26040 {
26041 vector<function_decl*>::const_iterator i;
26042 for (i = begin; i != end; ++i)
26043 o << "'" << fn_to_str(*i, m) << "' ";
26044 }
26045
26046 /// For each sequence of functions given in argument, generate a
26047 /// sequence of string that matches a given sequence of function. In
26048 /// the resulting sequence, each function is "uniquely representated"
26049 /// by a string. For instance, if the same function "foo" appears at
26050 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
26051 /// care about the actual string) would appear at index 1 and 3.
26052 ///
26053 /// @param a_begin the beginning of the sequence of functions to consider.
26054 ///
26055 /// @param a_end the end of the sequence of functions. This points to
26056 /// one-passed-the-end of the actual sequence.
26057 ///
26058 /// @param b_begin the beginning of the second sequence of functions
26059 /// to consider.
26060 ///
26061 /// @param b_end the end of the second sequence of functions.
26062 ///
26063 /// @param m the function_decl* <-> string map to be used by this
26064 /// function to generate strings associated to a function.
26065 ///
26066 /// @param o the output stream where to emit the generated list of
26067 /// strings to.
26068 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)26069 fns_to_str(vector<function_decl*>::const_iterator a_begin,
26070 vector<function_decl*>::const_iterator a_end,
26071 vector<function_decl*>::const_iterator b_begin,
26072 vector<function_decl*>::const_iterator b_end,
26073 fns_to_str_map_type& m,
26074 std::ostream& o)
26075 {
26076 fns_to_str(a_begin, a_end, m, o);
26077 o << "->|<- ";
26078 fns_to_str(b_begin, b_end, m, o);
26079 o << "\n";
26080 }
26081
26082 /// For each sequence of functions given in argument, generate a
26083 /// sequence of string that matches a given sequence of function. In
26084 /// the resulting sequence, each function is "uniquely representated"
26085 /// by a string. For instance, if the same function "foo" appears at
26086 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
26087 /// care about the actual string) would appear at index 1 and 3.
26088 ///
26089 /// @param a_begin the beginning of the sequence of functions to consider.
26090 ///
26091 /// @param a_end the end of the sequence of functions. This points to
26092 /// one-passed-the-end of the actual sequence.
26093 ///
26094 /// @param b_begin the beginning of the second sequence of functions
26095 /// to consider.
26096 ///
26097 /// @param b_end the end of the second sequence of functions.
26098 ///
26099 /// @param o the output stream where to emit the generated list of
26100 /// strings to.
26101 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)26102 fns_to_str(vector<function_decl*>::const_iterator a_begin,
26103 vector<function_decl*>::const_iterator a_end,
26104 vector<function_decl*>::const_iterator b_begin,
26105 vector<function_decl*>::const_iterator b_end,
26106 std::ostream& o)
26107 {
26108 fns_to_str_map_type m;
26109 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
26110 }
26111
26112 // </debugging facilities>
26113
26114 // </class template>
26115
26116 }// end namespace ir
26117 }//end namespace abigail
26118
26119 namespace
26120 {
26121
26122 /// Update the qualified parent name, qualified name and scoped name
26123 /// of a tree decl node.
26124 ///
26125 /// @return true if the tree walking should continue, false otherwise.
26126 ///
26127 /// @param d the tree node to take in account.
26128 bool
do_update(abigail::ir::decl_base * d)26129 qualified_name_setter::do_update(abigail::ir::decl_base* d)
26130 {
26131 std::string parent_qualified_name;
26132 abigail::ir::scope_decl* parent = d->get_scope();
26133 if (parent)
26134 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
26135 else
26136 d->priv_->qualified_parent_name_ = abigail::interned_string();
26137
26138 abigail::environment* env = d->get_environment();
26139 ABG_ASSERT(env);
26140 if (!d->priv_->qualified_parent_name_.empty())
26141 {
26142 if (d->get_name().empty())
26143 d->priv_->qualified_name_ = abigail::interned_string();
26144 else
26145 d->priv_->qualified_name_ =
26146 env->intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
26147 }
26148
26149 if (d->priv_->scoped_name_.empty())
26150 {
26151 if (parent
26152 && !parent->get_is_anonymous()
26153 && !parent->get_name().empty())
26154 d->priv_->scoped_name_ =
26155 env->intern(parent->get_name() + "::" + d->get_name());
26156 else
26157 d->priv_->scoped_name_ =
26158 env->intern(d->get_name());
26159 }
26160
26161 if (!is_scope_decl(d))
26162 return false;
26163
26164 return true;
26165 }
26166
26167 /// This is called when we start visiting a decl node, during the
26168 /// udpate of the qualified name of a given sub-tree.
26169 ///
26170 /// @param d the decl node we are visiting.
26171 ///
26172 /// @return true iff the traversal should keep going.
26173 bool
visit_begin(abigail::ir::decl_base * d)26174 qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
26175 {return do_update(d);}
26176
26177 /// This is called when we start visiting a type node, during the
26178 /// udpate of the qualified name of a given sub-tree.
26179 ///
26180 /// @param d the decl node we are visiting.
26181 ///
26182 /// @return true iff the traversal should keep going.
26183 bool
visit_begin(abigail::ir::type_base * t)26184 qualified_name_setter::visit_begin(abigail::ir::type_base* t)
26185 {
26186 if (abigail::ir::decl_base* d = get_type_declaration(t))
26187 return do_update(d);
26188 return false;
26189 }
26190 }// end anonymous namespace.
26191