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 <utility>
22 #include <vector>
23
24 #include "abg-internal.h"
25 // <headers defining libabigail's API go under here>
26 ABG_BEGIN_EXPORT_DECLARATIONS
27
28 #include "abg-interned-str.h"
29 #include "abg-ir.h"
30 #include "abg-corpus.h"
31 #include "abg-corpus-priv.h"
32
33 ABG_END_EXPORT_DECLARATIONS
34 // </headers defining libabigail's API>
35
36 #include "abg-tools-utils.h"
37 #include "abg-comp-filter.h"
38 #include "abg-ir-priv.h"
39
40 namespace
41 {
42 /// This internal type is a tree walker that walks the sub-tree of a
43 /// type and sets the environment of the type (including its sub-type)
44 /// to a new environment.
45 class environment_setter : public abigail::ir::ir_node_visitor
46 {
47 const abigail::ir::environment* env_;
48
49 public:
environment_setter(const abigail::ir::environment * env)50 environment_setter(const abigail::ir::environment* env)
51 : env_(env)
52 {}
53
54 /// This function is called on each sub-tree node that is a
55 /// declaration. Note that it's also called on some types because
56 /// most types that have a declarations also inherit the type @ref
57 /// decl_base.
58 ///
59 /// @param d the declaration being visited.
60 bool
visit_begin(abigail::ir::decl_base * d)61 visit_begin(abigail::ir::decl_base* d)
62 {
63 if (const abigail::ir::environment* env = d->get_environment())
64 {
65 ABG_ASSERT(env == env_);
66 return false;
67 }
68 else
69 d->set_environment(env_);
70
71 return true;
72
73 }
74
75 /// This function is called on each sub-tree node that is a type.
76 ///
77 /// @param t the type being visited.
78 bool
visit_begin(abigail::ir::type_base * t)79 visit_begin(abigail::ir::type_base* t)
80 {
81 if (abigail::ir::environment* env = t->get_environment())
82 {
83 ABG_ASSERT(env == env_);
84 return false;
85 }
86 else
87 {
88 ABG_ASSERT(!t->get_environment());
89 t->set_environment(env_);
90 }
91 return true;
92 }
93 };
94
95 /// This internal type is a tree walking that is used to set the
96 /// qualified name of a tree of decls and types. It used by the
97 /// function update_qualified_name().
98 class qualified_name_setter : public abigail::ir::ir_node_visitor
99 {
100
101 public:
102 bool
103 do_update(abigail::ir::decl_base* d);
104
105 bool
106 visit_begin(abigail::ir::decl_base* d);
107
108 bool
109 visit_begin(abigail::ir::type_base* d);
110 }; // end class qualified_name_setter
111
112 }// end anon namespace
113
114 namespace abigail
115 {
116
117 // Inject.
118 using std::string;
119 using std::list;
120 using std::vector;
121 using std::unordered_map;
122 using std::dynamic_pointer_cast;
123 using std::static_pointer_cast;
124
125 /// Convenience typedef for a map of string -> string*.
126 typedef unordered_map<string, string*> pool_map_type;
127
128 /// The type of the private data structure of type @ref
129 /// intered_string_pool.
130 struct interned_string_pool::priv
131 {
132 pool_map_type map;
133 }; //end struc struct interned_string_pool::priv
134
135 /// Default constructor.
interned_string_pool()136 interned_string_pool::interned_string_pool()
137 : priv_(new priv)
138 {
139 priv_->map[""] = 0;
140 }
141
142 /// Test if the interned string pool already contains a string with a
143 /// given value.
144 ///
145 /// @param s the string to test for.
146 ///
147 /// @return true if the pool contains a string with the value @p s.
148 bool
has_string(const char * s) const149 interned_string_pool::has_string(const char* s) const
150 {return priv_->map.find(s) != priv_->map.end();}
151
152 /// Get a pointer to the interned string which has a given value.
153 ///
154 /// @param s the value of the interned string to look for.
155 ///
156 /// @return a pointer to the raw string of characters which has the
157 /// value of @p s. Or null if no string with value @p s was interned.
158 const char*
get_string(const char * s) const159 interned_string_pool::get_string(const char* s) const
160 {
161 unordered_map<string, string*>::const_iterator i =
162 priv_->map.find(s);
163 if (i == priv_->map.end())
164 return 0;
165 if (i->second)
166 return i->second->c_str();
167 return "";
168 }
169
170 /// Create an interned string with a given value.
171 ///
172 /// @param str_value the value of the interned string to create.
173 ///
174 /// @return the new created instance of @ref interned_string created.
175 interned_string
create_string(const std::string & str_value)176 interned_string_pool::create_string(const std::string& str_value)
177 {
178 string*& result = priv_->map[str_value];
179 if (!result && !str_value.empty())
180 result = new string(str_value);
181 return interned_string(result);
182 }
183
184 /// Destructor.
~interned_string_pool()185 interned_string_pool::~interned_string_pool()
186 {
187 for (pool_map_type::iterator i = priv_->map.begin();
188 i != priv_->map.end();
189 ++i)
190 if (i->second)
191 delete i->second;
192 }
193
194 /// Equality operator.
195 ///
196 /// @param l the instance of std::string on the left-hand-side of the
197 /// equality operator.
198 ///
199 /// @param r the instance of @ref interned_string on the
200 /// right-hand-side of the equality operator.
201 ///
202 /// @return true iff the two string are equal.
203 bool
operator ==(const std::string & l,const interned_string & r)204 operator==(const std::string& l, const interned_string& r)
205 {return r.operator==(l);}
206
207 bool
operator !=(const std::string & l,const interned_string & r)208 operator!=(const std::string& l, const interned_string& r)
209 {return !(l == r);}
210
211 /// Streaming operator.
212 ///
213 /// Streams an instance of @ref interned_string to an output stream.
214 ///
215 /// @param o the destination output stream.
216 ///
217 /// @param s the instance of @ref interned_string to stream out.
218 ///
219 /// @return the output stream this function just streamed to.
220 std::ostream&
operator <<(std::ostream & o,const interned_string & s)221 operator<<(std::ostream& o, const interned_string& s)
222 {
223 o << static_cast<std::string>(s);
224 return o;
225 }
226
227 /// Concatenation operator.
228 ///
229 /// Concatenate two instances of @ref interned_string, builds an
230 /// instance of std::string with the resulting string and return it.
231 ///
232 /// @param s1 the first string to consider.
233 ///
234 /// @param s2 the second string to consider.
235 ///
236 /// @return the resuting concatenated string.
237 std::string
operator +(const interned_string & s1,const std::string & s2)238 operator+(const interned_string& s1,const std::string& s2)
239 {return static_cast<std::string>(s1) + s2;}
240
241 /// Concatenation operator.
242 ///
243 /// Concatenate two instances of @ref interned_string, builds an
244 /// instance of std::string with the resulting string and return it.
245 ///
246 /// @param s1 the first string to consider.
247 ///
248 /// @param s2 the second string to consider.
249 ///
250 /// @return the resuting concatenated string.
251 std::string
operator +(const std::string & s1,const interned_string & s2)252 operator+(const std::string& s1, const interned_string& s2)
253 {return s1 + static_cast<std::string>(s2);}
254
255 namespace ir
256 {
257
258 static size_t
259 hash_as_canonical_type_or_constant(const type_base *t);
260
261 static bool
262 has_generic_anonymous_internal_type_name(const decl_base *d);
263
264 static interned_string
265 get_generic_anonymous_internal_type_name(const decl_base *d);
266
267 /// @brief the location of a token represented in its simplest form.
268 /// Instances of this type are to be stored in a sorted vector, so the
269 /// type must have proper relational operators.
270 class expanded_location
271 {
272 string path_;
273 unsigned line_;
274 unsigned column_;
275
276 expanded_location();
277
278 public:
279
280 friend class location_manager;
281
expanded_location(const string & path,unsigned line,unsigned column)282 expanded_location(const string& path, unsigned line, unsigned column)
283 : path_(path), line_(line), column_(column)
284 {}
285
286 bool
operator ==(const expanded_location & l) const287 operator==(const expanded_location& l) const
288 {
289 return (path_ == l.path_
290 && line_ == l.line_
291 && column_ && l.column_);
292 }
293
294 bool
operator <(const expanded_location & l) const295 operator<(const expanded_location& l) const
296 {
297 if (path_ < l.path_)
298 return true;
299 else if (path_ > l.path_)
300 return false;
301
302 if (line_ < l.line_)
303 return true;
304 else if (line_ > l.line_)
305 return false;
306
307 return column_ < l.column_;
308 }
309 };
310
311 /// Expand the location into a tripplet path, line and column number.
312 ///
313 /// @param path the output parameter where this function sets the
314 /// expanded path.
315 ///
316 /// @param line the output parameter where this function sets the
317 /// expanded line.
318 ///
319 /// @param column the ouptut parameter where this function sets the
320 /// expanded column.
321 void
expand(std::string & path,unsigned & line,unsigned & column) const322 location::expand(std::string& path, unsigned& line, unsigned& column) const
323 {
324 ABG_ASSERT(get_location_manager());
325 get_location_manager()->expand_location(*this, path, line, column);
326 }
327
328
329 /// Expand the location into a string.
330 ///
331 /// @return the string representing the location.
332 string
expand(void) const333 location::expand(void) const
334 {
335 string path, result;
336 unsigned line = 0, column = 0;
337 expand(path, line, column);
338
339 std::ostringstream o;
340 o << path << ":" << line << ":" << column;
341 return o.str();
342 }
343
344 struct location_manager::priv
345 {
346 /// This sorted vector contains the expanded locations of the tokens
347 /// coming from a given ABI Corpus. The index of a given expanded
348 /// location in the table gives us an integer that is used to build
349 /// instance of location types.
350 std::vector<expanded_location> locs;
351 };
352
location_manager()353 location_manager::location_manager()
354 {priv_ = shared_ptr<location_manager::priv>(new location_manager::priv);}
355
356 /// Insert the triplet representing a source locus into our internal
357 /// vector of location triplet. Return an instance of location type,
358 /// built from an integral type that represents the index of the
359 /// source locus triplet into our source locus table.
360 ///
361 /// @param file_path the file path of the source locus
362 /// @param line the line number of the source location
363 /// @param col the column number of the source location
364 location
create_new_location(const std::string & file_path,size_t line,size_t col)365 location_manager::create_new_location(const std::string& file_path,
366 size_t line,
367 size_t col)
368 {
369 expanded_location l(file_path, line, col);
370
371 // Just append the new expanded location to the end of the vector
372 // and return its index. Note that indexes start at 1.
373 priv_->locs.push_back(l);
374 return location(priv_->locs.size(), this);
375 }
376
377 /// Given an instance of location type, return the triplet
378 /// {path,line,column} that represents the source locus. Note that
379 /// the location must have been previously created from the function
380 /// location_manager::create_new_location, otherwise this function yields
381 /// unexpected results, including possibly a crash.
382 ///
383 /// @param location the instance of location type to expand
384 /// @param path the resulting path of the source locus
385 /// @param line the resulting line of the source locus
386 /// @param column the resulting colum of the source locus
387 void
expand_location(const location & location,std::string & path,unsigned & line,unsigned & column) const388 location_manager::expand_location(const location& location,
389 std::string& path,
390 unsigned& line,
391 unsigned& column) const
392 {
393 if (location.value_ == 0)
394 return;
395 expanded_location &l = priv_->locs[location.value_ - 1];
396 path = l.path_;
397 line = l.line_;
398 column = l.column_;
399 }
400
401 typedef unordered_map<function_type_sptr,
402 bool,
403 function_type::hash,
404 type_shared_ptr_equal> fn_type_ptr_map;
405
406 // <type_maps stuff>
407
408 struct type_maps::priv
409 {
410 mutable istring_type_base_wptrs_map_type basic_types_;
411 mutable istring_type_base_wptrs_map_type class_types_;
412 mutable istring_type_base_wptrs_map_type union_types_;
413 mutable istring_type_base_wptrs_map_type enum_types_;
414 mutable istring_type_base_wptrs_map_type typedef_types_;
415 mutable istring_type_base_wptrs_map_type qualified_types_;
416 mutable istring_type_base_wptrs_map_type pointer_types_;
417 mutable istring_type_base_wptrs_map_type reference_types_;
418 mutable istring_type_base_wptrs_map_type array_types_;
419 mutable istring_type_base_wptrs_map_type subrange_types_;
420 mutable istring_type_base_wptrs_map_type function_types_;
421 mutable vector<type_base_wptr> sorted_types_;
422 }; // end struct type_maps::priv
423
type_maps()424 type_maps::type_maps()
425 : priv_(new priv)
426 {}
427
428 /// Test if the type_maps is empty.
429 ///
430 /// @return true iff the type_maps is empty.
431 bool
empty() const432 type_maps::empty() const
433 {
434 return (basic_types().empty()
435 && class_types().empty()
436 && union_types().empty()
437 && enum_types().empty()
438 && typedef_types().empty()
439 && qualified_types().empty()
440 && pointer_types().empty()
441 && reference_types().empty()
442 && array_types().empty()
443 && subrange_types().empty()
444 && function_types().empty());
445 }
446
447 /// Getter for the map that associates the name of a basic type to the
448 /// vector instances of type_decl_sptr that represents that type.
449 const istring_type_base_wptrs_map_type&
basic_types() const450 type_maps::basic_types() const
451 {return priv_->basic_types_;}
452
453 /// Getter for the map that associates the name of a basic type to the
454 /// vector of instances of @ref type_decl_sptr that represents that
455 /// type.
456 istring_type_base_wptrs_map_type&
basic_types()457 type_maps::basic_types()
458 {return priv_->basic_types_;}
459
460 /// Getter for the map that associates the name of a class type to the
461 /// vector of instances of @ref class_decl_sptr that represents that
462 /// type.
463 const istring_type_base_wptrs_map_type&
class_types() const464 type_maps::class_types() const
465 {return priv_->class_types_;}
466
467 /// Getter for the map that associates the name of a class type to the
468 /// vector of instances of @ref class_decl_sptr that represents that
469 /// type.
470 istring_type_base_wptrs_map_type&
class_types()471 type_maps::class_types()
472 {return priv_->class_types_;}
473
474 /// Getter for the map that associates the name of a union type to the
475 /// vector of instances of @ref union_decl_sptr that represents that
476 /// type.
477 istring_type_base_wptrs_map_type&
union_types()478 type_maps::union_types()
479 {return priv_->union_types_;}
480
481 /// Getter for the map that associates the name of a union type to the
482 /// vector of instances of @ref union_decl_sptr that represents that
483 /// type.
484 const istring_type_base_wptrs_map_type&
union_types() const485 type_maps::union_types() const
486 {return priv_->union_types_;}
487
488 /// Getter for the map that associates the name of an enum type to the
489 /// vector of instances of @ref enum_type_decl_sptr that represents
490 /// that type.
491 istring_type_base_wptrs_map_type&
enum_types()492 type_maps::enum_types()
493 {return priv_->enum_types_;}
494
495 /// Getter for the map that associates the name of an enum type to the
496 /// vector of instances of @ref enum_type_decl_sptr that represents
497 /// that type.
498 const istring_type_base_wptrs_map_type&
enum_types() const499 type_maps::enum_types() const
500 {return priv_->enum_types_;}
501
502 /// Getter for the map that associates the name of a typedef to the
503 /// vector of instances of @ref typedef_decl_sptr that represents tha
504 /// type.
505 istring_type_base_wptrs_map_type&
typedef_types()506 type_maps::typedef_types()
507 {return priv_->typedef_types_;}
508
509 /// Getter for the map that associates the name of a typedef to the
510 /// vector of instances of @ref typedef_decl_sptr that represents tha
511 /// type.
512 const istring_type_base_wptrs_map_type&
typedef_types() const513 type_maps::typedef_types() const
514 {return priv_->typedef_types_;}
515
516 /// Getter for the map that associates the name of a qualified type to
517 /// the vector of instances of @ref qualified_type_def_sptr.
518 istring_type_base_wptrs_map_type&
qualified_types()519 type_maps::qualified_types()
520 {return priv_->qualified_types_;}
521
522 /// Getter for the map that associates the name of a qualified type to
523 /// the vector of instances of @ref qualified_type_def_sptr.
524 const istring_type_base_wptrs_map_type&
qualified_types() const525 type_maps::qualified_types() const
526 {return priv_->qualified_types_;}
527
528 /// Getter for the map that associates the name of a pointer type to
529 /// the vector of instances of @ref pointer_type_def_sptr that
530 /// represents that type.
531 istring_type_base_wptrs_map_type&
pointer_types()532 type_maps::pointer_types()
533 {return priv_->pointer_types_;}
534
535 /// Getter for the map that associates the name of a pointer type to
536 /// the vector of instances of @ref pointer_type_def_sptr that
537 /// represents that type.
538 const istring_type_base_wptrs_map_type&
pointer_types() const539 type_maps::pointer_types() const
540 {return priv_->pointer_types_;}
541
542 /// Getter for the map that associates the name of a reference type to
543 /// the vector of instances of @ref reference_type_def_sptr that
544 /// represents that type.
545 istring_type_base_wptrs_map_type&
reference_types()546 type_maps::reference_types()
547 {return priv_->reference_types_;}
548
549 /// Getter for the map that associates the name of a reference type to
550 /// the vector of instances of @ref reference_type_def_sptr that
551 /// represents that type.
552 const istring_type_base_wptrs_map_type&
reference_types() const553 type_maps::reference_types() const
554 {return priv_->reference_types_;}
555
556 /// Getter for the map that associates the name of an array type to
557 /// the vector of instances of @ref array_type_def_sptr that
558 /// represents that type.
559 istring_type_base_wptrs_map_type&
array_types()560 type_maps::array_types()
561 {return priv_->array_types_;}
562
563 /// Getter for the map that associates the name of an array type to
564 /// the vector of instances of @ref array_type_def_sptr that
565 /// represents that type.
566 const istring_type_base_wptrs_map_type&
array_types() const567 type_maps::array_types() const
568 {return priv_->array_types_;}
569
570 /// Getter for the map that associates the name of a subrange type to
571 /// the vector of instances of @ref array_type_def::subrange_sptr that
572 /// represents that type.
573 istring_type_base_wptrs_map_type&
subrange_types()574 type_maps::subrange_types()
575 {return priv_->subrange_types_;}
576
577 /// Getter for the map that associates the name of a subrange type to
578 /// the vector of instances of @ref array_type_def::subrange_sptr that
579 /// represents that type.
580 const istring_type_base_wptrs_map_type&
subrange_types() const581 type_maps::subrange_types() const
582 {return priv_->subrange_types_;}
583
584 /// Getter for the map that associates the name of a function type to
585 /// the vector of instances of @ref function_type_sptr that represents
586 /// that type.
587 const istring_type_base_wptrs_map_type&
function_types() const588 type_maps::function_types() const
589 {return priv_->function_types_;}
590
591 /// Getter for the map that associates the name of a function type to
592 /// the vector of instances of @ref function_type_sptr that represents
593 /// that type.
594 istring_type_base_wptrs_map_type&
function_types()595 type_maps::function_types()
596 {return priv_->function_types_;}
597
598 /// A comparison functor to compare/sort types based on their pretty
599 /// representations.
600 struct type_name_comp
601 {
602 /// Comparison operator for two instances of @ref type_base.
603 ///
604 /// This compares the two types by lexicographically comparing their
605 /// pretty representation.
606 ///
607 /// @param l the left-most type to compare.
608 ///
609 /// @param r the right-most type to compare.
610 ///
611 /// @return true iff @p l < @p r.
612 bool
operator ()abigail::ir::type_name_comp613 operator()(type_base *l, type_base *r) const
614 {
615 if (l == 0 && r == 0)
616 return false;
617
618 string l_repr = get_pretty_representation(l);
619 string r_repr = get_pretty_representation(r);
620 return l_repr < r_repr;
621 }
622
623 /// Comparison operator for two instances of @ref type_base.
624 ///
625 /// This compares the two types by lexicographically comparing their
626 /// pretty representation.
627 ///
628 /// @param l the left-most type to compare.
629 ///
630 /// @param r the right-most type to compare.
631 ///
632 /// @return true iff @p l < @p r.
633 bool
operator ()abigail::ir::type_name_comp634 operator()(const type_base_sptr &l, const type_base_sptr &r) const
635 {return operator()(l.get(), r.get());}
636
637 /// Comparison operator for two instances of @ref type_base.
638 ///
639 /// This compares the two types by lexicographically comparing their
640 /// pretty representation.
641 ///
642 /// @param l the left-most type to compare.
643 ///
644 /// @param r the right-most type to compare.
645 ///
646 /// @return true iff @p l < @p r.
647 bool
operator ()abigail::ir::type_name_comp648 operator()(const type_base_wptr &l, const type_base_wptr &r) const
649 {return operator()(type_base_sptr(l), type_base_sptr(r));}
650 }; // end struct type_name_comp
651
652 /// Compare two types by comparing their canonical types if present.
653 ///
654 /// If the canonical types are not present (because the types have not
655 /// yet been canonicalized, for instance) then the types are compared
656 /// structurally.
657 ///
658 /// @param l the first type to take into account in the comparison.
659 ///
660 /// @param r the second type to take into account in the comparison.
661 template<typename T>
662 bool
try_canonical_compare(const T * l,const T * r)663 try_canonical_compare(const T *l, const T *r)
664 {
665 if (const type_base *lc = l->get_naked_canonical_type())
666 if (const type_base *rc = r->get_naked_canonical_type())
667 return lc == rc;
668 return equals(*l, *r, 0);
669 }
670
671 /// Getter of all types types sorted by their pretty representation.
672 ///
673 /// @return a sorted vector of all types sorted by their pretty
674 /// representation.
675 const vector<type_base_wptr>&
get_types_sorted_by_name() const676 type_maps::get_types_sorted_by_name() const
677 {
678 if (priv_->sorted_types_.empty())
679 {
680 istring_type_base_wptrs_map_type::const_iterator i;
681 vector<type_base_wptr>::const_iterator j;
682
683 for (i = basic_types().begin(); i != basic_types().end(); ++i)
684 for (j = i->second.begin(); j != i->second.end(); ++j)
685 priv_->sorted_types_.push_back(*j);
686
687 for (i = class_types().begin(); i != class_types().end(); ++i)
688 for (j = i->second.begin(); j != i->second.end(); ++j)
689 priv_->sorted_types_.push_back(*j);
690
691 for (i = union_types().begin(); i != union_types().end(); ++i)
692 for (j = i->second.begin(); j != i->second.end(); ++j)
693 priv_->sorted_types_.push_back(*j);
694
695 for (i = enum_types().begin(); i != enum_types().end(); ++i)
696 for (j = i->second.begin(); j != i->second.end(); ++j)
697 priv_->sorted_types_.push_back(*j);
698
699 for (i = typedef_types().begin(); i != typedef_types().end(); ++i)
700 for (j = i->second.begin(); j != i->second.end(); ++j)
701 priv_->sorted_types_.push_back(*j);
702
703 type_name_comp comp;
704 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
705 }
706
707 return priv_->sorted_types_;
708 }
709
710 // </type_maps stuff>
711
712 // <translation_unit stuff>
713
714 /// Constructor of translation_unit.
715 ///
716 /// @param env the environment of this translation unit. Please note
717 /// that the life time of the environment must be greater than the
718 /// life time of the translation unit because the translation uses
719 /// resources that are allocated in the environment.
720 ///
721 /// @param path the location of the translation unit.
722 ///
723 /// @param address_size the size of addresses in the translation unit,
724 /// in bits.
translation_unit(const environment * env,const std::string & path,char address_size)725 translation_unit::translation_unit(const environment* env,
726 const std::string& path,
727 char address_size)
728 : priv_(new priv(env))
729 {
730 priv_->path_ = path;
731 priv_->address_size_ = address_size;
732 }
733
734 /// Getter of the the global scope of the translation unit.
735 ///
736 /// @return the global scope of the current translation unit. If
737 /// there is not global scope allocated yet, this function creates one
738 /// and returns it.
739 const scope_decl_sptr&
get_global_scope() const740 translation_unit::get_global_scope() const
741 {
742 return const_cast<translation_unit*>(this)->get_global_scope();
743 }
744
745 /// Getter of the the global scope of the translation unit.
746 ///
747 /// @return the global scope of the current translation unit. If
748 /// there is not global scope allocated yet, this function creates one
749 /// and returns it.
750 scope_decl_sptr&
get_global_scope()751 translation_unit::get_global_scope()
752 {
753 if (!priv_->global_scope_)
754 {
755 priv_->global_scope_.reset
756 (new global_scope(const_cast<translation_unit*>(this)));
757 // The global scope must be out of the same environment as its
758 // translation unit.
759 priv_->global_scope_->
760 set_environment(const_cast<environment*>(get_environment()));
761 priv_->global_scope_->set_translation_unit
762 (const_cast<translation_unit*>(this));
763 }
764 return priv_->global_scope_;
765 }
766
767 /// Getter of the types of the current @ref translation_unit.
768 ///
769 /// @return the maps of the types of the translation unit.
770 const type_maps&
get_types() const771 translation_unit::get_types() const
772 {return priv_->types_;}
773
774 /// Getter of the types of the current @ref translation_unit.
775 ///
776 /// @return the maps of the types of the translation unit.
777 type_maps&
get_types()778 translation_unit::get_types()
779 {return priv_->types_;}
780
781 /// Get the vector of function types that are used in the current
782 /// translation unit.
783 ///
784 /// @return the vector of function types that are used in the current
785 /// translation unit.
786 const vector<function_type_sptr>&
get_live_fn_types() const787 translation_unit::get_live_fn_types() const
788 {return priv_->live_fn_types_;}
789
790 /// Getter of the environment of the current @ref translation_unit.
791 ///
792 /// @return the translation unit of the current translation unit.
793 const environment*
get_environment() const794 translation_unit::get_environment() const
795 {return priv_->env_;}
796
797 /// Getter of the environment of the current @ref translation_unit.
798 ///
799 /// @return the translation unit of the current translation unit.
800 environment*
get_environment()801 translation_unit::get_environment()
802 {return const_cast<environment*>(priv_->env_);}
803
804 /// Setter of the environment of the current @ref translation_unit.
805 ///
806 /// @param env the environment.
807 void
set_environment(const environment * env)808 translation_unit::set_environment(const environment* env)
809 {priv_->env_ = env;}
810
811 /// Getter of the language of the source code of the translation unit.
812 ///
813 /// @return the language of the source code.
814 translation_unit::language
get_language() const815 translation_unit::get_language() const
816 {return priv_->language_;}
817
818 /// Setter of the language of the source code of the translation unit.
819 ///
820 /// @param l the new language.
821 void
set_language(language l)822 translation_unit::set_language(language l)
823 {priv_->language_ = l;}
824
825
826 /// Get the path of the current translation unit.
827 ///
828 /// This path is relative to the build directory of the translation
829 /// unit as returned by translation_unit::get_compilation_dir_path.
830 ///
831 /// @return the relative path of the compilation unit associated to
832 /// the current instance of translation_unit.
833 //
834 const std::string&
get_path() const835 translation_unit::get_path() const
836 {return priv_->path_;}
837
838 /// Set the path associated to the current instance of
839 /// translation_unit.
840 ///
841 /// This path is relative to the build directory of the translation
842 /// unit as returned by translation_unit::get_compilation_dir_path.
843 ///
844 /// @param a_path the new relative path to set.
845 void
set_path(const string & a_path)846 translation_unit::set_path(const string& a_path)
847 {priv_->path_ = a_path;}
848
849
850 /// Get the path of the directory that was 'current' when the
851 /// translation unit was compiled.
852 ///
853 /// Note that the path returned by translation_unit::get_path is
854 /// relative to the path returned by this function.
855 ///
856 /// @return the compilation directory for the current translation
857 /// unit.
858 const std::string&
get_compilation_dir_path() const859 translation_unit::get_compilation_dir_path() const
860 {return priv_->comp_dir_path_;}
861
862 /// Set the path of the directory that was 'current' when the
863 /// translation unit was compiled.
864 ///
865 /// Note that the path returned by translation_unit::get_path is
866 /// relative to the path returned by this function.
867 ///
868 /// @param the compilation directory for the current translation unit.
869 void
set_compilation_dir_path(const std::string & d)870 translation_unit::set_compilation_dir_path(const std::string& d)
871 {priv_->comp_dir_path_ = d;}
872
873 /// Get the concatenation of the build directory and the relative path
874 /// of the translation unit.
875 ///
876 /// @return the absolute path of the translation unit.
877 const std::string&
get_absolute_path() const878 translation_unit::get_absolute_path() const
879 {
880 if (priv_->abs_path_.empty())
881 {
882 string path;
883 if (!priv_->path_.empty())
884 {
885 if (!priv_->comp_dir_path_.empty())
886 {
887 path = priv_->comp_dir_path_;
888 path += "/";
889 }
890 path += priv_->path_;
891 }
892 priv_->abs_path_ = path;
893 }
894
895 return priv_->abs_path_;
896 }
897
898 /// Set the corpus this translation unit is a member of.
899 ///
900 /// Note that adding a translation unit to a @ref corpus automatically
901 /// triggers a call to this member function.
902 ///
903 /// @param corpus the corpus.
904 void
set_corpus(corpus * c)905 translation_unit::set_corpus(corpus* c)
906 {priv_->corp = c;}
907
908 /// Get the corpus this translation unit is a member of.
909 ///
910 /// @return the parent corpus, or nil if this doesn't belong to any
911 /// corpus yet.
912 corpus*
get_corpus()913 translation_unit::get_corpus()
914 {return priv_->corp;}
915
916 /// Get the corpus this translation unit is a member of.
917 ///
918 /// @return the parent corpus, or nil if this doesn't belong to any
919 /// corpus yet.
920 const corpus*
get_corpus() const921 translation_unit::get_corpus() const
922 {return const_cast<translation_unit*>(this)->get_corpus();}
923
924 /// Getter of the location manager for the current translation unit.
925 ///
926 /// @return a reference to the location manager for the current
927 /// translation unit.
928 location_manager&
get_loc_mgr()929 translation_unit::get_loc_mgr()
930 {return priv_->loc_mgr_;}
931
932 /// const Getter of the location manager.
933 ///
934 /// @return a const reference to the location manager for the current
935 /// translation unit.
936 const location_manager&
get_loc_mgr() const937 translation_unit::get_loc_mgr() const
938 {return priv_->loc_mgr_;}
939
940 /// Tests whether if the current translation unit contains ABI
941 /// artifacts or not.
942 ///
943 /// @return true iff the current translation unit is empty.
944 bool
is_empty() const945 translation_unit::is_empty() const
946 {return get_global_scope()->is_empty();}
947
948 /// Getter of the address size in this translation unit.
949 ///
950 /// @return the address size, in bits.
951 char
get_address_size() const952 translation_unit::get_address_size() const
953 {return priv_->address_size_;}
954
955 /// Setter of the address size in this translation unit.
956 ///
957 /// @param a the new address size in bits.
958 void
set_address_size(char a)959 translation_unit::set_address_size(char a)
960 {priv_->address_size_= a;}
961
962 /// Getter of the 'is_constructed" flag. It says if the translation
963 /// unit is fully constructed or not.
964 ///
965 /// This flag is important for cases when comparison might depend on
966 /// if the translation unit is fully built or not. For instance, when
967 /// reading types from DWARF, the virtual methods of a class are not
968 /// necessarily fully constructed until we have reached the end of the
969 /// translation unit. In that case, before we've reached the end of
970 /// the translation unit, we might not take virtual functions into
971 /// account when comparing classes.
972 ///
973 /// @return true if the translation unit is constructed.
974 bool
is_constructed() const975 translation_unit::is_constructed() const
976 {return priv_->is_constructed_;}
977
978 /// Setter of the 'is_constructed" flag. It says if the translation
979 /// unit is fully constructed or not.
980 ///
981 /// This flag is important for cases when comparison might depend on
982 /// if the translation unit is fully built or not. For instance, when
983 /// reading types from DWARF, the virtual methods of a class are not
984 /// necessarily fully constructed until we have reached the end of the
985 /// translation unit. In that case, before we've reached the end of
986 /// the translation unit, we might not take virtual functions into
987 /// account when comparing classes.
988 ///
989 /// @param f true if the translation unit is constructed.
990 void
set_is_constructed(bool f)991 translation_unit::set_is_constructed(bool f)
992 {priv_->is_constructed_ = f;}
993
994 /// Compare the current translation unit against another one.
995 ///
996 /// @param other the other tu to compare against.
997 ///
998 /// @return true if the two translation units are equal, false
999 /// otherwise.
1000 bool
operator ==(const translation_unit & other) const1001 translation_unit::operator==(const translation_unit& other)const
1002 {
1003 if (get_address_size() != other.get_address_size())
1004 return false;
1005
1006 return *get_global_scope() == *other.get_global_scope();
1007 }
1008
1009 /// Inequality operator.
1010 ///
1011 /// @param o the instance of @ref translation_unit to compare the
1012 /// current instance against.
1013 ///
1014 /// @return true iff the current instance is different from @p o.
1015 bool
operator !=(const translation_unit & o) const1016 translation_unit::operator!=(const translation_unit& o) const
1017 {return ! operator==(o);}
1018
1019 /// Ensure that the life time of a function type is bound to the life
1020 /// time of the current translation unit.
1021 ///
1022 /// @param ftype the function time which life time to bind to the life
1023 /// time of the current instance of @ref translation_unit. That is,
1024 /// it's onlyh when the translation unit is destroyed that the
1025 /// function type can be destroyed to.
1026 void
bind_function_type_life_time(function_type_sptr ftype) const1027 translation_unit::bind_function_type_life_time(function_type_sptr ftype) const
1028 {
1029 const environment* env = get_environment();
1030 ABG_ASSERT(env);
1031
1032 const_cast<translation_unit*>(this)->priv_->live_fn_types_.push_back(ftype);
1033
1034 interned_string repr = get_type_name(ftype);
1035 const_cast<translation_unit*>(this)->get_types().function_types()[repr].
1036 push_back(ftype);
1037
1038 // The function type must be out of the same environment as its
1039 // translation unit.
1040 if (const environment* e = ftype->get_environment())
1041 ABG_ASSERT(env == e);
1042 ftype->set_environment(const_cast<environment*>(env));
1043
1044 if (const translation_unit* existing_tu = ftype->get_translation_unit())
1045 ABG_ASSERT(existing_tu == this);
1046 else
1047 ftype->set_translation_unit(const_cast<translation_unit*>(this));
1048 }
1049
1050 /// This implements the ir_traversable_base::traverse virtual
1051 /// function.
1052 ///
1053 /// @param v the visitor used on the member nodes of the translation
1054 /// unit during the traversal.
1055 ///
1056 /// @return true if the entire type IR tree got traversed, false
1057 /// otherwise.
1058 bool
traverse(ir_node_visitor & v)1059 translation_unit::traverse(ir_node_visitor& v)
1060 {return get_global_scope()->traverse(v);}
1061
~translation_unit()1062 translation_unit::~translation_unit()
1063 {}
1064
1065 /// Converts a translation_unit::language enumerator into a string.
1066 ///
1067 /// @param l the language enumerator to translate.
1068 ///
1069 /// @return the resulting string.
1070 string
translation_unit_language_to_string(translation_unit::language l)1071 translation_unit_language_to_string(translation_unit::language l)
1072 {
1073 switch (l)
1074 {
1075 case translation_unit::LANG_UNKNOWN:
1076 return "LANG_UNKNOWN";
1077 case translation_unit::LANG_Cobol74:
1078 return "LANG_Cobol74";
1079 case translation_unit::LANG_Cobol85:
1080 return "LANG_Cobol85";
1081 case translation_unit::LANG_C89:
1082 return "LANG_C89";
1083 case translation_unit::LANG_C99:
1084 return "LANG_C99";
1085 case translation_unit::LANG_C11:
1086 return "LANG_C11";
1087 case translation_unit::LANG_C:
1088 return "LANG_C";
1089 case translation_unit::LANG_C_plus_plus_11:
1090 return "LANG_C_plus_plus_11";
1091 case translation_unit::LANG_C_plus_plus_14:
1092 return "LANG_C_plus_plus_14";
1093 case translation_unit::LANG_C_plus_plus:
1094 return "LANG_C_plus_plus";
1095 case translation_unit::LANG_ObjC:
1096 return "LANG_ObjC";
1097 case translation_unit::LANG_ObjC_plus_plus:
1098 return "LANG_ObjC_plus_plus";
1099 case translation_unit::LANG_Fortran77:
1100 return "LANG_Fortran77";
1101 case translation_unit::LANG_Fortran90:
1102 return "LANG_Fortran90";
1103 case translation_unit::LANG_Fortran95:
1104 return "LANG_Fortran95";
1105 case translation_unit::LANG_Ada83:
1106 return "LANG_Ada83";
1107 case translation_unit::LANG_Ada95:
1108 return "LANG_Ada95";
1109 case translation_unit::LANG_Pascal83:
1110 return "LANG_Pascal83";
1111 case translation_unit::LANG_Modula2:
1112 return "LANG_Modula2";
1113 case translation_unit::LANG_Java:
1114 return "LANG_Java";
1115 case translation_unit::LANG_PL1:
1116 return "LANG_PL1";
1117 case translation_unit::LANG_UPC:
1118 return "LANG_UPC";
1119 case translation_unit::LANG_D:
1120 return "LANG_D";
1121 case translation_unit::LANG_Python:
1122 return "LANG_Python";
1123 case translation_unit::LANG_Go:
1124 return "LANG_Go";
1125 case translation_unit::LANG_Mips_Assembler:
1126 return "LANG_Mips_Assembler";
1127 default:
1128 return "LANG_UNKNOWN";
1129 }
1130
1131 return "LANG_UNKNOWN";
1132 }
1133
1134 /// Parse a string representing a language into a
1135 /// translation_unit::language enumerator into a string.
1136 ///
1137 /// @param l the string representing the language.
1138 ///
1139 /// @return the resulting translation_unit::language enumerator.
1140 translation_unit::language
string_to_translation_unit_language(const string & l)1141 string_to_translation_unit_language(const string& l)
1142 {
1143 if (l == "LANG_Cobol74")
1144 return translation_unit::LANG_Cobol74;
1145 else if (l == "LANG_Cobol85")
1146 return translation_unit::LANG_Cobol85;
1147 else if (l == "LANG_C89")
1148 return translation_unit::LANG_C89;
1149 else if (l == "LANG_C99")
1150 return translation_unit::LANG_C99;
1151 else if (l == "LANG_C11")
1152 return translation_unit::LANG_C11;
1153 else if (l == "LANG_C")
1154 return translation_unit::LANG_C;
1155 else if (l == "LANG_C_plus_plus_11")
1156 return translation_unit::LANG_C_plus_plus_11;
1157 else if (l == "LANG_C_plus_plus_14")
1158 return translation_unit::LANG_C_plus_plus_14;
1159 else if (l == "LANG_C_plus_plus")
1160 return translation_unit::LANG_C_plus_plus;
1161 else if (l == "LANG_ObjC")
1162 return translation_unit::LANG_ObjC;
1163 else if (l == "LANG_ObjC_plus_plus")
1164 return translation_unit::LANG_ObjC_plus_plus;
1165 else if (l == "LANG_Fortran77")
1166 return translation_unit::LANG_Fortran77;
1167 else if (l == "LANG_Fortran90")
1168 return translation_unit::LANG_Fortran90;
1169 else if (l == "LANG_Fortran95")
1170 return translation_unit::LANG_Fortran95;
1171 else if (l == "LANG_Ada83")
1172 return translation_unit::LANG_Ada83;
1173 else if (l == "LANG_Ada95")
1174 return translation_unit::LANG_Ada95;
1175 else if (l == "LANG_Pascal83")
1176 return translation_unit::LANG_Pascal83;
1177 else if (l == "LANG_Modula2")
1178 return translation_unit::LANG_Modula2;
1179 else if (l == "LANG_Java")
1180 return translation_unit::LANG_Java;
1181 else if (l == "LANG_PL1")
1182 return translation_unit::LANG_PL1;
1183 else if (l == "LANG_UPC")
1184 return translation_unit::LANG_UPC;
1185 else if (l == "LANG_D")
1186 return translation_unit::LANG_D;
1187 else if (l == "LANG_Python")
1188 return translation_unit::LANG_Python;
1189 else if (l == "LANG_Go")
1190 return translation_unit::LANG_Go;
1191 else if (l == "LANG_Mips_Assembler")
1192 return translation_unit::LANG_Mips_Assembler;
1193
1194 return translation_unit::LANG_UNKNOWN;
1195 }
1196
1197 /// Test if a language enumerator designates the C language.
1198 ///
1199 /// @param l the language enumerator to consider.
1200 ///
1201 /// @return true iff @p l designates the C language.
1202 bool
is_c_language(translation_unit::language l)1203 is_c_language(translation_unit::language l)
1204 {
1205 return (l == translation_unit::LANG_C89
1206 || l == translation_unit::LANG_C99
1207 || l == translation_unit::LANG_C11
1208 || l == translation_unit::LANG_C);
1209 }
1210
1211 /// Test if a language enumerator designates the C++ language.
1212 ///
1213 /// @param l the language enumerator to consider.
1214 ///
1215 /// @return true iff @p l designates the C++ language.
1216 bool
is_cplus_plus_language(translation_unit::language l)1217 is_cplus_plus_language(translation_unit::language l)
1218 {
1219 return (l == translation_unit::LANG_C_plus_plus_03
1220 || l == translation_unit::LANG_C_plus_plus_11
1221 || l == translation_unit::LANG_C_plus_plus_14
1222 || l == translation_unit::LANG_C_plus_plus);
1223 }
1224
1225 /// Test if a language enumerator designates the Java language.
1226 ///
1227 /// @param l the language enumerator to consider.
1228 ///
1229 /// @return true iff @p l designates the Java language.
1230 bool
is_java_language(translation_unit::language l)1231 is_java_language(translation_unit::language l)
1232 {return l == translation_unit::LANG_Java;}
1233
1234 /// Test if a language enumerator designates the Ada language.
1235 ///
1236 /// @param l the language enumerator to consider.
1237 ///
1238 /// @return true iff @p l designates the Ada language.
1239 bool
is_ada_language(translation_unit::language l)1240 is_ada_language(translation_unit::language l)
1241 {
1242 return (l == translation_unit::LANG_Ada83
1243 || l == translation_unit::LANG_Ada95);
1244 }
1245
1246 /// A deep comparison operator for pointers to translation units.
1247 ///
1248 /// @param l the first translation unit to consider for the comparison.
1249 ///
1250 /// @param r the second translation unit to consider for the comparison.
1251 ///
1252 /// @return true if the two translation units are equal, false otherwise.
1253 bool
operator ==(const translation_unit_sptr & l,const translation_unit_sptr & r)1254 operator==(const translation_unit_sptr& l, const translation_unit_sptr& r)
1255 {
1256 if (l.get() == r.get())
1257 return true;
1258
1259 if (!!l != !!r)
1260 return false;
1261
1262 return *l == *r;
1263 }
1264
1265 /// A deep inequality operator for pointers to translation units.
1266 ///
1267 /// @param l the first translation unit to consider for the comparison.
1268 ///
1269 /// @param r the second translation unit to consider for the comparison.
1270 ///
1271 /// @return true iff the two translation units are different.
1272 bool
operator !=(const translation_unit_sptr & l,const translation_unit_sptr & r)1273 operator!=(const translation_unit_sptr& l, const translation_unit_sptr& r)
1274 {return !operator==(l, r);}
1275
1276 // </translation_unit stuff>
1277
1278 // <elf_symbol stuff>
1279 struct elf_symbol::priv
1280 {
1281 const environment* env_;
1282 size_t index_;
1283 size_t size_;
1284 string name_;
1285 elf_symbol::type type_;
1286 elf_symbol::binding binding_;
1287 elf_symbol::version version_;
1288 elf_symbol::visibility visibility_;
1289 bool is_defined_;
1290 // This flag below says if the symbol is a common elf symbol. In
1291 // relocatable files, a common symbol is a symbol defined in a
1292 // section of kind SHN_COMMON.
1293 //
1294 // Note that a symbol of kind STT_COMMON is also considered a common
1295 // symbol. Here is what the gABI says about STT_COMMON and
1296 // SHN_COMMON:
1297 //
1298 // Symbols with type STT_COMMON label uninitialized common
1299 // blocks. In relocatable objects, these symbols are not
1300 // allocated and must have the special section index SHN_COMMON
1301 // (see below). In shared objects and executables these symbols
1302 // must be allocated to some section in the defining object.
1303 //
1304 // In relocatable objects, symbols with type STT_COMMON are
1305 // treated just as other symbols with index SHN_COMMON. If the
1306 // link-editor allocates space for the SHN_COMMON symbol in an
1307 // output section of the object it is producing, it must
1308 // preserve the type of the output symbol as STT_COMMON.
1309 //
1310 // When the dynamic linker encounters a reference to a symbol
1311 // that resolves to a definition of type STT_COMMON, it may (but
1312 // is not required to) change its symbol resolution rules as
1313 // follows: instead of binding the reference to the first symbol
1314 // found with the given name, the dynamic linker searches for
1315 // the first symbol with that name with type other than
1316 // STT_COMMON. If no such symbol is found, it looks for the
1317 // STT_COMMON definition of that name that has the largest size.
1318 bool is_common_;
1319 bool is_linux_string_cst_;
1320 bool is_in_ksymtab_;
1321 uint64_t crc_;
1322 bool is_suppressed_;
1323 elf_symbol_wptr main_symbol_;
1324 elf_symbol_wptr next_alias_;
1325 elf_symbol_wptr next_common_instance_;
1326 string id_string_;
1327
privabigail::ir::elf_symbol::priv1328 priv()
1329 : env_(),
1330 index_(),
1331 size_(),
1332 type_(elf_symbol::NOTYPE_TYPE),
1333 binding_(elf_symbol::GLOBAL_BINDING),
1334 visibility_(elf_symbol::DEFAULT_VISIBILITY),
1335 is_defined_(false),
1336 is_common_(false),
1337 is_linux_string_cst_(false),
1338 is_in_ksymtab_(false),
1339 crc_(0),
1340 is_suppressed_(false)
1341 {}
1342
privabigail::ir::elf_symbol::priv1343 priv(const environment* e,
1344 size_t i,
1345 size_t s,
1346 const string& n,
1347 elf_symbol::type t,
1348 elf_symbol::binding b,
1349 bool d,
1350 bool c,
1351 const elf_symbol::version& ve,
1352 elf_symbol::visibility vi,
1353 bool is_linux_string_cst,
1354 bool is_in_ksymtab,
1355 uint64_t crc,
1356 bool is_suppressed)
1357 : env_(e),
1358 index_(i),
1359 size_(s),
1360 name_(n),
1361 type_(t),
1362 binding_(b),
1363 version_(ve),
1364 visibility_(vi),
1365 is_defined_(d),
1366 is_common_(c),
1367 is_linux_string_cst_(is_linux_string_cst),
1368 is_in_ksymtab_(is_in_ksymtab),
1369 crc_(crc),
1370 is_suppressed_(is_suppressed)
1371 {
1372 if (!is_common_)
1373 is_common_ = type_ == COMMON_TYPE;
1374 }
1375 }; // end struct elf_symbol::priv
1376
1377 /// Default constructor of the @ref elf_symbol type.
1378 ///
1379 /// Note that this constructor is private, so client code cannot use
1380 /// it to create instances of @ref elf_symbol. Rather, client code
1381 /// should use the @ref elf_symbol::create() function to create
1382 /// instances of @ref elf_symbol instead.
elf_symbol()1383 elf_symbol::elf_symbol()
1384 : priv_(new priv)
1385 {}
1386
1387 /// Constructor of the @ref elf_symbol type.
1388 ///
1389 /// Note that this constructor is private, so client code cannot use
1390 /// it to create instances of @ref elf_symbol. Rather, client code
1391 /// should use the @ref elf_symbol::create() function to create
1392 /// instances of @ref elf_symbol instead.
1393 ///
1394 /// @param e the environment we are operating from.
1395 ///
1396 /// @param i the index of the symbol in the (ELF) symbol table.
1397 ///
1398 /// @param s the size of the symbol.
1399 ///
1400 /// @param n the name of the symbol.
1401 ///
1402 /// @param t the type of the symbol.
1403 ///
1404 /// @param b the binding of the symbol.
1405 ///
1406 /// @param d true if the symbol is defined, false otherwise.
1407 ///
1408 /// @param c true if the symbol is a common symbol, false otherwise.
1409 ///
1410 /// @param ve the version of the symbol.
1411 ///
1412 /// @param vi the visibility of the symbol.
1413 ///
1414 /// @param is_linux_string_cst true if the symbol is a Linux Kernel
1415 /// string constant defined in the __ksymtab_strings section.
1416 ///
1417 /// @param crc the CRC (modversions) value of Linux Kernel symbols
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_linux_string_cst,bool is_in_ksymtab,uint64_t crc,bool is_suppressed)1418 elf_symbol::elf_symbol(const environment* e,
1419 size_t i,
1420 size_t s,
1421 const string& n,
1422 type t,
1423 binding b,
1424 bool d,
1425 bool c,
1426 const version& ve,
1427 visibility vi,
1428 bool is_linux_string_cst,
1429 bool is_in_ksymtab,
1430 uint64_t crc,
1431 bool is_suppressed)
1432 : priv_(new priv(e,
1433 i,
1434 s,
1435 n,
1436 t,
1437 b,
1438 d,
1439 c,
1440 ve,
1441 vi,
1442 is_linux_string_cst,
1443 is_in_ksymtab,
1444 crc,
1445 is_suppressed))
1446 {}
1447
1448 /// Factory of instances of @ref elf_symbol.
1449 ///
1450 /// This is the function to use to create instances of @ref elf_symbol.
1451 ///
1452 /// @return a (smart) pointer to a newly created instance of @ref
1453 /// elf_symbol.
1454 elf_symbol_sptr
create()1455 elf_symbol::create()
1456 {
1457 elf_symbol_sptr e(new elf_symbol());
1458 e->priv_->main_symbol_ = e;
1459 return e;
1460 }
1461
1462 /// Factory of instances of @ref elf_symbol.
1463 ///
1464 /// This is the function to use to create instances of @ref elf_symbol.
1465 ///
1466 /// @param e the environment we are operating from.
1467 ///
1468 /// @param i the index of the symbol in the (ELF) symbol table.
1469 ///
1470 /// @param s the size of the symbol.
1471 ///
1472 /// @param n the name of the symbol.
1473 ///
1474 /// @param t the type of the symbol.
1475 ///
1476 /// @param b the binding of the symbol.
1477 ///
1478 /// @param d true if the symbol is defined, false otherwise.
1479 ///
1480 /// @param c true if the symbol is a common symbol.
1481 ///
1482 /// @param ve the version of the symbol.
1483 ///
1484 /// @param vi the visibility of the symbol.
1485 ///
1486 /// @param is_linux_string_cst if true, it means the symbol represents
1487 /// a string constant from a linux kernel binary.
1488 ///
1489 /// @param crc the CRC (modversions) value of Linux Kernel symbols
1490 ///
1491 /// @return a (smart) pointer to a newly created instance of @ref
1492 /// elf_symbol.
1493 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_linux_string_cst,bool is_in_ksymtab,uint64_t crc,bool is_suppressed)1494 elf_symbol::create(const environment* e,
1495 size_t i,
1496 size_t s,
1497 const string& n,
1498 type t,
1499 binding b,
1500 bool d,
1501 bool c,
1502 const version& ve,
1503 visibility vi,
1504 bool is_linux_string_cst,
1505 bool is_in_ksymtab,
1506 uint64_t crc,
1507 bool is_suppressed)
1508 {
1509 elf_symbol_sptr sym(new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
1510 is_linux_string_cst,
1511 is_in_ksymtab, crc, is_suppressed));
1512 sym->priv_->main_symbol_ = sym;
1513 return sym;
1514 }
1515
1516 /// Test textual equality between two symbols.
1517 ///
1518 /// Textual equality means that the aliases of the compared symbols
1519 /// are not taken into account. Only the name, type, and version of
1520 /// the symbols are compared.
1521 ///
1522 /// @return true iff the two symbols are textually equal.
1523 static bool
textually_equals(const elf_symbol & l,const elf_symbol & r)1524 textually_equals(const elf_symbol&l,
1525 const elf_symbol&r)
1526 {
1527 bool equals = (l.get_name() == r.get_name()
1528 && l.get_type() == r.get_type()
1529 && l.is_public() == r.is_public()
1530 && l.is_defined() == r.is_defined()
1531 && l.is_common_symbol() == r.is_common_symbol()
1532 && l.get_version() == r.get_version()
1533 && (l.get_crc() == 0 || r.get_crc() == 0
1534 || l.get_crc() == r.get_crc()));
1535
1536 if (equals && l.is_variable())
1537 // These are variable symbols. Let's compare their symbol size.
1538 // The symbol size in this case is the size taken by the storage
1539 // of the variable. If that size changes, then it's an ABI
1540 // change.
1541 equals = l.get_size() == r.get_size();
1542
1543 return equals;
1544 }
1545
1546 /// Getter of the environment used by the current instance of @ref
1547 /// elf_symbol.
1548 ///
1549 /// @return the enviroment used by the current instance of @ref elf_symbol.
1550 const environment*
get_environment() const1551 elf_symbol::get_environment() const
1552 {return priv_->env_;}
1553
1554 /// Setter of the environment used by the current instance of @ref
1555 /// elf_symbol.
1556 ///
1557 /// @param The new enviroment used by the current instance of @ref
1558 /// elf_symbol.
1559 void
set_environment(const environment * e) const1560 elf_symbol::set_environment(const environment* e) const
1561 {priv_->env_ = e;}
1562
1563 /// Getter for the index
1564 ///
1565 /// @return the index of the symbol.
1566 size_t
get_index() const1567 elf_symbol::get_index() const
1568 {return priv_->index_;}
1569
1570 /// Setter for the index.
1571 ///
1572 /// @param s the new index.
1573 void
set_index(size_t s)1574 elf_symbol::set_index(size_t s)
1575 {priv_->index_ = s;}
1576
1577 /// Test if the ELF symbol is for a string constant of a Linux binary
1578 /// defined in the __ksymtab_strings symbol table.
1579 ///
1580 /// @return true iff ELF symbol is for a string constant of a Linux
1581 /// binary defined in the __ksymtab_strings symbol table.
1582 bool
get_is_linux_string_cst() const1583 elf_symbol::get_is_linux_string_cst() const
1584 {return priv_->is_linux_string_cst_;}
1585
1586 /// Getter for the name of the @ref elf_symbol.
1587 ///
1588 /// @return a reference to the name of the @ref symbol.
1589 const string&
get_name() const1590 elf_symbol::get_name() const
1591 {return priv_->name_;}
1592
1593 /// Setter for the name of the current intance of @ref elf_symbol.
1594 ///
1595 /// @param n the new name.
1596 void
set_name(const string & n)1597 elf_symbol::set_name(const string& n)
1598 {
1599 priv_->name_ = n;
1600 priv_->id_string_.clear();
1601 }
1602
1603 /// Getter for the type of the current instance of @ref elf_symbol.
1604 ///
1605 /// @return the type of the elf symbol.
1606 elf_symbol::type
get_type() const1607 elf_symbol::get_type() const
1608 {return priv_->type_;}
1609
1610 /// Setter for the type of the current instance of @ref elf_symbol.
1611 ///
1612 /// @param t the new symbol type.
1613 void
set_type(type t)1614 elf_symbol::set_type(type t)
1615 {priv_->type_ = t;}
1616
1617 /// Getter of the size of the symbol.
1618 ///
1619 /// @return the size of the symbol, in bytes.
1620 size_t
get_size() const1621 elf_symbol::get_size() const
1622 {return priv_->size_;}
1623
1624 /// Setter of the size of the symbol.
1625 ///
1626 /// @param size the new size of the symbol, in bytes.
1627 void
set_size(size_t size)1628 elf_symbol::set_size(size_t size)
1629 {priv_->size_ = size;}
1630
1631 /// Getter for the binding of the current instance of @ref elf_symbol.
1632 ///
1633 /// @return the binding of the symbol.
1634 elf_symbol::binding
get_binding() const1635 elf_symbol::get_binding() const
1636 {return priv_->binding_;}
1637
1638 /// Setter for the binding of the current instance of @ref elf_symbol.
1639 ///
1640 /// @param b the new binding.
1641 void
set_binding(binding b)1642 elf_symbol::set_binding(binding b)
1643 {priv_->binding_ = b;}
1644
1645 /// Getter for the version of the current instanc of @ref elf_symbol.
1646 ///
1647 /// @return the version of the elf symbol.
1648 elf_symbol::version&
get_version() const1649 elf_symbol::get_version() const
1650 {return priv_->version_;}
1651
1652 /// Setter for the version of the current instance of @ref elf_symbol.
1653 ///
1654 /// @param v the new version of the elf symbol.
1655 void
set_version(const version & v)1656 elf_symbol::set_version(const version& v)
1657 {
1658 priv_->version_ = v;
1659 priv_->id_string_.clear();
1660 }
1661
1662 /// Setter of the visibility of the current instance of @ref
1663 /// elf_symbol.
1664 ///
1665 /// @param v the new visibility of the elf symbol.
1666 void
set_visibility(visibility v)1667 elf_symbol::set_visibility(visibility v)
1668 {priv_->visibility_ = v;}
1669
1670 /// Getter of the visibility of the current instance of @ref
1671 /// elf_symbol.
1672 ///
1673 /// @return the visibility of the elf symbol.
1674 elf_symbol::visibility
get_visibility() const1675 elf_symbol::get_visibility() const
1676 {return priv_->visibility_;}
1677
1678 /// Test if the current instance of @ref elf_symbol is defined or not.
1679 ///
1680 /// @return true if the current instance of @ref elf_symbol is
1681 /// defined, false otherwise.
1682 bool
is_defined() const1683 elf_symbol::is_defined() const
1684 {return priv_->is_defined_;}
1685
1686 /// Sets a flag saying if the current instance of @ref elf_symbol is
1687 /// defined
1688 ///
1689 /// @param b the new value of the flag.
1690 void
is_defined(bool d)1691 elf_symbol::is_defined(bool d)
1692 {priv_->is_defined_ = d;}
1693
1694 /// Test if the current instance of @ref elf_symbol is public or not.
1695 ///
1696 /// This tests if the symbol is defined, has default or protected
1697 ///visibility, and either:
1698 /// - has global binding
1699 /// - has weak binding
1700 /// - or has a GNU_UNIQUE binding.
1701 ///
1702 /// return true if the current instance of @ref elf_symbol is public,
1703 /// false otherwise.
1704 bool
is_public() const1705 elf_symbol::is_public() const
1706 {
1707 return (is_defined()
1708 && (get_binding() == GLOBAL_BINDING
1709 || get_binding() == WEAK_BINDING
1710 || get_binding() == GNU_UNIQUE_BINDING)
1711 && (get_visibility() == DEFAULT_VISIBILITY
1712 || get_visibility() == PROTECTED_VISIBILITY));
1713 }
1714
1715 /// Test if the current instance of @ref elf_symbol is a function
1716 /// symbol or not.
1717 ///
1718 /// @return true if the current instance of @ref elf_symbol is a
1719 /// function symbol, false otherwise.
1720 bool
is_function() const1721 elf_symbol::is_function() const
1722 {return get_type() == FUNC_TYPE || get_type() == GNU_IFUNC_TYPE;}
1723
1724 /// Test if the current instance of @ref elf_symbol is a variable
1725 /// symbol or not.
1726 ///
1727 /// @return true if the current instance of @ref elf_symbol is a
1728 /// variable symbol, false otherwise.
1729 bool
is_variable() const1730 elf_symbol::is_variable() const
1731 {return get_type() == OBJECT_TYPE || get_type() == TLS_TYPE;}
1732
1733 /// Getter of the 'is-in-ksymtab' property.
1734 ///
1735 /// @return true iff the current symbol is in the Linux Kernel
1736 /// specific 'ksymtab' symbol table.
1737 bool
is_in_ksymtab() const1738 elf_symbol::is_in_ksymtab() const
1739 {return priv_->is_in_ksymtab_;}
1740
1741 /// Setter of the 'is-in-ksymtab' property.
1742 ///
1743 /// @param is_in_ksymtab this is true iff the current symbol is in the
1744 /// Linux Kernel specific 'ksymtab' symbol table.
1745 void
set_is_in_ksymtab(bool is_in_ksymtab)1746 elf_symbol::set_is_in_ksymtab(bool is_in_ksymtab)
1747 {priv_->is_in_ksymtab_ = is_in_ksymtab;}
1748
1749 /// Getter of the 'crc' property.
1750 ///
1751 /// @return the CRC (modversions) value for Linux Kernel symbols (if present)
1752 uint64_t
get_crc() const1753 elf_symbol::get_crc() const
1754 {return priv_->crc_;}
1755
1756 /// Setter of the 'crc' property.
1757 ///
1758 /// @param crc the new CRC (modversions) value for Linux Kernel symbols
1759 void
set_crc(uint64_t crc)1760 elf_symbol::set_crc(uint64_t crc)
1761 {priv_->crc_ = crc;}
1762
1763 /// Getter for the 'is-suppressed' property.
1764 ///
1765 /// @return true iff the current symbol has been suppressed by a
1766 /// suppression specification that was provided in the context that
1767 /// led to the creation of the corpus this ELF symbol belongs to.
1768 bool
is_suppressed() const1769 elf_symbol::is_suppressed() const
1770 {return priv_->is_suppressed_;}
1771
1772 /// Setter for the 'is-suppressed' property.
1773 ///
1774 /// @param true iff the current symbol has been suppressed by a
1775 /// suppression specification that was provided in the context that
1776 /// led to the creation of the corpus this ELF symbol belongs to.
1777 void
set_is_suppressed(bool is_suppressed)1778 elf_symbol::set_is_suppressed(bool is_suppressed)
1779 {priv_->is_suppressed_ = is_suppressed;}
1780
1781 /// @name Elf symbol aliases
1782 ///
1783 /// An alias A for an elf symbol S is a symbol that is defined at the
1784 /// same address as S. S is chained to A through the
1785 /// elf_symbol::get_next_alias() method.
1786 ///
1787 /// When there are several aliases to a symbol, the main symbol is the
1788 /// the first symbol found in the symbol table for a given address.
1789 ///
1790 /// The alias chain is circular. That means if S is the main symbol
1791 /// and A is the alias, S is chained to A and A
1792 /// is chained back to the main symbol S. The last alias in an alias
1793 ///chain is always chained to the main symbol.
1794 ///
1795 /// Thus, when looping over the aliases of an elf_symbol A, detecting
1796 /// an alias that is equal to the main symbol should logically be a
1797 /// loop exit condition.
1798 ///
1799 /// Accessing and adding aliases for instances of elf_symbol is done
1800 /// through the member functions below.
1801
1802 /// @{
1803
1804 /// Get the main symbol of an alias chain.
1805 ///
1806 ///@return the main symbol.
1807 const elf_symbol_sptr
get_main_symbol() const1808 elf_symbol::get_main_symbol() const
1809 {return priv_->main_symbol_.lock();}
1810
1811 /// Get the main symbol of an alias chain.
1812 ///
1813 ///@return the main symbol.
1814 elf_symbol_sptr
get_main_symbol()1815 elf_symbol::get_main_symbol()
1816 {return priv_->main_symbol_.lock();}
1817
1818 /// Tests whether this symbol is the main symbol.
1819 ///
1820 /// @return true iff this symbol is the main symbol.
1821 bool
is_main_symbol() const1822 elf_symbol::is_main_symbol() const
1823 {return get_main_symbol().get() == this;}
1824
1825 /// Get the next alias of the current symbol.
1826 ///
1827 ///@return the alias, or NULL if there is no alias.
1828 elf_symbol_sptr
get_next_alias() const1829 elf_symbol::get_next_alias() const
1830 {return priv_->next_alias_.lock();}
1831
1832
1833 /// Check if the current elf_symbol has an alias.
1834 ///
1835 ///@return true iff the current elf_symbol has an alias.
1836 bool
has_aliases() const1837 elf_symbol::has_aliases() const
1838 {return bool(get_next_alias());}
1839
1840 /// Get the number of aliases to this elf symbol
1841 ///
1842 /// @return the number of aliases to this elf symbol.
1843 int
get_number_of_aliases() const1844 elf_symbol::get_number_of_aliases() const
1845 {
1846 int result = 0;
1847
1848 for (elf_symbol_sptr a = get_next_alias();
1849 a && a.get() != get_main_symbol().get();
1850 a = a->get_next_alias())
1851 ++result;
1852
1853 return result;
1854 }
1855
1856 /// Add an alias to the current elf symbol.
1857 ///
1858 /// @param alias the new alias. Note that this elf_symbol should *NOT*
1859 /// have aliases prior to the invocation of this function.
1860 void
add_alias(const elf_symbol_sptr & alias)1861 elf_symbol::add_alias(const elf_symbol_sptr& alias)
1862 {
1863 if (!alias)
1864 return;
1865
1866 ABG_ASSERT(!alias->has_aliases());
1867 ABG_ASSERT(is_main_symbol());
1868
1869 if (has_aliases())
1870 {
1871 elf_symbol_sptr last_alias;
1872 for (elf_symbol_sptr a = get_next_alias();
1873 a && !a->is_main_symbol();
1874 a = a->get_next_alias())
1875 {
1876 if (a->get_next_alias()->is_main_symbol())
1877 {
1878 ABG_ASSERT(last_alias == 0);
1879 last_alias = a;
1880 }
1881 }
1882 ABG_ASSERT(last_alias);
1883
1884 last_alias->priv_->next_alias_ = alias;
1885 }
1886 else
1887 priv_->next_alias_ = alias;
1888
1889 alias->priv_->next_alias_ = get_main_symbol();
1890 alias->priv_->main_symbol_ = get_main_symbol();
1891 }
1892
1893 /// Update the main symbol for a group of aliased symbols
1894 ///
1895 /// If after the construction of the symbols (in order of discovery), the
1896 /// actual main symbol can be identified (e.g. as the symbol that actually is
1897 /// defined in the code), this method offers a way of updating the main symbol
1898 /// through one of the aliased symbols.
1899 ///
1900 /// For that, locate the new main symbol by name and update all references to
1901 /// the main symbol among the group of aliased symbols.
1902 ///
1903 /// @param name the name of the main symbol
1904 ///
1905 /// @return the new main elf_symbol
1906 elf_symbol_sptr
update_main_symbol(const std::string & name)1907 elf_symbol::update_main_symbol(const std::string& name)
1908 {
1909 ABG_ASSERT(is_main_symbol());
1910 if (!has_aliases() || get_name() == name)
1911 return get_main_symbol();
1912
1913 // find the new main symbol
1914 elf_symbol_sptr new_main;
1915 // we've already checked this; check the rest of the aliases
1916 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
1917 a = a->get_next_alias())
1918 if (a->get_name() == name)
1919 {
1920 new_main = a;
1921 break;
1922 }
1923
1924 if (!new_main)
1925 return get_main_symbol();
1926
1927 // now update all main symbol references
1928 priv_->main_symbol_ = new_main;
1929 for (elf_symbol_sptr a = get_next_alias(); a.get() != this;
1930 a = a->get_next_alias())
1931 a->priv_->main_symbol_ = new_main;
1932
1933 return new_main;
1934 }
1935
1936 /// Return true if the symbol is a common one.
1937 ///
1938 /// @return true iff the symbol is common.
1939 bool
is_common_symbol() const1940 elf_symbol::is_common_symbol() const
1941 {return priv_->is_common_;}
1942
1943 /// Return true if this common common symbol has other common instances.
1944 ///
1945 /// A common instance of a given common symbol is another common
1946 /// symbol with the same name. Those exist in relocatable files. The
1947 /// linker normally allocates all the instances into a common block in
1948 /// the final output file.
1949 ///
1950 /// Note that the current object must be a common symbol, otherwise,
1951 /// this function aborts.
1952 ///
1953 /// @return true iff the current common symbol has other common
1954 /// instances.
1955 bool
has_other_common_instances() const1956 elf_symbol::has_other_common_instances() const
1957 {
1958 ABG_ASSERT(is_common_symbol());
1959 return bool(get_next_common_instance());
1960 }
1961
1962 /// Get the next common instance of the current common symbol.
1963 ///
1964 /// A common instance of a given common symbol is another common
1965 /// symbol with the same name. Those exist in relocatable files. The
1966 /// linker normally allocates all the instances into a common block in
1967 /// the final output file.
1968 ///
1969 /// @return the next common instance, or nil if there is not any.
1970 elf_symbol_sptr
get_next_common_instance() const1971 elf_symbol::get_next_common_instance() const
1972 {return priv_->next_common_instance_.lock();}
1973
1974 /// Add a common instance to the current common elf symbol.
1975 ///
1976 /// Note that this symbol must be the main symbol. Being the main
1977 /// symbol means being the first common symbol to appear in the symbol
1978 /// table.
1979 ///
1980 /// @param common the other common instance to add.
1981 void
add_common_instance(const elf_symbol_sptr & common)1982 elf_symbol::add_common_instance(const elf_symbol_sptr& common)
1983 {
1984 if (!common)
1985 return;
1986
1987 ABG_ASSERT(!common->has_other_common_instances());
1988 ABG_ASSERT(is_common_symbol());
1989 ABG_ASSERT(is_main_symbol());
1990
1991 if (has_other_common_instances())
1992 {
1993 elf_symbol_sptr last_common_instance;
1994 for (elf_symbol_sptr c = get_next_common_instance();
1995 c && (c.get() != get_main_symbol().get());
1996 c = c->get_next_common_instance())
1997 {
1998 if (c->get_next_common_instance().get() == get_main_symbol().get())
1999 {
2000 ABG_ASSERT(last_common_instance == 0);
2001 last_common_instance = c;
2002 }
2003 }
2004 ABG_ASSERT(last_common_instance);
2005
2006 last_common_instance->priv_->next_common_instance_ = common;
2007 }
2008 else
2009 priv_->next_common_instance_ = common;
2010
2011 common->priv_->next_common_instance_ = get_main_symbol();
2012 common->priv_->main_symbol_ = get_main_symbol();
2013 }
2014
2015 /// Get a string that is representative of a given elf_symbol.
2016 ///
2017 /// If the symbol has a version, then the ID string is the
2018 /// concatenation of the name of the symbol, the '@' character, and
2019 /// the version of the symbol. If the version is the default version
2020 /// of the symbol then the '@' character is replaced by a "@@" string.
2021 ///
2022 /// Otherwise, if the symbol does not have any version, this function
2023 /// returns the name of the symbol.
2024 ///
2025 /// @return a the ID string.
2026 const string&
get_id_string() const2027 elf_symbol::get_id_string() const
2028 {
2029 if (priv_->id_string_.empty())
2030 {
2031 string s = get_name ();
2032
2033 if (!get_version().is_empty())
2034 {
2035 if (get_version().is_default())
2036 s += "@@";
2037 else
2038 s += "@";
2039 s += get_version().str();
2040 }
2041 priv_->id_string_ = s;
2042 }
2043
2044 return priv_->id_string_;
2045 }
2046
2047 /// From the aliases of the current symbol, lookup one with a given name.
2048 ///
2049 /// @param name the name of symbol alias we are looking for.
2050 ///
2051 /// @return the symbol alias that has the name @p name, or nil if none
2052 /// has been found.
2053 elf_symbol_sptr
get_alias_from_name(const string & name) const2054 elf_symbol::get_alias_from_name(const string& name) const
2055 {
2056 if (name == get_name())
2057 return elf_symbol_sptr(priv_->main_symbol_);
2058
2059 for (elf_symbol_sptr a = get_next_alias();
2060 a && a.get() != get_main_symbol().get();
2061 a = a->get_next_alias())
2062 if (a->get_name() == name)
2063 return a;
2064
2065 return elf_symbol_sptr();
2066 }
2067
2068 /// In the list of aliases of a given elf symbol, get the alias that
2069 /// equals this current symbol.
2070 ///
2071 /// @param other the elf symbol to get the potential aliases from.
2072 ///
2073 /// @return the alias of @p other that texually equals the current
2074 /// symbol, or nil if no alias textually equals the current symbol.
2075 elf_symbol_sptr
get_alias_which_equals(const elf_symbol & other) const2076 elf_symbol::get_alias_which_equals(const elf_symbol& other) const
2077 {
2078 for (elf_symbol_sptr a = other.get_next_alias();
2079 a && a.get() != a->get_main_symbol().get();
2080 a = a->get_next_alias())
2081 if (textually_equals(*this, *a))
2082 return a;
2083 return elf_symbol_sptr();
2084 }
2085
2086 /// Return a comma separated list of the id of the current symbol as
2087 /// well as the id string of its aliases.
2088 ///
2089 /// @param syms a map of all the symbols of the corpus the current
2090 /// symbol belongs to.
2091 ///
2092 /// @param include_symbol_itself if set to true, then the name of the
2093 /// current symbol is included in the list of alias names that is emitted.
2094 ///
2095 /// @return the string.
2096 string
get_aliases_id_string(const string_elf_symbols_map_type & syms,bool include_symbol_itself) const2097 elf_symbol::get_aliases_id_string(const string_elf_symbols_map_type& syms,
2098 bool include_symbol_itself) const
2099 {
2100 string result;
2101
2102 if (include_symbol_itself)
2103 result = get_id_string();
2104
2105 vector<elf_symbol_sptr> aliases;
2106 compute_aliases_for_elf_symbol(*this, syms, aliases);
2107 if (!aliases.empty() && include_symbol_itself)
2108 result += ", ";
2109
2110 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2111 i != aliases.end();
2112 ++i)
2113 {
2114 if (i != aliases.begin())
2115 result += ", ";
2116 result += (*i)->get_id_string();
2117 }
2118 return result;
2119 }
2120
2121 /// Return a comma separated list of the id of the current symbol as
2122 /// well as the id string of its aliases.
2123 ///
2124 /// @param include_symbol_itself if set to true, then the name of the
2125 /// current symbol is included in the list of alias names that is emitted.
2126 ///
2127 /// @return the string.
2128 string
get_aliases_id_string(bool include_symbol_itself) const2129 elf_symbol::get_aliases_id_string(bool include_symbol_itself) const
2130 {
2131 vector<elf_symbol_sptr> aliases;
2132 if (include_symbol_itself)
2133 aliases.push_back(get_main_symbol());
2134
2135 for (elf_symbol_sptr a = get_next_alias();
2136 a && a.get() != get_main_symbol().get();
2137 a = a->get_next_alias())
2138 aliases.push_back(a);
2139
2140 string result;
2141 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
2142 i != aliases.end();
2143 ++i)
2144 {
2145 if (i != aliases.begin())
2146 result += ", ";
2147 result += (*i)->get_id_string();
2148 }
2149
2150 return result;
2151 }
2152
2153 /// Given the ID of a symbol, get the name and the version of said
2154 /// symbol.
2155 ///
2156 /// @param id the symbol ID to consider.
2157 ///
2158 /// @param name the symbol name extracted from the ID. This is set
2159 /// only if the function returned true.
2160 ///
2161 /// @param ver the symbol version extracted from the ID.
2162 bool
get_name_and_version_from_id(const string & id,string & name,string & ver)2163 elf_symbol::get_name_and_version_from_id(const string& id,
2164 string& name,
2165 string& ver)
2166 {
2167 name.clear(), ver.clear();
2168
2169 string::size_type i = id.find('@');
2170 if (i == string::npos)
2171 {
2172 name = id;
2173 return true;
2174 }
2175
2176 name = id.substr(0, i);
2177 ++i;
2178
2179 if (i >= id.size())
2180 return true;
2181
2182 string::size_type j = id.find('@', i);
2183 if (j == string::npos)
2184 j = i;
2185 else
2186 ++j;
2187
2188 if (j >= id.size())
2189 {
2190 ver = "";
2191 return true;
2192 }
2193
2194 ver = id.substr(j);
2195 return true;
2196 }
2197
2198 ///@}
2199
2200 /// Test if two main symbols are textually equal, or, if they have
2201 /// aliases that are textually equal.
2202 ///
2203 /// @param other the symbol to compare against.
2204 ///
2205 /// @return true iff the current instance of elf symbol equals the @p
2206 /// other.
2207 bool
operator ==(const elf_symbol & other) const2208 elf_symbol::operator==(const elf_symbol& other) const
2209 {
2210 bool are_equal = textually_equals(*this, other);
2211 if (!are_equal)
2212 are_equal = bool(get_alias_which_equals(other));
2213 return are_equal;
2214 }
2215
2216 /// Test if the current symbol aliases another one.
2217 ///
2218 /// @param o the other symbol to test against.
2219 ///
2220 /// @return true iff the current symbol aliases @p o.
2221 bool
does_alias(const elf_symbol & o) const2222 elf_symbol::does_alias(const elf_symbol& o) const
2223 {
2224 if (*this == o)
2225 return true;
2226
2227 if (get_main_symbol() == o.get_main_symbol())
2228 return true;
2229
2230 for (elf_symbol_sptr a = get_next_alias();
2231 a && !a->is_main_symbol();
2232 a = a->get_next_alias())
2233 {
2234 if (o == *a)
2235 return true;
2236 }
2237 return false;
2238 }
2239
2240 /// Equality operator for smart pointers to elf_symbol.
2241 ///
2242 /// @param lhs the first elf symbol to consider.
2243 ///
2244 /// @param rhs the second elf symbol to consider.
2245 ///
2246 /// @return true iff @p lhs equals @p rhs.
2247 bool
operator ==(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2248 operator==(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2249 {
2250 if (!!lhs != !!rhs)
2251 return false;
2252
2253 if (!lhs)
2254 return true;
2255
2256 return *lhs == *rhs;
2257 }
2258
2259 /// Inequality operator for smart pointers to elf_symbol.
2260 ///
2261 /// @param lhs the first elf symbol to consider.
2262 ///
2263 /// @param rhs the second elf symbol to consider.
2264 ///
2265 /// @return true iff @p lhs is different from @p rhs.
2266 bool
operator !=(const elf_symbol_sptr & lhs,const elf_symbol_sptr & rhs)2267 operator!=(const elf_symbol_sptr& lhs, const elf_symbol_sptr& rhs)
2268 {return !operator==(lhs, rhs);}
2269
2270 /// Test if two symbols alias.
2271 ///
2272 /// @param s1 the first symbol to consider.
2273 ///
2274 /// @param s2 the second symbol to consider.
2275 ///
2276 /// @return true if @p s1 aliases @p s2.
2277 bool
elf_symbols_alias(const elf_symbol & s1,const elf_symbol & s2)2278 elf_symbols_alias(const elf_symbol& s1, const elf_symbol& s2)
2279 {return s1.does_alias(s2) || s2.does_alias(s1);}
2280
2281 void
compute_aliases_for_elf_symbol(const elf_symbol & sym,const string_elf_symbols_map_type & symtab,vector<elf_symbol_sptr> & aliases)2282 compute_aliases_for_elf_symbol(const elf_symbol& sym,
2283 const string_elf_symbols_map_type& symtab,
2284 vector<elf_symbol_sptr>& aliases)
2285 {
2286
2287 if (elf_symbol_sptr a = sym.get_next_alias())
2288 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2289 aliases.push_back(a);
2290 else
2291 for (string_elf_symbols_map_type::const_iterator i = symtab.begin();
2292 i != symtab.end();
2293 ++i)
2294 for (elf_symbols::const_iterator j = i->second.begin();
2295 j != i->second.end();
2296 ++j)
2297 {
2298 if (**j == sym)
2299 for (elf_symbol_sptr s = (*j)->get_next_alias();
2300 s && !s->is_main_symbol();
2301 s = s->get_next_alias())
2302 aliases.push_back(s);
2303 else
2304 for (elf_symbol_sptr s = (*j)->get_next_alias();
2305 s && !s->is_main_symbol();
2306 s = s->get_next_alias())
2307 if (*s == sym)
2308 aliases.push_back(*j);
2309 }
2310 }
2311
2312 /// Test if two symbols alias.
2313 ///
2314 /// @param s1 the first symbol to consider.
2315 ///
2316 /// @param s2 the second symbol to consider.
2317 ///
2318 /// @return true if @p s1 aliases @p s2.
2319 bool
elf_symbols_alias(const elf_symbol * s1,const elf_symbol * s2)2320 elf_symbols_alias(const elf_symbol* s1, const elf_symbol* s2)
2321 {
2322 if (!!s1 != !!s2)
2323 return false;
2324 if (s1 == s2)
2325 return true;
2326 return elf_symbols_alias(*s1, *s2);
2327 }
2328
2329 /// Test if two symbols alias.
2330 ///
2331 /// @param s1 the first symbol to consider.
2332 ///
2333 /// @param s2 the second symbol to consider.
2334 ///
2335 /// @return true if @p s1 aliases @p s2.
2336 bool
elf_symbols_alias(const elf_symbol_sptr s1,const elf_symbol_sptr s2)2337 elf_symbols_alias(const elf_symbol_sptr s1, const elf_symbol_sptr s2)
2338 {return elf_symbols_alias(s1.get(), s2.get());}
2339
2340 /// Serialize an instance of @ref symbol_type and stream it to a given
2341 /// output stream.
2342 ///
2343 /// @param o the output stream to serialize the symbole type to.
2344 ///
2345 /// @param t the symbol type to serialize.
2346 std::ostream&
operator <<(std::ostream & o,elf_symbol::type t)2347 operator<<(std::ostream& o, elf_symbol::type t)
2348 {
2349 string repr;
2350
2351 switch (t)
2352 {
2353 case elf_symbol::NOTYPE_TYPE:
2354 repr = "unspecified symbol type";
2355 break;
2356 case elf_symbol::OBJECT_TYPE:
2357 repr = "variable symbol type";
2358 break;
2359 case elf_symbol::FUNC_TYPE:
2360 repr = "function symbol type";
2361 break;
2362 case elf_symbol::SECTION_TYPE:
2363 repr = "section symbol type";
2364 break;
2365 case elf_symbol::FILE_TYPE:
2366 repr = "file symbol type";
2367 break;
2368 case elf_symbol::COMMON_TYPE:
2369 repr = "common data object symbol type";
2370 break;
2371 case elf_symbol::TLS_TYPE:
2372 repr = "thread local data object symbol type";
2373 break;
2374 case elf_symbol::GNU_IFUNC_TYPE:
2375 repr = "indirect function symbol type";
2376 break;
2377 default:
2378 {
2379 std::ostringstream s;
2380 s << "unknown symbol type (" << (char)t << ')';
2381 repr = s.str();
2382 }
2383 break;
2384 }
2385
2386 o << repr;
2387 return o;
2388 }
2389
2390 /// Serialize an instance of @ref symbol_binding and stream it to a
2391 /// given output stream.
2392 ///
2393 /// @param o the output stream to serialize the symbole type to.
2394 ///
2395 /// @param b the symbol binding to serialize.
2396 std::ostream&
operator <<(std::ostream & o,elf_symbol::binding b)2397 operator<<(std::ostream& o, elf_symbol::binding b)
2398 {
2399 string repr;
2400
2401 switch (b)
2402 {
2403 case elf_symbol::LOCAL_BINDING:
2404 repr = "local binding";
2405 break;
2406 case elf_symbol::GLOBAL_BINDING:
2407 repr = "global binding";
2408 break;
2409 case elf_symbol::WEAK_BINDING:
2410 repr = "weak binding";
2411 break;
2412 case elf_symbol::GNU_UNIQUE_BINDING:
2413 repr = "GNU unique binding";
2414 break;
2415 default:
2416 {
2417 std::ostringstream s;
2418 s << "unknown binding (" << (unsigned char) b << ")";
2419 repr = s.str();
2420 }
2421 break;
2422 }
2423
2424 o << repr;
2425 return o;
2426 }
2427
2428 /// Serialize an instance of @ref elf_symbol::visibility and stream it
2429 /// to a given output stream.
2430 ///
2431 /// @param o the output stream to serialize the symbole type to.
2432 ///
2433 /// @param v the symbol visibility to serialize.
2434 std::ostream&
operator <<(std::ostream & o,elf_symbol::visibility v)2435 operator<<(std::ostream& o, elf_symbol::visibility v)
2436 {
2437 string repr;
2438
2439 switch (v)
2440 {
2441 case elf_symbol::DEFAULT_VISIBILITY:
2442 repr = "default visibility";
2443 break;
2444 case elf_symbol::PROTECTED_VISIBILITY:
2445 repr = "protected visibility";
2446 break;
2447 case elf_symbol::HIDDEN_VISIBILITY:
2448 repr = "hidden visibility";
2449 break;
2450 case elf_symbol::INTERNAL_VISIBILITY:
2451 repr = "internal visibility";
2452 break;
2453 default:
2454 {
2455 std::ostringstream s;
2456 s << "unknown visibility (" << (unsigned char) v << ")";
2457 repr = s.str();
2458 }
2459 break;
2460 }
2461
2462 o << repr;
2463 return o;
2464 }
2465
2466 /// Convert a string representing a symbol type into an
2467 /// elf_symbol::type.
2468 ///
2469 ///@param s the string to convert.
2470 ///
2471 ///@param t the resulting elf_symbol::type.
2472 ///
2473 /// @return true iff the conversion completed successfully.
2474 bool
string_to_elf_symbol_type(const string & s,elf_symbol::type & t)2475 string_to_elf_symbol_type(const string& s, elf_symbol::type& t)
2476 {
2477 if (s == "no-type")
2478 t = elf_symbol::NOTYPE_TYPE;
2479 else if (s == "object-type")
2480 t = elf_symbol::OBJECT_TYPE;
2481 else if (s == "func-type")
2482 t = elf_symbol::FUNC_TYPE;
2483 else if (s == "section-type")
2484 t = elf_symbol::SECTION_TYPE;
2485 else if (s == "file-type")
2486 t = elf_symbol::FILE_TYPE;
2487 else if (s == "common-type")
2488 t = elf_symbol::COMMON_TYPE;
2489 else if (s == "tls-type")
2490 t = elf_symbol::TLS_TYPE;
2491 else if (s == "gnu-ifunc-type")
2492 t = elf_symbol::GNU_IFUNC_TYPE;
2493 else
2494 return false;
2495
2496 return true;
2497 }
2498
2499 /// Convert a string representing a an elf symbol binding into an
2500 /// elf_symbol::binding.
2501 ///
2502 /// @param s the string to convert.
2503 ///
2504 /// @param b the resulting elf_symbol::binding.
2505 ///
2506 /// @return true iff the conversion completed successfully.
2507 bool
string_to_elf_symbol_binding(const string & s,elf_symbol::binding & b)2508 string_to_elf_symbol_binding(const string& s, elf_symbol::binding& b)
2509 {
2510 if (s == "local-binding")
2511 b = elf_symbol::LOCAL_BINDING;
2512 else if (s == "global-binding")
2513 b = elf_symbol::GLOBAL_BINDING;
2514 else if (s == "weak-binding")
2515 b = elf_symbol::WEAK_BINDING;
2516 else if (s == "gnu-unique-binding")
2517 b = elf_symbol::GNU_UNIQUE_BINDING;
2518 else
2519 return false;
2520
2521 return true;
2522 }
2523
2524 /// Convert a string representing a an elf symbol visibility into an
2525 /// elf_symbol::visibility.
2526 ///
2527 /// @param s the string to convert.
2528 ///
2529 /// @param b the resulting elf_symbol::visibility.
2530 ///
2531 /// @return true iff the conversion completed successfully.
2532 bool
string_to_elf_symbol_visibility(const string & s,elf_symbol::visibility & v)2533 string_to_elf_symbol_visibility(const string& s, elf_symbol::visibility& v)
2534 {
2535 if (s == "default-visibility")
2536 v = elf_symbol::DEFAULT_VISIBILITY;
2537 else if (s == "protected-visibility")
2538 v = elf_symbol::PROTECTED_VISIBILITY;
2539 else if (s == "hidden-visibility")
2540 v = elf_symbol::HIDDEN_VISIBILITY;
2541 else if (s == "internal-visibility")
2542 v = elf_symbol::INTERNAL_VISIBILITY;
2543 else
2544 return false;
2545
2546 return true;
2547 }
2548
2549 /// Test if the type of an ELF symbol denotes a function symbol.
2550 ///
2551 /// @param t the type of the ELF symbol.
2552 ///
2553 /// @return true iff elf symbol type @p t denotes a function symbol
2554 /// type.
2555 bool
elf_symbol_is_function(elf_symbol::type t)2556 elf_symbol_is_function(elf_symbol::type t)
2557 {return t == elf_symbol::FUNC_TYPE;}
2558
2559 /// Test if the type of an ELF symbol denotes a function symbol.
2560 ///
2561 /// @param t the type of the ELF symbol.
2562 ///
2563 /// @return true iff elf symbol type @p t denotes a function symbol
2564 /// type.
2565 bool
elf_symbol_is_variable(elf_symbol::type t)2566 elf_symbol_is_variable(elf_symbol::type t)
2567 {return t == elf_symbol::OBJECT_TYPE;}
2568
2569 // <elf_symbol::version stuff>
2570
2571 struct elf_symbol::version::priv
2572 {
2573 string version_;
2574 bool is_default_;
2575
privabigail::ir::elf_symbol::version::priv2576 priv()
2577 : is_default_(false)
2578 {}
2579
privabigail::ir::elf_symbol::version::priv2580 priv(const string& v,
2581 bool d)
2582 : version_(v),
2583 is_default_(d)
2584 {}
2585 }; // end struct elf_symbol::version::priv
2586
version()2587 elf_symbol::version::version()
2588 : priv_(new priv)
2589 {}
2590
2591 /// @param v the name of the version.
2592 ///
2593 /// @param is_default true if this is a default version.
version(const string & v,bool is_default)2594 elf_symbol::version::version(const string& v,
2595 bool is_default)
2596 : priv_(new priv(v, is_default))
2597 {}
2598
version(const elf_symbol::version & v)2599 elf_symbol::version::version(const elf_symbol::version& v)
2600 : priv_(new priv(v.str(), v.is_default()))
2601 {
2602 }
2603
2604 /// Cast the version_type into a string that is its name.
2605 ///
2606 /// @return the name of the version.
operator const string&() const2607 elf_symbol::version::operator const string&() const
2608 {return priv_->version_;}
2609
2610 /// Getter for the version name.
2611 ///
2612 /// @return the version name.
2613 const string&
str() const2614 elf_symbol::version::str() const
2615 {return priv_->version_;}
2616
2617 /// Setter for the version name.
2618 ///
2619 /// @param s the version name.
2620 void
str(const string & s)2621 elf_symbol::version::str(const string& s)
2622 {priv_->version_ = s;}
2623
2624 /// Getter for the 'is_default' property of the version.
2625 ///
2626 /// @return true iff this is a default version.
2627 bool
is_default() const2628 elf_symbol::version::is_default() const
2629 {return priv_->is_default_;}
2630
2631 /// Setter for the 'is_default' property of the version.
2632 ///
2633 /// @param f true if this is the default version.
2634 void
is_default(bool f)2635 elf_symbol::version::is_default(bool f)
2636 {priv_->is_default_ = f;}
2637
2638 bool
is_empty() const2639 elf_symbol::version::is_empty() const
2640 {return str().empty();}
2641
2642 /// Compares the current version against another one.
2643 ///
2644 /// @param o the other version to compare the current one to.
2645 ///
2646 /// @return true iff the current version equals @p o.
2647 bool
operator ==(const elf_symbol::version & o) const2648 elf_symbol::version::operator==(const elf_symbol::version& o) const
2649 {return str() == o.str();}
2650
2651 /// Inequality operator.
2652 ///
2653 /// @param o the version to compare against the current one.
2654 ///
2655 /// @return true iff both versions are different.
2656 bool
operator !=(const version & o) const2657 elf_symbol::version::operator!=(const version& o) const
2658 {return !operator==(o);}
2659
2660 /// Assign a version to the current one.
2661 ///
2662 /// @param o the other version to assign to this one.
2663 ///
2664 /// @return a reference to the assigned version.
2665 elf_symbol::version&
operator =(const elf_symbol::version & o)2666 elf_symbol::version::operator=(const elf_symbol::version& o)
2667 {
2668 str(o.str());
2669 is_default(o.is_default());
2670 return *this;
2671 }
2672
2673 // </elf_symbol::version stuff>
2674
2675 // </elf_symbol stuff>
2676
2677 // <class dm_context_rel stuff>
2678 struct dm_context_rel::priv
2679 {
2680 bool is_laid_out_;
2681 size_t offset_in_bits_;
2682 var_decl* anonymous_data_member_;
2683
privabigail::ir::dm_context_rel::priv2684 priv(bool is_static = false)
2685 : is_laid_out_(!is_static),
2686 offset_in_bits_(0),
2687 anonymous_data_member_()
2688 {}
2689
privabigail::ir::dm_context_rel::priv2690 priv(bool is_laid_out, size_t offset_in_bits)
2691 : is_laid_out_(is_laid_out),
2692 offset_in_bits_(offset_in_bits),
2693 anonymous_data_member_()
2694 {}
2695 }; //end struct dm_context_rel::priv
2696
dm_context_rel()2697 dm_context_rel::dm_context_rel()
2698 : context_rel(),
2699 priv_(new priv)
2700 {}
2701
dm_context_rel(scope_decl * s,bool is_laid_out,size_t offset_in_bits,access_specifier a,bool is_static)2702 dm_context_rel::dm_context_rel(scope_decl* s,
2703 bool is_laid_out,
2704 size_t offset_in_bits,
2705 access_specifier a,
2706 bool is_static)
2707 : context_rel(s, a, is_static),
2708 priv_(new priv(is_laid_out, offset_in_bits))
2709 {}
2710
dm_context_rel(scope_decl * s)2711 dm_context_rel::dm_context_rel(scope_decl* s)
2712 : context_rel(s),
2713 priv_(new priv())
2714 {}
2715
2716 bool
get_is_laid_out() const2717 dm_context_rel::get_is_laid_out() const
2718 {return priv_->is_laid_out_;}
2719
2720 void
set_is_laid_out(bool f)2721 dm_context_rel::set_is_laid_out(bool f)
2722 {priv_->is_laid_out_ = f;}
2723
2724 size_t
get_offset_in_bits() const2725 dm_context_rel::get_offset_in_bits() const
2726 {return priv_->offset_in_bits_;}
2727
2728 void
set_offset_in_bits(size_t o)2729 dm_context_rel::set_offset_in_bits(size_t o)
2730 {priv_->offset_in_bits_ = o;}
2731
2732 bool
operator ==(const dm_context_rel & o) const2733 dm_context_rel::operator==(const dm_context_rel& o) const
2734 {
2735 if (!context_rel::operator==(o))
2736 return false;
2737
2738 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
2739 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
2740 }
2741
2742 bool
operator !=(const dm_context_rel & o) const2743 dm_context_rel::operator!=(const dm_context_rel& o) const
2744 {return !operator==(o);}
2745
2746 /// Return a non-nil value if this data member context relationship
2747 /// has an anonymous data member. That means, if the data member this
2748 /// relation belongs to is part of an anonymous data member.
2749 ///
2750 /// @return the containing anonymous data member of this data member
2751 /// relationship. Nil if there is none.
2752 const var_decl*
get_anonymous_data_member() const2753 dm_context_rel::get_anonymous_data_member() const
2754 {return priv_->anonymous_data_member_;}
2755
2756 /// Set the containing anonymous data member of this data member
2757 /// context relationship. That means that the data member this
2758 /// relation belongs to is part of an anonymous data member.
2759 ///
2760 /// @param anon_dm the containing anonymous data member of this data
2761 /// member relationship. Nil if there is none.
2762 void
set_anonymous_data_member(var_decl * anon_dm)2763 dm_context_rel::set_anonymous_data_member(var_decl* anon_dm)
2764 {priv_->anonymous_data_member_ = anon_dm;}
2765
~dm_context_rel()2766 dm_context_rel::~dm_context_rel()
2767 {}
2768 // </class dm_context_rel stuff>
2769
2770 // <environment stuff>
2771
2772 /// Convenience typedef for a map of interned_string -> bool.
2773 typedef unordered_map<interned_string,
2774 bool, hash_interned_string> interned_string_bool_map_type;
2775
2776 /// The private data of the @ref environment type.
2777 struct environment::priv
2778 {
2779 config config_;
2780 canonical_types_map_type canonical_types_;
2781 mutable vector<type_base_sptr> sorted_canonical_types_;
2782 type_base_sptr void_type_;
2783 type_base_sptr variadic_marker_type_;
2784 unordered_set<const class_or_union*> classes_being_compared_;
2785 unordered_set<const function_type*> fn_types_being_compared_;
2786 vector<type_base_sptr> extra_live_types_;
2787 interned_string_pool string_pool_;
2788 bool canonicalization_is_done_;
2789 bool do_on_the_fly_canonicalization_;
2790 bool decl_only_class_equals_definition_;
2791
privabigail::ir::environment::priv2792 priv()
2793 : canonicalization_is_done_(),
2794 do_on_the_fly_canonicalization_(true),
2795 decl_only_class_equals_definition_(false)
2796 {}
2797 };// end struct environment::priv
2798
2799 /// Default constructor of the @ref environment type.
environment()2800 environment::environment()
2801 :priv_(new priv)
2802 {}
2803
2804 /// Destructor for the @ref environment type.
~environment()2805 environment::~environment()
2806 {}
2807
2808 /// Getter the map of canonical types.
2809 ///
2810 /// @return the map of canonical types. The key of the map is the
2811 /// hash of the canonical type and its value if the canonical type.
2812 environment::canonical_types_map_type&
get_canonical_types_map()2813 environment::get_canonical_types_map()
2814 {return priv_->canonical_types_;}
2815
2816 /// Getter the map of canonical types.
2817 ///
2818 /// @return the map of canonical types. The key of the map is the
2819 /// hash of the canonical type and its value if the canonical type.
2820 const environment::canonical_types_map_type&
get_canonical_types_map() const2821 environment::get_canonical_types_map() const
2822 {return const_cast<environment*>(this)->get_canonical_types_map();}
2823
2824 /// Helper to detect if a type is either a reference, a pointer, or a
2825 /// qualified type.
2826 static bool
is_ptr_ref_or_qual_type(const type_base * t)2827 is_ptr_ref_or_qual_type(const type_base *t)
2828 {
2829 if (is_pointer_type(t)
2830 || is_reference_type(t)
2831 || is_qualified_type(t))
2832 return true;
2833 return false;
2834 }
2835
2836 /// A functor to sort decls somewhat topologically. That is, types
2837 /// are sorted in a way that makes the ones that are defined "first"
2838 /// to come first.
2839 ///
2840 /// The topological criteria is a lexicographic sort of the definition
2841 /// location of the type. For types that have no location (or the
2842 /// same location), it's their qualified name that is used for the
2843 /// lexicographic sort.
2844 struct decl_topo_comp
2845 {
2846
2847 /// The "Less Than" comparison operator of this functor.
2848 ///
2849 /// @param f the first decl to be considered for the comparison.
2850 ///
2851 /// @param s the second decl to be considered for the comparison.
2852 ///
2853 /// @return true iff @p f is less than @p s.
2854 bool
operator ()abigail::ir::decl_topo_comp2855 operator()(const decl_base *f,
2856 const decl_base *s)
2857 {
2858 if (!!f != !!s)
2859 return f && !s;
2860
2861 if (!f)
2862 return false;
2863
2864 location fl = f->get_location();
2865 location sl = s->get_location();
2866 if (fl.get_value() != sl.get_value())
2867 return fl.get_value() < sl.get_value();
2868
2869 // We reach this point if location data is useless.
2870 return (get_pretty_representation(f, true)
2871 < get_pretty_representation(s, true));
2872 }
2873
2874 /// The "Less Than" comparison operator of this functor.
2875 ///
2876 /// @param f the first decl to be considered for the comparison.
2877 ///
2878 /// @param s the second decl to be considered for the comparison.
2879 ///
2880 /// @return true iff @p f is less than @p s.
2881 bool
operator ()abigail::ir::decl_topo_comp2882 operator()(const decl_base_sptr &f,
2883 const decl_base_sptr &s)
2884 {return operator()(f.get(), s.get());}
2885
2886 }; // end struct decl_topo_comp
2887
2888 /// A functor to sort types somewhat topologically. That is, types
2889 /// are sorted in a way that makes the ones that are defined "first"
2890 /// to come first.
2891 ///
2892 /// The topological criteria is a lexicographic sort of the definition
2893 /// location of the type. For types that have no location, it's their
2894 /// qualified name that is used for the lexicographic sort.
2895 struct type_topo_comp
2896 {
2897 /// The "Less Than" comparison operator of this functor.
2898 ///
2899 /// @param f the first type to be considered for the comparison.
2900 ///
2901 /// @param s the second type to be considered for the comparison.
2902 ///
2903 /// @return true iff @p f is less than @p s.
2904 bool
operator ()abigail::ir::type_topo_comp2905 operator()(const type_base_sptr &f,
2906 const type_base_sptr &s)
2907 {return operator()(f.get(), s.get());}
2908
2909 /// The "Less Than" comparison operator of this functor.
2910 ///
2911 /// @param f the first type to be considered for the comparison.
2912 ///
2913 /// @param s the second type to be considered for the comparison.
2914 ///
2915 /// @return true iff @p f is less than @p s.
2916 bool
operator ()abigail::ir::type_topo_comp2917 operator()(const type_base *f,
2918 const type_base *s)
2919 {
2920 bool f_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(f);
2921 bool s_is_ptr_ref_or_qual = is_ptr_ref_or_qual_type(s);
2922
2923 if (f_is_ptr_ref_or_qual != s_is_ptr_ref_or_qual)
2924 return !f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual;
2925
2926 if (f_is_ptr_ref_or_qual && s_is_ptr_ref_or_qual)
2927 {
2928 string s1 = get_pretty_representation(f, true);
2929 string s2 = get_pretty_representation(s, true);
2930 if (s1 == s2)
2931 if (qualified_type_def * q = is_qualified_type(f))
2932 if (q->get_cv_quals() == qualified_type_def::CV_NONE)
2933 if (!is_qualified_type(s))
2934 // We are looking at two types that are the result of
2935 // an optimization that happens during the IR
2936 // construction. Namely, type f is a cv-qualified
2937 // type with no qualifier (no const, no volatile, no
2938 // nothing, we call it an empty-qualified type).
2939 // These are the result of an optimization which
2940 // removes "redundant qualifiers" from some types.
2941 // For instance, consider a "const reference". The
2942 // const there is redundant because a reference is
2943 // always const. So as a result of the optimizaton
2944 // that type is going to be transformed into an
2945 // empty-qualified reference. If we don't make that
2946 // optimization, then we risk having spurious change
2947 // reports down the road. But then, as a consequence
2948 // of that optimization, we need to sort the
2949 // empty-qualified type and its non-qualified variant
2950 // e.g, to ensure stability in the abixml output; both
2951 // types are logically equal, but here, we decide that
2952 // the empty-qualified one is topologically "less
2953 // than" the non-qualified counterpart.
2954 //
2955 // So here, type f is an empty-qualified type and type
2956 // s is its non-qualified variant. We decide that f
2957 // is topologically less than s.
2958 return true;
2959 return (s1 < s2);
2960 }
2961
2962 decl_base *fd = is_decl(f);
2963 decl_base *sd = is_decl(s);
2964
2965 if (!!fd != !!sd)
2966 return fd && !sd;
2967
2968 if (!fd)
2969 {
2970 type_base *peeled_f = peel_pointer_or_reference_type(f);
2971 type_base *peeled_s = peel_pointer_or_reference_type(s);
2972
2973 fd = is_decl(peeled_f);
2974 sd = is_decl(peeled_s);
2975
2976 if (!!fd != !!sd)
2977 return fd && !sd;
2978
2979 if (!fd)
2980 return (get_pretty_representation(f, true)
2981 < get_pretty_representation(s, true));
2982 }
2983
2984 // From this point, fd and sd should be non-nil
2985 decl_topo_comp decl_comp;
2986 return decl_comp(fd, sd);
2987 }
2988 }; //end struct type_topo_comp
2989
2990 /// Get a @ref type_decl that represents a "void" type for the current
2991 /// environment.
2992 ///
2993 /// @return the @ref type_decl that represents a "void" type.
2994 const type_base_sptr&
get_void_type() const2995 environment::get_void_type() const
2996 {
2997 if (!priv_->void_type_)
2998 priv_->void_type_.reset(new type_decl(const_cast<environment*>(this),
2999 intern("void"),
3000 0, 0, location()));
3001 return priv_->void_type_;
3002 }
3003
3004 /// Get a @ref type_decl instance that represents a the type of a
3005 /// variadic function parameter.
3006 ///
3007 /// @return the Get a @ref type_decl instance that represents a the
3008 /// type of a variadic function parameter.
3009 const type_base_sptr&
get_variadic_parameter_type() const3010 environment::get_variadic_parameter_type() const
3011 {
3012 if (!priv_->variadic_marker_type_)
3013 priv_->variadic_marker_type_.
3014 reset(new type_decl(const_cast<environment*>(this),
3015 intern("variadic parameter type"),
3016 0, 0, location()));
3017 return priv_->variadic_marker_type_;
3018 }
3019
3020 /// Test if the canonicalization of types created out of the current
3021 /// environment is done.
3022 ///
3023 /// @return true iff the canonicalization of types created out of the current
3024 /// environment is done.
3025 bool
canonicalization_is_done() const3026 environment::canonicalization_is_done() const
3027 {return priv_->canonicalization_is_done_;}
3028
3029 /// Set a flag saying if the canonicalization of types created out of
3030 /// the current environment is done or not.
3031 ///
3032 /// Note that this function must only be called by internal code of
3033 /// the library that creates ABI artifacts (e.g, read an abi corpus
3034 /// from elf or from our own xml format and creates representations of
3035 /// types out of it) and thus needs to canonicalize types to speed-up
3036 /// further type comparison.
3037 ///
3038 /// @param f the new value of the flag.
3039 void
canonicalization_is_done(bool f)3040 environment::canonicalization_is_done(bool f)
3041 {priv_->canonicalization_is_done_ = f;}
3042
3043 /// Getter for the "on-the-fly-canonicalization" flag.
3044 ///
3045 /// @return true iff @ref OnTheFlyCanonicalization
3046 /// "on-the-fly-canonicalization" is to be performed during
3047 /// comparison.
3048 bool
do_on_the_fly_canonicalization() const3049 environment::do_on_the_fly_canonicalization() const
3050 {return priv_->do_on_the_fly_canonicalization_;}
3051
3052 /// Setter for the "on-the-fly-canonicalization" flag.
3053 ///
3054 /// @param f If this is true then @ref OnTheFlyCanonicalization
3055 /// "on-the-fly-canonicalization" is to be performed during
3056 /// comparison.
3057 void
do_on_the_fly_canonicalization(bool f)3058 environment::do_on_the_fly_canonicalization(bool f)
3059 {priv_->do_on_the_fly_canonicalization_ = f;}
3060
3061 /// Getter of the "decl-only-class-equals-definition" flag.
3062 ///
3063 /// Usually, a declaration-only class named 'struct foo' compares
3064 /// equal to any class definition named "struct foo'. This is at
3065 /// least true for C++.
3066 ///
3067 /// In C, though, because there can be multiple definitions of 'struct
3068 /// foo' in the binary, a declaration-only "struct foo" might be
3069 /// considered to *NOT* resolve to any of the struct foo defined. In
3070 /// that case, the declaration-only "struct foo" is considered
3071 /// different from the definitions.
3072 ///
3073 /// This flag controls the behaviour of the comparison of an
3074 /// unresolved decl-only class against a definition of the same name.
3075 ///
3076 /// If set to false, the the declaration equals the definition. If
3077 /// set to false, then the decalration is considered different from
3078 /// the declaration.
3079 ///
3080 /// @return the value of the "decl-only-class-equals-definition" flag.
3081 bool
decl_only_class_equals_definition() const3082 environment::decl_only_class_equals_definition() const
3083 {return priv_->decl_only_class_equals_definition_;}
3084
3085 /// Setter of the "decl-only-class-equals-definition" flag.
3086 ///
3087 /// Usually, a declaration-only class named 'struct foo' compares
3088 /// equal to any class definition named "struct foo'. This is at
3089 /// least true for C++.
3090 ///
3091 /// In C, though, because there can be multiple definitions of 'struct
3092 /// foo' in the binary, a declaration-only "struct foo" might be
3093 /// considered to *NOT* resolve to any of the struct foo defined. In
3094 /// that case, the declaration-only "struct foo" is considered
3095 /// different from the definitions.
3096 ///
3097 /// This flag controls the behaviour of the comparison of an
3098 /// unresolved decl-only class against a definition of the same name.
3099 ///
3100 /// If set to false, the the declaration equals the definition. If
3101 /// set to false, then the decalration is considered different from
3102 /// the declaration.
3103 ///
3104 /// @param the new value of the "decl-only-class-equals-definition"
3105 /// flag.
3106 void
decl_only_class_equals_definition(bool f) const3107 environment::decl_only_class_equals_definition(bool f) const
3108 {priv_->decl_only_class_equals_definition_ = f;}
3109
3110 /// Test if a given type is a void type as defined in the current
3111 /// environment.
3112 ///
3113 /// @param t the type to consider.
3114 ///
3115 /// @return true iff @p t is a void type as defined in the current
3116 /// environment.
3117 bool
is_void_type(const type_base_sptr & t) const3118 environment::is_void_type(const type_base_sptr& t) const
3119 {
3120 if (!t)
3121 return false;
3122 return t.get() == get_void_type().get();
3123 }
3124
3125 /// Test if a given type is a void type as defined in the current
3126 /// environment.
3127 ///
3128 /// @param t the type to consider.
3129 ///
3130 /// @return true iff @p t is a void type as defined in the current
3131 /// environment.
3132 bool
is_void_type(const type_base * t) const3133 environment::is_void_type(const type_base* t) const
3134 {
3135 if (!t)
3136 return false;
3137 return t == get_void_type().get();
3138 }
3139
3140 /// Test if a type is a variadic parameter type as defined in the
3141 /// current environment.
3142 ///
3143 /// @param t the type to consider.
3144 ///
3145 /// @return true iff @p t is a variadic parameter type as defined in
3146 /// the current environment.
3147 bool
is_variadic_parameter_type(const type_base * t) const3148 environment::is_variadic_parameter_type(const type_base* t) const
3149 {
3150 if (!t)
3151 return false;
3152 return t == get_variadic_parameter_type().get();
3153 }
3154
3155 /// Test if a type is a variadic parameter type as defined in the
3156 /// current environment.
3157 ///
3158 /// @param t the type to consider.
3159 ///
3160 /// @return true iff @p t is a variadic parameter type as defined in
3161 /// the current environment.
3162 bool
is_variadic_parameter_type(const type_base_sptr & t) const3163 environment::is_variadic_parameter_type(const type_base_sptr& t) const
3164 {return is_variadic_parameter_type(t.get());}
3165
3166 /// Do intern a string.
3167 ///
3168 /// If a value of this string already exists in the interned string
3169 /// pool of the current environment, then this function returns a new
3170 /// interned_string pointing to that already existing string.
3171 /// Otherwise, a new string is created, stored in the interned string
3172 /// pool and a new interned_string instance is created to point to
3173 /// that new intrerned string, and it's return.
3174 ///
3175 /// @param s the value of the string to intern.
3176 ///
3177 /// @return the interned string.
3178 interned_string
intern(const string & s) const3179 environment::intern(const string& s) const
3180 {return const_cast<environment*>(this)->priv_->string_pool_.create_string(s);}
3181
3182 /// Getter of the general configuration object.
3183 ///
3184 /// @return the configuration object.
3185 const config&
get_config() const3186 environment::get_config() const
3187 {return priv_->config_;}
3188
3189 // </environment stuff>
3190
3191 // <type_or_decl_base stuff>
3192
3193 /// The private data of @ref type_or_decl_base.
3194 struct type_or_decl_base::priv
3195 {
3196 // This holds the kind of dynamic type of particular instance.
3197 // Yes, this is part of the implementation of a "poor man" runtime
3198 // type identification. We are doing this because profiling shows
3199 // that using dynamic_cast in some places is really to slow and is
3200 // constituting a hotspot. This poor man's implementation made
3201 // things be much faster.
3202 enum type_or_decl_kind kind_;
3203 // This holds the runtime type instance pointer of particular
3204 // instance. In other words, this is the "this pointer" of the
3205 // dynamic type of a particular instance.
3206 void* rtti_;
3207 // This holds a pointer to either the type_base sub-object (if the
3208 // current instance is a type) or the decl_base sub-object (if the
3209 // current instance is a decl). This is used by the is_decl() and
3210 // is_type() functions, which also show up during profiling as
3211 // hotspots, due to their use of dynamic_cast.
3212 void* type_or_decl_ptr_;
3213 bool hashing_started_;
3214 const environment* env_;
3215 translation_unit* translation_unit_;
3216
3217 /// Constructor of the type_or_decl_base::priv private type.
3218 ///
3219 /// @param e the environment in which the ABI artifact was created.
3220 ///
3221 /// @param k the identifier of the runtime type of the current
3222 /// instance of ABI artifact.
privabigail::ir::type_or_decl_base::priv3223 priv(const environment* e = 0,
3224 enum type_or_decl_kind k = ABSTRACT_TYPE_OR_DECL)
3225 : kind_(k),
3226 rtti_(),
3227 type_or_decl_ptr_(),
3228 hashing_started_(),
3229 env_(e),
3230 translation_unit_()
3231 {}
3232
3233 enum type_or_decl_kind
kindabigail::ir::type_or_decl_base::priv3234 kind() const
3235 {return kind_;}
3236
3237 void
kindabigail::ir::type_or_decl_base::priv3238 kind (enum type_or_decl_kind k)
3239 {kind_ |= k;}
3240 }; // end struct type_or_decl_base::priv
3241
3242 /// bitwise "OR" operator for the type_or_decl_base::type_or_decl_kind
3243 /// bitmap type.
3244 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)3245 operator|(type_or_decl_base::type_or_decl_kind l,
3246 type_or_decl_base::type_or_decl_kind r)
3247 {
3248 return static_cast<type_or_decl_base::type_or_decl_kind>
3249 (static_cast<unsigned>(l) | static_cast<unsigned>(r));
3250 }
3251
3252 /// bitwise "|=" operator for the type_or_decl_base::type_or_decl_kind
3253 /// bitmap type.
3254 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)3255 operator|=(type_or_decl_base::type_or_decl_kind& l,
3256 type_or_decl_base::type_or_decl_kind r)
3257 {
3258 l = l | r;
3259 return l;
3260 }
3261
3262 /// bitwise "AND" operator for the
3263 /// type_or_decl_base::type_or_decl_kind bitmap type.
3264 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)3265 operator&(type_or_decl_base::type_or_decl_kind l,
3266 type_or_decl_base::type_or_decl_kind r)
3267 {
3268 return static_cast<type_or_decl_base::type_or_decl_kind>
3269 (static_cast<unsigned>(l) & static_cast<unsigned>(r));
3270 }
3271
3272 /// bitwise "A&=" operator for the
3273 /// type_or_decl_base::type_or_decl_kind bitmap type.
3274 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)3275 operator&=(type_or_decl_base::type_or_decl_kind& l,
3276 type_or_decl_base::type_or_decl_kind r)
3277 {
3278 l = l & r;
3279 return l;
3280 }
3281
3282 /// Default constructor of @ref type_or_decl_base.
type_or_decl_base()3283 type_or_decl_base::type_or_decl_base()
3284 :priv_(new priv)
3285 {}
3286
3287 /// Constructor of @ref type_or_decl_base.
3288 ///
3289 /// @param the environment the current ABI artifact is constructed
3290 /// from.
3291 ///
3292 /// @param k the runtime identifier bitmap of the type being built.
type_or_decl_base(const environment * e,enum type_or_decl_kind k)3293 type_or_decl_base::type_or_decl_base(const environment* e,
3294 enum type_or_decl_kind k)
3295 :priv_(new priv(e, k))
3296 {}
3297
3298 /// Copy constructor of @ref type_or_decl_base.
type_or_decl_base(const type_or_decl_base & o)3299 type_or_decl_base::type_or_decl_base(const type_or_decl_base& o)
3300 {*priv_ = *o.priv_;}
3301
3302 /// The destructor of the @ref type_or_decl_base type.
~type_or_decl_base()3303 type_or_decl_base::~type_or_decl_base()
3304 {}
3305
3306 /// Getter for the "kind" property of @ref type_or_decl_base type.
3307 ///
3308 /// This property holds the identifier bitmap of the runtime type of
3309 /// an ABI artifact.
3310 ///
3311 /// @return the runtime type identifier bitmap of the current ABI
3312 /// artifact.
3313 enum type_or_decl_base::type_or_decl_kind
kind() const3314 type_or_decl_base::kind() const
3315 {return priv_->kind();}
3316
3317 /// Setter for the "kind" property of @ref type_or_decl_base type.
3318 ///
3319 /// This property holds the identifier bitmap of the runtime type of
3320 /// an ABI artifact.
3321 ///
3322 /// @param the runtime type identifier bitmap of the current ABI
3323 /// artifact.
3324 void
kind(enum type_or_decl_kind k)3325 type_or_decl_base::kind(enum type_or_decl_kind k)
3326 {priv_->kind(k);}
3327
3328 /// Getter of the pointer to the runtime type sub-object of the
3329 /// current instance.
3330 ///
3331 /// @return the pointer to the runtime type sub-object of the current
3332 /// instance.
3333 const void*
runtime_type_instance() const3334 type_or_decl_base::runtime_type_instance() const
3335 {return priv_->rtti_;}
3336
3337 /// Getter of the pointer to the runtime type sub-object of the
3338 /// current instance.
3339 ///
3340 /// @return the pointer to the runtime type sub-object of the current
3341 /// instance.
3342 void*
runtime_type_instance()3343 type_or_decl_base::runtime_type_instance()
3344 {return priv_->rtti_;}
3345
3346 /// Setter of the pointer to the runtime type sub-object of the
3347 /// current instance.
3348 ///
3349 /// @param i the new pointer to the runtime type sub-object of the
3350 /// current instance.
3351 void
runtime_type_instance(void * i)3352 type_or_decl_base::runtime_type_instance(void* i)
3353 {
3354 priv_->rtti_ = i;
3355 if (type_base* t = dynamic_cast<type_base*>(this))
3356 priv_->type_or_decl_ptr_ = t;
3357 else if (decl_base *d = dynamic_cast<decl_base*>(this))
3358 priv_->type_or_decl_ptr_ = d;
3359 }
3360
3361 /// Getter of the pointer to either the type_base sub-object of the
3362 /// current instance if it's a type, or to the decl_base sub-object of
3363 /// the current instance if it's a decl.
3364 ///
3365 /// @return the pointer to either the type_base sub-object of the
3366 /// current instance if it's a type, or to the decl_base sub-object of
3367 /// the current instance if it's a decl.
3368 const void*
type_or_decl_base_pointer() const3369 type_or_decl_base::type_or_decl_base_pointer() const
3370 {return const_cast<type_or_decl_base*>(this)->type_or_decl_base_pointer();}
3371
3372 /// Getter of the pointer to either the type_base sub-object of the
3373 /// current instance if it's a type, or to the decl_base sub-object of
3374 /// the current instance if it's a decl.
3375 ///
3376 /// @return the pointer to either the type_base sub-object of the
3377 /// current instance if it's a type, or to the decl_base sub-object of
3378 /// the current instance if it's a decl.
3379 void*
type_or_decl_base_pointer()3380 type_or_decl_base::type_or_decl_base_pointer()
3381 {return priv_->type_or_decl_ptr_;}
3382
3383 /// Getter for the 'hashing_started' property.
3384 ///
3385 /// @return the 'hashing_started' property.
3386 bool
hashing_started() const3387 type_or_decl_base::hashing_started() const
3388 {return priv_->hashing_started_;}
3389
3390 /// Setter for the 'hashing_started' property.
3391 ///
3392 /// @param b the value to set the 'hashing_property' to.
3393 void
hashing_started(bool b) const3394 type_or_decl_base::hashing_started(bool b) const
3395 {priv_->hashing_started_ = b;}
3396
3397 /// Setter of the environment of the current ABI artifact.
3398 ///
3399 /// This just sets the environment artifact of the current ABI
3400 /// artifact, not on its sub-trees. If you want to set the
3401 /// environment of an ABI artifact including its sub-tree, use the
3402 /// abigail::ir::set_environment_for_artifact() function.
3403 ///
3404 /// @param env the new environment.
3405 void
set_environment(const environment * env)3406 type_or_decl_base::set_environment(const environment* env)
3407 {priv_->env_ = env;}
3408
3409 /// Getter of the environment of the current ABI artifact.
3410 ///
3411 /// @return the environment of the artifact.
3412 const environment*
get_environment() const3413 type_or_decl_base::get_environment() const
3414 {return priv_->env_;}
3415
3416 /// Getter of the environment of the current ABI artifact.
3417 ///
3418 /// @return the environment of the artifact.
3419 environment*
get_environment()3420 type_or_decl_base::get_environment()
3421 {return const_cast<environment*>(priv_->env_);}
3422
3423 /// Get the @ref corpus this ABI artifact belongs to.
3424 ///
3425 /// @return the corpus this ABI artifact belongs to, or nil if it
3426 /// belongs to none for now.
3427 corpus*
get_corpus()3428 type_or_decl_base::get_corpus()
3429 {
3430 translation_unit* tu = get_translation_unit();
3431 if (!tu)
3432 return 0;
3433 return tu->get_corpus();
3434 }
3435
3436
3437 /// Get the @ref corpus this ABI artifact belongs to.
3438 ///
3439 /// @return the corpus this ABI artifact belongs to, or nil if it
3440 /// belongs to none for now.
3441 const corpus*
get_corpus() const3442 type_or_decl_base::get_corpus() const
3443 {return const_cast<type_or_decl_base*>(this)->get_corpus();}
3444
3445 /// Set the @ref translation_unit this ABI artifact belongs to.
3446 ///
3447 /// Note that adding an ABI artifact to a containining on should
3448 /// invoke this member function.
3449 void
set_translation_unit(translation_unit * tu)3450 type_or_decl_base::set_translation_unit(translation_unit* tu)
3451 {priv_->translation_unit_ = tu;}
3452
3453
3454 /// Get the @ref translation_unit this ABI artifact belongs to.
3455 ///
3456 /// @return the translation unit this ABI artifact belongs to, or nil
3457 /// if belongs to none for now.
3458 translation_unit*
get_translation_unit()3459 type_or_decl_base::get_translation_unit()
3460 {return priv_->translation_unit_;}
3461
3462 /// Get the @ref translation_unit this ABI artifact belongs to.
3463 ///
3464 /// @return the translation unit this ABI artifact belongs to, or nil
3465 /// if belongs to none for now.
3466 const translation_unit*
get_translation_unit() const3467 type_or_decl_base::get_translation_unit() const
3468 {return const_cast<type_or_decl_base*>(this)->get_translation_unit();}
3469
3470 /// Assignment operator for @ref type_or_decl_base.
3471 ///
3472 /// @param o the other instance to assign the current instance to.
3473 ///
3474 /// return a reference to the assigned instance of @ref
3475 /// type_or_decl_base.
3476 type_or_decl_base&
operator =(const type_or_decl_base & o)3477 type_or_decl_base::operator=(const type_or_decl_base& o)
3478 {
3479 *priv_ = *o.priv_;
3480 return *this;
3481 }
3482
3483 /// Traverse the the ABI artifact.
3484 ///
3485 /// @param v the visitor used to traverse the sub-tree nodes of the
3486 /// artifact.
3487 bool
traverse(ir_node_visitor &)3488 type_or_decl_base::traverse(ir_node_visitor&)
3489 {return true;}
3490
3491 /// Set the environment of a given ABI artifact, including recursively
3492 /// setting the environment on the sub-trees of the artifact.
3493 ///
3494 /// @param artifact the artifact to set the environment for.
3495 ///
3496 /// @param env the new environment.
3497 void
set_environment_for_artifact(type_or_decl_base * artifact,const environment * env)3498 set_environment_for_artifact(type_or_decl_base* artifact,
3499 const environment* env)
3500 {
3501 ABG_ASSERT(artifact && env);
3502
3503 ::environment_setter s(env);
3504 artifact->traverse(s);
3505 }
3506
3507 /// Set the environment of a given ABI artifact, including recursively
3508 /// setting the environment on the sub-trees of the artifact.
3509 ///
3510 /// @param artifact the artifact to set the environment for.
3511 ///
3512 /// @param env the new environment.
3513 void
set_environment_for_artifact(type_or_decl_base_sptr artifact,const environment * env)3514 set_environment_for_artifact(type_or_decl_base_sptr artifact,
3515 const environment* env)
3516 {set_environment_for_artifact(artifact.get(), env);}
3517
3518 /// Non-member equality operator for the @type_or_decl_base type.
3519 ///
3520 /// @param lr the left-hand operand of the equality.
3521 ///
3522 /// @param rr the right-hand operatnr of the equality.
3523 ///
3524 /// @return true iff @p lr equals @p rr.
3525 bool
operator ==(const type_or_decl_base & lr,const type_or_decl_base & rr)3526 operator==(const type_or_decl_base& lr, const type_or_decl_base& rr)
3527 {
3528 const type_or_decl_base* l = &lr;
3529 const type_or_decl_base* r = &rr;
3530
3531 const decl_base* dl = dynamic_cast<const decl_base*>(l),
3532 *dr = dynamic_cast<const decl_base*>(r);
3533
3534 if (!!dl != !!dr)
3535 return false;
3536
3537 if (dl && dr)
3538 return *dl == *dr;
3539
3540 const type_base* tl = dynamic_cast<const type_base*>(l),
3541 *tr = dynamic_cast<const type_base*>(r);
3542
3543 if (!!tl != !!tr)
3544 return false;
3545
3546 if (tl && tr)
3547 return *tl == *tr;
3548
3549 return false;
3550 }
3551
3552 /// Non-member equality operator for the @type_or_decl_base type.
3553 ///
3554 /// @param l the left-hand operand of the equality.
3555 ///
3556 /// @param r the right-hand operatnr of the equality.
3557 ///
3558 /// @return true iff @p l equals @p r.
3559 bool
operator ==(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)3560 operator==(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
3561 {
3562 if (!! l != !!r)
3563 return false;
3564
3565 if (!l)
3566 return true;
3567
3568 return *r == *l;
3569 }
3570
3571 /// Non-member inequality operator for the @type_or_decl_base type.
3572 ///
3573 /// @param l the left-hand operand of the equality.
3574 ///
3575 /// @param r the right-hand operator of the equality.
3576 ///
3577 /// @return true iff @p l is different from @p r.
3578 bool
operator !=(const type_or_decl_base_sptr & l,const type_or_decl_base_sptr & r)3579 operator!=(const type_or_decl_base_sptr& l, const type_or_decl_base_sptr& r)
3580 {return !operator==(l, r);}
3581
3582 // </type_or_decl_base stuff>
3583
3584 // <Decl definition>
3585
3586 struct decl_base::priv
3587 {
3588 bool in_pub_sym_tab_;
3589 bool is_anonymous_;
3590 bool is_artificial_;
3591 bool has_anonymous_parent_;
3592 location location_;
3593 context_rel *context_;
3594 interned_string name_;
3595 interned_string qualified_parent_name_;
3596 // This temporary qualified name is the cache used for the qualified
3597 // name before the type associated to this decl (if applicable) is
3598 // canonicalized. Once the type is canonicalized, the cached use is
3599 // the data member qualified_parent_name_ above.
3600 interned_string temporary_qualified_name_;
3601 // This is the fully qualified name of the decl. It contains the
3602 // name of the decl and the qualified name of its scope. So if in
3603 // the parent scopes of the decl, there is one anonymous struct,
3604 // somewhere in the name, there is going to by an
3605 // __anonymous_struct__ string, even if the anonymous struct is not
3606 // the direct containing scope of this decl.
3607 interned_string qualified_name_;
3608 // Unline qualified_name_, scoped_name_ contains the name of the
3609 // decl and the name of its scope; not the qualified name of the
3610 // scope.
3611 interned_string scoped_name_;
3612 interned_string linkage_name_;
3613 visibility visibility_;
3614 decl_base_sptr declaration_;
3615 decl_base_wptr definition_of_declaration_;
3616 decl_base* naked_definition_of_declaration_;
3617 bool is_declaration_only_;
3618
privabigail::ir::decl_base::priv3619 priv()
3620 : in_pub_sym_tab_(false),
3621 is_anonymous_(true),
3622 is_artificial_(false),
3623 has_anonymous_parent_(false),
3624 context_(),
3625 visibility_(VISIBILITY_DEFAULT),
3626 naked_definition_of_declaration_(),
3627 is_declaration_only_(false)
3628 {}
3629
privabigail::ir::decl_base::priv3630 priv(interned_string name, const location& locus,
3631 interned_string linkage_name, visibility vis)
3632 : in_pub_sym_tab_(false),
3633 location_(locus),
3634 context_(),
3635 name_(name),
3636 qualified_name_(name),
3637 linkage_name_(linkage_name),
3638 visibility_(vis),
3639 naked_definition_of_declaration_(),
3640 is_declaration_only_(false)
3641 {
3642 is_anonymous_ = name_.empty();
3643 has_anonymous_parent_ = false;
3644 }
3645
privabigail::ir::decl_base::priv3646 priv(const location& l)
3647 : in_pub_sym_tab_(false),
3648 is_anonymous_(true),
3649 has_anonymous_parent_(false),
3650 location_(l),
3651 context_(),
3652 visibility_(VISIBILITY_DEFAULT),
3653 naked_definition_of_declaration_(),
3654 is_declaration_only_(false)
3655 {}
3656
~privabigail::ir::decl_base::priv3657 ~priv()
3658 {
3659 delete context_;
3660 }
3661 };// end struct decl_base::priv
3662
3663 /// Constructor for the @ref decl_base type.
3664 ///
3665 /// @param e the environment the current @ref decl_base is being
3666 /// created in.
3667 ///
3668 /// @param name the name of the declaration.
3669 ///
3670 /// @param locus the location where to find the declaration in the
3671 /// source code.
3672 ///
3673 /// @param linkage_name the linkage name of the declaration.
3674 ///
3675 /// @param vis the visibility of the declaration.
decl_base(const environment * e,const string & name,const location & locus,const string & linkage_name,visibility vis)3676 decl_base::decl_base(const environment* e,
3677 const string& name,
3678 const location& locus,
3679 const string& linkage_name,
3680 visibility vis)
3681 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
3682 priv_(new priv(e->intern(name), locus, e->intern(linkage_name), vis))
3683 {
3684 }
3685
3686 /// Constructor.
3687 ///
3688 /// @param e the environment this instance of @ref decl_base is
3689 /// created in.
3690 ///
3691 /// @param name the name of the declaration being constructed.
3692 ///
3693 /// @param locus the source location of the declaration being constructed.
3694 ///
3695 /// @param linkage_name the linkage name of the declaration being
3696 /// constructed.
3697 ///
3698 /// @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)3699 decl_base::decl_base(const environment* e,
3700 const interned_string& name,
3701 const location& locus,
3702 const interned_string& linkage_name,
3703 visibility vis)
3704 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
3705 priv_(new priv(name, locus, linkage_name, vis))
3706 {}
3707
3708 /// Constructor for the @ref decl_base type.
3709 ///
3710 ///@param environment the environment this instance of @ref decl_base
3711 /// is being constructed in.
3712 ///
3713 /// @param l the location where to find the declaration in the source
3714 /// code.
decl_base(const environment * e,const location & l)3715 decl_base::decl_base(const environment* e, const location& l)
3716 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
3717 priv_(new priv(l))
3718 {}
3719
decl_base(const decl_base & d)3720 decl_base::decl_base(const decl_base& d)
3721 : type_or_decl_base(d)
3722 {
3723 priv_->in_pub_sym_tab_ = d.priv_->in_pub_sym_tab_;
3724 priv_->location_ = d.priv_->location_;
3725 priv_->name_ = d.priv_->name_;
3726 priv_->qualified_parent_name_ = d.priv_->qualified_parent_name_;
3727 priv_->qualified_name_ = d.priv_->qualified_name_;
3728 priv_->linkage_name_ = d.priv_->linkage_name_;
3729 priv_->context_ = d.priv_->context_;
3730 priv_->visibility_ = d.priv_->visibility_;
3731 }
3732
3733 /// Getter for the qualified name.
3734 ///
3735 /// Unlike decl_base::get_qualified_name() this doesn't try to update
3736 /// the qualified name.
3737 ///
3738 /// @return the qualified name.
3739 const interned_string&
peek_qualified_name() const3740 decl_base::peek_qualified_name() const
3741 {return priv_->qualified_name_;}
3742
3743 /// Clear the qualified name of this decl.
3744 ///
3745 /// This is useful to ensure that the cache for the qualified name of
3746 /// the decl is refreshed right after type canonicalization, for
3747 /// instance.
3748 void
clear_qualified_name()3749 decl_base::clear_qualified_name()
3750 {priv_->qualified_name_.clear();}
3751
3752 /// Setter for the qualified name.
3753 ///
3754 /// @param n the new qualified name.
3755 void
set_qualified_name(const interned_string & n) const3756 decl_base::set_qualified_name(const interned_string& n) const
3757 {priv_->qualified_name_ = n;}
3758
3759 /// Getter of the temporary qualified name of the current declaration.
3760 ///
3761 /// This temporary qualified name is used as a qualified name cache by
3762 /// the type for which this is the declaration (when applicable)
3763 /// before the type is canonicalized. Once the type is canonicalized,
3764 /// it's the result of decl_base::peek_qualified_name() that becomes
3765 /// the qualified name cached.
3766 ///
3767 /// @return the temporary qualified name.
3768 const interned_string&
peek_temporary_qualified_name() const3769 decl_base::peek_temporary_qualified_name() const
3770 {return priv_->temporary_qualified_name_;}
3771
3772 /// Setter for the temporary qualified name of the current
3773 /// declaration.
3774 ///
3775 ///@param n the new temporary qualified name.
3776 ///
3777 /// This temporary qualified name is used as a qualified name cache by
3778 /// the type for which this is the declaration (when applicable)
3779 /// before the type is canonicalized. Once the type is canonicalized,
3780 /// it's the result of decl_base::peek_qualified_name() that becomes
3781 /// the qualified name cached.
3782 void
set_temporary_qualified_name(const interned_string & n) const3783 decl_base::set_temporary_qualified_name(const interned_string& n) const
3784 {priv_->temporary_qualified_name_ = n;}
3785
3786 ///Getter for the context relationship.
3787 ///
3788 ///@return the context relationship for the current decl_base.
3789 const context_rel*
get_context_rel() const3790 decl_base::get_context_rel() const
3791 {return priv_->context_;}
3792
3793 ///Getter for the context relationship.
3794 ///
3795 ///@return the context relationship for the current decl_base.
3796 context_rel*
get_context_rel()3797 decl_base::get_context_rel()
3798 {return priv_->context_;}
3799
3800 void
set_context_rel(context_rel * c)3801 decl_base::set_context_rel(context_rel *c)
3802 {priv_->context_ = c;}
3803
3804 /// Get the hash of a decl. If the hash hasn't been computed yet,
3805 /// compute it ans store its value; otherwise, just return the hash.
3806 ///
3807 /// @return the hash of the decl.
3808 size_t
get_hash() const3809 decl_base::get_hash() const
3810 {
3811 size_t result = 0;
3812
3813 if (const type_base* t = dynamic_cast<const type_base*>(this))
3814 {
3815 type_base::dynamic_hash hash;
3816 result = hash(t);
3817 }
3818 else
3819 // If we reach this point, it mean we are missing a virtual
3820 // overload for decl_base::get_hash. Add it!
3821 abort();
3822
3823 return result;
3824 }
3825
3826 /// Test if the decl is defined in a ELF symbol table as a public
3827 /// symbol.
3828 ///
3829 /// @return true iff the decl is defined in a ELF symbol table as a
3830 /// public symbol.
3831 bool
get_is_in_public_symbol_table() const3832 decl_base::get_is_in_public_symbol_table() const
3833 {return priv_->in_pub_sym_tab_;}
3834
3835 /// Set the flag saying if this decl is from a symbol that is in
3836 /// a public symbols table, defined as public (global or weak).
3837 ///
3838 /// @param f the new flag value.
3839 void
set_is_in_public_symbol_table(bool f)3840 decl_base::set_is_in_public_symbol_table(bool f)
3841 {priv_->in_pub_sym_tab_ = f;}
3842
3843 /// Get the location of a given declaration.
3844 ///
3845 /// The location is an abstraction for the tripplet {file path,
3846 /// line, column} that defines where the declaration appeared in the
3847 /// source code.
3848 ///
3849 /// To get the value of the tripplet {file path, line, column} from
3850 /// the @ref location, you need to use the
3851 /// location_manager::expand_location() method.
3852 ///
3853 /// The instance of @ref location_manager that you want is
3854 /// accessible from the instance of @ref translation_unit that the
3855 /// current instance of @ref decl_base belongs to, via a call to
3856 /// translation_unit::get_loc_mgr().
3857 ///
3858 /// @return the location of the current instance of @ref decl_base.
3859 const location&
get_location() const3860 decl_base::get_location() const
3861 {return priv_->location_;}
3862
3863 /// Set the location for a given declaration.
3864 ///
3865 /// The location is an abstraction for the tripplet {file path,
3866 /// line, column} that defines where the declaration appeared in the
3867 /// source code.
3868 ///
3869 /// To create a location from a tripplet {file path, line, column},
3870 /// you need to use the method @ref
3871 /// location_manager::create_new_location().
3872 ///
3873 /// The instance of @ref location_manager that you want is
3874 /// accessible from the instance of @ref translation_unit that the
3875 /// current instance of @ref decl_base belongs to, via a call to
3876 /// translation_unit::get_loc_mgr().
3877 void
set_location(const location & l)3878 decl_base::set_location(const location& l)
3879 {priv_->location_ = l;}
3880
3881 /// Setter for the name of the decl.
3882 ///
3883 /// @param n the new name to set.
3884 void
set_name(const string & n)3885 decl_base::set_name(const string& n)
3886 {
3887 priv_->name_ = get_environment()->intern(n);
3888 priv_->is_anonymous_ = n.empty();
3889 }
3890
3891 /// Test if the current declaration is anonymous.
3892 ///
3893 /// Being anonymous means that the declaration was created without a
3894 /// name. This can usually happen for enum or struct types.
3895 ///
3896 /// @return true iff the type is anonymous.
3897 bool
get_is_anonymous() const3898 decl_base::get_is_anonymous() const
3899 {return priv_->is_anonymous_;}
3900
3901 /// Set the "is_anonymous" flag of the current declaration.
3902 ///
3903 /// Being anonymous means that the declaration was created without a
3904 /// name. This can usually happen for enum or struct types.
3905 ///
3906 /// @param f the new value of the flag.
3907 void
set_is_anonymous(bool f)3908 decl_base::set_is_anonymous(bool f)
3909 {priv_->is_anonymous_ = f;}
3910
3911 /// Getter of the flag that says if the declaration is artificial.
3912 ///
3913 /// Being artificial means the parameter was not explicitely
3914 /// mentionned in the source code, but was rather artificially created
3915 /// by the compiler.
3916 ///
3917 /// @return true iff the declaration is artificial.
3918 bool
get_is_artificial() const3919 decl_base::get_is_artificial() const
3920 {return priv_->is_artificial_;}
3921
3922 /// Setter of the flag that says if the declaration is artificial.
3923 ///
3924 /// Being artificial means the parameter was not explicitely
3925 /// mentionned in the source code, but was rather artificially created
3926 /// by the compiler.
3927 ///
3928 /// @param f the new value of the flag that says if the declaration is
3929 /// artificial.
3930 void
set_is_artificial(bool f)3931 decl_base::set_is_artificial(bool f)
3932 {priv_->is_artificial_ = f;}
3933
3934 /// Get the "has_anonymous_parent" flag of the current declaration.
3935 ///
3936 /// Having an anoymous parent means having a anonymous parent scope
3937 /// (containing type or namespace) which is either direct or indirect.
3938 ///
3939 /// @return true iff the current decl has a direct or indirect scope
3940 /// which is anonymous.
3941 bool
get_has_anonymous_parent() const3942 decl_base::get_has_anonymous_parent() const
3943 {return priv_->has_anonymous_parent_;}
3944
3945 /// Set the "has_anonymous_parent" flag of the current declaration.
3946 ///
3947 /// Having an anonymous parent means having a anonymous parent scope
3948 /// (containing type or namespace) which is either direct or indirect.
3949 ///
3950 /// @param f set the flag which says if the current decl has a direct
3951 /// or indirect scope which is anonymous.
3952 void
set_has_anonymous_parent(bool f) const3953 decl_base::set_has_anonymous_parent(bool f) const
3954 {priv_->has_anonymous_parent_ = f;}
3955
3956 /// @return the logical "OR" of decl_base::get_is_anonymous() and
3957 /// decl_base::get_has_anonymous_parent().
3958 bool
get_is_anonymous_or_has_anonymous_parent() const3959 decl_base::get_is_anonymous_or_has_anonymous_parent() const
3960 {return get_is_anonymous() || get_has_anonymous_parent();}
3961
3962 /// Getter for the mangled name.
3963 ///
3964 /// @return the new mangled name.
3965 const interned_string&
get_linkage_name() const3966 decl_base::get_linkage_name() const
3967 {return priv_->linkage_name_;}
3968
3969 /// Setter for the linkage name.
3970 ///
3971 /// @param m the new linkage name.
3972 void
set_linkage_name(const string & m)3973 decl_base::set_linkage_name(const string& m)
3974 {
3975 const environment* env = get_environment();
3976 ABG_ASSERT(env);
3977 priv_->linkage_name_ = env->intern(m);
3978 }
3979
3980 /// Getter for the visibility of the decl.
3981 ///
3982 /// @return the new visibility.
3983 decl_base::visibility
get_visibility() const3984 decl_base::get_visibility() const
3985 {return priv_->visibility_;}
3986
3987 /// Setter for the visibility of the decl.
3988 ///
3989 /// @param v the new visibility.
3990 void
set_visibility(visibility v)3991 decl_base::set_visibility(visibility v)
3992 {priv_->visibility_ = v;}
3993
3994 /// Return the type containing the current decl, if any.
3995 ///
3996 /// @return the type that contains the current decl, or NULL if there
3997 /// is none.
3998 scope_decl*
get_scope() const3999 decl_base::get_scope() const
4000 {
4001 if (priv_->context_)
4002 return priv_->context_->get_scope();
4003 return 0;
4004 }
4005
4006 /// Return a copy of the qualified name of the parent of the current
4007 /// decl.
4008 ///
4009 /// @return the newly-built qualified name of the of the current decl.
4010 const interned_string&
get_qualified_parent_name() const4011 decl_base::get_qualified_parent_name() const
4012 {return priv_->qualified_parent_name_;}
4013
4014 /// Getter for the name of the current decl.
4015 ///
4016 /// @return the name of the current decl.
4017 const interned_string&
get_name() const4018 decl_base::get_name() const
4019 {return priv_->name_;}
4020
4021 /// Compute the qualified name of the decl.
4022 ///
4023 /// @param qn the resulting qualified name.
4024 ///
4025 /// @param internal set to true if the call is intended for an
4026 /// internal use (for technical use inside the library itself), false
4027 /// otherwise. If you don't know what this is for, then set it to
4028 /// false.
4029 void
get_qualified_name(interned_string & qn,bool internal) const4030 decl_base::get_qualified_name(interned_string& qn, bool internal) const
4031 {qn = get_qualified_name(internal);}
4032
4033 /// Get the pretty representatin of the current declaration.
4034 ///
4035 ///
4036 /// @param internal set to true if the call is intended for an
4037 /// internal use (for technical use inside the library itself), false
4038 /// otherwise. If you don't know what this is for, then set it to
4039 /// false.
4040 ///
4041 /// @param qualified_name if true, names emitted in the pretty
4042 /// representation are fully qualified.
4043 ///
4044 /// @return the default pretty representation for a decl. This is
4045 /// basically the fully qualified name of the decl optionally prefixed
4046 /// with a meaningful string to add context for the user.
4047 string
get_pretty_representation(bool internal,bool qualified_name) const4048 decl_base::get_pretty_representation(bool internal,
4049 bool qualified_name) const
4050 {
4051 if (internal
4052 && get_is_anonymous()
4053 && has_generic_anonymous_internal_type_name(this))
4054 {
4055 // We are looking at an anonymous enum, union or class and we
4056 // want an *internal* pretty representation for it. All
4057 // anonymous types of this kind in the same namespace must have
4058 // the same internal representation for type canonicalization to
4059 // work properly.
4060 //
4061 // OK, in practise, we are certainly looking at an enum because
4062 // classes and unions should have their own overloaded virtual
4063 // member function for this.
4064 string name = get_generic_anonymous_internal_type_name(this);
4065 if (qualified_name && !get_qualified_parent_name().empty())
4066 name = get_qualified_parent_name() + "::" + name;
4067 return name;
4068 }
4069
4070 if (qualified_name)
4071 return get_qualified_name(internal);
4072 return get_name();
4073 }
4074
4075 /// Return the qualified name of the decl.
4076 ///
4077 /// This is the fully qualified name of the decl. It's made of the
4078 /// concatenation of the name of the decl with the qualified name of
4079 /// its scope.
4080 ///
4081 /// Note that the value returned by this function is computed by @ref
4082 /// update_qualified_name when the decl is added to its scope.
4083 ///
4084 /// @param internal set to true if the call is intended for an
4085 /// internal use (for technical use inside the library itself), false
4086 /// otherwise. If you don't know what this is for, then set it to
4087 /// false.
4088 ///
4089 /// @return the resulting qualified name.
4090 const interned_string&
get_qualified_name(bool) const4091 decl_base::get_qualified_name(bool /*internal*/) const
4092 {return priv_->qualified_name_;}
4093
4094 /// Return the scoped name of the decl.
4095 ///
4096 /// This is made of the concatenation of the name of the decl with the
4097 /// name of its scope. It doesn't contain the qualified name of its
4098 /// scope, unlike what is returned by decl_base::get_qualified_name.
4099 ///
4100 /// Note that the value returned by this function is computed by @ref
4101 /// update_qualified_name when the decl is added to its scope.
4102 ///
4103 /// @return the scoped name of the decl.
4104 const interned_string&
get_scoped_name() const4105 decl_base::get_scoped_name() const
4106 {return priv_->scoped_name_;}
4107
4108 /// If this @ref decl_base is a definition, get its earlier
4109 /// declaration.
4110 ///
4111 /// @return the earlier declaration of the class, if any.
4112 const decl_base_sptr
get_earlier_declaration() const4113 decl_base::get_earlier_declaration() const
4114 {return priv_->declaration_;}
4115
4116 /// set the earlier declaration of this @ref decl_base definition.
4117 ///
4118 /// @param d the earlier declaration to set. Note that it's set only
4119 /// if it's a pure declaration.
4120 void
set_earlier_declaration(const decl_base_sptr & d)4121 decl_base::set_earlier_declaration(const decl_base_sptr& d)
4122 {
4123 if (d && d->get_is_declaration_only())
4124 priv_->declaration_ = d;
4125 }
4126
4127
4128 /// If this @ref decl_base is declaration-only, get its definition, if
4129 /// any.
4130 ///
4131 /// @return the definition of this decl-only @ref decl_base.
4132 const decl_base_sptr
get_definition_of_declaration() const4133 decl_base::get_definition_of_declaration() const
4134 {return priv_->definition_of_declaration_.lock();}
4135
4136 /// If this @ref decl_base is declaration-only, get its definition,
4137 /// if any.
4138 ///
4139 /// Note that this function doesn't return a smart pointer, but rather
4140 /// the underlying pointer managed by the smart pointer. So it's as
4141 /// fast as possible. This getter is to be used in code paths that
4142 /// are proven to be performance hot spots; especially, when comparing
4143 /// sensitive types like enums, classes or unions. Those are compared
4144 /// extremely frequently and thus, their access to the definition of
4145 /// declaration must be fast.
4146 ///
4147 /// @return the definition of the declaration.
4148 const decl_base*
get_naked_definition_of_declaration() const4149 decl_base::get_naked_definition_of_declaration() const
4150 {return priv_->naked_definition_of_declaration_;}
4151
4152 /// Test if a @ref decl_base is a declaration-only decl.
4153 ///
4154 /// @return true iff the current @ref decl_base is declaration-only.
4155 bool
get_is_declaration_only() const4156 decl_base::get_is_declaration_only() const
4157 {return priv_->is_declaration_only_;}
4158
4159 /// Set a flag saying if the @ref enum_type_decl is a declaration-only
4160 /// @ref enum_type_decl.
4161 ///
4162 /// @param f true if the @ref enum_type_decl is a declaration-only
4163 /// @ref enum_type_decl.
4164 void
set_is_declaration_only(bool f)4165 decl_base::set_is_declaration_only(bool f)
4166 {
4167 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
4168
4169 priv_->is_declaration_only_ = f;
4170
4171 if (update_types_lookup_map)
4172 if (scope_decl* s = get_scope())
4173 {
4174 scope_decl::declarations::iterator i;
4175 if (s->find_iterator_for_member(this, i))
4176 maybe_update_types_lookup_map(*i);
4177 else
4178 ABG_ASSERT_NOT_REACHED;
4179 }
4180 }
4181
4182 change_kind
operator |(change_kind l,change_kind r)4183 operator|(change_kind l, change_kind r)
4184 {
4185 return static_cast<change_kind>(static_cast<unsigned>(l)
4186 | static_cast<unsigned>(r));
4187 }
4188
4189 change_kind
operator &(change_kind l,change_kind r)4190 operator&(change_kind l, change_kind r)
4191 {
4192 return static_cast<change_kind>(static_cast<unsigned>(l)
4193 & static_cast<unsigned>(r));
4194 }
4195
4196 change_kind&
operator |=(change_kind & l,change_kind r)4197 operator|=(change_kind& l, change_kind r)
4198 {
4199 l = l | r;
4200 return l;
4201 }
4202
4203 change_kind&
operator &=(change_kind & l,change_kind r)4204 operator&=(change_kind& l, change_kind r)
4205 {
4206 l = l & r;
4207 return l;
4208 }
4209
4210 /// Compare the properties that belong to the "is-a-member-relation"
4211 /// of a decl.
4212 ///
4213 /// For instance, access specifiers are part of the
4214 /// "is-a-member-relation" of a decl.
4215 ///
4216 /// This comparison however doesn't take decl names into account. So
4217 /// typedefs for instance are decls that we want to compare with this
4218 /// function.
4219 ///
4220 /// This function is a sub-routine of the more general 'equals'
4221 /// overload for instances of decl_base.
4222 ///
4223 /// @param l the left-hand side operand of the comparison.
4224 ///
4225 /// @param r the right-hand side operand of the comparison.
4226 ///
4227 /// @return true iff @p l compare equals, as a member decl, to @p r.
4228 bool
maybe_compare_as_member_decls(const decl_base & l,const decl_base & r,change_kind * k)4229 maybe_compare_as_member_decls(const decl_base& l,
4230 const decl_base& r,
4231 change_kind* k)
4232 {
4233 bool result = true;
4234 if (is_member_decl(l) && is_member_decl(r))
4235 {
4236 context_rel* r1 = const_cast<context_rel*>(l.get_context_rel());
4237 context_rel *r2 = const_cast<context_rel*>(r.get_context_rel());
4238
4239 access_specifier la = no_access, ra = no_access;
4240 bool member_types_or_functions =
4241 ((is_type(l) && is_type(r))
4242 || (is_function_decl(l) && is_function_decl(r)));
4243
4244 if (member_types_or_functions)
4245 {
4246 // Access specifiers on member types in DWARF is not
4247 // reliable; in the same DSO, the same struct can be either
4248 // a class or a struct, and the access specifiers of its
4249 // member types are not necessarily given, so they
4250 // effectively can be considered differently, again, in the
4251 // same DSO. So, here, let's avoid considering those!
4252 // during comparison.
4253 la = r1->get_access_specifier();
4254 ra = r2->get_access_specifier();
4255 r1->set_access_specifier(no_access);
4256 r2->set_access_specifier(no_access);
4257 }
4258
4259 bool rels_are_different = *r1 != *r2;
4260
4261 if (member_types_or_functions)
4262 {
4263 // restore the access specifiers.
4264 r1->set_access_specifier(la);
4265 r2->set_access_specifier(ra);
4266 }
4267
4268 if (rels_are_different)
4269 {
4270 result = false;
4271 if (k)
4272 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
4273 }
4274 }
4275 return result;
4276 }
4277
4278 /// Compares two instances of @ref decl_base.
4279 ///
4280 /// If the two intances are different, set a bitfield to give some
4281 /// insight about the kind of differences there are.
4282 ///
4283 /// @param l the first artifact of the comparison.
4284 ///
4285 /// @param r the second artifact of the comparison.
4286 ///
4287 /// @param k a pointer to a bitfield that gives information about the
4288 /// kind of changes there are between @p l and @p r. This one is set
4289 /// iff it's non-null and if the function returns false.
4290 ///
4291 /// Please note that setting k to a non-null value does have a
4292 /// negative performance impact because even if @p l and @p r are not
4293 /// equal, the function keeps up the comparison in order to determine
4294 /// the different kinds of ways in which they are different.
4295 ///
4296 /// @return true if @p l equals @p r, false otherwise.
4297 bool
equals(const decl_base & l,const decl_base & r,change_kind * k)4298 equals(const decl_base& l, const decl_base& r, change_kind* k)
4299 {
4300 bool result = true;
4301 const interned_string &l_linkage_name = l.get_linkage_name();
4302 const interned_string &r_linkage_name = r.get_linkage_name();
4303 if (!l_linkage_name.empty() && !r_linkage_name.empty())
4304 {
4305 if (l_linkage_name != r_linkage_name)
4306 {
4307 // Linkage names are different. That usually means the two
4308 // decls are different, unless we are looking at two
4309 // function declarations which have two different symbols
4310 // that are aliases of each other.
4311 const function_decl *f1 = is_function_decl(&l),
4312 *f2 = is_function_decl(&r);
4313 if (f1 && f2 && function_decls_alias(*f1, *f2))
4314 ;// The two functions are aliases, so they are not different.
4315 else
4316 {
4317 result = false;
4318 if (k)
4319 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
4320 else
4321 return false;
4322 }
4323 }
4324 }
4325
4326 // This is the name of the decls that we want to compare.
4327 interned_string ln = l.get_qualified_name(), rn = r.get_qualified_name();
4328
4329 /// If both of the current decls have an anonymous scope then let's
4330 /// compare their name component by component by properly handling
4331 /// anonymous scopes. That's the slow path.
4332 ///
4333 /// Otherwise, let's just compare their name, the obvious way.
4334 /// That's the fast path because in that case the names are
4335 /// interned_string and comparing them is much faster.
4336 bool decls_are_same = (ln == rn);
4337 if (!decls_are_same
4338 && l.get_is_anonymous()
4339 && !l.get_has_anonymous_parent()
4340 && r.get_is_anonymous()
4341 && !r.get_has_anonymous_parent()
4342 && (l.get_qualified_parent_name() == r.get_qualified_parent_name()))
4343 // Both decls are anonymous and their scope are *NOT* anonymous.
4344 // So we consider the decls to have equivalent names (both
4345 // anonymous, remember). We are still in the fast path here.
4346 decls_are_same = true;
4347
4348 if (!decls_are_same
4349 && l.get_has_anonymous_parent()
4350 && r.get_has_anonymous_parent())
4351 // This is the slow path as we are comparing the decl qualified
4352 // names component by component, properly handling anonymous
4353 // scopes.
4354 decls_are_same = tools_utils::decl_names_equal(ln, rn);
4355
4356 if (!decls_are_same)
4357 {
4358 result = false;
4359 if (k)
4360 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
4361 else
4362 return false;
4363 }
4364
4365 result &= maybe_compare_as_member_decls(l, r, k);
4366
4367 return result;
4368 }
4369
4370 /// Return true iff the two decls have the same name.
4371 ///
4372 /// This function doesn't test if the scopes of the the two decls are
4373 /// equal.
4374 ///
4375 /// Note that this virtual function is to be implemented by classes
4376 /// that extend the \p decl_base class.
4377 bool
operator ==(const decl_base & other) const4378 decl_base::operator==(const decl_base& other) const
4379 {return equals(*this, other, 0);}
4380
4381 /// Inequality operator.
4382 ///
4383 /// @param other to other instance of @ref decl_base to compare the
4384 /// current instance to.
4385 ///
4386 /// @return true iff the current instance of @ref decl_base is
4387 /// different from @p other.
4388 bool
operator !=(const decl_base & other) const4389 decl_base::operator!=(const decl_base& other) const
4390 {return !operator==(other);}
4391
4392 /// Destructor of the @ref decl_base type.
~decl_base()4393 decl_base::~decl_base()
4394 {delete priv_;}
4395
4396 /// This implements the ir_traversable_base::traverse pure virtual
4397 /// function.
4398 ///
4399 /// @param v the visitor used on the member nodes of the translation
4400 /// unit during the traversal.
4401 ///
4402 /// @return true if the entire IR node tree got traversed, false
4403 /// otherwise.
4404 bool
traverse(ir_node_visitor &)4405 decl_base::traverse(ir_node_visitor&)
4406 {
4407 // Do nothing in the base class.
4408 return true;
4409 }
4410
4411 /// Setter of the scope of the current decl.
4412 ///
4413 /// Note that the decl won't hold a reference on the scope. It's
4414 /// rather the scope that holds a reference on its members.
4415 void
set_scope(scope_decl * scope)4416 decl_base::set_scope(scope_decl* scope)
4417 {
4418 if (!priv_->context_)
4419 priv_->context_ = new context_rel(scope);
4420 else
4421 priv_->context_->set_scope(scope);
4422 }
4423
4424 // </decl_base definition>
4425
4426 /// Streaming operator for the decl_base::visibility.
4427 ///
4428 /// @param o the output stream to serialize the visibility to.
4429 ///
4430 /// @param v the visibility to serialize.
4431 ///
4432 /// @return the output stream.
4433 std::ostream&
operator <<(std::ostream & o,decl_base::visibility v)4434 operator<<(std::ostream& o, decl_base::visibility v)
4435 {
4436 string r;
4437 switch (v)
4438 {
4439 case decl_base::VISIBILITY_NONE:
4440 r = "none";
4441 break;
4442 case decl_base::VISIBILITY_DEFAULT:
4443 r = "default";
4444 break;
4445 case decl_base::VISIBILITY_PROTECTED:
4446 r = "protected";
4447 break;
4448 case decl_base::VISIBILITY_HIDDEN:
4449 r = "hidden";
4450 break;
4451 case decl_base::VISIBILITY_INTERNAL:
4452 r = "internal";
4453 break;
4454 }
4455 return o;
4456 }
4457
4458 /// Streaming operator for decl_base::binding.
4459 ///
4460 /// @param o the output stream to serialize the visibility to.
4461 ///
4462 /// @param b the binding to serialize.
4463 ///
4464 /// @return the output stream.
4465 std::ostream&
operator <<(std::ostream & o,decl_base::binding b)4466 operator<<(std::ostream& o, decl_base::binding b)
4467 {
4468 string r;
4469 switch (b)
4470 {
4471 case decl_base::BINDING_NONE:
4472 r = "none";
4473 break;
4474 case decl_base::BINDING_LOCAL:
4475 r = "local";
4476 break;
4477 case decl_base::BINDING_GLOBAL:
4478 r = "global";
4479 break;
4480 case decl_base::BINDING_WEAK:
4481 r = "weak";
4482 break;
4483 }
4484 o << r;
4485 return o;
4486 }
4487
4488 /// Turn equality of shared_ptr of decl_base into a deep equality;
4489 /// that is, make it compare the pointed to objects, not just the
4490 /// pointers.
4491 ///
4492 /// @param l the shared_ptr of decl_base on left-hand-side of the
4493 /// equality.
4494 ///
4495 /// @param r the shared_ptr of decl_base on right-hand-side of the
4496 /// equality.
4497 ///
4498 /// @return true if the decl_base pointed to by the shared_ptrs are
4499 /// equal, false otherwise.
4500 bool
operator ==(const decl_base_sptr & l,const decl_base_sptr & r)4501 operator==(const decl_base_sptr& l, const decl_base_sptr& r)
4502 {
4503 if (l.get() == r.get())
4504 return true;
4505 if (!!l != !!r)
4506 return false;
4507
4508 return *l == *r;
4509 }
4510
4511 /// Inequality operator of shared_ptr of @ref decl_base.
4512 ///
4513 /// This is a deep equality operator, that is, it compares the
4514 /// pointed-to objects, rather than just the pointers.
4515 ///
4516 /// @param l the left-hand-side operand.
4517 ///
4518 /// @param r the right-hand-side operand.
4519 ///
4520 /// @return true iff @p l is different from @p r.
4521 bool
operator !=(const decl_base_sptr & l,const decl_base_sptr & r)4522 operator!=(const decl_base_sptr& l, const decl_base_sptr& r)
4523 {return !operator==(l, r);}
4524
4525 /// Turn equality of shared_ptr of type_base into a deep equality;
4526 /// that is, make it compare the pointed to objects too.
4527 ///
4528 /// @param l the shared_ptr of type_base on left-hand-side of the
4529 /// equality.
4530 ///
4531 /// @param r the shared_ptr of type_base on right-hand-side of the
4532 /// equality.
4533 ///
4534 /// @return true if the type_base pointed to by the shared_ptrs are
4535 /// equal, false otherwise.
4536 bool
operator ==(const type_base_sptr & l,const type_base_sptr & r)4537 operator==(const type_base_sptr& l, const type_base_sptr& r)
4538 {
4539 if (l.get() == r.get())
4540 return true;
4541 if (!!l != !!r)
4542 return false;
4543
4544 return *l == *r;
4545 }
4546
4547 /// Turn inequality of shared_ptr of type_base into a deep equality;
4548 /// that is, make it compare the pointed to objects..
4549 ///
4550 /// @param l the shared_ptr of type_base on left-hand-side of the
4551 /// equality.
4552 ///
4553 /// @param r the shared_ptr of type_base on right-hand-side of the
4554 /// equality.
4555 ///
4556 /// @return true iff the type_base pointed to by the shared_ptrs are
4557 /// different.
4558 bool
operator !=(const type_base_sptr & l,const type_base_sptr & r)4559 operator!=(const type_base_sptr& l, const type_base_sptr& r)
4560 {return !operator==(l, r);}
4561
4562 /// Tests if a declaration has got a scope.
4563 ///
4564 /// @param d the declaration to consider.
4565 ///
4566 /// @return true if the declaration has got a scope, false otherwise.
4567 bool
has_scope(const decl_base & d)4568 has_scope(const decl_base& d)
4569 {return (d.get_scope());}
4570
4571 /// Tests if a declaration has got a scope.
4572 ///
4573 /// @param d the declaration to consider.
4574 ///
4575 /// @return true if the declaration has got a scope, false otherwise.
4576 bool
has_scope(const decl_base_sptr d)4577 has_scope(const decl_base_sptr d)
4578 {return has_scope(*d.get());}
4579
4580 /// Tests if a declaration is a class member.
4581 ///
4582 /// @param d the declaration to consider.
4583 ///
4584 /// @return true if @p d is a class member, false otherwise.
4585 bool
is_member_decl(const decl_base_sptr d)4586 is_member_decl(const decl_base_sptr d)
4587 {return is_at_class_scope(d) || is_method_decl(d);}
4588
4589 /// Tests if a declaration is a class member.
4590 ///
4591 /// @param d the declaration to consider.
4592 ///
4593 /// @return true if @p d is a class member, false otherwise.
4594 bool
is_member_decl(const decl_base * d)4595 is_member_decl(const decl_base* d)
4596 {return is_at_class_scope(d) || is_method_decl(d);}
4597
4598 /// Tests if a declaration is a class member.
4599 ///
4600 /// @param d the declaration to consider.
4601 ///
4602 /// @return true if @p d is a class member, false otherwise.
4603 bool
is_member_decl(const decl_base & d)4604 is_member_decl(const decl_base& d)
4605 {return is_at_class_scope(d) || is_method_decl(d);}
4606
4607 /// Test if a declaration is a @ref scope_decl.
4608 ///
4609 /// @param d the declaration to take in account.
4610 ///
4611 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
4612 /// if d is a @ref scope_decl.
4613 scope_decl*
is_scope_decl(decl_base * d)4614 is_scope_decl(decl_base* d)
4615 {return dynamic_cast<scope_decl*>(d);}
4616
4617 /// Test if a declaration is a @ref scope_decl.
4618 ///
4619 /// @param d the declaration to take in account.
4620 ///
4621 /// @return the a pointer to the @ref scope_decl sub-object of @p d,
4622 /// if d is a @ref scope_decl.
4623 scope_decl_sptr
is_scope_decl(const decl_base_sptr & d)4624 is_scope_decl(const decl_base_sptr& d)
4625 {return dynamic_pointer_cast<scope_decl>(d);}
4626
4627 /// Tests if a type is a class member.
4628 ///
4629 /// @param t the type to consider.
4630 ///
4631 /// @return true if @p t is a class member type, false otherwise.
4632 bool
is_member_type(const type_base_sptr & t)4633 is_member_type(const type_base_sptr& t)
4634 {
4635 decl_base_sptr d = get_type_declaration(t);
4636 return is_member_decl(d);
4637 }
4638
4639 /// Test if a type is user-defined.
4640 ///
4641 /// A type is considered user-defined if it's a
4642 /// struct/class/union/enum that is *NOT* artificial.
4643 ///
4644 /// @param t the type to consider.
4645 ///
4646 /// @return true iff the type @p t is user-defined.
4647 bool
is_user_defined_type(const type_base * t)4648 is_user_defined_type(const type_base* t)
4649 {
4650 if (t == 0)
4651 return false;
4652
4653 t = peel_qualified_or_typedef_type(t);
4654 decl_base *d = is_decl(t);
4655
4656 if ((is_class_or_union_type(t) || is_enum_type(t))
4657 && d && !d->get_is_artificial())
4658 return true;
4659
4660 return false;
4661 }
4662
4663 /// Test if a type is user-defined.
4664 ///
4665 /// A type is considered user-defined if it's a
4666 /// struct/class/union/enum.
4667 ///
4668 ///
4669 /// @param t the type to consider.
4670 ///
4671 /// @return true iff the type @p t is user-defined.
4672 bool
is_user_defined_type(const type_base_sptr & t)4673 is_user_defined_type(const type_base_sptr& t)
4674 {return is_user_defined_type(t.get());}
4675
4676 /// Gets the access specifier for a class member.
4677 ///
4678 /// @param d the declaration of the class member to consider. Note
4679 /// that this must be a class member otherwise the function aborts the
4680 /// current process.
4681 ///
4682 /// @return the access specifier for the class member @p d.
4683 access_specifier
get_member_access_specifier(const decl_base & d)4684 get_member_access_specifier(const decl_base& d)
4685 {
4686 ABG_ASSERT(is_member_decl(d));
4687
4688 const context_rel* c = d.get_context_rel();
4689 ABG_ASSERT(c);
4690
4691 return c->get_access_specifier();
4692 }
4693
4694 /// Gets the access specifier for a class member.
4695 ///
4696 /// @param d the declaration of the class member to consider. Note
4697 /// that this must be a class member otherwise the function aborts the
4698 /// current process.
4699 ///
4700 /// @return the access specifier for the class member @p d.
4701 access_specifier
get_member_access_specifier(const decl_base_sptr & d)4702 get_member_access_specifier(const decl_base_sptr& d)
4703 {return get_member_access_specifier(*d);}
4704
4705 /// Sets the access specifier for a class member.
4706 ///
4707 /// @param d the class member to set the access specifier for. Note
4708 /// that this must be a class member otherwise the function aborts the
4709 /// current process.
4710 ///
4711 /// @param a the new access specifier to set the class member to.
4712 void
set_member_access_specifier(decl_base & d,access_specifier a)4713 set_member_access_specifier(decl_base& d,
4714 access_specifier a)
4715 {
4716 ABG_ASSERT(is_member_decl(d));
4717
4718 context_rel* c = d.get_context_rel();
4719 ABG_ASSERT(c);
4720
4721 c->set_access_specifier(a);
4722 }
4723
4724 /// Sets the access specifier for a class member.
4725 ///
4726 /// @param d the class member to set the access specifier for. Note
4727 /// that this must be a class member otherwise the function aborts the
4728 /// current process.
4729 ///
4730 /// @param a the new access specifier to set the class member to.
4731 void
set_member_access_specifier(const decl_base_sptr & d,access_specifier a)4732 set_member_access_specifier(const decl_base_sptr& d,
4733 access_specifier a)
4734 {set_member_access_specifier(*d, a);}
4735
4736 /// Gets a flag saying if a class member is static or not.
4737 ///
4738 /// @param d the declaration for the class member to consider. Note
4739 /// that this must be a class member otherwise the function aborts the
4740 /// current process.
4741 ///
4742 /// @return true if the class member @p d is static, false otherwise.
4743 bool
get_member_is_static(const decl_base & d)4744 get_member_is_static(const decl_base&d)
4745 {
4746 ABG_ASSERT(is_member_decl(d));
4747
4748 const context_rel* c = d.get_context_rel();
4749 ABG_ASSERT(c);
4750
4751 return c->get_is_static();
4752 }
4753
4754 /// Gets a flag saying if a class member is static or not.
4755 ///
4756 /// @param d the declaration for the class member to consider. Note
4757 /// that this must be a class member otherwise the function aborts the
4758 /// current process.
4759 ///
4760 /// @return true if the class member @p d is static, false otherwise.
4761 bool
get_member_is_static(const decl_base * d)4762 get_member_is_static(const decl_base* d)
4763 {return get_member_is_static(*d);}
4764
4765 /// Gets a flag saying if a class member is static or not.
4766 ///
4767 /// @param d the declaration for the class member to consider. Note
4768 /// that this must be a class member otherwise the function aborts the
4769 /// current process.
4770 ///
4771 /// @return true if the class member @p d is static, false otherwise.
4772 bool
get_member_is_static(const decl_base_sptr & d)4773 get_member_is_static(const decl_base_sptr& d)
4774 {return get_member_is_static(*d);}
4775
4776 /// Test if a var_decl is a data member.
4777 ///
4778 /// @param v the var_decl to consider.
4779 ///
4780 /// @return true if @p v is data member, false otherwise.
4781 bool
is_data_member(const var_decl & v)4782 is_data_member(const var_decl& v)
4783 {return is_at_class_scope(v);}
4784
4785 /// Test if a var_decl is a data member.
4786 ///
4787 /// @param v the var_decl to consider.
4788 ///
4789 /// @return true if @p v is data member, false otherwise.
4790 bool
is_data_member(const var_decl * v)4791 is_data_member(const var_decl* v)
4792 {return is_data_member(*v);}
4793
4794 /// Test if a var_decl is a data member.
4795 ///
4796 /// @param v the var_decl to consider.
4797 ///
4798 /// @return true if @p v is data member, false otherwise.
4799 bool
is_data_member(const var_decl_sptr d)4800 is_data_member(const var_decl_sptr d)
4801 {return is_at_class_scope(d);}
4802
4803 /// Test if a decl is a data member.
4804 ///
4805 /// @param d the decl to consider.
4806 ///
4807 /// @return a pointer to the data member iff @p d is a data member, or
4808 /// a null pointer.
4809 var_decl_sptr
is_data_member(const decl_base_sptr & d)4810 is_data_member(const decl_base_sptr& d)
4811 {
4812 if (var_decl_sptr v = is_var_decl(d))
4813 {
4814 if (is_data_member(v))
4815 return v;
4816 }
4817 return var_decl_sptr();
4818 }
4819
4820 /// Test if a decl is a data member.
4821 ///
4822 /// @param d the decl to consider.
4823 ///
4824 /// @return a pointer to the data member iff @p d is a data member, or
4825 /// a null pointer.
4826 var_decl_sptr
is_data_member(const type_or_decl_base_sptr & d)4827 is_data_member(const type_or_decl_base_sptr& d)
4828 {
4829 if (var_decl_sptr v = is_var_decl(d))
4830 {
4831 if (is_data_member(v))
4832 return v;
4833 }
4834 return var_decl_sptr();
4835 }
4836
4837 /// Test if a decl is a data member.
4838 ///
4839 /// @param d the decl to consider.
4840 ///
4841 /// @return a pointer to the data member iff @p d is a data member, or
4842 /// a null pointer.
4843 var_decl*
is_data_member(const type_or_decl_base * d)4844 is_data_member(const type_or_decl_base* d)
4845 {
4846 if (var_decl *v = is_var_decl(d))
4847 if (is_data_member(v))
4848 return v;
4849 return 0;
4850 }
4851
4852 /// Test if a decl is a data member.
4853 ///
4854 /// @param d the decl to consider.
4855 ///
4856 /// @return a pointer to the data member iff @p d is a data member, or
4857 /// a null pointer.
4858 var_decl*
is_data_member(const decl_base * d)4859 is_data_member(const decl_base *d)
4860 {
4861 if (var_decl *v = is_var_decl(d))
4862 if (is_data_member(v))
4863 return v;
4864 return 0;
4865 }
4866
4867 /// Get the first non-anonymous data member of a given anonymous data
4868 /// member.
4869 ///
4870 /// E.g:
4871 ///
4872 /// struct S
4873 /// {
4874 /// union // <-- for this anonymous data member, the function
4875 /// // returns a.
4876 /// {
4877 /// int a;
4878 /// charb;
4879 /// };
4880 /// };
4881 ///
4882 /// @return anon_dm the anonymous data member to consider.
4883 ///
4884 /// @return the first non-anonymous data member of @p anon_dm. If no
4885 /// data member was found then this function returns @p anon_dm.
4886 const var_decl_sptr
get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)4887 get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
4888 {
4889 if (!anon_dm || !is_anonymous_data_member(anon_dm))
4890 return anon_dm;
4891
4892 class_or_union_sptr klass = anonymous_data_member_to_class_or_union(anon_dm);
4893 var_decl_sptr first = *klass->get_non_static_data_members().begin();
4894
4895 if (is_anonymous_data_member(first))
4896 return get_first_non_anonymous_data_member(first);
4897
4898 return first;
4899 }
4900
4901 /// In the context of a given class or union, this function returns
4902 /// the data member that is located after a given data member.
4903 ///
4904 /// @param klass the class or union to consider.
4905 ///
4906 /// @param the data member to consider.
4907 ///
4908 /// @return the data member that is located right after @p
4909 /// data_member.
4910 const var_decl_sptr
get_next_data_member(const class_or_union_sptr & klass,const var_decl_sptr & data_member)4911 get_next_data_member(const class_or_union_sptr &klass,
4912 const var_decl_sptr &data_member)
4913 {
4914 if (!klass ||!data_member)
4915 return var_decl_sptr();
4916
4917 for (class_or_union::data_members::const_iterator it =
4918 klass->get_non_static_data_members().begin();
4919 it != klass->get_non_static_data_members().end();
4920 ++it)
4921 if (**it == *data_member)
4922 {
4923 ++it;
4924 if (it != klass->get_non_static_data_members().end())
4925 return get_first_non_anonymous_data_member(*it);
4926 break;
4927 }
4928
4929 return var_decl_sptr();
4930 }
4931
4932 /// Test if a decl is an anonymous data member.
4933 ///
4934 /// @param d the decl to consider.
4935 ///
4936 /// @return true iff @p d is an anonymous data member.
4937 bool
is_anonymous_data_member(const decl_base & d)4938 is_anonymous_data_member(const decl_base& d)
4939 {return is_anonymous_data_member(&d);}
4940
4941 /// Test if a decl is an anonymous data member.
4942 ///
4943 /// @param d the decl to consider.
4944 ///
4945 /// @return the var_decl representing the data member iff @p d is an
4946 /// anonymous data member.
4947 const var_decl*
is_anonymous_data_member(const type_or_decl_base * d)4948 is_anonymous_data_member(const type_or_decl_base* d)
4949 {
4950 if (const var_decl* v = is_data_member(d))
4951 {
4952 if (is_anonymous_data_member(v))
4953 return v;
4954 }
4955 return 0;
4956 }
4957
4958 /// Test if a decl is an anonymous data member.
4959 ///
4960 /// @param d the decl to consider.
4961 ///
4962 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
4963 /// it's an anonymous data member. Otherwise returns a nil pointer.
4964 const var_decl*
is_anonymous_data_member(const decl_base * d)4965 is_anonymous_data_member(const decl_base* d)
4966 {
4967 if (const var_decl* v = is_data_member(d))
4968 {
4969 if (is_anonymous_data_member(v))
4970 return v;
4971 }
4972 return 0;
4973 }
4974
4975 /// Test if a decl is an anonymous data member.
4976 ///
4977 /// @param d the decl to consider.
4978 ///
4979 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
4980 /// it's an anonymous data member. Otherwise returns a nil pointer.
4981 var_decl_sptr
is_anonymous_data_member(const type_or_decl_base_sptr & d)4982 is_anonymous_data_member(const type_or_decl_base_sptr& d)
4983 {
4984 if (var_decl_sptr v = is_data_member(d))
4985 {
4986 if (is_anonymous_data_member(v))
4987 return v;
4988 }
4989 return var_decl_sptr();
4990 }
4991
4992 /// Test if a decl is an anonymous data member.
4993 ///
4994 /// @param d the decl to consider.
4995 ///
4996 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
4997 /// it's an anonymous data member. Otherwise returns a nil pointer.
4998 var_decl_sptr
is_anonymous_data_member(const decl_base_sptr & d)4999 is_anonymous_data_member(const decl_base_sptr& d)
5000 {
5001 if (var_decl_sptr v = is_data_member(d))
5002 return is_anonymous_data_member(v);
5003 return var_decl_sptr();
5004 }
5005
5006 /// Test if a @ref var_decl is an anonymous data member.
5007 ///
5008 /// @param d the @ref var_decl to consider.
5009 ///
5010 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5011 /// it's an anonymous data member. Otherwise returns a nil pointer.
5012 var_decl_sptr
is_anonymous_data_member(const var_decl_sptr & d)5013 is_anonymous_data_member(const var_decl_sptr& d)
5014 {
5015 if (is_anonymous_data_member(d.get()))
5016 return d;
5017 return var_decl_sptr();
5018 }
5019
5020 /// Test if a @ref var_decl is an anonymous data member.
5021 ///
5022 /// @param d the @ref var_decl to consider.
5023 ///
5024 /// @return a non-nil pointer to the @ref var_decl denoted by @p d if
5025 /// it's an anonymous data member. Otherwise returns a nil pointer.
5026 const var_decl*
is_anonymous_data_member(const var_decl * d)5027 is_anonymous_data_member(const var_decl* d)
5028 {
5029 if (d && is_anonymous_data_member(*d))
5030 return d;
5031 return 0;
5032 }
5033
5034 /// Test if a @ref var_decl is an anonymous data member.
5035 ///
5036 /// @param d the @ref var_decl to consider.
5037 ///
5038 /// @return true iff @p d is an anonymous data member.
5039 bool
is_anonymous_data_member(const var_decl & d)5040 is_anonymous_data_member(const var_decl& d)
5041 {
5042 return (is_data_member(d)
5043 && d.get_name().empty()
5044 && is_class_or_union_type(d.get_type()));
5045 }
5046
5047 /// Get the @ref class_or_union type of a given anonymous data member.
5048 ///
5049 /// @param d the anonymous data member to consider.
5050 ///
5051 /// @return the @ref class_or_union type of the anonymous data member
5052 /// @p d.
5053 class_or_union*
anonymous_data_member_to_class_or_union(const var_decl * d)5054 anonymous_data_member_to_class_or_union(const var_decl* d)
5055 {
5056 if ((d = is_anonymous_data_member(d)))
5057 return is_class_or_union_type(d->get_type().get());
5058 return 0;
5059 }
5060
5061 /// Test if a data member has annonymous type or not.
5062 ///
5063 /// @param d the data member to consider.
5064 ///
5065 /// @return the anonymous class or union type iff @p turns out to have
5066 /// an anonymous type. Otherwise, returns nil.
5067 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl & d)5068 data_member_has_anonymous_type(const var_decl& d)
5069 {
5070 if (is_data_member(d))
5071 if (const class_or_union_sptr cou = is_class_or_union_type(d.get_type()))
5072 if (cou->get_is_anonymous())
5073 return cou;
5074
5075 return class_or_union_sptr();
5076 }
5077
5078 /// Test if a data member has annonymous type or not.
5079 ///
5080 /// @param d the data member to consider.
5081 ///
5082 /// @return the anonymous class or union type iff @p turns out to have
5083 /// an anonymous type. Otherwise, returns nil.
5084 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl * d)5085 data_member_has_anonymous_type(const var_decl* d)
5086 {
5087 if (d)
5088 return data_member_has_anonymous_type(*d);
5089 return class_or_union_sptr();
5090 }
5091
5092 /// Test if a data member has annonymous type or not.
5093 ///
5094 /// @param d the data member to consider.
5095 ///
5096 /// @return the anonymous class or union type iff @p turns out to have
5097 /// an anonymous type. Otherwise, returns nil.
5098 const class_or_union_sptr
data_member_has_anonymous_type(const var_decl_sptr & d)5099 data_member_has_anonymous_type(const var_decl_sptr& d)
5100 {return data_member_has_anonymous_type(d.get());}
5101
5102 /// Get the @ref class_or_union type of a given anonymous data member.
5103 ///
5104 /// @param d the anonymous data member to consider.
5105 ///
5106 /// @return the @ref class_or_union type of the anonymous data member
5107 /// @p d.
5108 class_or_union_sptr
anonymous_data_member_to_class_or_union(const var_decl_sptr & d)5109 anonymous_data_member_to_class_or_union(const var_decl_sptr &d)
5110 {
5111 if (var_decl_sptr v = is_anonymous_data_member(d))
5112 return is_class_or_union_type(v->get_type());
5113 return class_or_union_sptr();
5114 }
5115
5116 /// Set the offset of a data member into its containing class.
5117 ///
5118 /// @param m the data member to consider.
5119 ///
5120 /// @param o the offset, in bits.
5121 void
set_data_member_offset(var_decl_sptr m,uint64_t o)5122 set_data_member_offset(var_decl_sptr m, uint64_t o)
5123 {
5124 ABG_ASSERT(is_data_member(m));
5125
5126 dm_context_rel* ctxt_rel =
5127 dynamic_cast<dm_context_rel*>(m->get_context_rel());
5128 ABG_ASSERT(ctxt_rel);
5129
5130 ctxt_rel->set_offset_in_bits(o);
5131 }
5132
5133 /// Get the offset of a data member.
5134 ///
5135 /// @param m the data member to consider.
5136 ///
5137 /// @return the offset (in bits) of @p m in its containing class.
5138 uint64_t
get_data_member_offset(const var_decl & m)5139 get_data_member_offset(const var_decl& m)
5140 {
5141 ABG_ASSERT(is_data_member(m));
5142 const dm_context_rel* ctxt_rel =
5143 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
5144 ABG_ASSERT(ctxt_rel);
5145 return ctxt_rel->get_offset_in_bits();
5146 }
5147
5148 /// Get the offset of a data member.
5149 ///
5150 /// @param m the data member to consider.
5151 ///
5152 /// @return the offset (in bits) of @p m in its containing class.
5153 uint64_t
get_data_member_offset(const var_decl_sptr m)5154 get_data_member_offset(const var_decl_sptr m)
5155 {return get_data_member_offset(*m);}
5156
5157 /// Get the offset of a data member.
5158 ///
5159 /// @param m the data member to consider.
5160 ///
5161 /// @return the offset (in bits) of @p m in its containing class.
5162 uint64_t
get_data_member_offset(const decl_base_sptr d)5163 get_data_member_offset(const decl_base_sptr d)
5164 {return get_data_member_offset(dynamic_pointer_cast<var_decl>(d));}
5165
5166 /// Get the absolute offset of a data member.
5167 ///
5168 /// If the data member is part of an anonymous data member then this
5169 /// returns the absolute offset -- relative to the beginning of the
5170 /// containing class of the anonymous data member.
5171 ///
5172 /// @param m the data member to consider.
5173 ///
5174 /// @return the aboslute offset of the data member @p m.
5175 uint64_t
get_absolute_data_member_offset(const var_decl & m)5176 get_absolute_data_member_offset(const var_decl& m)
5177 {
5178 ABG_ASSERT(is_data_member(m));
5179 const dm_context_rel* ctxt_rel =
5180 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
5181 ABG_ASSERT(ctxt_rel);
5182
5183 const var_decl *containing_anonymous_data_member =
5184 ctxt_rel->get_anonymous_data_member();
5185
5186 uint64_t containing_anonymous_data_member_offset = 0;
5187 if (containing_anonymous_data_member)
5188 containing_anonymous_data_member_offset =
5189 get_absolute_data_member_offset(*containing_anonymous_data_member);
5190
5191 return (ctxt_rel->get_offset_in_bits()
5192 +
5193 containing_anonymous_data_member_offset);
5194 }
5195
5196 /// Get the absolute offset of a data member.
5197 ///
5198 /// If the data member is part of an anonymous data member then this
5199 /// returns the absolute offset -- relative to the beginning of the
5200 /// containing class of the anonymous data member.
5201 ///
5202 /// @param m the data member to consider.
5203 ///
5204 /// @return the aboslute offset of the data member @p m.
5205 uint64_t
get_absolute_data_member_offset(const var_decl_sptr & m)5206 get_absolute_data_member_offset(const var_decl_sptr& m)
5207 {
5208 if (!m)
5209 return 0;
5210 return get_absolute_data_member_offset(*m);
5211 }
5212
5213 /// Get the size of a given variable.
5214 ///
5215 /// @param v the variable to consider.
5216 ///
5217 /// @return the size of variable @p v.
5218 uint64_t
get_var_size_in_bits(const var_decl_sptr & v)5219 get_var_size_in_bits(const var_decl_sptr& v)
5220 {
5221 type_base_sptr t = v->get_type();
5222 ABG_ASSERT(t);
5223
5224 return t->get_size_in_bits();
5225 }
5226
5227 /// Set a flag saying if a data member is laid out.
5228 ///
5229 /// @param m the data member to consider.
5230 ///
5231 /// @param l true if @p m is to be considered as laid out.
5232 void
set_data_member_is_laid_out(var_decl_sptr m,bool l)5233 set_data_member_is_laid_out(var_decl_sptr m, bool l)
5234 {
5235 ABG_ASSERT(is_data_member(m));
5236 dm_context_rel* ctxt_rel =
5237 dynamic_cast<dm_context_rel*>(m->get_context_rel());
5238 ctxt_rel->set_is_laid_out(l);
5239 }
5240
5241 /// Test whether a data member is laid out.
5242 ///
5243 /// @param m the data member to consider.
5244 ///
5245 /// @return true if @p m is laid out, false otherwise.
5246 bool
get_data_member_is_laid_out(const var_decl & m)5247 get_data_member_is_laid_out(const var_decl& m)
5248 {
5249 ABG_ASSERT(is_data_member(m));
5250 const dm_context_rel* ctxt_rel =
5251 dynamic_cast<const dm_context_rel*>(m.get_context_rel());
5252
5253 return ctxt_rel->get_is_laid_out();
5254 }
5255
5256 /// Test whether a data member is laid out.
5257 ///
5258 /// @param m the data member to consider.
5259 ///
5260 /// @return true if @p m is laid out, false otherwise.
5261 bool
get_data_member_is_laid_out(const var_decl_sptr m)5262 get_data_member_is_laid_out(const var_decl_sptr m)
5263 {return get_data_member_is_laid_out(*m);}
5264
5265 /// Test whether a function_decl is a member function.
5266 ///
5267 /// @param f the function_decl to test.
5268 ///
5269 /// @return true if @p f is a member function, false otherwise.
5270 bool
is_member_function(const function_decl & f)5271 is_member_function(const function_decl& f)
5272 {return is_member_decl(f);}
5273
5274 /// Test whether a function_decl is a member function.
5275 ///
5276 /// @param f the function_decl to test.
5277 ///
5278 /// @return true if @p f is a member function, false otherwise.
5279 bool
is_member_function(const function_decl * f)5280 is_member_function(const function_decl* f)
5281 {return is_member_decl(*f);}
5282
5283 /// Test whether a function_decl is a member function.
5284 ///
5285 /// @param f the function_decl to test.
5286 ///
5287 /// @return true if @p f is a member function, false otherwise.
5288 bool
is_member_function(const function_decl_sptr & f)5289 is_member_function(const function_decl_sptr& f)
5290 {return is_member_decl(*f);}
5291
5292 /// Test whether a member function is a constructor.
5293 ///
5294 /// @param f the member function to test.
5295 ///
5296 /// @return true if @p f is a constructor, false otherwise.
5297 bool
get_member_function_is_ctor(const function_decl & f)5298 get_member_function_is_ctor(const function_decl& f)
5299 {
5300 ABG_ASSERT(is_member_function(f));
5301
5302 const method_decl* m = is_method_decl(&f);
5303 ABG_ASSERT(m);
5304
5305 const mem_fn_context_rel* ctxt =
5306 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
5307
5308 return ctxt->is_constructor();
5309 }
5310
5311 /// Test whether a member function is a constructor.
5312 ///
5313 /// @param f the member function to test.
5314 ///
5315 /// @return true if @p f is a constructor, false otherwise.
5316 bool
get_member_function_is_ctor(const function_decl_sptr & f)5317 get_member_function_is_ctor(const function_decl_sptr& f)
5318 {return get_member_function_is_ctor(*f);}
5319
5320
5321 /// Setter for the is_ctor property of the member function.
5322 ///
5323 /// @param f the member function to set.
5324 ///
5325 /// @param f the new boolean value of the is_ctor property. Is true
5326 /// if @p f is a constructor, false otherwise.
5327 void
set_member_function_is_ctor(function_decl & f,bool c)5328 set_member_function_is_ctor(function_decl& f, bool c)
5329 {
5330 ABG_ASSERT(is_member_function(f));
5331
5332 method_decl* m = is_method_decl(&f);
5333 ABG_ASSERT(m);
5334
5335 mem_fn_context_rel* ctxt =
5336 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
5337
5338 ctxt->is_constructor(c);
5339 }
5340
5341 /// Setter for the is_ctor property of the member function.
5342 ///
5343 /// @param f the member function to set.
5344 ///
5345 /// @param f the new boolean value of the is_ctor property. Is true
5346 /// if @p f is a constructor, false otherwise.
5347 void
set_member_function_is_ctor(const function_decl_sptr & f,bool c)5348 set_member_function_is_ctor(const function_decl_sptr& f, bool c)
5349 {set_member_function_is_ctor(*f, c);}
5350
5351 /// Test whether a member function is a destructor.
5352 ///
5353 /// @param f the function to test.
5354 ///
5355 /// @return true if @p f is a destructor, false otherwise.
5356 bool
get_member_function_is_dtor(const function_decl & f)5357 get_member_function_is_dtor(const function_decl& f)
5358 {
5359 ABG_ASSERT(is_member_function(f));
5360
5361 const method_decl* m = is_method_decl(&f);
5362 ABG_ASSERT(m);
5363
5364 const mem_fn_context_rel* ctxt =
5365 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
5366
5367 return ctxt->is_destructor();
5368 }
5369
5370 /// Test whether a member function is a destructor.
5371 ///
5372 /// @param f the function to test.
5373 ///
5374 /// @return true if @p f is a destructor, false otherwise.
5375 bool
get_member_function_is_dtor(const function_decl_sptr & f)5376 get_member_function_is_dtor(const function_decl_sptr& f)
5377 {return get_member_function_is_dtor(*f);}
5378
5379 /// Set the destructor-ness property of a member function.
5380 ///
5381 /// @param f the function to set.
5382 ///
5383 /// @param d true if @p f is a destructor, false otherwise.
5384 void
set_member_function_is_dtor(function_decl & f,bool d)5385 set_member_function_is_dtor(function_decl& f, bool d)
5386 {
5387 ABG_ASSERT(is_member_function(f));
5388
5389 method_decl* m = is_method_decl(&f);
5390 ABG_ASSERT(m);
5391
5392 mem_fn_context_rel* ctxt =
5393 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
5394
5395 ctxt->is_destructor(d);
5396 }
5397
5398 /// Set the destructor-ness property of a member function.
5399 ///
5400 /// @param f the function to set.
5401 ///
5402 /// @param d true if @p f is a destructor, false otherwise.
5403 void
set_member_function_is_dtor(const function_decl_sptr & f,bool d)5404 set_member_function_is_dtor(const function_decl_sptr& f, bool d)
5405 {set_member_function_is_dtor(*f, d);}
5406
5407 /// Test whether a member function is const.
5408 ///
5409 /// @param f the function to test.
5410 ///
5411 /// @return true if @p f is const, false otherwise.
5412 bool
get_member_function_is_const(const function_decl & f)5413 get_member_function_is_const(const function_decl& f)
5414 {
5415 ABG_ASSERT(is_member_function(f));
5416
5417 const method_decl* m = is_method_decl(&f);
5418 ABG_ASSERT(m);
5419
5420 const mem_fn_context_rel* ctxt =
5421 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
5422
5423 return ctxt->is_const();
5424 }
5425
5426 /// Test whether a member function is const.
5427 ///
5428 /// @param f the function to test.
5429 ///
5430 /// @return true if @p f is const, false otherwise.
5431 bool
get_member_function_is_const(const function_decl_sptr & f)5432 get_member_function_is_const(const function_decl_sptr& f)
5433 {return get_member_function_is_const(*f);}
5434
5435 /// set the const-ness property of a member function.
5436 ///
5437 /// @param f the function to set.
5438 ///
5439 /// @param is_const the new value of the const-ness property of @p f
5440 void
set_member_function_is_const(function_decl & f,bool is_const)5441 set_member_function_is_const(function_decl& f, bool is_const)
5442 {
5443 ABG_ASSERT(is_member_function(f));
5444
5445 method_decl* m = is_method_decl(&f);
5446 ABG_ASSERT(m);
5447
5448 mem_fn_context_rel* ctxt =
5449 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
5450
5451 ctxt->is_const(is_const);
5452 }
5453
5454 /// set the const-ness property of a member function.
5455 ///
5456 /// @param f the function to set.
5457 ///
5458 /// @param is_const the new value of the const-ness property of @p f
5459 void
set_member_function_is_const(const function_decl_sptr & f,bool is_const)5460 set_member_function_is_const(const function_decl_sptr& f, bool is_const)
5461 {set_member_function_is_const(*f, is_const);}
5462
5463 /// Test if a virtual member function has a vtable offset set.
5464 ///
5465 /// @param f the virtual member function to consider.
5466 ///
5467 /// @return true iff the virtual member function has its vtable offset
5468 /// set, i.e, if the vtable offset of @p is different from -1.
5469 bool
member_function_has_vtable_offset(const function_decl & f)5470 member_function_has_vtable_offset(const function_decl& f)
5471 {return get_member_function_vtable_offset(f) != -1;}
5472
5473 /// Get the vtable offset of a member function.
5474 ///
5475 /// @param f the member function to consider.
5476 ///
5477 /// @return the vtable offset of @p f. Note that a vtable offset of
5478 /// value -1 means that the member function does *NOT* yet have a
5479 /// vtable offset associated to it.
5480 ssize_t
get_member_function_vtable_offset(const function_decl & f)5481 get_member_function_vtable_offset(const function_decl& f)
5482 {
5483 ABG_ASSERT(is_member_function(f));
5484
5485 const method_decl* m =
5486 dynamic_cast<const method_decl*>(&f);
5487 ABG_ASSERT(m);
5488
5489 const mem_fn_context_rel* ctxt =
5490 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
5491
5492 return ctxt->vtable_offset();
5493 }
5494
5495 /// Get the vtable offset of a member function.
5496 ///
5497 /// @param f the member function to consider.
5498 ///
5499 /// @return the vtable offset of @p f. Note that a vtable offset of
5500 /// value -1 means that the member function does *NOT* yet have a
5501 /// vtable offset associated to it.
5502 ssize_t
get_member_function_vtable_offset(const function_decl_sptr & f)5503 get_member_function_vtable_offset(const function_decl_sptr& f)
5504 {return get_member_function_vtable_offset(*f);}
5505
5506 /// Set the vtable offset of a member function.
5507 ///
5508 /// @param f the member function to consider.
5509 ///
5510 /// @param s the new vtable offset. Please note that a vtable offset
5511 /// of value -1 means that the virtual member function does not (yet)
5512 /// have any vtable offset associated to it.
5513 void
set_member_function_vtable_offset(function_decl & f,ssize_t s)5514 set_member_function_vtable_offset(function_decl& f, ssize_t s)
5515 {
5516 ABG_ASSERT(is_member_function(f));
5517
5518 method_decl* m = is_method_decl(&f);
5519 ABG_ASSERT(m);
5520
5521 mem_fn_context_rel* ctxt =
5522 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
5523
5524 ctxt->vtable_offset(s);
5525 }
5526
5527 /// Get the vtable offset of a member function.
5528 ///
5529 /// @param f the member function to consider.
5530 ///
5531 /// @param s the new vtable offset. Please note that a vtable offset
5532 /// of value -1 means that the virtual member function does not (yet)
5533 /// have any vtable offset associated to it.
5534 void
set_member_function_vtable_offset(const function_decl_sptr & f,ssize_t s)5535 set_member_function_vtable_offset(const function_decl_sptr& f, ssize_t s)
5536 {return set_member_function_vtable_offset(*f, s);}
5537
5538 /// Test if a given member function is virtual.
5539 ///
5540 /// @param mem_fn the member function to consider.
5541 ///
5542 /// @return true iff a @p mem_fn is virtual.
5543 bool
get_member_function_is_virtual(const function_decl & f)5544 get_member_function_is_virtual(const function_decl& f)
5545 {
5546 ABG_ASSERT(is_member_function(f));
5547
5548 const method_decl* m =
5549 dynamic_cast<const method_decl*>(&f);
5550 ABG_ASSERT(m);
5551
5552 const mem_fn_context_rel* ctxt =
5553 dynamic_cast<const mem_fn_context_rel*>(m->get_context_rel());
5554
5555 return ctxt->is_virtual();
5556 }
5557
5558 /// Test if a given member function is virtual.
5559 ///
5560 /// @param mem_fn the member function to consider.
5561 ///
5562 /// @return true iff a @p mem_fn is virtual.
5563 bool
get_member_function_is_virtual(const function_decl_sptr & mem_fn)5564 get_member_function_is_virtual(const function_decl_sptr& mem_fn)
5565 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
5566
5567 /// Test if a given member function is virtual.
5568 ///
5569 /// @param mem_fn the member function to consider.
5570 ///
5571 /// @return true iff a @p mem_fn is virtual.
5572 bool
get_member_function_is_virtual(const function_decl * mem_fn)5573 get_member_function_is_virtual(const function_decl* mem_fn)
5574 {return mem_fn ? get_member_function_is_virtual(*mem_fn) : false;}
5575
5576 /// Set the virtual-ness of a member function.
5577 ///
5578 /// @param f the member function to consider.
5579 ///
5580 /// @param is_virtual set to true if the function is virtual.
5581 void
set_member_function_is_virtual(function_decl & f,bool is_virtual)5582 set_member_function_is_virtual(function_decl& f, bool is_virtual)
5583 {
5584 ABG_ASSERT(is_member_function(f));
5585
5586 method_decl* m = is_method_decl(&f);
5587 ABG_ASSERT(m);
5588
5589 mem_fn_context_rel* ctxt =
5590 dynamic_cast<mem_fn_context_rel*>(m->get_context_rel());
5591
5592 ctxt->is_virtual(is_virtual);
5593 }
5594
5595 /// Set the virtual-ness of a member function.
5596 ///
5597 /// @param f the member function to consider.
5598 ///
5599 /// @param is_virtual set to true if the function is virtual.
5600 void
set_member_function_is_virtual(const function_decl_sptr & fn,bool is_virtual)5601 set_member_function_is_virtual(const function_decl_sptr& fn, bool is_virtual)
5602 {
5603 if (fn)
5604 {
5605 set_member_function_is_virtual(*fn, is_virtual);
5606 fixup_virtual_member_function
5607 (dynamic_pointer_cast<method_decl>(fn));
5608 }
5609 }
5610
5611 /// Recursively returns the the underlying type of a typedef. The
5612 /// return type should not be a typedef of anything anymore.
5613 ///
5614 ///
5615 /// Also recursively strip typedefs from the sub-types of the type
5616 /// given in arguments.
5617 ///
5618 /// Note that this function builds types in which typedefs are
5619 /// stripped off. Usually, types are held by their scope, so their
5620 /// life time is bound to the life time of their scope. But as this
5621 /// function cannot really insert the built type into it's scope, it
5622 /// must ensure that the newly built type stays live long enough.
5623 ///
5624 /// So, if the newly built type has a canonical type, this function
5625 /// returns the canonical type. Otherwise, this function ensure that
5626 /// the newly built type has a life time that is the same as the life
5627 /// time of the entire libabigail library.
5628 ///
5629 /// @param type the type to strip the typedefs from.
5630 ///
5631 /// @return the resulting type stripped from its typedefs, or just
5632 /// return @p type if it has no typedef in any of its sub-types.
5633 type_base_sptr
strip_typedef(const type_base_sptr type)5634 strip_typedef(const type_base_sptr type)
5635 {
5636 if (!type)
5637 return type;
5638
5639 // If type is a class type then do not try to strip typedefs from it.
5640 // And if it has no canonical type (which can mean that it's a
5641 // declaration-only class), then, make sure its live for ever and
5642 // return it.
5643 if (class_decl_sptr cl = is_class_type(type))
5644 {
5645 if (!cl->get_canonical_type())
5646 keep_type_alive(type);
5647 return type;
5648 }
5649
5650 environment* env = type->get_environment();
5651 ABG_ASSERT(env);
5652 type_base_sptr t = type;
5653
5654 if (const typedef_decl_sptr ty = is_typedef(t))
5655 t = strip_typedef(type_or_void(ty->get_underlying_type(), env));
5656 else if (const reference_type_def_sptr ty = is_reference_type(t))
5657 {
5658 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
5659 env));
5660 ABG_ASSERT(p);
5661 t.reset(new reference_type_def(p,
5662 ty->is_lvalue(),
5663 ty->get_size_in_bits(),
5664 ty->get_alignment_in_bits(),
5665 ty->get_location()));
5666 }
5667 else if (const pointer_type_def_sptr ty = is_pointer_type(t))
5668 {
5669 type_base_sptr p = strip_typedef(type_or_void(ty->get_pointed_to_type(),
5670 env));
5671 ABG_ASSERT(p);
5672 t.reset(new pointer_type_def(p,
5673 ty->get_size_in_bits(),
5674 ty->get_alignment_in_bits(),
5675 ty->get_location()));
5676 }
5677 else if (const qualified_type_def_sptr ty = is_qualified_type(t))
5678 {
5679 type_base_sptr p = strip_typedef(type_or_void(ty->get_underlying_type(),
5680 env));
5681 ABG_ASSERT(p);
5682 t.reset(new qualified_type_def(p,
5683 ty->get_cv_quals(),
5684 ty->get_location()));
5685 }
5686 else if (const array_type_def_sptr ty = is_array_type(t))
5687 {
5688 type_base_sptr p = strip_typedef(ty->get_element_type());
5689 ABG_ASSERT(p);
5690 t.reset(new array_type_def(p, ty->get_subranges(), ty->get_location()));
5691 }
5692 else if (const method_type_sptr ty = is_method_type(t))
5693 {
5694 function_decl::parameters parm;
5695 for (function_decl::parameters::const_iterator i =
5696 ty->get_parameters().begin();
5697 i != ty->get_parameters().end();
5698 ++i)
5699 {
5700 function_decl::parameter_sptr p = *i;
5701 type_base_sptr typ = strip_typedef(p->get_type());
5702 ABG_ASSERT(typ);
5703 function_decl::parameter_sptr stripped
5704 (new function_decl::parameter(typ,
5705 p->get_index(),
5706 p->get_name(),
5707 p->get_location(),
5708 p->get_variadic_marker(),
5709 p->get_is_artificial()));
5710 parm.push_back(stripped);
5711 }
5712 type_base_sptr p = strip_typedef(ty->get_return_type());
5713 ABG_ASSERT(!!p == !!ty->get_return_type());
5714 t.reset(new method_type(p, ty->get_class_type(),
5715 parm, ty->get_is_const(),
5716 ty->get_size_in_bits(),
5717 ty->get_alignment_in_bits()));
5718 }
5719 else if (const function_type_sptr ty = is_function_type(t))
5720 {
5721 function_decl::parameters parm;
5722 for (function_decl::parameters::const_iterator i =
5723 ty->get_parameters().begin();
5724 i != ty->get_parameters().end();
5725 ++i)
5726 {
5727 function_decl::parameter_sptr p = *i;
5728 type_base_sptr typ = strip_typedef(p->get_type());
5729 ABG_ASSERT(typ);
5730 function_decl::parameter_sptr stripped
5731 (new function_decl::parameter(typ,
5732 p->get_index(),
5733 p->get_name(),
5734 p->get_location(),
5735 p->get_variadic_marker(),
5736 p->get_is_artificial()));
5737 parm.push_back(stripped);
5738 }
5739 type_base_sptr p = strip_typedef(ty->get_return_type());
5740 ABG_ASSERT(!!p == !!ty->get_return_type());
5741 t.reset(new function_type(p, parm,
5742 ty->get_size_in_bits(),
5743 ty->get_alignment_in_bits()));
5744 }
5745
5746 if (!t->get_environment())
5747 set_environment_for_artifact(t, env);
5748
5749 if (!t->get_translation_unit())
5750 t->set_translation_unit(type->get_translation_unit());
5751
5752 if (!(type->get_canonical_type() && canonicalize(t)))
5753 keep_type_alive(t);
5754
5755 return t->get_canonical_type() ? t->get_canonical_type() : t;
5756 }
5757
5758 /// Return the leaf underlying type node of a @ref typedef_decl node.
5759 ///
5760 /// If the underlying type of a @ref typedef_decl node is itself a
5761 /// @ref typedef_decl node, then recursively look at the underlying
5762 /// type nodes to get the first one that is not a a @ref typedef_decl
5763 /// node. This is what a leaf underlying type node means.
5764 ///
5765 /// Otherwise, if the underlying type node of @ref typedef_decl is
5766 /// *NOT* a @ref typedef_decl node, then just return the underlying
5767 /// type node.
5768 ///
5769 /// And if the type node considered is not a @ref typedef_decl node,
5770 /// then just return it.
5771 ///
5772 /// @return the leaf underlying type node of a @p type.
5773 type_base_sptr
peel_typedef_type(const type_base_sptr & type)5774 peel_typedef_type(const type_base_sptr& type)
5775 {
5776 typedef_decl_sptr t = is_typedef(type);
5777 if (!t)
5778 return type;
5779
5780 if (is_typedef(t->get_underlying_type()))
5781 return peel_typedef_type(t->get_underlying_type());
5782 return t->get_underlying_type();
5783 }
5784
5785 /// Return the leaf underlying type node of a @ref typedef_decl node.
5786 ///
5787 /// If the underlying type of a @ref typedef_decl node is itself a
5788 /// @ref typedef_decl node, then recursively look at the underlying
5789 /// type nodes to get the first one that is not a a @ref typedef_decl
5790 /// node. This is what a leaf underlying type node means.
5791 ///
5792 /// Otherwise, if the underlying type node of @ref typedef_decl is
5793 /// *NOT* a @ref typedef_decl node, then just return the underlying
5794 /// type node.
5795 ///
5796 /// And if the type node considered is not a @ref typedef_decl node,
5797 /// then just return it.
5798 ///
5799 /// @return the leaf underlying type node of a @p type.
5800 const type_base*
peel_typedef_type(const type_base * type)5801 peel_typedef_type(const type_base* type)
5802 {
5803 const typedef_decl* t = is_typedef(type);
5804 if (!t)
5805 return type;
5806
5807 return peel_typedef_type(t->get_underlying_type()).get();
5808 }
5809
5810 /// Return the leaf pointed-to type node of a @ref pointer_type_def
5811 /// node.
5812 ///
5813 /// If the pointed-to type of a @ref pointer_type_def node is itself a
5814 /// @ref pointer_type_def node, then recursively look at the
5815 /// pointed-to type nodes to get the first one that is not a a @ref
5816 /// pointer_type_def node. This is what a leaf pointed-to type node
5817 /// means.
5818 ///
5819 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
5820 /// *NOT* a @ref pointer_type_def node, then just return the
5821 /// pointed-to type node.
5822 ///
5823 /// And if the type node considered is not a @ref pointer_type_def
5824 /// node, then just return it.
5825 ///
5826 /// @return the leaf pointed-to type node of a @p type.
5827 type_base_sptr
peel_pointer_type(const type_base_sptr & type)5828 peel_pointer_type(const type_base_sptr& type)
5829 {
5830 pointer_type_def_sptr t = is_pointer_type(type);
5831 if (!t)
5832 return type;
5833
5834 if (is_pointer_type(t->get_pointed_to_type()))
5835 return peel_pointer_type(t->get_pointed_to_type());
5836 return t->get_pointed_to_type();
5837 }
5838
5839 /// Return the leaf pointed-to type node of a @ref pointer_type_def
5840 /// node.
5841 ///
5842 /// If the pointed-to type of a @ref pointer_type_def node is itself a
5843 /// @ref pointer_type_def node, then recursively look at the
5844 /// pointed-to type nodes to get the first one that is not a a @ref
5845 /// pointer_type_def node. This is what a leaf pointed-to type node
5846 /// means.
5847 ///
5848 /// Otherwise, if the pointed-to type node of @ref pointer_type_def is
5849 /// *NOT* a @ref pointer_type_def node, then just return the
5850 /// pointed-to type node.
5851 ///
5852 /// And if the type node considered is not a @ref pointer_type_def
5853 /// node, then just return it.
5854 ///
5855 /// @return the leaf pointed-to type node of a @p type.
5856 const type_base*
peel_pointer_type(const type_base * type)5857 peel_pointer_type(const type_base* type)
5858 {
5859 const pointer_type_def* t = is_pointer_type(type);
5860 if (!t)
5861 return type;
5862
5863 return peel_pointer_type(t->get_pointed_to_type()).get();
5864 }
5865
5866 /// Return the leaf pointed-to type node of a @ref reference_type_def
5867 /// node.
5868 ///
5869 /// If the pointed-to type of a @ref reference_type_def node is itself
5870 /// a @ref reference_type_def node, then recursively look at the
5871 /// pointed-to type nodes to get the first one that is not a a @ref
5872 /// reference_type_def node. This is what a leaf pointed-to type node
5873 /// means.
5874 ///
5875 /// Otherwise, if the pointed-to type node of @ref reference_type_def
5876 /// is *NOT* a @ref reference_type_def node, then just return the
5877 /// pointed-to type node.
5878 ///
5879 /// And if the type node considered is not a @ref reference_type_def
5880 /// node, then just return it.
5881 ///
5882 /// @return the leaf pointed-to type node of a @p type.
5883 type_base_sptr
peel_reference_type(const type_base_sptr & type)5884 peel_reference_type(const type_base_sptr& type)
5885 {
5886 reference_type_def_sptr t = is_reference_type(type);
5887 if (!t)
5888 return type;
5889
5890 if (is_reference_type(t->get_pointed_to_type()))
5891 return peel_reference_type(t->get_pointed_to_type());
5892 return t->get_pointed_to_type();
5893 }
5894
5895 /// Return the leaf pointed-to type node of a @ref reference_type_def
5896 /// node.
5897 ///
5898 /// If the pointed-to type of a @ref reference_type_def node is itself
5899 /// a @ref reference_type_def node, then recursively look at the
5900 /// pointed-to type nodes to get the first one that is not a a @ref
5901 /// reference_type_def node. This is what a leaf pointed-to type node
5902 /// means.
5903 ///
5904 /// Otherwise, if the pointed-to type node of @ref reference_type_def
5905 /// is *NOT* a @ref reference_type_def node, then just return the
5906 /// pointed-to type node.
5907 ///
5908 /// And if the type node considered is not a @ref reference_type_def
5909 /// node, then just return it.
5910 ///
5911 /// @return the leaf pointed-to type node of a @p type.
5912 const type_base*
peel_reference_type(const type_base * type)5913 peel_reference_type(const type_base* type)
5914 {
5915 const reference_type_def* t = is_reference_type(type);
5916 if (!t)
5917 return type;
5918
5919 return peel_reference_type(t->get_pointed_to_type()).get();
5920 }
5921
5922 /// Return the leaf element type of an array.
5923 ///
5924 /// If the element type is itself an array, then recursively return
5925 /// the element type of that array itself.
5926 ///
5927 /// @param type the array type to consider. If this is not an array
5928 /// type, this type is returned by the function.
5929 ///
5930 /// @return the leaf element type of the array @p type, or, if it's
5931 /// not an array type, then just return @p.
5932 const type_base_sptr
peel_array_type(const type_base_sptr & type)5933 peel_array_type(const type_base_sptr& type)
5934 {
5935 const array_type_def_sptr t = is_array_type(type);
5936 if (!t)
5937 return type;
5938
5939 return peel_array_type(t->get_element_type());
5940 }
5941
5942 /// Return the leaf element type of an array.
5943 ///
5944 /// If the element type is itself an array, then recursively return
5945 /// the element type of that array itself.
5946 ///
5947 /// @param type the array type to consider. If this is not an array
5948 /// type, this type is returned by the function.
5949 ///
5950 /// @return the leaf element type of the array @p type, or, if it's
5951 /// not an array type, then just return @p.
5952 const type_base*
peel_array_type(const type_base * type)5953 peel_array_type(const type_base* type)
5954 {
5955 const array_type_def* t = is_array_type(type);
5956 if (!t)
5957 return type;
5958
5959 return peel_array_type(t->get_element_type()).get();
5960 }
5961
5962 /// Return the leaf underlying type of a qualified type.
5963 ///
5964 /// If the underlying type is itself a qualified type, then
5965 /// recursively return the first underlying type of that qualified
5966 /// type to return the first underlying type that is not a qualified type.
5967 ///
5968 /// If the underlying type is NOT a qualified type, then just return
5969 /// that underlying type.
5970 ///
5971 /// @param type the qualified type to consider.
5972 ///
5973 /// @return the leaf underlying type.
5974 const type_base*
peel_qualified_type(const type_base * type)5975 peel_qualified_type(const type_base* type)
5976 {
5977 const qualified_type_def* t = is_qualified_type(type);
5978 if (!t)
5979 return type;
5980
5981 return peel_qualified_type(t->get_underlying_type().get());
5982 }
5983
5984 /// Return the leaf underlying type of a qualified type.
5985 ///
5986 /// If the underlying type is itself a qualified type, then
5987 /// recursively return the first underlying type of that qualified
5988 /// type to return the first underlying type that is not a qualified type.
5989 ///
5990 /// If the underlying type is NOT a qualified type, then just return
5991 /// that underlying type.
5992 ///
5993 /// @param type the qualified type to consider.
5994 ///
5995 /// @return the leaf underlying type.
5996 const type_base_sptr
peel_qualified_type(const type_base_sptr & type)5997 peel_qualified_type(const type_base_sptr& type)
5998 {
5999 const qualified_type_def_sptr t = is_qualified_type(type);
6000 if (!t)
6001 return type;
6002
6003 return peel_qualified_type(t->get_underlying_type());
6004 }
6005
6006 /// Return the leaf underlying type of a qualified or typedef type.
6007 ///
6008 /// If the underlying type is itself a qualified or typedef type, then
6009 /// recursively return the first underlying type of that qualified or
6010 /// typedef type to return the first underlying type that is not a
6011 /// qualified or typedef type.
6012 ///
6013 /// If the underlying type is NOT a qualified nor a typedef type, then
6014 /// just return that underlying type.
6015 ///
6016 /// @param type the qualified or typedef type to consider.
6017 ///
6018 /// @return the leaf underlying type.
6019 type_base*
peel_qualified_or_typedef_type(const type_base * type)6020 peel_qualified_or_typedef_type(const type_base* type)
6021 {
6022 while (is_typedef(type) || is_qualified_type(type))
6023 {
6024 if (const typedef_decl* t = is_typedef(type))
6025 type = peel_typedef_type(t);
6026
6027 if (const qualified_type_def* t = is_qualified_type(type))
6028 type = peel_qualified_type(t);
6029 }
6030
6031 return const_cast<type_base*>(type);
6032 }
6033
6034 /// Return the leaf underlying type of a qualified or typedef type.
6035 ///
6036 /// If the underlying type is itself a qualified or typedef type, then
6037 /// recursively return the first underlying type of that qualified or
6038 /// typedef type to return the first underlying type that is not a
6039 /// qualified or typedef type.
6040 ///
6041 /// If the underlying type is NOT a qualified nor a typedef type, then
6042 /// just return that underlying type.
6043 ///
6044 /// @param type the qualified or typedef type to consider.
6045 ///
6046 /// @return the leaf underlying type.
6047 type_base_sptr
peel_qualified_or_typedef_type(const type_base_sptr & t)6048 peel_qualified_or_typedef_type(const type_base_sptr &t)
6049 {
6050 type_base_sptr type = t;
6051 while (is_typedef(type) || is_qualified_type(type))
6052 {
6053 if (typedef_decl_sptr t = is_typedef(type))
6054 type = peel_typedef_type(t);
6055
6056 if (qualified_type_def_sptr t = is_qualified_type(type))
6057 type = peel_qualified_type(t);
6058 }
6059
6060 return type;
6061 }
6062
6063 /// Return the leaf underlying or pointed-to type node of a @ref
6064 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
6065 /// node.
6066 ///
6067 /// @param type the type to peel.
6068 ///
6069 /// @return the leaf underlying or pointed-to type node of @p type.
6070 type_base_sptr
peel_typedef_pointer_or_reference_type(const type_base_sptr type)6071 peel_typedef_pointer_or_reference_type(const type_base_sptr type)
6072 {
6073 type_base_sptr typ = type;
6074 while (is_typedef(typ)
6075 || is_pointer_type(typ)
6076 || is_reference_type(typ))
6077 {
6078 if (typedef_decl_sptr t = is_typedef(typ))
6079 typ = peel_typedef_type(t);
6080
6081 if (pointer_type_def_sptr t = is_pointer_type(typ))
6082 typ = peel_pointer_type(t);
6083
6084 if (reference_type_def_sptr t = is_reference_type(typ))
6085 typ = peel_reference_type(t);
6086 }
6087
6088 return typ;
6089 }
6090
6091 /// Return the leaf underlying or pointed-to type node of a @ref
6092 /// typedef_decl, @ref pointer_type_def or @ref reference_type_def
6093 /// node.
6094 ///
6095 /// @param type the type to peel.
6096 ///
6097 /// @return the leaf underlying or pointed-to type node of @p type.
6098 type_base*
peel_typedef_pointer_or_reference_type(const type_base * type)6099 peel_typedef_pointer_or_reference_type(const type_base* type)
6100 {
6101 while (is_typedef(type)
6102 || is_pointer_type(type)
6103 || is_reference_type(type))
6104 {
6105 if (const typedef_decl* t = is_typedef(type))
6106 type = peel_typedef_type(t);
6107
6108 if (const pointer_type_def* t = is_pointer_type(type))
6109 type = peel_pointer_type(t);
6110
6111 if (const reference_type_def* t = is_reference_type(type))
6112 type = peel_reference_type(t);
6113 }
6114
6115 return const_cast<type_base*>(type);
6116 }
6117
6118 /// Return the leaf underlying or pointed-to type node of a, @ref
6119 /// pointer_type_def, @ref reference_type_def or @ref
6120 /// qualified_type_def type node.
6121 ///
6122 /// @param type the type to peel.
6123 ///
6124 /// @param peel_qualified_type if true, also peel qualified types.
6125 ///
6126 /// @return the leaf underlying or pointed-to type node of @p type.
6127 type_base*
peel_pointer_or_reference_type(const type_base * type,bool peel_qual_type)6128 peel_pointer_or_reference_type(const type_base *type,
6129 bool peel_qual_type)
6130 {
6131 while (is_pointer_type(type)
6132 || is_reference_type(type)
6133 || (peel_qual_type && is_qualified_type(type)))
6134 {
6135 if (const pointer_type_def* t = is_pointer_type(type))
6136 type = peel_pointer_type(t);
6137
6138 if (const reference_type_def* t = is_reference_type(type))
6139 type = peel_reference_type(t);
6140
6141 if (const array_type_def* t = is_array_type(type))
6142 type = peel_array_type(t);
6143
6144 if (peel_qual_type)
6145 if (const qualified_type_def* t = is_qualified_type(type))
6146 type = peel_qualified_type(t);
6147 }
6148
6149 return const_cast<type_base*>(type);
6150 }
6151
6152 /// Clone an array type.
6153 ///
6154 /// Note that the element type of the new array is shared witht the
6155 /// old one.
6156 ///
6157 /// @param array the array type to clone.
6158 ///
6159 /// @return a newly built array type. Note that it needs to be added
6160 /// to a scope (e.g, using add_decl_to_scope) for its lifetime to be
6161 /// bound to the one of that scope. Otherwise, its lifetime is bound
6162 /// to the lifetime of its containing shared pointer.
6163 array_type_def_sptr
clone_array(const array_type_def_sptr & array)6164 clone_array(const array_type_def_sptr& array)
6165 {
6166 vector<array_type_def::subrange_sptr> subranges;
6167
6168 for (vector<array_type_def::subrange_sptr>::const_iterator i =
6169 array->get_subranges().begin();
6170 i != array->get_subranges().end();
6171 ++i)
6172 {
6173 array_type_def::subrange_sptr subrange
6174 (new array_type_def::subrange_type(array->get_environment(),
6175 (*i)->get_name(),
6176 (*i)->get_lower_bound(),
6177 (*i)->get_upper_bound(),
6178 (*i)->get_underlying_type(),
6179 (*i)->get_location(),
6180 (*i)->get_language()));
6181 subrange->is_infinite((*i)->is_infinite());
6182 if (scope_decl *scope = (*i)->get_scope())
6183 add_decl_to_scope(subrange, scope);
6184 subranges.push_back(subrange);
6185 }
6186
6187 array_type_def_sptr result
6188 (new array_type_def(array->get_element_type(),
6189 subranges, array->get_location()));
6190
6191 return result;
6192 }
6193
6194 /// Clone a typedef type.
6195 ///
6196 /// Note that the underlying type of the newly constructed typedef is
6197 /// shared with the old one.
6198 ///
6199 /// @param t the typedef to clone.
6200 ///
6201 /// @return the newly constructed typedef. Note that it needs to be
6202 /// added to a scope (e.g, using add_decl_to_scope) for its lifetime
6203 /// to be bound to the one of that scope. Otherwise, its lifetime is
6204 /// bound to the lifetime of its containing shared pointer.
6205 typedef_decl_sptr
clone_typedef(const typedef_decl_sptr & t)6206 clone_typedef(const typedef_decl_sptr& t)
6207 {
6208 if (!t)
6209 return t;
6210
6211 typedef_decl_sptr result
6212 (new typedef_decl(t->get_name(), t->get_underlying_type(),
6213 t->get_location(), t->get_linkage_name(),
6214 t->get_visibility()));
6215 return result;
6216 }
6217
6218 /// Clone a qualifiend type.
6219 ///
6220 /// Note that underlying type of the newly constructed qualified type
6221 /// is shared with the old one.
6222 ///
6223 /// @param t the qualified type to clone.
6224 ///
6225 /// @return the newly constructed qualified type. Note that it needs
6226 /// to be added to a scope (e.g, using add_decl_to_scope) for its
6227 /// lifetime to be bound to the one of that scope. Otherwise, its
6228 /// lifetime is bound to the lifetime of its containing shared
6229 /// pointer.
6230 qualified_type_def_sptr
clone_qualified_type(const qualified_type_def_sptr & t)6231 clone_qualified_type(const qualified_type_def_sptr& t)
6232 {
6233 if (!t)
6234 return t;
6235
6236 qualified_type_def_sptr result
6237 (new qualified_type_def(t->get_underlying_type(),
6238 t->get_cv_quals(), t->get_location()));
6239
6240 return result;
6241 }
6242
6243 /// Clone a typedef, an array or a qualified tree.
6244 ///
6245 /// @param type the typedef, array or qualified tree to clone. any
6246 /// order.
6247 ///
6248 /// @return the cloned type, or NULL if @type was neither a typedef,
6249 /// array nor a qualified type.
6250 static type_base_sptr
clone_typedef_array_qualified_type(type_base_sptr type)6251 clone_typedef_array_qualified_type(type_base_sptr type)
6252 {
6253 if (!type)
6254 return type;
6255
6256 scope_decl* scope = is_decl(type) ? is_decl(type)->get_scope() : 0;
6257 type_base_sptr result;
6258
6259 if (typedef_decl_sptr t = is_typedef(type))
6260 result = clone_typedef(is_typedef(t));
6261 else if (qualified_type_def_sptr t = is_qualified_type(type))
6262 result = clone_qualified_type(t);
6263 else if (array_type_def_sptr t = is_array_type(type))
6264 result = clone_array(t);
6265 else
6266 return type_base_sptr();
6267
6268 if (scope)
6269 add_decl_to_scope(is_decl(result), scope);
6270
6271 return result;
6272 }
6273
6274 /// Clone a type tree made of an array or a typedef of array.
6275 ///
6276 /// Note that this can be a tree which root node is a typedef an which
6277 /// sub-tree can be any arbitrary combination of typedef, qualified
6278 /// type and arrays.
6279 ///
6280 /// @param t the array or typedef of qualified array to consider.
6281 ///
6282 /// @return a clone of @p t.
6283 type_base_sptr
clone_array_tree(const type_base_sptr t)6284 clone_array_tree(const type_base_sptr t)
6285 {
6286 ABG_ASSERT(is_typedef_of_array(t) || is_array_type(t));
6287
6288 scope_decl* scope = is_decl(t)->get_scope();
6289 type_base_sptr result = clone_typedef_array_qualified_type(t);
6290 ABG_ASSERT(is_typedef_of_array(result) || is_array_type(result));
6291
6292 type_base_sptr subtree;
6293 if (typedef_decl_sptr type = is_typedef(result))
6294 {
6295 type_base_sptr s =
6296 clone_typedef_array_qualified_type(type->get_underlying_type());
6297 if (s)
6298 {
6299 subtree = s;
6300 type->set_underlying_type(subtree);
6301 }
6302 }
6303 else if (array_type_def_sptr type = is_array_type(result))
6304 {
6305 type_base_sptr s =
6306 clone_typedef_array_qualified_type(type->get_element_type());
6307 if (s)
6308 {
6309 subtree = s;
6310 type->set_element_type(subtree);
6311 }
6312 }
6313 add_decl_to_scope(is_decl(subtree), scope);
6314
6315 for (;;)
6316 {
6317 if (typedef_decl_sptr t = is_typedef(subtree))
6318 {
6319 type_base_sptr s =
6320 clone_typedef_array_qualified_type(t->get_underlying_type());
6321 if (s)
6322 {
6323 scope_decl* scope =
6324 is_decl(t->get_underlying_type())->get_scope();
6325 ABG_ASSERT(scope);
6326 add_decl_to_scope(is_decl(s), scope);
6327 t->set_underlying_type (s);
6328 subtree = s;
6329 }
6330 else
6331 break;
6332 }
6333 else if (qualified_type_def_sptr t = is_qualified_type(subtree))
6334 {
6335 type_base_sptr s =
6336 clone_typedef_array_qualified_type(t->get_underlying_type());
6337 if (s)
6338 {
6339 scope_decl* scope =
6340 is_decl(t->get_underlying_type())->get_scope();
6341 ABG_ASSERT(scope);
6342 add_decl_to_scope(is_decl(s), scope);
6343 t->set_underlying_type(s);
6344 subtree = s;
6345 }
6346 else
6347 break;
6348 }
6349 else if (array_type_def_sptr t = is_array_type(subtree))
6350 {
6351 type_base_sptr e = t->get_element_type();
6352 if (is_typedef(e) || is_qualified_type(e))
6353 {
6354 type_base_sptr s =
6355 clone_typedef_array_qualified_type(e);
6356 if (s)
6357 {
6358 scope_decl* scope = is_decl(e)->get_scope();
6359 ABG_ASSERT(scope);
6360 add_decl_to_scope(is_decl(s), scope);
6361 t->set_element_type(s);
6362 }
6363 else
6364 break;
6365 }
6366 break;
6367 }
6368 else
6369 break;
6370 }
6371 return result;
6372 }
6373
6374 /// Update the qualified name of a given sub-tree.
6375 ///
6376 /// @param d the sub-tree for which to update the qualified name.
6377 static void
update_qualified_name(decl_base * d)6378 update_qualified_name(decl_base * d)
6379 {
6380 ::qualified_name_setter setter;
6381 d->traverse(setter);
6382 }
6383
6384 /// Update the qualified name of a given sub-tree.
6385 ///
6386 /// @param d the sub-tree for which to update the qualified name.
6387 static void
update_qualified_name(decl_base_sptr d)6388 update_qualified_name(decl_base_sptr d)
6389 {return update_qualified_name(d.get());}
6390
6391 // <scope_decl stuff>
6392
6393 /// Hash a type by returning the pointer value of its canonical type.
6394 ///
6395 /// @param l the type to hash.
6396 ///
6397 /// @return the the pointer value of the canonical type of @p l.
6398 size_t
operator ()(const type_base_sptr & l) const6399 canonical_type_hash::operator()(const type_base_sptr& l) const
6400 {return operator()(l.get());}
6401
6402 /// Hash a (canonical) type by returning its pointer value
6403 ///
6404 /// @param l the canonical type to hash.
6405 ///
6406 /// @return the pointer value of the canonical type of @p l.
6407 size_t
operator ()(const type_base * l) const6408 canonical_type_hash::operator()(const type_base *l) const
6409 {return reinterpret_cast<size_t>(l);}
6410
6411 struct scope_decl::priv
6412 {
6413 declarations members_;
6414 declarations sorted_members_;
6415 scopes member_scopes_;
6416 canonical_type_sptr_set_type canonical_types_;
6417 type_base_sptrs_type sorted_canonical_types_;
6418 }; // end struct scope_decl::priv
6419
6420 /// Constructor of the @ref scope_decl type.
6421 ///
6422 /// @param the environment to use for the new instance.
6423 ///
6424 /// @param the name of the scope decl.
6425 ///
6426 /// @param locus the source location where the scope_decl is defined.
6427 ///
6428 /// @param vis the visibility of the declaration.
scope_decl(const environment * env,const string & name,const location & locus,visibility vis)6429 scope_decl::scope_decl(const environment* env,
6430 const string& name,
6431 const location& locus,
6432 visibility vis)
6433 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
6434 decl_base(env, name, locus, /*mangled_name=*/name, vis),
6435 priv_(new priv)
6436 {}
6437
6438 /// Constructor of the @ref scope_decl type.
6439 ///
6440 /// @param the environment to use for the new instance.
6441 ///
6442 /// @param l the source location where the scope_decl is defined.
6443 ///
6444 /// @param vis the visibility of the declaration.
scope_decl(const environment * env,location & l)6445 scope_decl::scope_decl(const environment* env, location& l)
6446 : type_or_decl_base(env, ABSTRACT_SCOPE_DECL|ABSTRACT_DECL_BASE),
6447 decl_base(env, "", l),
6448 priv_(new priv)
6449 {}
6450
6451 /// @eturn the set of canonical types of the the current scope.
6452 canonical_type_sptr_set_type&
get_canonical_types()6453 scope_decl::get_canonical_types()
6454 {return priv_->canonical_types_;}
6455
6456 /// @eturn the set of canonical types of the the current scope.
6457 const canonical_type_sptr_set_type&
get_canonical_types() const6458 scope_decl::get_canonical_types() const
6459 {return const_cast<scope_decl*>(this)->get_canonical_types();}
6460
6461 /// Return a vector of sorted canonical types of the current scope.
6462 ///
6463 /// The types are sorted "almost topologically". That means, they are
6464 /// sorted using the lexicographic order of the string representing
6465 /// the location their definition point. If a type doesn't have a
6466 /// location, then its pretty representation is used.
6467 ///
6468 /// @return a vector of sorted canonical types of the current scope.
6469 const type_base_sptrs_type&
get_sorted_canonical_types() const6470 scope_decl::get_sorted_canonical_types() const
6471 {
6472 if (priv_->sorted_canonical_types_.empty())
6473 {
6474 for (canonical_type_sptr_set_type::const_iterator e =
6475 get_canonical_types().begin();
6476 e != get_canonical_types().end();
6477 ++e)
6478 priv_->sorted_canonical_types_.push_back(*e);
6479
6480 type_topo_comp comp;
6481 std::stable_sort(priv_->sorted_canonical_types_.begin(),
6482 priv_->sorted_canonical_types_.end(),
6483 comp);
6484 }
6485 return priv_->sorted_canonical_types_;
6486 }
6487
6488 /// Getter for the member declarations carried by the current @ref
6489 /// scope_decl.
6490 ///
6491 /// @return the member declarations carried by the current @ref
6492 /// scope_decl.
6493 const scope_decl::declarations&
get_member_decls() const6494 scope_decl::get_member_decls() const
6495 {return priv_->members_;}
6496
6497 /// Getter for the member declarations carried by the current @ref
6498 /// scope_decl.
6499 ///
6500 /// @return the member declarations carried by the current @ref
6501 /// scope_decl.
6502 scope_decl::declarations&
get_member_decls()6503 scope_decl::get_member_decls()
6504 {return priv_->members_;}
6505
6506 /// Getter for the sorted member declarations carried by the current
6507 /// @ref scope_decl.
6508 ///
6509 /// @return the sorted member declarations carried by the current @ref
6510 /// scope_decl. The declarations are sorted topologically.
6511 const scope_decl::declarations&
get_sorted_member_decls() const6512 scope_decl::get_sorted_member_decls() const
6513 {
6514 decl_topo_comp comp;
6515 if (priv_->sorted_members_.empty())
6516 {
6517 for (declarations::const_iterator i = get_member_decls().begin();
6518 i != get_member_decls().end();
6519 ++i)
6520 priv_->sorted_members_.push_back(*i);
6521
6522 std::stable_sort(priv_->sorted_members_.begin(),
6523 priv_->sorted_members_.end(),
6524 comp);
6525 }
6526 return priv_->sorted_members_;
6527 }
6528
6529 /// Getter for the number of anonymous classes contained in this
6530 /// scope.
6531 ///
6532 /// @return the number of anonymous classes contained in this scope.
6533 size_t
get_num_anonymous_member_classes() const6534 scope_decl::get_num_anonymous_member_classes() const
6535 {
6536 int result = 0;
6537 for (declarations::const_iterator it = get_member_decls().begin();
6538 it != get_member_decls().end();
6539 ++it)
6540 if (class_decl_sptr t = is_class_type(*it))
6541 if (t->get_is_anonymous())
6542 ++result;
6543
6544 return result;
6545 }
6546
6547 /// Getter for the number of anonymous unions contained in this
6548 /// scope.
6549 ///
6550 /// @return the number of anonymous unions contained in this scope.
6551 size_t
get_num_anonymous_member_unions() const6552 scope_decl::get_num_anonymous_member_unions() const
6553 {
6554 int result = 0;
6555 for (declarations::const_iterator it = get_member_decls().begin();
6556 it != get_member_decls().end();
6557 ++it)
6558 if (union_decl_sptr t = is_union_type(*it))
6559 if (t->get_is_anonymous())
6560 ++result;
6561
6562 return result;
6563 }
6564
6565 /// Getter for the number of anonymous enums contained in this
6566 /// scope.
6567 ///
6568 /// @return the number of anonymous enums contained in this scope.
6569 size_t
get_num_anonymous_member_enums() const6570 scope_decl::get_num_anonymous_member_enums() const
6571 {
6572 int result = 0;
6573 for (declarations::const_iterator it = get_member_decls().begin();
6574 it != get_member_decls().end();
6575 ++it)
6576 if (enum_type_decl_sptr t = is_enum_type(*it))
6577 if (t->get_is_anonymous())
6578 ++result;
6579
6580 return result;
6581 }
6582
6583 /// Getter for the scopes carried by the current scope.
6584 ///
6585 /// @return the scopes carried by the current scope.
6586 scope_decl::scopes&
get_member_scopes()6587 scope_decl::get_member_scopes()
6588 {return priv_->member_scopes_;}
6589
6590 /// Getter for the scopes carried by the current scope.
6591 ///
6592 /// @return the scopes carried by the current scope.
6593 const scope_decl::scopes&
get_member_scopes() const6594 scope_decl::get_member_scopes() const
6595 {return priv_->member_scopes_;}
6596
6597 /// Test if the current scope is empty.
6598 ///
6599 /// @return true iff the current scope is empty.
6600 bool
is_empty() const6601 scope_decl::is_empty() const
6602 {
6603 return (get_member_decls().empty()
6604 && get_canonical_types().empty());
6605 }
6606
6607 /// Add a member decl to this scope. Note that user code should not
6608 /// use this, but rather use add_decl_to_scope.
6609 ///
6610 /// Note that this function updates the qualified name of the member
6611 /// decl that is added. It also sets the scope of the member. Thus,
6612 /// it ABG_ASSERTs that member should not have its scope set, prior to
6613 /// calling this function.
6614 ///
6615 /// @param member the new member decl to add to this scope.
6616 decl_base_sptr
add_member_decl(const decl_base_sptr & member)6617 scope_decl::add_member_decl(const decl_base_sptr& member)
6618 {
6619 ABG_ASSERT(!has_scope(member));
6620
6621 member->set_scope(this);
6622 priv_->members_.push_back(member);
6623
6624 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
6625 priv_->member_scopes_.push_back(m);
6626
6627 update_qualified_name(member);
6628
6629 // Propagate scope anonymity
6630 if (get_has_anonymous_parent()
6631 || (!is_global_scope(this) && get_is_anonymous()))
6632 member->set_has_anonymous_parent(true);
6633
6634 if (const environment* env = get_environment())
6635 set_environment_for_artifact(member, env);
6636
6637 if (translation_unit* tu = get_translation_unit())
6638 {
6639 if (translation_unit* existing_tu = member->get_translation_unit())
6640 ABG_ASSERT(tu == existing_tu);
6641 else
6642 member->set_translation_unit(tu);
6643 }
6644
6645 maybe_update_types_lookup_map(member);
6646
6647 return member;
6648 }
6649
6650 /// Insert a member decl to this scope, right before an element
6651 /// pointed to by a given iterator. Note that user code should not
6652 /// use this, but rather use insert_decl_into_scope.
6653 ///
6654 /// Note that this function updates the qualified name of the inserted
6655 /// member.
6656 ///
6657 /// @param member the new member decl to add to this scope.
6658 ///
6659 /// @param before an interator pointing to the element before which
6660 /// the new member should be inserted.
6661 decl_base_sptr
insert_member_decl(decl_base_sptr member,declarations::iterator before)6662 scope_decl::insert_member_decl(decl_base_sptr member,
6663 declarations::iterator before)
6664 {
6665 ABG_ASSERT(!member->get_scope());
6666
6667 member->set_scope(this);
6668 priv_->members_.insert(before, member);
6669
6670 if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
6671 priv_-> member_scopes_.push_back(m);
6672
6673 update_qualified_name(member);
6674
6675 if (const environment* env = get_environment())
6676 set_environment_for_artifact(member, env);
6677
6678 if (translation_unit* tu = get_translation_unit())
6679 {
6680 if (translation_unit* existing_tu = member->get_translation_unit())
6681 ABG_ASSERT(tu == existing_tu);
6682 else
6683 member->set_translation_unit(tu);
6684 }
6685
6686 maybe_update_types_lookup_map(member);
6687
6688 return member;
6689 }
6690
6691 /// Remove a declaration from the current scope.
6692 ///
6693 /// @param member the declaration to remove from the scope.
6694 void
remove_member_decl(decl_base_sptr member)6695 scope_decl::remove_member_decl(decl_base_sptr member)
6696 {
6697 for (declarations::iterator i = priv_->members_.begin();
6698 i != priv_->members_.end();
6699 ++i)
6700 {
6701 if (**i == *member)
6702 {
6703 priv_->members_.erase(i);
6704 // Do not access i after this point as it's invalided by the
6705 // erase call.
6706 break;
6707 }
6708 }
6709
6710 scope_decl_sptr scope = dynamic_pointer_cast<scope_decl>(member);
6711 if (scope)
6712 {
6713 for (scopes::iterator i = priv_->member_scopes_.begin();
6714 i != priv_->member_scopes_.end();
6715 ++i)
6716 {
6717 if (**i == *member)
6718 {
6719 priv_->member_scopes_.erase(i);
6720 break;
6721 }
6722 }
6723 }
6724 }
6725
6726 /// Return the hash value for the current instance of scope_decl.
6727 ///
6728 /// This method can trigger the computing of the hash value, if need be.
6729 ///
6730 /// @return the hash value.
6731 size_t
get_hash() const6732 scope_decl::get_hash() const
6733 {
6734 scope_decl::hash hash_scope;
6735 return hash_scope(this);
6736 }
6737
6738 /// Compares two instances of @ref scope_decl.
6739 ///
6740 /// If the two intances are different, set a bitfield to give some
6741 /// insight about the kind of differences there are.
6742 ///
6743 /// @param l the first artifact of the comparison.
6744 ///
6745 /// @param r the second artifact of the comparison.
6746 ///
6747 /// @param k a pointer to a bitfield that gives information about the
6748 /// kind of changes there are between @p l and @p r. This one is set
6749 /// iff @p k is non-null and the function returns false.
6750 ///
6751 /// Please note that setting k to a non-null value does have a
6752 /// negative performance impact because even if @p l and @p r are not
6753 /// equal, the function keeps up the comparison in order to determine
6754 /// the different kinds of ways in which they are different.
6755 ///
6756 /// @return true if @p l equals @p r, false otherwise.
6757 bool
equals(const scope_decl & l,const scope_decl & r,change_kind * k)6758 equals(const scope_decl& l, const scope_decl& r, change_kind* k)
6759 {
6760 bool result = true;
6761
6762 if (!l.decl_base::operator==(r))
6763 {
6764 result = false;
6765 if (k)
6766 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
6767 else
6768 return false;
6769 }
6770
6771 scope_decl::declarations::const_iterator i, j;
6772 for (i = l.get_member_decls().begin(), j = r.get_member_decls().begin();
6773 i != l.get_member_decls().end() && j != r.get_member_decls().end();
6774 ++i, ++j)
6775 {
6776 if (**i != **j)
6777 {
6778 result = false;
6779 if (k)
6780 {
6781 *k |= SUBTYPE_CHANGE_KIND;
6782 break;
6783 }
6784 else
6785 return false;
6786 }
6787 }
6788
6789 if (i != l.get_member_decls().end() || j != r.get_member_decls().end())
6790 {
6791 result = false;
6792 if (k)
6793 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
6794 else
6795 return false;
6796 }
6797
6798 return result;
6799 }
6800
6801 /// Return true iff both scopes have the same names and have the same
6802 /// member decls.
6803 ///
6804 /// This function doesn't check for equality of the scopes of its
6805 /// arguments.
6806 bool
operator ==(const decl_base & o) const6807 scope_decl::operator==(const decl_base& o) const
6808 {
6809 const scope_decl* other = dynamic_cast<const scope_decl*>(&o);
6810 if (!other)
6811 return false;
6812
6813 return equals(*this, *other, 0);
6814 }
6815
6816 /// Equality operator for @ref scope_decl_sptr.
6817 ///
6818 /// @param l the left hand side operand of the equality operator.
6819 ///
6820 /// @pram r the right hand side operand of the equalify operator.
6821 ///
6822 /// @return true iff @p l equals @p r.
6823 bool
operator ==(const scope_decl_sptr & l,const scope_decl_sptr & r)6824 operator==(const scope_decl_sptr& l, const scope_decl_sptr& r)
6825 {
6826 if (!!l != !!r)
6827 return false;
6828 if (l.get() == r.get())
6829 return true;
6830 return *l == *r;
6831 }
6832
6833 /// Inequality operator for @ref scope_decl_sptr.
6834 ///
6835 /// @param l the left hand side operand of the equality operator.
6836 ///
6837 /// @pram r the right hand side operand of the equalify operator.
6838 ///
6839 /// @return true iff @p l equals @p r.
6840 bool
operator !=(const scope_decl_sptr & l,const scope_decl_sptr & r)6841 operator!=(const scope_decl_sptr& l, const scope_decl_sptr& r)
6842 {return !operator==(l, r);}
6843
6844 /// Find a member of the current scope and return an iterator on it.
6845 ///
6846 /// @param decl the scope member to find.
6847 ///
6848 /// @param i the iterator to set to the member @p decl. This is set
6849 /// iff the function returns true.
6850 ///
6851 /// @return true if the member decl was found, false otherwise.
6852 bool
find_iterator_for_member(const decl_base * decl,declarations::iterator & i)6853 scope_decl::find_iterator_for_member(const decl_base* decl,
6854 declarations::iterator& i)
6855 {
6856 if (!decl)
6857 return false;
6858
6859 if (get_member_decls().empty())
6860 {
6861 i = get_member_decls().end();
6862 return false;
6863 }
6864
6865 for (declarations::iterator it = get_member_decls().begin();
6866 it != get_member_decls().end();
6867 ++it)
6868 {
6869 if ((*it).get() == decl)
6870 {
6871 i = it;
6872 return true;
6873 }
6874 }
6875
6876 return false;
6877 }
6878
6879 /// Find a member of the current scope and return an iterator on it.
6880 ///
6881 /// @param decl the scope member to find.
6882 ///
6883 /// @param i the iterator to set to the member @p decl. This is set
6884 /// iff the function returns true.
6885 ///
6886 /// @return true if the member decl was found, false otherwise.
6887 bool
find_iterator_for_member(const decl_base_sptr decl,declarations::iterator & i)6888 scope_decl::find_iterator_for_member(const decl_base_sptr decl,
6889 declarations::iterator& i)
6890 {return find_iterator_for_member(decl.get(), i);}
6891
6892 /// This implements the ir_traversable_base::traverse pure virtual
6893 /// function.
6894 ///
6895 /// @param v the visitor used on the current instance of scope_decl
6896 /// and on its member nodes.
6897 ///
6898 /// @return true if the traversal of the tree should continue, false
6899 /// otherwise.
6900 bool
traverse(ir_node_visitor & v)6901 scope_decl::traverse(ir_node_visitor &v)
6902 {
6903 if (visiting())
6904 return true;
6905
6906 if (v.visit_begin(this))
6907 {
6908 visiting(true);
6909 for (scope_decl::declarations::const_iterator i =
6910 get_member_decls().begin();
6911 i != get_member_decls ().end();
6912 ++i)
6913 if (!(*i)->traverse(v))
6914 break;
6915 visiting(false);
6916 }
6917 return v.visit_end(this);
6918 }
6919
~scope_decl()6920 scope_decl::~scope_decl()
6921 {}
6922
6923 /// Appends a declaration to a given scope, if the declaration
6924 /// doesn't already belong to one.
6925 ///
6926 /// @param decl the declaration to add to the scope
6927 ///
6928 /// @param scope the scope to append the declaration to
6929 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,scope_decl * scope)6930 add_decl_to_scope(decl_base_sptr decl, scope_decl* scope)
6931 {
6932 ABG_ASSERT(scope);
6933
6934 if (scope && decl && !decl->get_scope())
6935 decl = scope->add_member_decl(decl);
6936
6937 return decl;
6938 }
6939
6940 /// Appends a declaration to a given scope, if the declaration doesn't
6941 /// already belong to a scope.
6942 ///
6943 /// @param decl the declaration to add append to the scope
6944 ///
6945 /// @param scope the scope to append the decl to
6946 decl_base_sptr
add_decl_to_scope(decl_base_sptr decl,const scope_decl_sptr & scope)6947 add_decl_to_scope(decl_base_sptr decl, const scope_decl_sptr& scope)
6948 {return add_decl_to_scope(decl, scope.get());}
6949
6950 /// Remove a given decl from its scope
6951 ///
6952 /// @param decl the decl to remove from its scope.
6953 void
remove_decl_from_scope(decl_base_sptr decl)6954 remove_decl_from_scope(decl_base_sptr decl)
6955 {
6956 if (!decl)
6957 return;
6958
6959 scope_decl* scope = decl->get_scope();
6960 scope->remove_member_decl(decl);
6961 decl->set_scope(0);
6962 }
6963
6964 /// Inserts a declaration into a given scope, before a given IR child
6965 /// node of the scope.
6966 ///
6967 /// @param decl the declaration to insert into the scope.
6968 ///
6969 /// @param before an iterator pointing to the child IR node before
6970 /// which to insert the declaration.
6971 ///
6972 /// @param scope the scope into which to insert the declaration.
6973 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl * scope)6974 insert_decl_into_scope(decl_base_sptr decl,
6975 scope_decl::declarations::iterator before,
6976 scope_decl* scope)
6977 {
6978 if (scope && decl && !decl->get_scope())
6979 {
6980 decl_base_sptr d = scope->insert_member_decl(decl, before);
6981 decl = d;
6982 }
6983 return decl;
6984 }
6985
6986 /// Inserts a declaration into a given scope, before a given IR child
6987 /// node of the scope.
6988 ///
6989 /// @param decl the declaration to insert into the scope.
6990 ///
6991 /// @param before an iterator pointing to the child IR node before
6992 /// which to insert the declaration.
6993 ///
6994 /// @param scope the scope into which to insert the declaration.
6995 decl_base_sptr
insert_decl_into_scope(decl_base_sptr decl,scope_decl::declarations::iterator before,scope_decl_sptr scope)6996 insert_decl_into_scope(decl_base_sptr decl,
6997 scope_decl::declarations::iterator before,
6998 scope_decl_sptr scope)
6999 {return insert_decl_into_scope(decl, before, scope.get());}
7000
7001 /// Constructor of the @ref global_scope type.
7002 ///
7003 /// @param tu the translation unit the scope belongs to.
global_scope(translation_unit * tu)7004 global_scope::global_scope(translation_unit *tu)
7005 : type_or_decl_base(tu->get_environment(),
7006 GLOBAL_SCOPE_DECL
7007 | ABSTRACT_DECL_BASE
7008 | ABSTRACT_SCOPE_DECL),
7009 decl_base(tu->get_environment(), "", location()),
7010 scope_decl(tu->get_environment(), "", location()),
7011 translation_unit_(tu)
7012 {
7013 runtime_type_instance(this);
7014 }
7015
7016 /// return the global scope as seen by a given declaration.
7017 ///
7018 /// @param decl the declaration to consider.
7019 ///
7020 /// @return the global scope of the decl, or a null pointer if the
7021 /// decl is not yet added to a translation_unit.
7022 const global_scope*
get_global_scope(const decl_base & decl)7023 get_global_scope(const decl_base& decl)
7024 {
7025 if (const global_scope* s = dynamic_cast<const global_scope*>(&decl))
7026 return s;
7027
7028 scope_decl* scope = decl.get_scope();
7029 while (scope && !dynamic_cast<global_scope*>(scope))
7030 scope = scope->get_scope();
7031
7032 return scope ? dynamic_cast<global_scope*> (scope) : 0;
7033 }
7034
7035 /// return the global scope as seen by a given declaration.
7036 ///
7037 /// @param decl the declaration to consider.
7038 ///
7039 /// @return the global scope of the decl, or a null pointer if the
7040 /// decl is not yet added to a translation_unit.
7041 const global_scope*
get_global_scope(const decl_base * decl)7042 get_global_scope(const decl_base* decl)
7043 {return get_global_scope(*decl);}
7044
7045 /// Return the global scope as seen by a given declaration.
7046 ///
7047 /// @param decl the declaration to consider.
7048 ///
7049 /// @return the global scope of the decl, or a null pointer if the
7050 /// decl is not yet added to a translation_unit.
7051 const global_scope*
get_global_scope(const shared_ptr<decl_base> decl)7052 get_global_scope(const shared_ptr<decl_base> decl)
7053 {return get_global_scope(decl.get());}
7054
7055 /// Return the a scope S containing a given declaration and that is
7056 /// right under a given scope P.
7057 ///
7058 /// Note that @p scope must come before @p decl in topological
7059 /// order.
7060 ///
7061 /// @param decl the decl for which to find a scope.
7062 ///
7063 /// @param scope the scope under which the resulting scope must be.
7064 ///
7065 /// @return the resulting scope.
7066 const scope_decl*
get_top_most_scope_under(const decl_base * decl,const scope_decl * scope)7067 get_top_most_scope_under(const decl_base* decl,
7068 const scope_decl* scope)
7069 {
7070 if (!decl)
7071 return 0;
7072
7073 if (scope == 0)
7074 return get_global_scope(decl);
7075
7076 // Handle the case where decl is a scope itself.
7077 const scope_decl* s = dynamic_cast<const scope_decl*>(decl);
7078 if (!s)
7079 s = decl->get_scope();
7080
7081 if (is_global_scope(s))
7082 return scope;
7083
7084 // Here, decl is in the scope 'scope', or decl and 'scope' are the
7085 // same. The caller needs to be prepared to deal with this case.
7086 if (s == scope)
7087 return s;
7088
7089 while (s && !is_global_scope(s) && s->get_scope() != scope)
7090 s = s->get_scope();
7091
7092 if (!s || is_global_scope(s))
7093 // SCOPE must come before decl in topological order, but I don't
7094 // know how to ensure that ...
7095 return scope;
7096 ABG_ASSERT(s);
7097
7098 return s;
7099 }
7100
7101 /// Return the a scope S containing a given declaration and that is
7102 /// right under a given scope P.
7103 ///
7104 /// @param decl the decl for which to find a scope.
7105 ///
7106 /// @param scope the scope under which the resulting scope must be.
7107 ///
7108 /// @return the resulting scope.
7109 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl * scope)7110 get_top_most_scope_under(const decl_base_sptr decl,
7111 const scope_decl* scope)
7112 {return get_top_most_scope_under(decl.get(), scope);}
7113
7114 /// Return the a scope S containing a given declaration and that is
7115 /// right under a given scope P.
7116 ///
7117 /// @param decl the decl for which to find a scope.
7118 ///
7119 /// @param scope the scope under which the resulting scope must be.
7120 ///
7121 /// @return the resulting scope.
7122 const scope_decl*
get_top_most_scope_under(const decl_base_sptr decl,const scope_decl_sptr scope)7123 get_top_most_scope_under(const decl_base_sptr decl,
7124 const scope_decl_sptr scope)
7125 {return get_top_most_scope_under(decl, scope.get());}
7126
7127 // </scope_decl stuff>
7128
7129
7130 /// Get the string representation of a CV qualifier bitmap.
7131 ///
7132 /// @param cv_quals the bitmap of CV qualifiers to consider.
7133 ///
7134 /// @return the string representation.
7135 string
get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)7136 get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
7137 {
7138 string repr;
7139 if (cv_quals & qualified_type_def::CV_RESTRICT)
7140 repr = "restrict";
7141 if (cv_quals & qualified_type_def::CV_CONST)
7142 {
7143 if (!repr.empty())
7144 repr += ' ';
7145 repr += "const";
7146 }
7147 if (cv_quals & qualified_type_def::CV_VOLATILE)
7148 {
7149 if (!repr.empty())
7150 repr += ' ';
7151 repr += "volatile";
7152 }
7153 return repr;
7154 }
7155
7156 /// Build and return a copy of the name of an ABI artifact that is
7157 /// either a type or a decl.
7158 ///
7159 /// @param tod the ABI artifact to get the name for.
7160 ///
7161 /// @param qualified if yes, return the qualified name of @p tod;
7162 /// otherwise, return the non-qualified name;
7163 ///
7164 /// @return the name of @p tod.
7165 string
get_name(const type_or_decl_base * tod,bool qualified)7166 get_name(const type_or_decl_base *tod, bool qualified)
7167 {
7168 string result;
7169
7170 type_or_decl_base* a = const_cast<type_or_decl_base*>(tod);
7171
7172 if (type_base* t = dynamic_cast<type_base*>(a))
7173 result = get_type_name(t, qualified);
7174 else if (decl_base *d = dynamic_cast<decl_base*>(a))
7175 {
7176 if (qualified)
7177 result = d->get_qualified_name();
7178 else
7179 result = d->get_name();
7180 }
7181 else
7182 // We should never reach this point.
7183 abort();
7184
7185 return result;
7186 }
7187
7188 /// Build and return a copy of the name of an ABI artifact that is
7189 /// either a type of a decl.
7190 ///
7191 /// @param tod the ABI artifact to get the name for.
7192 ///
7193 /// @param qualified if yes, return the qualified name of @p tod;
7194 /// otherwise, return the non-qualified name;
7195 ///
7196 /// @return the name of @p tod.
7197 string
get_name(const type_or_decl_base_sptr & tod,bool qualified)7198 get_name(const type_or_decl_base_sptr& tod, bool qualified)
7199 {return get_name(tod.get(), qualified);}
7200
7201 /// Build and return a qualified name from a name and its scope.
7202 ///
7203 /// The name is supposed to be for an entity that is part of the
7204 /// scope.
7205 ///
7206 /// @param the scope to consider.
7207 ///
7208 /// @param name of the name to consider.
7209 ///
7210 /// @return a copy of the string that represents the qualified name.
7211 string
build_qualified_name(const scope_decl * scope,const string & name)7212 build_qualified_name(const scope_decl* scope, const string& name)
7213 {
7214 if (name.empty())
7215 return "";
7216
7217 string qualified_name;
7218 if (scope)
7219 qualified_name = scope->get_qualified_name();
7220
7221 if (qualified_name.empty())
7222 qualified_name = name;
7223 else
7224 qualified_name = qualified_name + "::" + name;
7225
7226 return qualified_name;
7227 }
7228
7229 /// Build and return the qualified name of a type in its scope.
7230 ///
7231 /// @param scope the scope of the type to consider.
7232 ///
7233 /// @param type the type to consider.
7234 string
build_qualified_name(const scope_decl * scope,const type_base_sptr & type)7235 build_qualified_name(const scope_decl* scope, const type_base_sptr& type)
7236 {return build_qualified_name(scope, get_name((type)));}
7237
7238 // </scope_decl stuff>
7239
7240 /// Get the location of the declaration of a given type.
7241 ///
7242 /// @param type the type to consider.
7243 ///
7244 /// @return the location of the declaration of type @p type.
7245 location
get_location(const type_base_sptr & type)7246 get_location(const type_base_sptr& type)
7247 {
7248 if (decl_base_sptr decl = get_type_declaration(type))
7249 return get_location(decl);
7250 return location();
7251 }
7252
7253 /// Get the location of a given declaration.
7254 ///
7255 /// @param decl the declaration to consider.
7256 ///
7257 /// @return the location of the declaration @p decl.
7258 location
get_location(const decl_base_sptr & decl)7259 get_location(const decl_base_sptr& decl)
7260 {
7261 location loc = decl->get_location();
7262 if (!loc)
7263 {
7264 if (class_or_union_sptr c = is_class_or_union_type(decl))
7265 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
7266 {
7267 c = is_class_or_union_type(c->get_definition_of_declaration());
7268 loc = c->get_location();
7269 }
7270 }
7271 return loc;
7272 }
7273
7274 /// Get the scope of a given type.
7275 ///
7276 /// @param t the type to consider.
7277 ///
7278 /// @return the scope of type @p t or 0 if the type has no scope yet.
7279 scope_decl*
get_type_scope(type_base * t)7280 get_type_scope(type_base* t)
7281 {
7282 if (!t)
7283 return 0;
7284
7285 decl_base* d = get_type_declaration(t);
7286 if (d)
7287 return d->get_scope();
7288 return 0;
7289 }
7290
7291 /// Get the scope of a given type.
7292 ///
7293 /// @param t the type to consider.
7294 ///
7295 /// @return the scope of type @p t or 0 if the type has no scope yet.
7296 scope_decl*
get_type_scope(const type_base_sptr & t)7297 get_type_scope(const type_base_sptr& t)
7298 {return get_type_scope(t.get());}
7299
7300 /// Get the name of a given type and return a copy of it.
7301 ///
7302 /// @param t the type to consider.
7303 ///
7304 /// @param qualified if true then return the qualified name of the
7305 /// type.
7306 ///
7307 /// @param internal set to true if the call is intended for an
7308 /// internal use (for technical use inside the library itself), false
7309 /// otherwise. If you don't know what this is for, then set it to
7310 /// false.
7311 ///
7312 /// @return a copy of the type name if the type has a name, or the
7313 /// empty string if it does not.
7314 interned_string
get_type_name(const type_base_sptr & t,bool qualified,bool internal)7315 get_type_name(const type_base_sptr& t, bool qualified, bool internal)
7316 {return get_type_name(t.get(), qualified, internal);}
7317
7318 /// Return true iff a decl is for a type type that has a generic
7319 /// anonymous internal type name.
7320 ///
7321 /// @param d the decl to considier.
7322 ///
7323 /// @return true iff @p d is for a type type that has a generic
7324 /// anonymous internal type name.
7325 static bool
has_generic_anonymous_internal_type_name(const decl_base * d)7326 has_generic_anonymous_internal_type_name(const decl_base *d)
7327 {
7328 return is_class_or_union_type(d) || is_enum_type(d);
7329 }
7330
7331 /// Return the generic internal name of an anonymous type.
7332 ///
7333 /// For internal purposes, we want to define a generic name for all
7334 /// anonymous types of a certain kind. For instance, all anonymous
7335 /// structs will be have a generic name of "__anonymous_struct__", all
7336 /// anonymous unions will have a generic name of
7337 /// "__anonymous_union__", etc.
7338 ///
7339 /// That generic name can be used as a hash to put all anonymous types
7340 /// of a certain kind in the same hash table bucket, for instance.
7341 static interned_string
get_generic_anonymous_internal_type_name(const decl_base * d)7342 get_generic_anonymous_internal_type_name(const decl_base *d)
7343 {
7344 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
7345
7346 const environment *env = d->get_environment();
7347
7348 interned_string result;
7349 if (is_class_type(d))
7350 result =
7351 env->intern(tools_utils::get_anonymous_struct_internal_name_prefix());
7352 else if (is_union_type(d))
7353 result =
7354 env->intern(tools_utils::get_anonymous_union_internal_name_prefix());
7355 else if (is_enum_type(d))
7356 result =
7357 env->intern(tools_utils::get_anonymous_enum_internal_name_prefix());
7358 else
7359 ABG_ASSERT_NOT_REACHED;
7360
7361 return result;
7362 }
7363
7364 /// Get the name of a given type and return a copy of it.
7365 ///
7366 /// @param t the type to consider.
7367 ///
7368 /// @param qualified if true then return the qualified name of the
7369 /// type.
7370 ///
7371 /// @param internal set to true if the call is intended for an
7372 /// internal use (for technical use inside the library itself), false
7373 /// otherwise. If you don't know what this is for, then set it to
7374 /// false.
7375 ///
7376 /// @return a copy of the type name if the type has a name, or the
7377 /// empty string if it does not.
7378 interned_string
get_type_name(const type_base * t,bool qualified,bool internal)7379 get_type_name(const type_base* t, bool qualified, bool internal)
7380 {
7381 const decl_base* d = dynamic_cast<const decl_base*>(t);
7382 if (!d)
7383 {
7384 const function_type* fn_type = is_function_type(t);
7385 ABG_ASSERT(fn_type);
7386 return fn_type->get_cached_name(internal);
7387 }
7388
7389 // All anonymous types of a given kind get to have the same internal
7390 // name for internal purpose. This to allow them to be compared
7391 // among themselves during type canonicalization.
7392 if (internal && d->get_is_anonymous())
7393 {
7394 string r;
7395 if (qualified)
7396 {
7397 r = d->get_qualified_parent_name();
7398 if (!r.empty())
7399 r += "::";
7400 }
7401 r += get_generic_anonymous_internal_type_name(d);
7402 return t->get_environment()->intern(r);
7403 }
7404
7405 if (qualified)
7406 return d->get_qualified_name(internal);
7407 return d->get_name();
7408 }
7409
7410 /// Get the name of a given type and return a copy of it.
7411 ///
7412 /// @param t the type to consider.
7413 ///
7414 /// @param qualified if true then return the qualified name of the
7415 /// type.
7416 ///
7417 /// @param internal set to true if the call is intended for an
7418 /// internal use (for technical use inside the library itself), false
7419 /// otherwise. If you don't know what this is for, then set it to
7420 /// false.
7421 ///
7422 /// @return a copy of the type name if the type has a name, or the
7423 /// empty string if it does not.
7424 interned_string
get_type_name(const type_base & t,bool qualified,bool internal)7425 get_type_name(const type_base& t, bool qualified, bool internal)
7426 {return get_type_name(&t, qualified, internal);}
7427
7428 /// Get the name of the pointer to a given type.
7429 ///
7430 /// @param pointed_to_type the pointed-to-type to consider.
7431 ///
7432 /// @param qualified this is true if the resulting name should be of a
7433 /// pointer to a *fully-qualified* pointed-to-type.
7434 ///
7435 /// @param internal true if the name is for libabigail-internal
7436 /// purposes.
7437 ///
7438 /// @return the name (string representation) of the pointer.
7439 interned_string
get_name_of_pointer_to_type(const type_base & pointed_to_type,bool qualified,bool internal)7440 get_name_of_pointer_to_type(const type_base& pointed_to_type,
7441 bool qualified, bool internal)
7442 {
7443 const environment* env = pointed_to_type.get_environment();
7444 ABG_ASSERT(env);
7445
7446 string tn = get_type_name(pointed_to_type, qualified, internal);
7447 tn = tn + "*";
7448
7449 return env->intern(tn);
7450 }
7451
7452 /// Get the name of the reference to a given type.
7453 ///
7454 /// @param pointed_to_type the pointed-to-type to consider.
7455 ///
7456 /// @param qualified this is true if the resulting name should be of a
7457 /// reference to a *fully-qualified* pointed-to-type.
7458 ///
7459 /// @param internal true if the name is for libabigail-internal
7460 /// purposes.
7461 ///
7462 /// @return the name (string representation) of the reference.
7463 interned_string
get_name_of_reference_to_type(const type_base & pointed_to_type,bool lvalue_reference,bool qualified,bool internal)7464 get_name_of_reference_to_type(const type_base& pointed_to_type,
7465 bool lvalue_reference,
7466 bool qualified, bool internal)
7467 {
7468 const environment* env = pointed_to_type.get_environment();
7469 ABG_ASSERT(env);
7470
7471 string name = get_type_name(pointed_to_type, qualified, internal);
7472 if (lvalue_reference)
7473 name = name + "&";
7474 else
7475 name = name + "&&";
7476
7477 return env->intern(name);
7478 }
7479
7480 /// Get the name of a qualified type, given the underlying type and
7481 /// its qualifiers.
7482 ///
7483 /// @param underlying_type the underlying type to consider.
7484 ///
7485 /// @param quals the CV qualifiers of the name.
7486 ///
7487 /// @param qualified true if we should consider the fully qualified
7488 /// name of @p underlying_type.
7489 ///
7490 /// @param internal true if the result is to be used for
7491 /// libabigail-internal purposes.
7492 ///
7493 /// @return the name (string representation) of the qualified type.
7494 interned_string
get_name_of_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,bool qualified,bool internal)7495 get_name_of_qualified_type(const type_base_sptr& underlying_type,
7496 qualified_type_def::CV quals,
7497 bool qualified, bool internal)
7498 {
7499 const environment* env = underlying_type->get_environment();
7500 ABG_ASSERT(env);
7501
7502 string quals_repr = get_string_representation_of_cv_quals(quals);
7503 string name = get_type_name(underlying_type, qualified, internal);
7504
7505 if (quals_repr.empty() && internal)
7506 // We are asked to return the internal name, that might be used
7507 // for type canonicalization. For that canonicalization, we need
7508 // to make a difference between a no-op qualified type which
7509 // underlying type is foo (the qualified type is named "none
7510 // foo"), and the name of foo, which is just "foo".
7511 //
7512 // Please remember that this has to be kept in sync with what is
7513 // done in die_qualified_name, in abg-dwarf-reader.cc. So if you
7514 // change this code here, please change that code there too.
7515 quals_repr = "";
7516
7517 if (!quals_repr.empty())
7518 {
7519 if (is_pointer_type(underlying_type)
7520 || is_reference_type(underlying_type)
7521 || is_array_type(underlying_type))
7522 {
7523 name += " ";
7524 name += quals_repr;
7525 }
7526 else
7527 name = quals_repr + " " + name;
7528 }
7529
7530 return env->intern(name);
7531 }
7532
7533 /// Get the name of a given function type and return a copy of it.
7534 ///
7535 /// @param fn_type the function type to consider.
7536 ///
7537 /// @param internal set to true if the call is intended for an
7538 /// internal use (for technical use inside the library itself), false
7539 /// otherwise. If you don't know what this is for, then set it to
7540 /// false.
7541 ///
7542 /// @return a copy of the function type name
7543 interned_string
get_function_type_name(const function_type_sptr & fn_type,bool internal)7544 get_function_type_name(const function_type_sptr& fn_type,
7545 bool internal)
7546 {return get_function_type_name(fn_type.get(), internal);}
7547
7548 /// Get the name of a given function type and return a copy of it.
7549 ///
7550 /// @param fn_type the function type to consider.
7551 ///
7552 /// @param internal set to true if the call is intended for an
7553 /// internal use (for technical use inside the library itself), false
7554 /// otherwise. If you don't know what this is for, then set it to
7555 /// false.
7556 ///
7557 /// @return a copy of the function type name
7558 interned_string
get_function_type_name(const function_type * fn_type,bool internal)7559 get_function_type_name(const function_type* fn_type,
7560 bool internal)
7561 {
7562 ABG_ASSERT(fn_type);
7563
7564 if (const method_type* method = is_method_type(fn_type))
7565 return get_method_type_name(method, internal);
7566
7567 return get_function_type_name(*fn_type, internal);
7568 }
7569
7570 /// Get the name of a given function type and return a copy of it.
7571 ///
7572 /// @param fn_type the function type to consider.
7573 ///
7574 /// @param internal set to true if the call is intended for an
7575 /// internal use (for technical use inside the library itself), false
7576 /// otherwise. If you don't know what this is for, then set it to
7577 /// false.
7578 ///
7579 /// @return a copy of the function type name
7580 interned_string
get_function_type_name(const function_type & fn_type,bool internal)7581 get_function_type_name(const function_type& fn_type,
7582 bool internal)
7583 {
7584 std::ostringstream o;
7585 type_base_sptr return_type = fn_type.get_return_type();
7586 const environment* env = fn_type.get_environment();
7587 ABG_ASSERT(env);
7588
7589 o << get_pretty_representation(return_type, internal);
7590
7591 o << " (";
7592 for (function_type::parameters::const_iterator i =
7593 fn_type.get_parameters().begin();
7594 i != fn_type.get_parameters().end();
7595 ++i)
7596 {
7597 if (i != fn_type.get_parameters().begin())
7598 o << ", ";
7599 o << get_pretty_representation((*i)->get_type(), internal);
7600 }
7601 o <<")";
7602
7603 return env->intern(o.str());
7604 }
7605
7606 /// Get the name of a given method type and return a copy of it.
7607 ///
7608 /// @param fn_type the function type to consider.
7609 ///
7610 /// @param internal set to true if the call is intended for an
7611 /// internal use (for technical use inside the library itself), false
7612 /// otherwise. If you don't know what this is for, then set it to
7613 /// false.
7614 ///
7615 /// @return a copy of the function type name
7616 interned_string
get_method_type_name(const method_type_sptr fn_type,bool internal)7617 get_method_type_name(const method_type_sptr fn_type,
7618 bool internal)
7619 {return get_method_type_name(fn_type.get(), internal);}
7620
7621 /// Get the name of a given method type and return a copy of it.
7622 ///
7623 /// @param fn_type the function type to consider.
7624 ///
7625 /// @param internal set to true if the call is intended for an
7626 /// internal use (for technical use inside the library itself), false
7627 /// otherwise. If you don't know what this is for, then set it to
7628 /// false.
7629 ///
7630 /// @return a copy of the function type name
7631 interned_string
get_method_type_name(const method_type * fn_type,bool internal)7632 get_method_type_name(const method_type* fn_type,
7633 bool internal)
7634 {
7635 if (fn_type)
7636 return get_method_type_name(*fn_type, internal);
7637
7638 return interned_string();
7639 }
7640
7641 /// Get the name of a given method type and return a copy of it.
7642 ///
7643 /// @param fn_type the function type to consider.
7644 ///
7645 /// @param internal set to true if the call is intended for an
7646 /// internal use (for technical use inside the library itself), false
7647 /// otherwise. If you don't know what this is for, then set it to
7648 /// false.
7649 ///
7650 /// @return a copy of the function type name
7651 interned_string
get_method_type_name(const method_type & fn_type,bool internal)7652 get_method_type_name(const method_type& fn_type,
7653 bool internal)
7654 {
7655 std::ostringstream o;
7656 type_base_sptr return_type= fn_type.get_return_type();
7657 const environment* env = fn_type.get_environment();
7658 ABG_ASSERT(env);
7659
7660 if (return_type)
7661 o << return_type->get_cached_pretty_representation(internal);
7662 else
7663 // There are still some abixml files out there in which "void"
7664 // can be expressed as an empty type.
7665 o << "void";
7666
7667 class_or_union_sptr class_type = fn_type.get_class_type();
7668 ABG_ASSERT(class_type);
7669
7670 o << " (" << class_type->get_qualified_name(internal) << "::*)"
7671 << " (";
7672
7673 for (function_type::parameters::const_iterator i =
7674 fn_type.get_parameters().begin();
7675 i != fn_type.get_parameters().end();
7676 ++i)
7677 {
7678 if (i != fn_type.get_parameters().begin())
7679 o << ", ";
7680 if (*i)
7681 o << (*i)->get_type()->get_cached_pretty_representation(internal);
7682 else
7683 // There are still some abixml files out there in which "void"
7684 // can be expressed as an empty type.
7685 o << "void";
7686 }
7687 o <<")";
7688
7689 return env->intern(o.str());
7690 }
7691
7692 /// Build and return a copy of the pretty representation of an ABI
7693 /// artifact that could be either a type of a decl.
7694 ///
7695 /// param tod the ABI artifact to consider.
7696 ///
7697 /// @param internal set to true if the call is intended for an
7698 /// internal use (for technical use inside the library itself), false
7699 /// otherwise. If you don't know what this is for, then set it to
7700 /// false.
7701 ///
7702 /// @return a copy of the pretty representation of an ABI artifact
7703 /// that could be either a type of a decl.
7704 string
get_pretty_representation(const type_or_decl_base * tod,bool internal)7705 get_pretty_representation(const type_or_decl_base* tod, bool internal)
7706 {
7707 string result;
7708
7709 if (type_base* t = is_type(const_cast<type_or_decl_base*>(tod)))
7710 result = get_pretty_representation(t, internal);
7711 else if (decl_base* d = is_decl(const_cast<type_or_decl_base*>(tod)))
7712 result = get_pretty_representation(d, internal);
7713 else
7714 // We should never reach this point
7715 abort();
7716
7717 return result;
7718 }
7719
7720 /// Build and return a copy of the pretty representation of an ABI
7721 /// artifact that could be either a type of a decl.
7722 ///
7723 /// param tod the ABI artifact to consider.
7724 ///
7725 /// @param internal set to true if the call is intended for an
7726 /// internal use (for technical use inside the library itself), false
7727 /// otherwise. If you don't know what this is for, then set it to
7728 /// false.
7729 ///
7730 /// @return a copy of the pretty representation of an ABI artifact
7731 /// that could be either a type of a decl.
7732 string
get_pretty_representation(const type_or_decl_base_sptr & tod,bool internal)7733 get_pretty_representation(const type_or_decl_base_sptr& tod, bool internal)
7734 {return get_pretty_representation(tod.get(), internal);}
7735
7736 /// Get a copy of the pretty representation of a decl.
7737 ///
7738 /// @param d the decl to consider.
7739 ///
7740 /// @param internal set to true if the call is intended for an
7741 /// internal use (for technical use inside the library itself), false
7742 /// otherwise. If you don't know what this is for, then set it to
7743 /// false.
7744 ///
7745 /// @return the pretty representation of the decl.
7746 string
get_pretty_representation(const decl_base * d,bool internal)7747 get_pretty_representation(const decl_base* d, bool internal)
7748 {
7749 if (!d)
7750 return "";
7751 return d->get_pretty_representation(internal);
7752 }
7753
7754 /// Get a copy of the pretty representation of a type.
7755 ///
7756 /// @param d the type to consider.
7757 ///
7758 /// @param internal set to true if the call is intended for an
7759 /// internal use (for technical use inside the library itself), false
7760 /// otherwise. If you don't know what this is for, then set it to
7761 /// false.
7762 ///
7763 /// @return the pretty representation of the type.
7764 string
get_pretty_representation(const type_base * t,bool internal)7765 get_pretty_representation(const type_base* t, bool internal)
7766 {
7767 if (!t)
7768 return "void";
7769 if (const function_type* fn_type = is_function_type(t))
7770 return get_pretty_representation(fn_type, internal);
7771
7772 const decl_base* d = get_type_declaration(t);
7773 ABG_ASSERT(d);
7774 return get_pretty_representation(d, internal);
7775 }
7776
7777 /// Get a copy of the pretty representation of a decl.
7778 ///
7779 /// @param d the decl to consider.
7780 ///
7781 /// @param internal set to true if the call is intended for an
7782 /// internal use (for technical use inside the library itself), false
7783 /// otherwise. If you don't know what this is for, then set it to
7784 /// false.
7785 ///
7786 /// @return the pretty representation of the decl.
7787 string
get_pretty_representation(const decl_base_sptr & d,bool internal)7788 get_pretty_representation(const decl_base_sptr& d, bool internal)
7789 {return get_pretty_representation(d.get(), internal);}
7790
7791 /// Get a copy of the pretty representation of a type.
7792 ///
7793 /// @param d the type to consider.
7794 ///
7795 /// @param internal set to true if the call is intended for an
7796 /// internal use (for technical use inside the library itself), false
7797 /// otherwise. If you don't know what this is for, then set it to
7798 /// false.
7799 ///
7800 /// @return the pretty representation of the type.
7801 string
get_pretty_representation(const type_base_sptr & t,bool internal)7802 get_pretty_representation(const type_base_sptr& t, bool internal)
7803 {return get_pretty_representation(t.get(), internal);}
7804
7805 /// Get the pretty representation of a function type.
7806 ///
7807 /// @param fn_type the function type to consider.
7808 ///
7809 /// @param internal set to true if the call is intended for an
7810 /// internal use (for technical use inside the library itself), false
7811 /// otherwise. If you don't know what this is for, then set it to
7812 /// false.
7813 ///
7814 /// @return the string represenation of the function type.
7815 string
get_pretty_representation(const function_type_sptr & fn_type,bool internal)7816 get_pretty_representation(const function_type_sptr& fn_type,
7817 bool internal)
7818 {return get_pretty_representation(fn_type.get(), internal);}
7819
7820 /// Get the pretty representation of a function type.
7821 ///
7822 /// @param fn_type the function type to consider.
7823 ///
7824 /// @param internal set to true if the call is intended for an
7825 /// internal use (for technical use inside the library itself), false
7826 /// otherwise. If you don't know what this is for, then set it to
7827 /// false.
7828 ///
7829 /// @return the string represenation of the function type.
7830 string
get_pretty_representation(const function_type * fn_type,bool internal)7831 get_pretty_representation(const function_type* fn_type, bool internal)
7832 {
7833 if (!fn_type)
7834 return "void";
7835
7836 if (const method_type* method = is_method_type(fn_type))
7837 return get_pretty_representation(method, internal);
7838
7839 return get_pretty_representation(*fn_type, internal);
7840 }
7841
7842 /// Get the pretty representation of a function type.
7843 ///
7844 /// @param fn_type the function type to consider.
7845 ///
7846 /// @param internal set to true if the call is intended for an
7847 /// internal use (for technical use inside the library itself), false
7848 /// otherwise. If you don't know what this is for, then set it to
7849 /// false.
7850 ///
7851 /// @return the string represenation of the function type.
7852 string
get_pretty_representation(const function_type & fn_type,bool internal)7853 get_pretty_representation(const function_type& fn_type, bool internal)
7854 {
7855 std::ostringstream o;
7856 o << "function type " << get_function_type_name(fn_type, internal);
7857 return o.str();
7858 }
7859
7860 /// Get the pretty representation of a method type.
7861 ///
7862 /// @param method the method type to consider.
7863 ///
7864 /// @param internal set to true if the call is intended for an
7865 /// internal use (for technical use inside the library itself), false
7866 /// otherwise. If you don't know what this is for, then set it to
7867 /// false.
7868 ///
7869 /// @return the string represenation of the method type.
7870 string
get_pretty_representation(const method_type & method,bool internal)7871 get_pretty_representation(const method_type& method, bool internal)
7872 {
7873 std::ostringstream o;
7874 o << "method type " << get_method_type_name(method, internal);
7875 return o.str();
7876 }
7877
7878 /// Get the pretty representation of a method type.
7879 ///
7880 /// @param method the method type to consider.
7881 ///
7882 /// @param internal set to true if the call is intended for an
7883 /// internal use (for technical use inside the library itself), false
7884 /// otherwise. If you don't know what this is for, then set it to
7885 /// false.
7886 ///
7887 /// @return the string represenation of the method type.
7888 string
get_pretty_representation(const method_type * method,bool internal)7889 get_pretty_representation(const method_type* method, bool internal)
7890 {
7891 if (!method)
7892 return "void";
7893 return get_pretty_representation(*method, internal);
7894 }
7895
7896 /// Get the pretty representation of a method type.
7897 ///
7898 /// @param method the method type to consider.
7899 ///
7900 /// @param internal set to true if the call is intended for an
7901 /// internal use (for technical use inside the library itself), false
7902 /// otherwise. If you don't know what this is for, then set it to
7903 /// false.
7904 ///
7905 /// @return the string represenation of the method type.
7906 string
get_pretty_representation(const method_type_sptr method,bool internal)7907 get_pretty_representation(const method_type_sptr method, bool internal)
7908 {return get_pretty_representation(method.get(), internal);}
7909
7910 /// Get the flat representation of an instance of @ref class_or_union
7911 /// type.
7912 ///
7913 /// The flat representation of a given @ref class_or_union type is the
7914 /// actual definition of the type, for instance:
7915 ///
7916 /// struct foo {int a; char b;}
7917 ///
7918 ///@param cou the instance of @ref class_or_union to consider.
7919 ///
7920 ///@param indent the identation spaces to use in the representation.
7921 ///
7922 ///@param one_line if true, then the flat representation stands on one
7923 ///line. Otherwise, it stands on multiple lines.
7924 ///
7925 ///@return the resulting flat representation.
7926 string
get_class_or_union_flat_representation(const class_or_union & cou,const string & indent,bool one_line,bool internal,bool qualified_names)7927 get_class_or_union_flat_representation(const class_or_union& cou,
7928 const string& indent,
7929 bool one_line,
7930 bool internal,
7931 bool qualified_names)
7932 {
7933 string repr;
7934 string local_indent = " ";
7935
7936 if (class_decl* clazz = is_class_type(&cou))
7937 {
7938 repr = indent;
7939 if (!internal && clazz->is_struct())
7940 repr += "struct";
7941 else
7942 repr += "class";
7943 }
7944 else if (is_union_type(cou))
7945 repr = indent + "union";
7946 else
7947 return "";
7948
7949 repr += " ";
7950
7951 string name = cou.get_qualified_name();
7952
7953 if (!cou.get_is_anonymous())
7954 repr += name;
7955
7956 repr += "{";
7957
7958 if (!one_line)
7959 repr += "\n";
7960
7961 string real_indent;
7962 const class_or_union::data_members &dmems = cou.get_data_members();
7963 for (class_or_union::data_members::const_iterator dm = dmems.begin();
7964 dm != dmems.end();
7965 ++dm)
7966 {
7967 if (dm != dmems.begin())
7968 {
7969 if (one_line)
7970 real_indent = " ";
7971 else
7972 real_indent = "\n" + indent + local_indent;
7973 }
7974
7975 if (var_decl_sptr v = is_anonymous_data_member(*dm))
7976 repr +=
7977 get_class_or_union_flat_representation
7978 (anonymous_data_member_to_class_or_union(*dm),
7979 real_indent, one_line, internal, qualified_names);
7980 else
7981 {
7982 if (one_line)
7983 {
7984 if (dm != dmems.begin())
7985 repr += real_indent;
7986 repr += (*dm)->get_pretty_representation(internal,
7987 qualified_names);
7988 }
7989 else
7990 repr +=
7991 real_indent+ (*dm)->get_pretty_representation(internal,
7992 qualified_names);
7993 }
7994 repr += ";";
7995 }
7996
7997 if (one_line)
7998 repr += "}";
7999 else
8000 repr += indent + "}";
8001
8002 return repr;
8003 }
8004
8005 /// Get the flat representation of an instance of @ref class_or_union
8006 /// type.
8007 ///
8008 /// The flat representation of a given @ref class_or_union type is the
8009 /// actual definition of the type, for instance:
8010 ///
8011 /// struct foo {int a; char b;}
8012 ///
8013 ///@param cou the instance of @ref class_or_union to consider.
8014 ///
8015 ///@param indent the identation spaces to use in the representation.
8016 ///
8017 ///@param one_line if true, then the flat representation stands on one
8018 ///line. Otherwise, it stands on multiple lines.
8019 ///
8020 ///@return the resulting flat representation.
8021 string
get_class_or_union_flat_representation(const class_or_union * cou,const string & indent,bool one_line,bool internal,bool qualified_names)8022 get_class_or_union_flat_representation(const class_or_union* cou,
8023 const string& indent,
8024 bool one_line,
8025 bool internal,
8026 bool qualified_names)
8027 {
8028 if (cou)
8029 return get_class_or_union_flat_representation(*cou, indent, one_line,
8030 internal, qualified_names);
8031 return "";
8032 }
8033
8034 /// Get the flat representation of an instance of @ref class_or_union
8035 /// type.
8036 ///
8037 /// The flat representation of a given @ref class_or_union type is the
8038 /// actual definition of the type, for instance:
8039 ///
8040 /// struct foo {int a; char b;}
8041 ///
8042 ///@param cou the instance of @ref class_or_union to consider.
8043 ///
8044 ///@param indent the identation spaces to use in the representation.
8045 ///
8046 ///@param one_line if true, then the flat representation stands on one
8047 ///line. Otherwise, it stands on multiple lines.
8048 ///
8049 ///@return the resulting flat representation.
8050 string
get_class_or_union_flat_representation(const class_or_union_sptr & cou,const string & indent,bool one_line,bool internal,bool qualified_names)8051 get_class_or_union_flat_representation(const class_or_union_sptr& cou,
8052 const string& indent,
8053 bool one_line,
8054 bool internal,
8055 bool qualified_names)
8056 {return get_class_or_union_flat_representation(cou.get(),
8057 indent,
8058 one_line,
8059 internal,
8060 qualified_names);}
8061
8062 /// By looking at the language of the TU a given ABI artifact belongs
8063 /// to, test if the ONE Definition Rule should apply.
8064 ///
8065 /// To date, it applies to c++, java and ada.
8066 ///
8067 /// @param artifact the ABI artifact to consider.
8068 ///
8069 /// @return true iff the One Definition Rule should apply.
8070 bool
odr_is_relevant(const type_or_decl_base & artifact)8071 odr_is_relevant(const type_or_decl_base& artifact)
8072 {
8073 translation_unit::language l =
8074 artifact.get_translation_unit()->get_language();
8075
8076 if (is_cplus_plus_language(l)
8077 || is_java_language(l)
8078 || is_ada_language(l))
8079 return true;
8080
8081 return false;
8082 }
8083
8084 /// Get the declaration for a given type.
8085 ///
8086 /// @param t the type to consider.
8087 ///
8088 /// @return the declaration for the type to return.
8089 const decl_base*
get_type_declaration(const type_base * t)8090 get_type_declaration(const type_base* t)
8091 {return dynamic_cast<const decl_base*>(t);}
8092
8093 /// Get the declaration for a given type.
8094 ///
8095 /// @param t the type to consider.
8096 ///
8097 /// @return the declaration for the type to return.
8098 decl_base*
get_type_declaration(type_base * t)8099 get_type_declaration(type_base* t)
8100 {return dynamic_cast<decl_base*>(t);}
8101
8102 /// Get the declaration for a given type.
8103 ///
8104 /// @param t the type to consider.
8105 ///
8106 /// @return the declaration for the type to return.
8107 decl_base_sptr
get_type_declaration(const type_base_sptr t)8108 get_type_declaration(const type_base_sptr t)
8109 {return dynamic_pointer_cast<decl_base>(t);}
8110
8111 /// Test if two types are equal modulo a typedef.
8112 ///
8113 /// Type A and B are compatible if
8114 ///
8115 /// - A and B are equal
8116 /// - or if one type is a typedef of the other one.
8117 ///
8118 /// @param type1 the first type to consider.
8119 ///
8120 /// @param type2 the second type to consider.
8121 ///
8122 /// @return true iff @p type1 and @p type2 are compatible.
8123 bool
types_are_compatible(const type_base_sptr type1,const type_base_sptr type2)8124 types_are_compatible(const type_base_sptr type1,
8125 const type_base_sptr type2)
8126 {
8127 if (!type1 || !type2)
8128 return false;
8129
8130 if (type1 == type2)
8131 return true;
8132
8133 // Normally we should strip typedefs entirely, but this is
8134 // potentially costly, especially on binaries with huge changesets
8135 // like the Linux Kernel. So we just get the leaf types for now.
8136 //
8137 // Maybe there should be an option by which users accepts to pay the
8138 // CPU usage toll in exchange for finer filtering?
8139
8140 // type_base_sptr t1 = strip_typedef(type1);
8141 // type_base_sptr t2 = strip_typedef(type2);
8142
8143 type_base_sptr t1 = peel_typedef_type(type1);
8144 type_base_sptr t2 = peel_typedef_type(type2);
8145
8146 return t1 == t2;
8147 }
8148
8149 /// Test if two types are equal modulo a typedef.
8150 ///
8151 /// Type A and B are compatible if
8152 ///
8153 /// - A and B are equal
8154 /// - or if one type is a typedef of the other one.
8155 ///
8156 /// @param type1 the declaration of the first type to consider.
8157 ///
8158 /// @param type2 the declaration of the second type to consider.
8159 ///
8160 /// @return true iff @p type1 and @p type2 are compatible.
8161 bool
types_are_compatible(const decl_base_sptr d1,const decl_base_sptr d2)8162 types_are_compatible(const decl_base_sptr d1,
8163 const decl_base_sptr d2)
8164 {return types_are_compatible(is_type(d1), is_type(d2));}
8165
8166 /// Return the translation unit a declaration belongs to.
8167 ///
8168 /// @param decl the declaration to consider.
8169 ///
8170 /// @return the resulting translation unit, or null if the decl is not
8171 /// yet added to a translation unit.
8172 translation_unit*
get_translation_unit(const decl_base & decl)8173 get_translation_unit(const decl_base& decl)
8174 {return const_cast<translation_unit*>(decl.get_translation_unit());}
8175
8176 /// Return the translation unit a declaration belongs to.
8177 ///
8178 /// @param decl the declaration to consider.
8179 ///
8180 /// @return the resulting translation unit, or null if the decl is not
8181 /// yet added to a translation unit.
8182 translation_unit*
get_translation_unit(const decl_base * decl)8183 get_translation_unit(const decl_base* decl)
8184 {return decl ? get_translation_unit(*decl) : 0;}
8185
8186 /// Return the translation unit a declaration belongs to.
8187 ///
8188 /// @param decl the declaration to consider.
8189 ///
8190 /// @return the resulting translation unit, or null if the decl is not
8191 /// yet added to a translation unit.
8192 translation_unit*
get_translation_unit(const shared_ptr<decl_base> decl)8193 get_translation_unit(const shared_ptr<decl_base> decl)
8194 {return get_translation_unit(decl.get());}
8195
8196 /// Tests whether if a given scope is the global scope.
8197 ///
8198 /// @param scope the scope to consider.
8199 ///
8200 /// @return true iff the current scope is the global one.
8201 bool
is_global_scope(const scope_decl & scope)8202 is_global_scope(const scope_decl& scope)
8203 {return !!dynamic_cast<const global_scope*>(&scope);}
8204
8205 /// Tests whether if a given scope is the global scope.
8206 ///
8207 /// @param scope the scope to consider.
8208 ///
8209 /// @return the @ref global_scope* representing the scope @p scope or
8210 /// 0 if @p scope is not a global scope.
8211 const global_scope*
is_global_scope(const scope_decl * scope)8212 is_global_scope(const scope_decl* scope)
8213 {return dynamic_cast<const global_scope*>(scope);}
8214
8215 /// Tests whether if a given scope is the global scope.
8216 ///
8217 /// @param scope the scope to consider.
8218 ///
8219 /// @return true iff the current scope is the global one.
8220 bool
is_global_scope(const shared_ptr<scope_decl> scope)8221 is_global_scope(const shared_ptr<scope_decl>scope)
8222 {return is_global_scope(scope.get());}
8223
8224 /// Tests whether a given declaration is at global scope.
8225 ///
8226 /// @param decl the decl to consider.
8227 ///
8228 /// @return true iff decl is at global scope.
8229 bool
is_at_global_scope(const decl_base & decl)8230 is_at_global_scope(const decl_base& decl)
8231 {return (is_global_scope(decl.get_scope()));}
8232
8233 /// Tests whether a given declaration is at global scope.
8234 ///
8235 /// @param decl the decl to consider.
8236 ///
8237 /// @return true iff decl is at global scope.
8238 bool
is_at_global_scope(const decl_base_sptr decl)8239 is_at_global_scope(const decl_base_sptr decl)
8240 {return (decl && is_global_scope(decl->get_scope()));}
8241
8242 /// Tests whether a given decl is at class scope.
8243 ///
8244 /// @param decl the decl to consider.
8245 ///
8246 /// @return true iff decl is at class scope.
8247 class_or_union*
is_at_class_scope(const decl_base_sptr decl)8248 is_at_class_scope(const decl_base_sptr decl)
8249 {return is_at_class_scope(decl.get());}
8250
8251 /// Tests whether a given decl is at class scope.
8252 ///
8253 /// @param decl the decl to consider.
8254 ///
8255 /// @return true iff decl is at class scope.
8256 class_or_union*
is_at_class_scope(const decl_base * decl)8257 is_at_class_scope(const decl_base* decl)
8258 {
8259 if (!decl)
8260 return 0;
8261
8262 return is_at_class_scope(*decl);
8263 }
8264
8265 /// Tests whether a given decl is at class scope.
8266 ///
8267 /// @param decl the decl to consider.
8268 ///
8269 /// @return true iff decl is at class scope.
8270 class_or_union*
is_at_class_scope(const decl_base & decl)8271 is_at_class_scope(const decl_base& decl)
8272 {
8273 scope_decl* scope = decl.get_scope();
8274 if (class_or_union* cl = is_class_type(scope))
8275 return cl;
8276 if (class_or_union* cl = is_union_type(scope))
8277 return cl;
8278 return 0;
8279 }
8280
8281 /// Find a data member inside an anonymous data member.
8282 ///
8283 /// An anonymous data member has a type which is a class or union.
8284 /// This function looks for a data member inside the type of that
8285 /// anonymous data member.
8286 ///
8287 /// @param anon_dm the anonymous data member to consider.
8288 ///
8289 /// @param name the name of the data member to look for.
8290 var_decl_sptr
find_data_member_from_anonymous_data_member(const var_decl_sptr & anon_dm,const string & name)8291 find_data_member_from_anonymous_data_member(const var_decl_sptr& anon_dm,
8292 const string& name)
8293 {
8294 const class_or_union* containing_class_or_union =
8295 anonymous_data_member_to_class_or_union(anon_dm.get());
8296
8297 if (!containing_class_or_union)
8298 return var_decl_sptr();
8299
8300 var_decl_sptr result = containing_class_or_union->find_data_member(name);
8301 return result;
8302 }
8303
8304 /// Tests whether a given decl is at template scope.
8305 ///
8306 /// Note that only template parameters , types that are compositions,
8307 /// and template patterns (function or class) can be at template scope.
8308 ///
8309 /// @param decl the decl to consider.
8310 ///
8311 /// @return true iff the decl is at template scope.
8312 bool
is_at_template_scope(const shared_ptr<decl_base> decl)8313 is_at_template_scope(const shared_ptr<decl_base> decl)
8314 {return (decl && dynamic_cast<template_decl*>(decl->get_scope()));}
8315
8316 /// Tests whether a decl is a template parameter.
8317 ///
8318 /// @param decl the decl to consider.
8319 ///
8320 /// @return true iff decl is a template parameter.
8321 bool
is_template_parameter(const shared_ptr<decl_base> decl)8322 is_template_parameter(const shared_ptr<decl_base> decl)
8323 {
8324 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
8325 || dynamic_pointer_cast<non_type_tparameter>(decl)
8326 || dynamic_pointer_cast<template_tparameter>(decl)));
8327 }
8328
8329 /// Test whether a declaration is a @ref function_decl.
8330 ///
8331 /// @param d the declaration to test for.
8332 ///
8333 /// @return a shared pointer to @ref function_decl if @p d is a @ref
8334 /// function_decl. Otherwise, a nil shared pointer.
8335 function_decl*
is_function_decl(const type_or_decl_base * d)8336 is_function_decl(const type_or_decl_base* d)
8337 {return dynamic_cast<function_decl*>(const_cast<type_or_decl_base*>(d));}
8338
8339 /// Test whether a declaration is a @ref function_decl.
8340 ///
8341 /// @param d the declaration to test for.
8342 ///
8343 /// @return true if @p d is a function_decl.
8344 bool
is_function_decl(const type_or_decl_base & d)8345 is_function_decl(const type_or_decl_base& d)
8346 {return is_function_decl(&d);}
8347
8348 /// Test whether a declaration is a @ref function_decl.
8349 ///
8350 /// @param d the declaration to test for.
8351 ///
8352 /// @return a shared pointer to @ref function_decl if @p d is a @ref
8353 /// function_decl. Otherwise, a nil shared pointer.
8354 function_decl_sptr
is_function_decl(const type_or_decl_base_sptr & d)8355 is_function_decl(const type_or_decl_base_sptr& d)
8356 {return dynamic_pointer_cast<function_decl>(d);}
8357
8358 /// Test whether a declaration is a @ref function_decl.
8359 ///
8360 /// @param d the declaration to test for.
8361 ///
8362 /// @return a pointer to @ref function_decl if @p d is a @ref
8363 /// function_decl. Otherwise, a nil shared pointer.
8364 function_decl::parameter*
is_function_parameter(const type_or_decl_base * tod)8365 is_function_parameter(const type_or_decl_base* tod)
8366 {
8367 return dynamic_cast<function_decl::parameter*>
8368 (const_cast<type_or_decl_base*>(tod));
8369 }
8370
8371 /// Test whether an ABI artifact is a @ref function_decl.
8372 ///
8373 /// @param tod the declaration to test for.
8374 ///
8375 /// @return a pointer to @ref function_decl if @p d is a @ref
8376 /// function_decl. Otherwise, a nil shared pointer.
8377 function_decl::parameter_sptr
is_function_parameter(const type_or_decl_base_sptr tod)8378 is_function_parameter(const type_or_decl_base_sptr tod)
8379 {return dynamic_pointer_cast<function_decl::parameter>(tod);}
8380
8381 /// Test if an ABI artifact is a declaration.
8382 ///
8383 /// @param d the artifact to consider.
8384 ///
8385 /// @param return the declaration sub-object of @p d if it's a
8386 /// declaration, or NULL if it is not.
8387 decl_base*
is_decl(const type_or_decl_base * d)8388 is_decl(const type_or_decl_base* d)
8389 {
8390 if (d && (d->kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
8391 {
8392 if (!(d->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
8393 // The artifact is a decl-only (like a function or a
8394 // variable). That is, it's not a type that also has a
8395 // declaration. In this case, we are in the fast path and we
8396 // have a pointer to the decl sub-object handy. Just return
8397 // it ...
8398 return reinterpret_cast<decl_base*>
8399 (const_cast<type_or_decl_base*>(d)->type_or_decl_base_pointer());
8400
8401 // ... Otherwise, we are in the slow path, which is that the
8402 // artifact is a type which has a declaration. In that case,
8403 // let's use the slow dynamic_cast because we don't have the
8404 // pointer to the decl sub-object handily present.
8405 return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(d));
8406 }
8407 return 0;
8408 }
8409
8410 /// Test if an ABI artifact is a declaration.
8411 ///
8412 /// @param d the artifact to consider.
8413 ///
8414 /// @param return the declaration sub-object of @p d if it's a
8415 /// declaration, or NULL if it is not.
8416 decl_base_sptr
is_decl(const type_or_decl_base_sptr & d)8417 is_decl(const type_or_decl_base_sptr& d)
8418 {return dynamic_pointer_cast<decl_base>(d);}
8419
8420 /// Test if an ABI artifact is a declaration.
8421 ///
8422 /// This is done using a slow path that uses dynamic_cast.
8423 ///
8424 /// @param d the artifact to consider.
8425 ///
8426 /// @param return the declaration sub-object of @p d if it's a
8427 decl_base*
is_decl_slow(const type_or_decl_base * t)8428 is_decl_slow(const type_or_decl_base* t)
8429 {return dynamic_cast<decl_base*>(const_cast<type_or_decl_base*>(t));}
8430
8431 /// Test if an ABI artifact is a declaration.
8432 ///
8433 /// This is done using a slow path that uses dynamic_cast.
8434 ///
8435 /// @param d the artifact to consider.
8436 ///
8437 /// @param return the declaration sub-object of @p d if it's a
8438 decl_base_sptr
is_decl_slow(const type_or_decl_base_sptr & t)8439 is_decl_slow(const type_or_decl_base_sptr& t)
8440 {return dynamic_pointer_cast<decl_base>(t);}
8441
8442 /// Test whether a declaration is a type.
8443 ///
8444 /// @param d the IR artefact to test for.
8445 ///
8446 /// @return true if the artifact is a type, false otherwise.
8447 bool
is_type(const type_or_decl_base & tod)8448 is_type(const type_or_decl_base& tod)
8449 {
8450 if (dynamic_cast<const type_base*>(&tod))
8451 return true;
8452 return false;
8453 }
8454
8455 /// Test whether a declaration is a type.
8456 ///
8457 /// @param d the IR artefact to test for.
8458 ///
8459 /// @return true if the artifact is a type, false otherwise.
8460 type_base*
is_type(const type_or_decl_base * t)8461 is_type(const type_or_decl_base* t)
8462 {
8463 if (t && (t->kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
8464 return reinterpret_cast<type_base*>
8465 (const_cast<type_or_decl_base*>(t)->type_or_decl_base_pointer());
8466
8467 return 0;
8468 }
8469
8470 /// Test whether a declaration is a type.
8471 ///
8472 /// @param d the IR artefact to test for.
8473 ///
8474 /// @return true if the artifact is a type, false otherwise.
8475 type_base_sptr
is_type(const type_or_decl_base_sptr & tod)8476 is_type(const type_or_decl_base_sptr& tod)
8477 {return dynamic_pointer_cast<type_base>(tod);}
8478
8479 /// Test whether a declaration is a type.
8480 ///
8481 /// @param d the declaration to test for.
8482 ///
8483 /// @return true if the declaration is a type, false otherwise.
8484
8485 /// Test if a given type is anonymous.
8486 ///
8487 /// Note that this function considers that an anonymous class that is
8488 /// named by a typedef is not anonymous anymore. This is the C idiom:
8489 ///
8490 /// typedef struct {int member;} s_type;
8491 ///
8492 /// The typedef s_type becomes the name of the originally anonymous
8493 /// struct.
8494 ///
8495 /// @param t the type to consider.
8496 ///
8497 /// @return true iff @p t is anonymous.
8498 bool
is_anonymous_type(type_base * t)8499 is_anonymous_type(type_base* t)
8500 {
8501 decl_base* d = get_type_declaration(t);
8502 if (d)
8503 if (d->get_is_anonymous())
8504 {
8505 if (class_or_union *cou = is_class_or_union_type(t))
8506 {
8507 // An anonymous class that is named by a typedef is not
8508 // considered anonymous anymore.
8509 if (!cou->get_naming_typedef())
8510 return true;
8511 }
8512 else
8513 return true;
8514 }
8515 return false;
8516 }
8517
8518 /// Test if a given type is anonymous.
8519 ///
8520 /// @param t the type to consider.
8521 ///
8522 /// @return true iff @p t is anonymous.
8523 bool
is_anonymous_type(const type_base_sptr & t)8524 is_anonymous_type(const type_base_sptr& t)
8525 {return is_anonymous_type(t.get());}
8526
8527 /// Test whether a type is a type_decl (a builtin type).
8528 ///
8529 /// @return the type_decl* for @t if it's type_decl, otherwise, return
8530 /// nil.
8531 const type_decl*
is_type_decl(const type_or_decl_base * t)8532 is_type_decl(const type_or_decl_base* t)
8533 {return dynamic_cast<const type_decl*>(t);}
8534
8535 /// Test whether a type is a type_decl (a builtin type).
8536 ///
8537 /// @return the type_decl_sptr for @t if it's type_decl, otherwise,
8538 /// return nil.
8539 type_decl_sptr
is_type_decl(const type_or_decl_base_sptr & t)8540 is_type_decl(const type_or_decl_base_sptr& t)
8541 {return dynamic_pointer_cast<type_decl>(t);}
8542
8543 /// Test whether a type is a typedef.
8544 ///
8545 /// @param t the type to test for.
8546 ///
8547 /// @return the typedef declaration of the @p t, or NULL if it's not a
8548 /// typedef.
8549 typedef_decl_sptr
is_typedef(const type_or_decl_base_sptr t)8550 is_typedef(const type_or_decl_base_sptr t)
8551 {return dynamic_pointer_cast<typedef_decl>(t);}
8552
8553 /// Test whether a type is a typedef.
8554 ///
8555 /// @param t the declaration of the type to test for.
8556 ///
8557 /// @return the typedef declaration of the @p t, or NULL if it's not a
8558 /// typedef.
8559 const typedef_decl*
is_typedef(const type_base * t)8560 is_typedef(const type_base* t)
8561 {return dynamic_cast<const typedef_decl*>(t);}
8562
8563 /// Test whether a type is a typedef.
8564 ///
8565 /// @param t the declaration of the type to test for.
8566 ///
8567 /// @return the typedef declaration of the @p t, or NULL if it's not a
8568 /// typedef.
8569 typedef_decl*
is_typedef(type_base * t)8570 is_typedef(type_base* t)
8571 {return dynamic_cast<typedef_decl*>(t);}
8572
8573 /// Test if a type is an enum. This function looks through typedefs.
8574 ///
8575 /// @parm t the type to consider.
8576 ///
8577 /// @return the enum_decl if @p t is an @ref enum_decl or null
8578 /// otherwise.
8579 enum_type_decl_sptr
is_compatible_with_enum_type(const type_base_sptr & t)8580 is_compatible_with_enum_type(const type_base_sptr& t)
8581 {
8582 if (!t)
8583 return enum_type_decl_sptr();
8584
8585 // Normally we should strip typedefs entirely, but this is
8586 // potentially costly, especially on binaries with huge changesets
8587 // like the Linux Kernel. So we just get the leaf types for now.
8588 //
8589 // Maybe there should be an option by which users accepts to pay the
8590 // CPU usage toll in exchange for finer filtering?
8591
8592 // type_base_sptr ty = strip_typedef(t);
8593 type_base_sptr ty = peel_typedef_type(t);;
8594 return is_enum_type(ty);
8595 }
8596
8597 /// Test if a type is an enum. This function looks through typedefs.
8598 ///
8599 /// @parm t the type to consider.
8600 ///
8601 /// @return the enum_decl if @p t is an @ref enum_decl or null
8602 /// otherwise.
8603 enum_type_decl_sptr
is_compatible_with_enum_type(const decl_base_sptr & t)8604 is_compatible_with_enum_type(const decl_base_sptr& t)
8605 {return is_compatible_with_enum_type(is_type(t));}
8606
8607 /// Test if a decl is an enum_type_decl
8608 ///
8609 /// @param d the decl to test for.
8610 ///
8611 /// @return the enum_type_decl* if @p d is an enum, nil otherwise.
8612 const enum_type_decl*
is_enum_type(const type_or_decl_base * d)8613 is_enum_type(const type_or_decl_base* d)
8614 {return dynamic_cast<const enum_type_decl*>(d);}
8615
8616 /// Test if a decl is an enum_type_decl
8617 ///
8618 /// @param d the decl to test for.
8619 ///
8620 /// @return the enum_type_decl_sptr if @p d is an enum, nil otherwise.
8621 enum_type_decl_sptr
is_enum_type(const type_or_decl_base_sptr & d)8622 is_enum_type(const type_or_decl_base_sptr& d)
8623 {return dynamic_pointer_cast<enum_type_decl>(d);}
8624
8625 /// Test if a type is a class. This function looks through typedefs.
8626 ///
8627 /// @parm t the type to consider.
8628 ///
8629 /// @return the class_decl if @p t is a class_decl or null otherwise.
8630 class_decl_sptr
is_compatible_with_class_type(const type_base_sptr & t)8631 is_compatible_with_class_type(const type_base_sptr& t)
8632 {
8633 if (!t)
8634 return class_decl_sptr();
8635
8636 // Normally we should strip typedefs entirely, but this is
8637 // potentially costly, especially on binaries with huge changesets
8638 // like the Linux Kernel. So we just get the leaf types for now.
8639 //
8640 // Maybe there should be an option by which users accepts to pay the
8641 // CPU usage toll in exchange for finer filtering?
8642
8643 // type_base_sptr ty = strip_typedef(t);
8644 type_base_sptr ty = peel_typedef_type(t);
8645 return is_class_type(ty);
8646 }
8647
8648 /// Test if a type is a class. This function looks through typedefs.
8649 ///
8650 /// @parm t the type to consider.
8651 ///
8652 /// @return the class_decl if @p t is a class_decl or null otherwise.
8653 class_decl_sptr
is_compatible_with_class_type(const decl_base_sptr & t)8654 is_compatible_with_class_type(const decl_base_sptr& t)
8655 {return is_compatible_with_class_type(is_type(t));}
8656
8657 /// Test whether a type is a class.
8658 ///
8659 /// @parm t the type to consider.
8660 ///
8661 /// @return true iff @p t is a class_decl.
8662 bool
is_class_type(const type_or_decl_base & t)8663 is_class_type(const type_or_decl_base& t)
8664 {return is_class_type(&t);}
8665
8666 /// Test whether a type is a class.
8667 ///
8668 /// @parm t the type to consider.
8669 ///
8670 /// @return the class_decl if @p t is a class_decl or null otherwise.
8671 class_decl*
is_class_type(const type_or_decl_base * t)8672 is_class_type(const type_or_decl_base* t)
8673 {
8674 if (!t)
8675 return 0;
8676
8677 if (t->kind() & type_or_decl_base::CLASS_TYPE)
8678 return reinterpret_cast<class_decl*>
8679 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
8680
8681 return 0;
8682 }
8683
8684 /// Test whether a type is a class.
8685 ///
8686 /// @parm t the type to consider.
8687 ///
8688 /// @return the class_decl if @p t is a class_decl or null otherwise.
8689 class_decl_sptr
is_class_type(const type_or_decl_base_sptr & d)8690 is_class_type(const type_or_decl_base_sptr& d)
8691 {return dynamic_pointer_cast<class_decl>(d);}
8692
8693
8694 /// Test wheter a type is a declaration-only class.
8695 ///
8696 /// @param t the type to considier.
8697 ///
8698 /// @return true iff @p t is a declaration-only class.
8699 bool
is_declaration_only_class_or_union_type(const type_base * t)8700 is_declaration_only_class_or_union_type(const type_base *t)
8701 {
8702 if (const class_or_union *klass = is_class_or_union_type(t))
8703 return klass->get_is_declaration_only();
8704 return false;
8705 }
8706
8707 /// Test wheter a type is a declaration-only class.
8708 ///
8709 /// @param t the type to considier.
8710 ///
8711 /// @return true iff @p t is a declaration-only class.
8712 bool
is_declaration_only_class_type(const type_base_sptr & t)8713 is_declaration_only_class_type(const type_base_sptr& t)
8714 {return is_declaration_only_class_or_union_type(t.get());}
8715
8716 /// Test if a type is a @ref class_or_union.
8717 ///
8718 /// @param t the type to consider.
8719 ///
8720 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
8721 /// nil otherwise.
8722 class_or_union*
is_class_or_union_type(const type_or_decl_base * t)8723 is_class_or_union_type(const type_or_decl_base* t)
8724 {return dynamic_cast<class_or_union*>(const_cast<type_or_decl_base*>(t));}
8725
8726 /// Test if a type is a @ref class_or_union.
8727 ///
8728 /// @param t the type to consider.
8729 ///
8730 /// @return the @ref class_or_union is @p is a @ref class_or_union, or
8731 /// nil otherwise.
8732 shared_ptr<class_or_union>
is_class_or_union_type(const shared_ptr<type_or_decl_base> & t)8733 is_class_or_union_type(const shared_ptr<type_or_decl_base>& t)
8734 {return dynamic_pointer_cast<class_or_union>(t);}
8735
8736 /// Test if a type is a @ref union_decl.
8737 ///
8738 /// @param t the type to consider.
8739 ///
8740 /// @return true iff @p t is a union_decl.
8741 bool
is_union_type(const type_or_decl_base & t)8742 is_union_type(const type_or_decl_base& t)
8743 {return is_union_type(&t);}
8744
8745 /// Test if a type is a @ref union_decl.
8746 ///
8747 /// @param t the type to consider.
8748 ///
8749 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
8750 /// otherwise.
8751 union_decl*
is_union_type(const type_or_decl_base * t)8752 is_union_type(const type_or_decl_base* t)
8753 {return dynamic_cast<union_decl*>(const_cast<type_or_decl_base*>(t));}
8754
8755 /// Test if a type is a @ref union_decl.
8756 ///
8757 /// @param t the type to consider.
8758 ///
8759 /// @return the @ref union_decl is @p is a @ref union_decl, or nil
8760 /// otherwise.
8761 union_decl_sptr
is_union_type(const shared_ptr<type_or_decl_base> & t)8762 is_union_type(const shared_ptr<type_or_decl_base>& t)
8763 {return dynamic_pointer_cast<union_decl>(t);}
8764
8765 /// Test whether a type is a pointer_type_def.
8766 ///
8767 /// @param t the type to test.
8768 ///
8769 /// @return the @ref pointer_type_def_sptr if @p t is a
8770 /// pointer_type_def, null otherwise.
8771 pointer_type_def*
is_pointer_type(type_or_decl_base * t)8772 is_pointer_type(type_or_decl_base* t)
8773 {
8774 if (!t)
8775 return 0;
8776
8777 if (t->kind() & type_or_decl_base::POINTER_TYPE)
8778 return reinterpret_cast<pointer_type_def*>
8779 (const_cast<type_or_decl_base*>(t)->runtime_type_instance());
8780
8781 return 0;
8782 }
8783
8784 /// Test whether a type is a pointer_type_def.
8785 ///
8786 /// @param t the type to test.
8787 ///
8788 /// @return the @ref pointer_type_def_sptr if @p t is a
8789 /// pointer_type_def, null otherwise.
8790 const pointer_type_def*
is_pointer_type(const type_or_decl_base * t)8791 is_pointer_type(const type_or_decl_base* t)
8792 {
8793 return is_pointer_type(const_cast<type_or_decl_base*>(t));
8794 }
8795
8796 /// Test whether a type is a pointer_type_def.
8797 ///
8798 /// @param t the type to test.
8799 ///
8800 /// @return the @ref pointer_type_def_sptr if @p t is a
8801 /// pointer_type_def, null otherwise.
8802 pointer_type_def_sptr
is_pointer_type(const type_or_decl_base_sptr & t)8803 is_pointer_type(const type_or_decl_base_sptr &t)
8804 {return dynamic_pointer_cast<pointer_type_def>(t);}
8805
8806 /// Test whether a type is a reference_type_def.
8807 ///
8808 /// @param t the type to test.
8809 ///
8810 /// @return the @ref reference_type_def_sptr if @p t is a
8811 /// reference_type_def, null otherwise.
8812 reference_type_def*
is_reference_type(type_or_decl_base * t)8813 is_reference_type(type_or_decl_base* t)
8814 {return dynamic_cast<reference_type_def*>(t);}
8815
8816 /// Test whether a type is a reference_type_def.
8817 ///
8818 /// @param t the type to test.
8819 ///
8820 /// @return the @ref reference_type_def_sptr if @p t is a
8821 /// reference_type_def, null otherwise.
8822 const reference_type_def*
is_reference_type(const type_or_decl_base * t)8823 is_reference_type(const type_or_decl_base* t)
8824 {return dynamic_cast<const reference_type_def*>(t);}
8825
8826 /// Test whether a type is a reference_type_def.
8827 ///
8828 /// @param t the type to test.
8829 ///
8830 /// @return the @ref reference_type_def_sptr if @p t is a
8831 /// reference_type_def, null otherwise.
8832 reference_type_def_sptr
is_reference_type(const type_or_decl_base_sptr & t)8833 is_reference_type(const type_or_decl_base_sptr& t)
8834 {return dynamic_pointer_cast<reference_type_def>(t);}
8835
8836 /// Test if a type is a pointer to void type.
8837 ///
8838 /// Note that this looks trough typedefs or CV qualifiers to look for
8839 /// the void pointer.
8840 ///
8841 /// @param type the type to consider.
8842 ///
8843 /// @return the actual void pointer if @p is a void pointer or NULL if
8844 /// it's not.
8845 const type_base*
is_void_pointer_type(const type_base * type)8846 is_void_pointer_type(const type_base* type)
8847 {
8848 type = peel_qualified_or_typedef_type(type);
8849
8850 const pointer_type_def * t = is_pointer_type(type);
8851 if (!t)
8852 return 0;
8853
8854 // Look through typedefs in the pointed-to type as well.
8855 type_base * ty = t->get_pointed_to_type().get();
8856 ty = peel_qualified_or_typedef_type(ty);
8857 if (ty->get_environment()->is_void_type(ty))
8858 return ty;
8859
8860 return 0;
8861 }
8862
8863 /// Test whether a type is a reference_type_def.
8864 ///
8865 /// @param t the type to test.
8866 ///
8867 /// @return the @ref reference_type_def_sptr if @p t is a
8868 /// reference_type_def, null otherwise.
8869 qualified_type_def*
is_qualified_type(const type_or_decl_base * t)8870 is_qualified_type(const type_or_decl_base* t)
8871 {return dynamic_cast<qualified_type_def*>(const_cast<type_or_decl_base*>(t));}
8872
8873 /// Test whether a type is a qualified_type_def.
8874 ///
8875 /// @param t the type to test.
8876 ///
8877 /// @return the @ref qualified_type_def_sptr if @p t is a
8878 /// qualified_type_def, null otherwise.
8879 qualified_type_def_sptr
is_qualified_type(const type_or_decl_base_sptr & t)8880 is_qualified_type(const type_or_decl_base_sptr& t)
8881 {return dynamic_pointer_cast<qualified_type_def>(t);}
8882
8883 /// Strip a type from its top level no-op qualifier.
8884 ///
8885 /// Note that a no-op qualifier is how we represents, for instance, a
8886 /// "const reference". As a reference is always const, that const
8887 /// qualifier just adds noise in terms of change analysis. Se we
8888 /// represent it as a no-op qualifier so that we can strip it.
8889 ///
8890 /// @param t to type to strip from its potential top-level no-op
8891 /// qualifier.
8892 ///
8893 /// @return If @t is a no-op qualified type, then return the first
8894 /// underlying type that is not a no-op qualified type.
8895 type_base_sptr
look_through_no_op_qualified_type(const type_base_sptr & t)8896 look_through_no_op_qualified_type(const type_base_sptr& t)
8897 {
8898 type_base_sptr ty;
8899 if (qualified_type_def_sptr qt = is_qualified_type(t))
8900 if (qt->get_cv_quals() == qualified_type_def::CV_NONE)
8901 ty = qt->get_underlying_type();
8902
8903 if (is_qualified_type(ty))
8904 return look_through_no_op_qualified_type(ty);
8905
8906 return ty ? ty : t;
8907 }
8908
8909 /// Test whether a type is a function_type.
8910 ///
8911 /// @param t the type to test.
8912 ///
8913 /// @return the @ref function_type_sptr if @p t is a
8914 /// function_type, null otherwise.
8915 function_type_sptr
is_function_type(const type_or_decl_base_sptr & t)8916 is_function_type(const type_or_decl_base_sptr& t)
8917 {return dynamic_pointer_cast<function_type>(t);}
8918
8919 /// Test whether a type is a function_type.
8920 ///
8921 /// @param t the type to test.
8922 ///
8923 /// @return the @ref function_type_sptr if @p t is a
8924 /// function_type, null otherwise.
8925 function_type*
is_function_type(type_or_decl_base * t)8926 is_function_type(type_or_decl_base* t)
8927 {return dynamic_cast<function_type*>(t);}
8928
8929 /// Test whether a type is a function_type.
8930 ///
8931 /// @param t the type to test.
8932 ///
8933 /// @return the @ref function_type_sptr if @p t is a
8934 /// function_type, null otherwise.
8935 const function_type*
is_function_type(const type_or_decl_base * t)8936 is_function_type(const type_or_decl_base* t)
8937 {return dynamic_cast<const function_type*>(t);}
8938
8939 /// Test whether a type is a method_type.
8940 ///
8941 /// @param t the type to test.
8942 ///
8943 /// @return the @ref method_type_sptr if @p t is a
8944 /// method_type, null otherwise.
8945 method_type_sptr
is_method_type(const type_or_decl_base_sptr & t)8946 is_method_type(const type_or_decl_base_sptr& t)
8947 {return dynamic_pointer_cast<method_type>(t);}
8948
8949 /// Test whether a type is a method_type.
8950 ///
8951 /// @param t the type to test.
8952 ///
8953 /// @return the @ref method_type_sptr if @p t is a
8954 /// method_type, null otherwise.
8955 const method_type*
is_method_type(const type_or_decl_base * t)8956 is_method_type(const type_or_decl_base* t)
8957 {return dynamic_cast<const method_type*>(t);}
8958
8959 /// Test whether a type is a method_type.
8960 ///
8961 /// @param t the type to test.
8962 ///
8963 /// @return the @ref method_type_sptr if @p t is a
8964 /// method_type, null otherwise.
8965 method_type*
is_method_type(type_or_decl_base * t)8966 is_method_type(type_or_decl_base* t)
8967 {return dynamic_cast<method_type*>(t);}
8968
8969 /// If a class (or union) is a decl-only class, get its definition.
8970 /// Otherwise, just return the initial class.
8971 ///
8972 /// @param the_class the class (or union) to consider.
8973 ///
8974 /// @return either the definition of the class, or the class itself.
8975 class_or_union*
look_through_decl_only_class(class_or_union * the_class)8976 look_through_decl_only_class(class_or_union* the_class)
8977 {return is_class_or_union_type(look_through_decl_only(the_class));}
8978
8979 /// If a class (or union) is a decl-only class, get its definition.
8980 /// Otherwise, just return the initial class.
8981 ///
8982 /// @param the_class the class (or union) to consider.
8983 ///
8984 /// @return either the definition of the class, or the class itself.
8985 class_or_union_sptr
look_through_decl_only_class(const class_or_union & the_class)8986 look_through_decl_only_class(const class_or_union& the_class)
8987 {return is_class_or_union_type(look_through_decl_only(the_class));}
8988
8989 /// If a class (or union) is a decl-only class, get its definition.
8990 /// Otherwise, just return the initial class.
8991 ///
8992 /// @param klass the class (or union) to consider.
8993 ///
8994 /// @return either the definition of the class, or the class itself.
8995 class_or_union_sptr
look_through_decl_only_class(class_or_union_sptr klass)8996 look_through_decl_only_class(class_or_union_sptr klass)
8997 {return is_class_or_union_type(look_through_decl_only(klass));}
8998
8999 /// If an enum is a decl-only enum, get its definition.
9000 /// Otherwise, just return the initial enum.
9001 ///
9002 /// @param the_enum the enum to consider.
9003 ///
9004 /// @return either the definition of the enum, or the enum itself.
9005 enum_type_decl_sptr
look_through_decl_only_enum(const enum_type_decl & the_enum)9006 look_through_decl_only_enum(const enum_type_decl& the_enum)
9007 {return is_enum_type(look_through_decl_only(the_enum));}
9008
9009 /// If an enum is a decl-only enum, get its definition.
9010 /// Otherwise, just return the initial enum.
9011 ///
9012 /// @param enom the enum to consider.
9013 ///
9014 /// @return either the definition of the enum, or the enum itself.
9015 enum_type_decl_sptr
look_through_decl_only_enum(enum_type_decl_sptr enom)9016 look_through_decl_only_enum(enum_type_decl_sptr enom)
9017 {return is_enum_type(look_through_decl_only(enom));}
9018
9019 /// If a decl is decl-only get its definition. Otherwise, just return nil.
9020 ///
9021 /// @param d the decl to consider.
9022 ///
9023 /// @return either the definition of the decl, or nil.
9024 decl_base_sptr
look_through_decl_only(const decl_base & d)9025 look_through_decl_only(const decl_base& d)
9026 {
9027 decl_base_sptr decl;
9028 if (d.get_is_declaration_only())
9029 decl = d.get_definition_of_declaration();
9030
9031 if (!decl)
9032 return decl;
9033
9034 while (decl->get_is_declaration_only()
9035 && decl->get_definition_of_declaration())
9036 decl = decl->get_definition_of_declaration();
9037
9038 return decl;
9039 }
9040
9041 /// If a decl is decl-only enum, get its definition. Otherwise, just
9042 /// return the initial decl.
9043 ///
9044 /// @param d the decl to consider.
9045 ///
9046 /// @return either the definition of the enum, or the decl itself.
9047 decl_base*
look_through_decl_only(decl_base * d)9048 look_through_decl_only(decl_base* d)
9049 {
9050 if (!d)
9051 return d;
9052
9053 decl_base* result = look_through_decl_only(*d).get();
9054 if (!result)
9055 result = d;
9056
9057 return result;
9058 }
9059
9060 /// If a decl is decl-only get its definition. Otherwise, just return nil.
9061 ///
9062 /// @param d the decl to consider.
9063 ///
9064 /// @return either the definition of the decl, or nil.
9065 decl_base_sptr
look_through_decl_only(const decl_base_sptr & d)9066 look_through_decl_only(const decl_base_sptr& d)
9067 {
9068 if (!d)
9069 return d;
9070
9071 decl_base_sptr result = look_through_decl_only(*d);
9072 if (!result)
9073 result = d;
9074
9075 return result;
9076 }
9077
9078 /// Tests if a declaration is a variable declaration.
9079 ///
9080 /// @param decl the decl to test.
9081 ///
9082 /// @return the var_decl_sptr iff decl is a variable declaration; nil
9083 /// otherwise.
9084 var_decl*
is_var_decl(const type_or_decl_base * tod)9085 is_var_decl(const type_or_decl_base* tod)
9086 {return dynamic_cast<var_decl*>(const_cast<type_or_decl_base*>(tod));}
9087
9088 /// Tests if a declaration is a variable declaration.
9089 ///
9090 /// @param decl the decl to test.
9091 ///
9092 /// @return the var_decl_sptr iff decl is a variable declaration; nil
9093 /// otherwise.
9094 var_decl_sptr
is_var_decl(const type_or_decl_base_sptr & decl)9095 is_var_decl(const type_or_decl_base_sptr& decl)
9096 {return dynamic_pointer_cast<var_decl>(decl);}
9097
9098 /// Tests if a declaration is a namespace declaration.
9099 ///
9100 /// @param d the decalration to consider.
9101 ///
9102 /// @return the namespace declaration if @p d is a namespace.
9103 namespace_decl_sptr
is_namespace(const decl_base_sptr & d)9104 is_namespace(const decl_base_sptr& d)
9105 {return dynamic_pointer_cast<namespace_decl>(d);}
9106
9107 /// Tests if a declaration is a namespace declaration.
9108 ///
9109 /// @param d the decalration to consider.
9110 ///
9111 /// @return the namespace declaration if @p d is a namespace.
9112 namespace_decl*
is_namespace(const decl_base * d)9113 is_namespace(const decl_base* d)
9114 {return dynamic_cast<namespace_decl*>(const_cast<decl_base*>(d));}
9115
9116 /// Tests whether a decl is a template parameter composition type.
9117 ///
9118 /// @param decl the declaration to consider.
9119 ///
9120 /// @return true iff decl is a template parameter composition type.
9121 bool
is_template_parm_composition_type(const shared_ptr<decl_base> decl)9122 is_template_parm_composition_type(const shared_ptr<decl_base> decl)
9123 {
9124 return (decl
9125 && is_at_template_scope(decl)
9126 && is_type(decl)
9127 && !is_template_parameter(decl));
9128 }
9129
9130 /// Test whether a decl is the pattern of a function template.
9131 ///
9132 /// @param decl the decl to consider.
9133 ///
9134 /// @return true iff decl is the pattern of a function template.
9135 bool
is_function_template_pattern(const shared_ptr<decl_base> decl)9136 is_function_template_pattern(const shared_ptr<decl_base> decl)
9137 {
9138 return (decl
9139 && dynamic_pointer_cast<function_decl>(decl)
9140 && dynamic_cast<template_decl*>(decl->get_scope()));
9141 }
9142
9143 /// Test if a type is an array_type_def.
9144 ///
9145 /// @param type the type to consider.
9146 ///
9147 /// @return true iff @p type is an array_type_def.
9148 array_type_def*
is_array_type(const type_or_decl_base * type)9149 is_array_type(const type_or_decl_base* type)
9150 {return dynamic_cast<array_type_def*>(const_cast<type_or_decl_base*>(type));}
9151
9152 /// Test if a type is an array_type_def.
9153 ///
9154 /// @param type the type to consider.
9155 ///
9156 /// @return true iff @p type is an array_type_def.
9157 array_type_def_sptr
is_array_type(const type_or_decl_base_sptr & type)9158 is_array_type(const type_or_decl_base_sptr& type)
9159 {return dynamic_pointer_cast<array_type_def>(type);}
9160
9161 /// Tests if the element of a given array is a qualified type.
9162 ///
9163 /// @param array the array type to consider.
9164 ///
9165 /// @return the qualified element of the array iff it's a qualified
9166 /// type. Otherwise, return a nil object.
9167 qualified_type_def_sptr
is_array_of_qualified_element(const array_type_def_sptr & array)9168 is_array_of_qualified_element(const array_type_def_sptr& array)
9169 {
9170 if (!array)
9171 return qualified_type_def_sptr();
9172
9173 return is_qualified_type(array->get_element_type());
9174 }
9175
9176 /// Test if an array type is an array to a qualified element type.
9177 ///
9178 /// @param type the array type to consider.
9179 ///
9180 /// @return true the array @p type iff it's an array to a qualified
9181 /// element type.
9182 array_type_def_sptr
is_array_of_qualified_element(const type_base_sptr & type)9183 is_array_of_qualified_element(const type_base_sptr& type)
9184 {
9185 if (array_type_def_sptr array = is_array_type(type))
9186 if (is_array_of_qualified_element(array))
9187 return array;
9188
9189 return array_type_def_sptr();
9190 }
9191
9192 /// Test if a type is a typedef of an array.
9193 ///
9194 /// Note that the function looks through qualified and typedefs types
9195 /// of the underlying type of the current typedef. In other words, if
9196 /// we are looking at a typedef of a CV-qualified array, or at a
9197 /// typedef of a CV-qualified typedef of an array, this function will
9198 /// still return TRUE.
9199 ///
9200 /// @param t the type to consider.
9201 ///
9202 /// @return true if t is a typedef which underlying type is an array.
9203 /// That array might be either cv-qualified array or a typedef'ed
9204 /// array, or a combination of both.
9205 array_type_def_sptr
is_typedef_of_array(const type_base_sptr & t)9206 is_typedef_of_array(const type_base_sptr& t)
9207 {
9208 array_type_def_sptr result;
9209
9210 if (typedef_decl_sptr typdef = is_typedef(t))
9211 {
9212 type_base_sptr u =
9213 peel_qualified_or_typedef_type(typdef->get_underlying_type());
9214 result = is_array_type(u);
9215 }
9216
9217 return result;
9218 }
9219
9220 /// Test if a type is an array_type_def::subrange_type.
9221 ///
9222 /// @param type the type to consider.
9223 ///
9224 /// @return the array_type_def::subrange_type which @p type is a type
9225 /// of, or nil if it's not of that type.
9226 array_type_def::subrange_type*
is_subrange_type(const type_or_decl_base * type)9227 is_subrange_type(const type_or_decl_base *type)
9228 {
9229 return dynamic_cast<array_type_def::subrange_type*>
9230 (const_cast<type_or_decl_base*>(type));
9231 }
9232
9233 /// Test if a type is an array_type_def::subrange_type.
9234 ///
9235 /// @param type the type to consider.
9236 ///
9237 /// @return the array_type_def::subrange_type which @p type is a type
9238 /// of, or nil if it's not of that type.
9239 array_type_def::subrange_sptr
is_subrange_type(const type_or_decl_base_sptr & type)9240 is_subrange_type(const type_or_decl_base_sptr &type)
9241 {return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
9242
9243 /// Tests whether a decl is a template.
9244 ///
9245 /// @param decl the decl to consider.
9246 ///
9247 /// @return true iff decl is a function template, class template, or
9248 /// template template parameter.
9249 bool
is_template_decl(const shared_ptr<decl_base> decl)9250 is_template_decl(const shared_ptr<decl_base> decl)
9251 {return decl && dynamic_pointer_cast<template_decl>(decl);}
9252
9253 /// This enum describe the kind of entity to lookup, while using the
9254 /// lookup API.
9255 enum lookup_entity_kind
9256 {
9257 LOOKUP_ENTITY_TYPE,
9258 LOOKUP_ENTITY_VAR,
9259 };
9260
9261 /// Find the first relevant delimiter (the "::" string) in a fully
9262 /// qualified C++ type name, starting from a given position. The
9263 /// delimiter returned separates a type name from the name of its
9264 /// context.
9265 ///
9266 /// This is supposed to work correctly on names in cases like this:
9267 ///
9268 /// foo<ns1::name1, ns2::name2>
9269 ///
9270 /// In that case when called with with parameter @p begin set to 0, no
9271 /// delimiter is returned, because the type name in this case is:
9272 /// 'foo<ns1::name1, ns2::name2>'.
9273 ///
9274 /// But in this case:
9275 ///
9276 /// foo<p1, bar::name>::some_type
9277 ///
9278 /// The "::" returned is the one right before 'some_type'.
9279 ///
9280 /// @param fqn the fully qualified name of the type to consider.
9281 ///
9282 /// @param begin the position from which to look for the delimiter.
9283 ///
9284 /// @param delim_pos out parameter. Is set to the position of the
9285 /// delimiter iff the function returned true.
9286 ///
9287 /// @return true iff the function found and returned the delimiter.
9288 static bool
find_next_delim_in_cplus_type(const string & fqn,size_t begin,size_t & delim_pos)9289 find_next_delim_in_cplus_type(const string& fqn,
9290 size_t begin,
9291 size_t& delim_pos)
9292 {
9293 int angle_count = 0;
9294 bool found = false;
9295 size_t i = begin;
9296 for (; i < fqn.size(); ++i)
9297 {
9298 if (fqn[i] == '<')
9299 ++angle_count;
9300 else if (fqn[i] == '>')
9301 --angle_count;
9302 else if (i + 1 < fqn.size()
9303 && !angle_count
9304 && fqn[i] == ':'
9305 && fqn[i+1] == ':')
9306 {
9307 delim_pos = i;
9308 found = true;
9309 break;
9310 }
9311 }
9312 return found;
9313 }
9314
9315 /// Decompose a fully qualified name into the list of its components.
9316 ///
9317 /// @param fqn the fully qualified name to decompose.
9318 ///
9319 /// @param comps the resulting list of component to fill.
9320 void
fqn_to_components(const string & fqn,list<string> & comps)9321 fqn_to_components(const string& fqn,
9322 list<string>& comps)
9323 {
9324 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
9325 do
9326 {
9327 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
9328 comp_end = fqn_size;
9329
9330 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
9331 comps.push_back(comp);
9332
9333 comp_begin = comp_end + 2;
9334 if (comp_begin >= fqn_size)
9335 break;
9336 } while (true);
9337 }
9338
9339 /// Turn a set of qualified name components (that name a type) into a
9340 /// qualified name string.
9341 ///
9342 /// @param comps the name components
9343 ///
9344 /// @return the resulting string, which would be the qualified name of
9345 /// a type.
9346 string
components_to_type_name(const list<string> & comps)9347 components_to_type_name(const list<string>& comps)
9348 {
9349 string result;
9350 for (list<string>::const_iterator c = comps.begin();
9351 c != comps.end();
9352 ++c)
9353 if (c == comps.begin())
9354 result = *c;
9355 else
9356 result += "::" + *c;
9357 return result;
9358 }
9359
9360 /// This predicate returns true if a given container iterator points
9361 /// to the last element of the container, false otherwise.
9362 ///
9363 /// @tparam T the type of the container of the iterator.
9364 ///
9365 /// @param container the container the iterator points into.
9366 ///
9367 /// @param i the iterator to consider.
9368 ///
9369 /// @return true iff the iterator points to the last element of @p
9370 /// container.
9371 template<typename T>
9372 static bool
iterator_is_last(T & container,typename T::const_iterator i)9373 iterator_is_last(T& container,
9374 typename T::const_iterator i)
9375 {
9376 typename T::const_iterator next = i;
9377 ++next;
9378 return (next == container.end());
9379 }
9380
9381 //--------------------------------
9382 // <type and decls lookup stuff>
9383 // ------------------------------
9384
9385 /// Lookup all the type*s* that have a given fully qualified name.
9386 ///
9387 /// @param type_name the fully qualified name of the type to
9388 /// lookup.
9389 ///
9390 /// @param type_map the map to look into.
9391 ///
9392 /// @return the vector containing the types named @p type_name. If
9393 /// the lookup didn't yield any type, then this function returns nil.
9394 static const type_base_wptrs_type*
lookup_types_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)9395 lookup_types_in_map(const interned_string& type_name,
9396 const istring_type_base_wptrs_map_type& type_map)
9397 {
9398 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
9399 if (i != type_map.end())
9400 return &i->second;
9401 return 0;
9402 }
9403
9404 /// Lookup a type (with a given name) in a map that associates a type
9405 /// name to a type. If there are several types with a given name,
9406 /// then return the last of such types, that is, the last one that got
9407 /// registered.
9408 ///
9409 /// @tparam TypeKind the type of the type this function is supposed to
9410 /// return.
9411 ///
9412 /// @param type_name the name of the type to lookup.
9413 ///
9414 /// @param type_map the map in which to look.
9415 ///
9416 /// @return a shared_ptr to the type found. If no type was found or
9417 /// if the type found was not of type @p TypeKind then the function
9418 /// returns nil.
9419 template <class TypeKind>
9420 static shared_ptr<TypeKind>
lookup_type_in_map(const interned_string & type_name,const istring_type_base_wptrs_map_type & type_map)9421 lookup_type_in_map(const interned_string& type_name,
9422 const istring_type_base_wptrs_map_type& type_map)
9423 {
9424 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
9425 if (i != type_map.end())
9426 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
9427 return shared_ptr<TypeKind>();
9428 }
9429
9430 /// Lookup a basic type from a translation unit.
9431 ///
9432 /// This is done by looking the type up in the type map that is
9433 /// maintained in the translation unit. So this is as fast as
9434 /// possible.
9435 ///
9436 /// @param type_name the name of the basic type to look for.
9437 ///
9438 /// @param tu the translation unit to look into.
9439 ///
9440 /// @return the basic type found or nil if no basic type was found.
9441 type_decl_sptr
lookup_basic_type(const interned_string & type_name,const translation_unit & tu)9442 lookup_basic_type(const interned_string& type_name, const translation_unit& tu)
9443 {
9444 return lookup_type_in_map<type_decl>(type_name,
9445 tu.get_types().basic_types());
9446 }
9447
9448 /// Lookup a basic type from a translation unit.
9449 ///
9450 /// This is done by looking the type up in the type map that is
9451 /// maintained in the translation unit. So this is as fast as
9452 /// possible.
9453 ///
9454 /// @param type_name the name of the basic type to look for.
9455 ///
9456 /// @param tu the translation unit to look into.
9457 ///
9458 /// @return the basic type found or nil if no basic type was found.
9459 type_decl_sptr
lookup_basic_type(const string & type_name,const translation_unit & tu)9460 lookup_basic_type(const string& type_name, const translation_unit& tu)
9461 {
9462 const environment* env = tu.get_environment();
9463 ABG_ASSERT(env);
9464
9465 interned_string s = env->intern(type_name);
9466 return lookup_basic_type(s, tu);
9467 }
9468
9469 /// Lookup a class type from a translation unit.
9470 ///
9471 /// This is done by looking the type up in the type map that is
9472 /// maintained in the translation unit. So this is as fast as
9473 /// possible.
9474 ///
9475 /// @param fqn the fully qualified name of the class type node to look
9476 /// up.
9477 ///
9478 /// @param tu the translation unit to perform lookup from.
9479 ///
9480 /// @return the declaration of the class type IR node found, NULL
9481 /// otherwise.
9482 class_decl_sptr
lookup_class_type(const string & fqn,const translation_unit & tu)9483 lookup_class_type(const string& fqn, const translation_unit& tu)
9484 {
9485 const environment* env = tu.get_environment();
9486 ABG_ASSERT(env);
9487
9488 interned_string s = env->intern(fqn);
9489 return lookup_class_type(s, tu);
9490 }
9491
9492 /// Lookup a class type from a translation unit.
9493 ///
9494 /// This is done by looking the type up in the type map that is
9495 /// maintained in the translation unit. So this is as fast as
9496 /// possible.
9497 ///
9498 /// @param type_name the name of the class type to look for.
9499 ///
9500 /// @param tu the translation unit to look into.
9501 ///
9502 /// @return the class type found or nil if no class type was found.
9503 class_decl_sptr
lookup_class_type(const interned_string & type_name,const translation_unit & tu)9504 lookup_class_type(const interned_string& type_name, const translation_unit& tu)
9505 {
9506 return lookup_type_in_map<class_decl>(type_name,
9507 tu.get_types().class_types());
9508 }
9509
9510 /// Lookup a union type from a translation unit.
9511 ///
9512 /// This is done by looking the type up in the type map that is
9513 /// maintained in the translation unit. So this is as fast as
9514 /// possible.
9515 ///
9516 /// @param type_name the name of the union type to look for.
9517 ///
9518 /// @param tu the translation unit to look into.
9519 ///
9520 /// @return the union type found or nil if no union type was found.
9521 union_decl_sptr
lookup_union_type(const interned_string & type_name,const translation_unit & tu)9522 lookup_union_type(const interned_string& type_name, const translation_unit& tu)
9523 {
9524 return lookup_type_in_map<union_decl>(type_name,
9525 tu.get_types().union_types());
9526 }
9527
9528 /// Lookup a union type from a translation unit.
9529 ///
9530 /// This is done by looking the type up in the type map that is
9531 /// maintained in the translation unit. So this is as fast as
9532 /// possible.
9533 ///
9534 /// @param fqn the fully qualified name of the type to lookup.
9535 ///
9536 /// @param tu the translation unit to look into.
9537 ///
9538 /// @return the union type found or nil if no union type was found.
9539 union_decl_sptr
lookup_union_type(const string & fqn,const translation_unit & tu)9540 lookup_union_type(const string& fqn, const translation_unit& tu)
9541 {
9542 const environment* env = tu.get_environment();
9543 ABG_ASSERT(env);
9544
9545 interned_string s = env->intern(fqn);
9546 return lookup_union_type(s, tu);
9547 }
9548
9549 /// Lookup a union type in a given corpus, from its location.
9550 ///
9551 /// @param loc the location of the union type to look for.
9552 ///
9553 /// @param corp the corpus to look it from.
9554 ///
9555 /// @return the resulting union_decl.
9556 union_decl_sptr
lookup_union_type_per_location(const interned_string & loc,const corpus & corp)9557 lookup_union_type_per_location(const interned_string &loc, const corpus& corp)
9558 {
9559 const istring_type_base_wptrs_map_type& m =
9560 corp.get_type_per_loc_map().union_types();
9561 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
9562
9563 return result;
9564 }
9565
9566 /// Lookup a union type in a given corpus, from its location.
9567 ///
9568 /// @param loc the location of the union type to look for.
9569 ///
9570 /// @param corp the corpus to look it from.
9571 ///
9572 /// @return the resulting union_decl.
9573 union_decl_sptr
lookup_union_type_per_location(const string & loc,const corpus & corp)9574 lookup_union_type_per_location(const string& loc, const corpus& corp)
9575 {
9576 const environment* env = corp.get_environment();
9577 ABG_ASSERT(env);
9578
9579 return lookup_union_type_per_location(env->intern(loc), corp);
9580 }
9581
9582 /// Lookup an enum type from a translation unit.
9583 ///
9584 /// This is done by looking the type up in the type map that is
9585 /// maintained in the translation unit. So this is as fast as
9586 /// possible.
9587 ///
9588 /// @param type_name the name of the enum type to look for.
9589 ///
9590 /// @param tu the translation unit to look into.
9591 ///
9592 /// @return the enum type found or nil if no enum type was found.
9593 enum_type_decl_sptr
lookup_enum_type(const interned_string & type_name,const translation_unit & tu)9594 lookup_enum_type(const interned_string& type_name, const translation_unit& tu)
9595 {
9596 return lookup_type_in_map<enum_type_decl>(type_name,
9597 tu.get_types().enum_types());
9598 }
9599
9600 /// Lookup an enum type from a translation unit.
9601 ///
9602 /// This is done by looking the type up in the type map that is
9603 /// maintained in the translation unit. So this is as fast as
9604 /// possible.
9605 ///
9606 /// @param type_name the name of the enum type to look for.
9607 ///
9608 /// @param tu the translation unit to look into.
9609 ///
9610 /// @return the enum type found or nil if no enum type was found.
9611 enum_type_decl_sptr
lookup_enum_type(const string & type_name,const translation_unit & tu)9612 lookup_enum_type(const string& type_name, const translation_unit& tu)
9613 {
9614 const environment* env = tu.get_environment();
9615 ABG_ASSERT(env);
9616
9617 interned_string s = env->intern(type_name);
9618 return lookup_enum_type(s, tu);
9619 }
9620
9621 /// Lookup a typedef type from a translation unit.
9622 ///
9623 /// This is done by looking the type up in the type map that is
9624 /// maintained in the translation unit. So this is as fast as
9625 /// possible.
9626 ///
9627 /// @param type_name the name of the typedef type to look for.
9628 ///
9629 /// @param tu the translation unit to look into.
9630 ///
9631 /// @return the typedef type found or nil if no typedef type was
9632 /// found.
9633 typedef_decl_sptr
lookup_typedef_type(const interned_string & type_name,const translation_unit & tu)9634 lookup_typedef_type(const interned_string& type_name,
9635 const translation_unit& tu)
9636 {
9637 return lookup_type_in_map<typedef_decl>(type_name,
9638 tu.get_types().typedef_types());
9639 }
9640
9641 /// Lookup a typedef type from a translation unit.
9642 ///
9643 /// This is done by looking the type up in the type map that is
9644 /// maintained in the translation unit. So this is as fast as
9645 /// possible.
9646 ///
9647 /// @param type_name the name of the typedef type to look for.
9648 ///
9649 /// @param tu the translation unit to look into.
9650 ///
9651 /// @return the typedef type found or nil if no typedef type was
9652 /// found.
9653 typedef_decl_sptr
lookup_typedef_type(const string & type_name,const translation_unit & tu)9654 lookup_typedef_type(const string& type_name, const translation_unit& tu)
9655 {
9656 const environment* env = tu.get_environment();
9657 ABG_ASSERT(env);
9658
9659 interned_string s = env->intern(type_name);
9660 return lookup_typedef_type(s, tu);
9661 }
9662
9663 /// Lookup a qualified type from a translation unit.
9664 ///
9665 /// This is done by looking the type up in the type map that is
9666 /// maintained in the translation unit. So this is as fast as
9667 /// possible.
9668 ///
9669 /// @param type_name the name of the qualified type to look for.
9670 ///
9671 /// @param tu the translation unit to look into.
9672 ///
9673 /// @return the qualified type found or nil if no qualified type was
9674 /// found.
9675 qualified_type_def_sptr
lookup_qualified_type(const interned_string & type_name,const translation_unit & tu)9676 lookup_qualified_type(const interned_string& type_name,
9677 const translation_unit& tu)
9678 {
9679 const type_maps& m = tu.get_types();
9680 return lookup_type_in_map<qualified_type_def>(type_name,
9681 m.qualified_types());
9682 }
9683
9684 /// Lookup a qualified type from a translation unit.
9685 ///
9686 /// This is done by looking the type up in the type map that is
9687 /// maintained in the translation unit. So this is as fast as
9688 /// possible.
9689 ///
9690 /// @param underlying_type the underying type of the qualified type to
9691 /// look up.
9692 ///
9693 /// @param quals the CV-qualifiers of the qualified type to look for.
9694 ///
9695 /// @param tu the translation unit to look into.
9696 ///
9697 /// @return the qualified type found or nil if no qualified type was
9698 /// found.
9699 qualified_type_def_sptr
lookup_qualified_type(const type_base_sptr & underlying_type,qualified_type_def::CV quals,const translation_unit & tu)9700 lookup_qualified_type(const type_base_sptr& underlying_type,
9701 qualified_type_def::CV quals,
9702 const translation_unit& tu)
9703 {
9704 interned_string type_name = get_name_of_qualified_type(underlying_type,
9705 quals);
9706 return lookup_qualified_type(type_name, tu);
9707 }
9708
9709 /// Lookup a pointer type from a translation unit.
9710 ///
9711 /// This is done by looking the type up in the type map that is
9712 /// maintained in the translation unit. So this is as fast as
9713 /// possible.
9714 ///
9715 /// @param type_name the name of the pointer type to look for.
9716 ///
9717 /// @param tu the translation unit to look into.
9718 ///
9719 /// @return the pointer type found or nil if no pointer type was
9720 /// found.
9721 pointer_type_def_sptr
lookup_pointer_type(const interned_string & type_name,const translation_unit & tu)9722 lookup_pointer_type(const interned_string& type_name,
9723 const translation_unit& tu)
9724 {
9725 const type_maps& m = tu.get_types();
9726 return lookup_type_in_map<pointer_type_def>(type_name,
9727 m.pointer_types());
9728 }
9729
9730 /// Lookup a pointer type from a translation unit.
9731 ///
9732 /// This is done by looking the type up in the type map that is
9733 /// maintained in the translation unit. So this is as fast as
9734 /// possible.
9735 ///
9736 /// @param type_name the name of the pointer type to look for.
9737 ///
9738 /// @param tu the translation unit to look into.
9739 ///
9740 /// @return the pointer type found or nil if no pointer type was
9741 /// found.
9742 pointer_type_def_sptr
lookup_pointer_type(const string & type_name,const translation_unit & tu)9743 lookup_pointer_type(const string& type_name, const translation_unit& tu)
9744 {
9745 const environment* env = tu.get_environment();
9746 ABG_ASSERT(env);
9747
9748 interned_string s = env->intern(type_name);
9749 return lookup_pointer_type(s, tu);
9750 }
9751
9752 /// Lookup a pointer type from a translation unit.
9753 ///
9754 /// This is done by looking the type up in the type map that is
9755 /// maintained in the translation unit. So this is as fast as
9756 /// possible.
9757 ///
9758 /// @param pointed_to_type the pointed-to-type of the pointer to look for.
9759 ///
9760 /// @param tu the translation unit to look into.
9761 ///
9762 /// @return the pointer type found or nil if no pointer type was
9763 /// found.
9764 pointer_type_def_sptr
lookup_pointer_type(const type_base_sptr & pointed_to_type,const translation_unit & tu)9765 lookup_pointer_type(const type_base_sptr& pointed_to_type,
9766 const translation_unit& tu)
9767 {
9768 interned_string type_name = get_name_of_pointer_to_type(*pointed_to_type);
9769 return lookup_pointer_type(type_name, tu);
9770 }
9771
9772 /// Lookup a reference type from a translation unit.
9773 ///
9774 /// This is done by looking the type up in the type map that is
9775 /// maintained in the translation unit. So this is as fast as
9776 /// possible.
9777 ///
9778 /// @param type_name the name of the reference type to look for.
9779 ///
9780 /// @param tu the translation unit to look into.
9781 ///
9782 /// @return the reference type found or nil if no reference type was
9783 /// found.
9784 reference_type_def_sptr
lookup_reference_type(const interned_string & type_name,const translation_unit & tu)9785 lookup_reference_type(const interned_string& type_name,
9786 const translation_unit& tu)
9787 {
9788 const type_maps& m = tu.get_types();
9789 return lookup_type_in_map<reference_type_def>(type_name,
9790 m.reference_types());
9791 }
9792
9793 /// Lookup a reference type from a translation unit.
9794 ///
9795 /// This is done by looking the type up in the type map that is
9796 /// maintained in the translation unit. So this is as fast as
9797 /// possible.
9798 ///
9799 /// @param pointed_to_type the pointed-to-type of the reference to
9800 /// look up.
9801 ///
9802 /// @param tu the translation unit to look into.
9803 ///
9804 /// @return the reference type found or nil if no reference type was
9805 /// found.
9806 const reference_type_def_sptr
lookup_reference_type(const type_base_sptr & pointed_to_type,bool lvalue_reference,const translation_unit & tu)9807 lookup_reference_type(const type_base_sptr& pointed_to_type,
9808 bool lvalue_reference,
9809 const translation_unit& tu)
9810 {
9811 interned_string type_name =
9812 get_name_of_reference_to_type(*pointed_to_type, lvalue_reference);
9813 return lookup_reference_type(type_name, tu);
9814 }
9815
9816 /// Lookup an array type from a translation unit.
9817 ///
9818 /// This is done by looking the type up in the type map that is
9819 /// maintained in the translation unit. So this is as fast as
9820 /// possible.
9821 ///
9822 /// @param type_name the name of the array type to look for.
9823 ///
9824 /// @param tu the translation unit to look into.
9825 ///
9826 /// @return the array type found or nil if no array type was found.
9827 array_type_def_sptr
lookup_array_type(const interned_string & type_name,const translation_unit & tu)9828 lookup_array_type(const interned_string& type_name,
9829 const translation_unit& tu)
9830 {
9831 const type_maps& m = tu.get_types();
9832 return lookup_type_in_map<array_type_def>(type_name,
9833 m.array_types());
9834 }
9835
9836 /// Lookup a function type from a translation unit.
9837 ///
9838 /// This is done by looking the type up in the type map that is
9839 /// maintained in the translation unit. So this is as fast as
9840 /// possible.
9841 ///
9842 /// @param type_name the name of the type to lookup.
9843 ///
9844 /// @param tu the translation unit to look into.
9845 ///
9846 /// @return the function type found, or NULL of none was found.
9847 function_type_sptr
lookup_function_type(const interned_string & type_name,const translation_unit & tu)9848 lookup_function_type(const interned_string& type_name,
9849 const translation_unit& tu)
9850 {
9851 const type_maps& m = tu.get_types();
9852 return lookup_type_in_map<function_type>(type_name,
9853 m.function_types());
9854 }
9855
9856 /// Lookup a function type from a translation unit.
9857 ///
9858 /// This walks all the function types held by the translation unit and
9859 /// compare their sub-type *names*. If the names match then return
9860 /// the function type found in the translation unit.
9861 ///
9862 /// @param t the function type to look for.
9863 ///
9864 /// @param tu the translation unit to look into.
9865 ///
9866 /// @return the function type found, or NULL of none was found.
9867 function_type_sptr
lookup_function_type(const function_type & t,const translation_unit & tu)9868 lookup_function_type(const function_type& t,
9869 const translation_unit& tu)
9870 {
9871 interned_string type_name = get_type_name(t);
9872 return lookup_function_type(type_name, tu);
9873 }
9874
9875 /// Lookup a function type from a translation unit.
9876 ///
9877 /// This is done by looking the type up in the type map that is
9878 /// maintained in the translation unit. So this is as fast as
9879 /// possible.
9880 ///
9881 /// @param t the function type to look for.
9882 ///
9883 /// @param tu the translation unit to look into.
9884 ///
9885 /// @return the function type found, or NULL of none was found.
9886 function_type_sptr
lookup_function_type(const function_type_sptr & t,const translation_unit & tu)9887 lookup_function_type(const function_type_sptr& t,
9888 const translation_unit& tu)
9889 {return lookup_function_type(*t, tu);}
9890
9891 /// Lookup a type in a translation unit.
9892 ///
9893 /// @param fqn the fully qualified name of the type to lookup.
9894 ///
9895 /// @param tu the translation unit to consider.
9896 ///
9897 /// @return the declaration of the type if found, NULL otherwise.
9898 const type_base_sptr
lookup_type(const interned_string & fqn,const translation_unit & tu)9899 lookup_type(const interned_string& fqn,
9900 const translation_unit& tu)
9901 {
9902 type_base_sptr result;
9903 ((result = lookup_typedef_type(fqn, tu))
9904 || (result = lookup_class_type(fqn, tu))
9905 || (result = lookup_union_type(fqn, tu))
9906 || (result = lookup_enum_type(fqn, tu))
9907 || (result = lookup_qualified_type(fqn, tu))
9908 || (result = lookup_pointer_type(fqn, tu))
9909 || (result = lookup_reference_type(fqn, tu))
9910 || (result = lookup_array_type(fqn, tu))
9911 || (result = lookup_function_type(fqn, tu))
9912 || (result = lookup_basic_type(fqn, tu)));
9913
9914 return result;
9915 }
9916
9917 /// Lookup a type in a translation unit, starting from the global
9918 /// namespace.
9919 ///
9920 /// @param fqn the fully qualified name of the type to lookup.
9921 ///
9922 /// @param tu the translation unit to consider.
9923 ///
9924 /// @return the declaration of the type if found, NULL otherwise.
9925 type_base_sptr
lookup_type(const string & fqn,const translation_unit & tu)9926 lookup_type(const string& fqn, const translation_unit& tu)
9927 {
9928 const environment *env = tu.get_environment();
9929 ABG_ASSERT(env);
9930 interned_string ifqn = env->intern(fqn);
9931 return lookup_type(ifqn, tu);
9932 }
9933
9934 /// Lookup a type from a translation unit.
9935 ///
9936 /// @param fqn the components of the fully qualified name of the node
9937 /// to look up.
9938 ///
9939 /// @param tu the translation unit to perform lookup from.
9940 ///
9941 /// @return the declaration of the IR node found, NULL otherwise.
9942 const type_base_sptr
lookup_type(const type_base_sptr type,const translation_unit & tu)9943 lookup_type(const type_base_sptr type,
9944 const translation_unit& tu)
9945 {
9946 interned_string type_name = get_type_name(type);
9947 return lookup_type(type_name, tu);
9948 }
9949
9950 /// Lookup a type in a scope.
9951 ///
9952 /// This is really slow as it walks the member types of the scope in
9953 /// sequence to find the type with a given name.
9954 ///
9955 /// If possible, users should prefer looking up types from the
9956 /// enclosing translation unit or even ABI corpus because both the
9957 /// translation unit and the corpus have a map of type, indexed by
9958 /// their name. Looking up a type from those maps is thus much
9959 /// faster.
9960 ///
9961 /// @param fqn the fully qualified name of the type to lookup.
9962 ///
9963 /// @param skope the scope to look into.
9964 ///
9965 /// @return the declaration of the type if found, NULL otherwise.
9966 const type_base_sptr
lookup_type_in_scope(const string & fqn,const scope_decl_sptr & skope)9967 lookup_type_in_scope(const string& fqn,
9968 const scope_decl_sptr& skope)
9969 {
9970 list<string> comps;
9971 fqn_to_components(fqn, comps);
9972 return lookup_type_in_scope(comps, skope);
9973 }
9974
9975 /// Lookup a @ref var_decl in a scope.
9976 ///
9977 /// @param fqn the fuly qualified name of the @var_decl to lookup.
9978 ///
9979 /// @param skope the scope to look into.
9980 ///
9981 /// @return the declaration of the @ref var_decl if found, NULL
9982 /// otherwise.
9983 const decl_base_sptr
lookup_var_decl_in_scope(const string & fqn,const scope_decl_sptr & skope)9984 lookup_var_decl_in_scope(const string& fqn,
9985 const scope_decl_sptr& skope)
9986 {
9987 list<string> comps;
9988 fqn_to_components(fqn, comps);
9989 return lookup_var_decl_in_scope(comps, skope);
9990 }
9991
9992 /// A generic function (template) to get the name of a node, whatever
9993 /// node it is. This has to be specialized for the kind of node we
9994 /// want.
9995 ///
9996 /// Note that a node is a member of a scope.
9997 ///
9998 /// @tparam NodeKind the kind of node to consider.
9999 ///
10000 /// @param node the node to get the name from.
10001 ///
10002 /// @return the name of the node.
10003 template<typename NodeKind>
10004 static const interned_string&
10005 get_node_name(shared_ptr<NodeKind> node);
10006
10007 /// Gets the name of a class_decl node.
10008 ///
10009 /// @param node the decl_base node to get the name from.
10010 ///
10011 /// @return the name of the node.
10012 template<>
10013 const interned_string&
get_node_name(class_decl_sptr node)10014 get_node_name(class_decl_sptr node)
10015 {return node->get_name();}
10016
10017 /// Gets the name of a type_base node.
10018 ///
10019 /// @param node the type_base node to get the name from.
10020 ///
10021 /// @return the name of the node.
10022 template<>
10023 const interned_string&
get_node_name(type_base_sptr node)10024 get_node_name(type_base_sptr node)
10025 {return get_type_declaration(node)->get_name();}
10026
10027 /// Gets the name of a var_decl node.
10028 ///
10029 /// @param node the var_decl node to get the name from.
10030 ///
10031 /// @return the name of the node.
10032 template<>
10033 const interned_string&
get_node_name(var_decl_sptr node)10034 get_node_name(var_decl_sptr node)
10035 {return node->get_name();}
10036
10037 /// Generic function to get the declaration of a given node, whatever
10038 /// it is. There has to be specializations for the kind of the nodes
10039 /// we want to support.
10040 ///
10041 /// @tparam NodeKind the type of the node we are looking at.
10042 ///
10043 /// @return the declaration.
10044 template<typename NodeKind>
10045 static decl_base_sptr
10046 convert_node_to_decl(shared_ptr<NodeKind> node);
10047
10048 /// Lookup a node in a given scope.
10049 ///
10050 /// @tparam the type of the node to lookup.
10051 ///
10052 /// @param fqn the components of the fully qualified name of the node
10053 /// to lookup.
10054 ///
10055 /// @param skope the scope to look into.
10056 ///
10057 /// @return the declaration of the looked up node, or NULL if it
10058 /// wasn't found.
10059 template<typename NodeKind>
10060 static const type_or_decl_base_sptr
lookup_node_in_scope(const list<string> & fqn,const scope_decl_sptr & skope)10061 lookup_node_in_scope(const list<string>& fqn,
10062 const scope_decl_sptr& skope)
10063 {
10064 type_or_decl_base_sptr resulting_decl;
10065 shared_ptr<NodeKind> node;
10066 bool it_is_last = false;
10067 scope_decl_sptr cur_scope = skope, new_scope, scope;
10068
10069 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
10070 {
10071 new_scope.reset();
10072 it_is_last = iterator_is_last(fqn, c);
10073 for (scope_decl::declarations::const_iterator m =
10074 cur_scope->get_member_decls().begin();
10075 m != cur_scope->get_member_decls().end();
10076 ++m)
10077 {
10078 if (!it_is_last)
10079 {
10080 // looking for a scope
10081 scope = dynamic_pointer_cast<scope_decl>(*m);
10082 if (scope && scope->get_name() == *c)
10083 {
10084 new_scope = scope;
10085 break;
10086 }
10087 }
10088 else
10089 {
10090 //looking for a final type.
10091 node = dynamic_pointer_cast<NodeKind>(*m);
10092 if (node && get_node_name(node) == *c)
10093 {
10094 if (class_decl_sptr cl =
10095 dynamic_pointer_cast<class_decl>(node))
10096 if (cl->get_is_declaration_only()
10097 && !cl->get_definition_of_declaration())
10098 continue;
10099 resulting_decl = node;
10100 break;
10101 }
10102 }
10103 }
10104 if (!new_scope && !resulting_decl)
10105 return decl_base_sptr();
10106 cur_scope = new_scope;
10107 }
10108 ABG_ASSERT(resulting_decl);
10109 return resulting_decl;
10110 }
10111
10112 /// lookup a type in a scope.
10113 ///
10114 ///
10115 /// This is really slow as it walks the member types of the scope in
10116 /// sequence to find the type with a given name.
10117 ///
10118 /// If possible, users should prefer looking up types from the
10119 /// enclosing translation unit or even ABI corpus because both the
10120 /// translation unit and the corpus have a map of type, indexed by
10121 /// their name. Looking up a type from those maps is thus much
10122 /// faster.
10123 ///
10124 /// @param comps the components of the fully qualified name of the
10125 /// type to lookup.
10126 ///
10127 /// @param skope the scope to look into.
10128 ///
10129 /// @return the declaration of the type found.
10130 const type_base_sptr
lookup_type_in_scope(const list<string> & comps,const scope_decl_sptr & scope)10131 lookup_type_in_scope(const list<string>& comps,
10132 const scope_decl_sptr& scope)
10133 {return is_type(lookup_node_in_scope<type_base>(comps, scope));}
10134
10135 /// lookup a type in a scope.
10136 ///
10137 /// This is really slow as it walks the member types of the scope in
10138 /// sequence to find the type with a given name.
10139 ///
10140 /// If possible, users should prefer looking up types from the
10141 /// enclosing translation unit or even ABI corpus because both the
10142 /// translation unit and the corpus have a map of type, indexed by
10143 /// their name. Looking up a type from those maps is thus much
10144 /// faster.
10145 ///
10146 /// @param type the type to look for.
10147 ///
10148 /// @param access_path a vector of scopes the path of scopes to follow
10149 /// before reaching the scope into which to look for @p type. Note
10150 /// that the deepest scope (the one immediately containing @p type) is
10151 /// at index 0 of this vector, and the top-most scope is the last
10152 /// element of the vector.
10153 ///
10154 /// @param scope the top-most scope into which to look for @p type.
10155 ///
10156 /// @return the scope found in @p scope, or NULL if it wasn't found.
10157 static const type_base_sptr
lookup_type_in_scope(const type_base & type,const vector<scope_decl * > & access_path,const scope_decl * scope)10158 lookup_type_in_scope(const type_base& type,
10159 const vector<scope_decl*>& access_path,
10160 const scope_decl* scope)
10161 {
10162 vector<scope_decl*> a = access_path;
10163 type_base_sptr result;
10164
10165 scope_decl* first_scope = 0;
10166 if (!a.empty())
10167 {
10168 first_scope = a.back();
10169 ABG_ASSERT(first_scope->get_name() == scope->get_name());
10170 a.pop_back();
10171 }
10172
10173 if (a.empty())
10174 {
10175 interned_string n = get_type_name(type, false);
10176 for (scope_decl::declarations::const_iterator i =
10177 scope->get_member_decls().begin();
10178 i != scope->get_member_decls().end();
10179 ++i)
10180 if (is_type(*i) && (*i)->get_name() == n)
10181 {
10182 result = is_type(*i);
10183 break;
10184 }
10185 }
10186 else
10187 {
10188 first_scope = a.back();
10189 interned_string scope_name, cur_scope_name = first_scope->get_name();
10190 for (scope_decl::scopes::const_iterator i =
10191 scope->get_member_scopes().begin();
10192 i != scope->get_member_scopes().end();
10193 ++i)
10194 {
10195 scope_name = (*i)->get_name();
10196 if (scope_name == cur_scope_name)
10197 {
10198 result = lookup_type_in_scope(type, a, (*i).get());
10199 break;
10200 }
10201 }
10202 }
10203 return result;
10204 }
10205
10206 /// lookup a type in a scope.
10207 ///
10208 /// This is really slow as it walks the member types of the scope in
10209 /// sequence to find the type with a given name.
10210 ///
10211 /// If possible, users should prefer looking up types from the
10212 /// enclosing translation unit or even ABI corpus because both the
10213 /// translation unit and the corpus have a map of type, indexed by
10214 /// their name. Looking up a type from those maps is thus much
10215 /// faster.
10216 ///
10217 /// @param type the type to look for.
10218 ///
10219 /// @param scope the top-most scope into which to look for @p type.
10220 ///
10221 /// @return the scope found in @p scope, or NULL if it wasn't found.
10222 static const type_base_sptr
lookup_type_in_scope(const type_base_sptr type,const scope_decl * scope)10223 lookup_type_in_scope(const type_base_sptr type,
10224 const scope_decl* scope)
10225 {
10226 if (!type || is_function_type(type))
10227 return type_base_sptr();
10228
10229 decl_base_sptr type_decl = get_type_declaration(type);
10230 ABG_ASSERT(type_decl);
10231 vector<scope_decl*> access_path;
10232 for (scope_decl* s = type_decl->get_scope(); s != 0; s = s->get_scope())
10233 {
10234 access_path.push_back(s);
10235 if (is_global_scope(s))
10236 break;
10237 }
10238 return lookup_type_in_scope(*type, access_path, scope);
10239 }
10240
10241 /// Lookup a type from a translation unit by walking the scopes of the
10242 /// translation unit in sequence and looking into them.
10243 ///
10244 /// This is really slow as it walks the member types of the scopes in
10245 /// sequence to find the type with a given name.
10246 ///
10247 /// If possible, users should prefer looking up types from the
10248 /// translation unit or even ABI corpus in a more direct way, by using
10249 /// the lookup_type() functins.
10250 ///
10251 ///
10252 /// This is because both the translation unit and the corpus have a
10253 /// map of types, indexed by their name. Looking up a type from those
10254 /// maps is thus much faster. @param fqn the components of the fully
10255 /// qualified name of the node to look up.
10256 ///
10257 /// @param tu the translation unit to perform lookup from.
10258 ///
10259 /// @return the declaration of the IR node found, NULL otherwise.
10260 const type_base_sptr
lookup_type_through_scopes(const type_base_sptr type,const translation_unit & tu)10261 lookup_type_through_scopes(const type_base_sptr type,
10262 const translation_unit& tu)
10263 {
10264 if (function_type_sptr fn_type = is_function_type(type))
10265 return lookup_function_type(fn_type, tu);
10266 return lookup_type_in_scope(type, tu.get_global_scope().get());
10267 }
10268
10269 /// lookup a var_decl in a scope.
10270 ///
10271 /// @param comps the components of the fully qualified name of the
10272 /// var_decl to lookup.
10273 ///
10274 /// @param skope the scope to look into.
10275 const decl_base_sptr
lookup_var_decl_in_scope(const std::list<string> & comps,const scope_decl_sptr & skope)10276 lookup_var_decl_in_scope(const std::list<string>& comps,
10277 const scope_decl_sptr& skope)
10278 {return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
10279
10280 /// Lookup an IR node from a translation unit.
10281 ///
10282 /// @tparam NodeKind the type of the IR node to lookup from the
10283 /// translation unit.
10284 ///
10285 /// @param fqn the components of the fully qualified name of the node
10286 /// to look up.
10287 ///
10288 /// @param tu the translation unit to perform lookup from.
10289 ///
10290 /// @return the declaration of the IR node found, NULL otherwise.
10291 template<typename NodeKind>
10292 static const type_or_decl_base_sptr
lookup_node_in_translation_unit(const list<string> & fqn,const translation_unit & tu)10293 lookup_node_in_translation_unit(const list<string>& fqn,
10294 const translation_unit& tu)
10295 {return lookup_node_in_scope<NodeKind>(fqn, tu.get_global_scope());}
10296
10297 /// Lookup a type from a translation unit by walking its scopes in
10298 /// sequence and by looking into them.
10299 ///
10300 /// This is much slower than using the lookup_type() function.
10301 ///
10302 /// @param fqn the components of the fully qualified name of the node
10303 /// to look up.
10304 ///
10305 /// @param tu the translation unit to perform lookup from.
10306 ///
10307 /// @return the declaration of the IR node found, NULL otherwise.
10308 type_base_sptr
lookup_type_through_scopes(const list<string> & fqn,const translation_unit & tu)10309 lookup_type_through_scopes(const list<string>& fqn,
10310 const translation_unit& tu)
10311 {return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
10312
10313
10314 /// Lookup a class type from a translation unit by walking its scopes
10315 /// in sequence and by looking into them.
10316 ///
10317 /// This is much slower than using the lookup_class_type() function
10318 /// because it walks all the scopes of the translation unit in
10319 /// sequence and lookup the types to find one that has a given name.
10320 ///
10321 /// @param fqn the components of the fully qualified name of the class
10322 /// type node to look up.
10323 ///
10324 /// @param tu the translation unit to perform lookup from.
10325 ///
10326 /// @return the declaration of the class type IR node found, NULL
10327 /// otherwise.
10328 class_decl_sptr
lookup_class_type_through_scopes(const list<string> & fqn,const translation_unit & tu)10329 lookup_class_type_through_scopes(const list<string>& fqn,
10330 const translation_unit& tu)
10331 {return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
10332
10333 /// Lookup a basic type from all the translation units of a given
10334 /// corpus.
10335 ///
10336 /// @param fqn the components of the fully qualified name of the basic
10337 /// type node to look up.
10338 ///
10339 /// @param tu the translation unit to perform lookup from.
10340 ///
10341 /// @return the declaration of the basic type IR node found, NULL
10342 /// otherwise.
10343 static type_decl_sptr
lookup_basic_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10344 lookup_basic_type_through_translation_units(const interned_string& type_name,
10345 const corpus& abi_corpus)
10346 {
10347 type_decl_sptr result;
10348
10349 for (translation_units::const_iterator tu =
10350 abi_corpus.get_translation_units().begin();
10351 tu != abi_corpus.get_translation_units().end();
10352 ++tu)
10353 if ((result = lookup_basic_type(type_name, **tu)))
10354 break;
10355
10356 return result;
10357 }
10358
10359 /// Lookup a union type from all the translation units of a given
10360 /// corpus.
10361 ///
10362 /// @param fqn the components of the fully qualified name of the union
10363 /// type node to look up.
10364 ///
10365 /// @param tu the translation unit to perform lookup from.
10366 ///
10367 /// @return the declaration of the union type IR node found, NULL
10368 /// otherwise.
10369 static union_decl_sptr
lookup_union_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10370 lookup_union_type_through_translation_units(const interned_string& type_name,
10371 const corpus & abi_corpus)
10372 {
10373 union_decl_sptr result;
10374
10375 for (translation_units::const_iterator tu =
10376 abi_corpus.get_translation_units().begin();
10377 tu != abi_corpus.get_translation_units().end();
10378 ++tu)
10379 if ((result = lookup_union_type(type_name, **tu)))
10380 break;
10381
10382 return result;
10383 }
10384
10385 /// Lookup an enum type from all the translation units of a given
10386 /// corpus.
10387 ///
10388 /// @param fqn the components of the fully qualified name of the enum
10389 /// type node to look up.
10390 ///
10391 /// @param tu the translation unit to perform lookup from.
10392 ///
10393 /// @return the declaration of the enum type IR node found, NULL
10394 /// otherwise.
10395 static enum_type_decl_sptr
lookup_enum_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10396 lookup_enum_type_through_translation_units(const interned_string& type_name,
10397 const corpus & abi_corpus)
10398 {
10399 enum_type_decl_sptr result;
10400
10401 for (translation_units::const_iterator tu =
10402 abi_corpus.get_translation_units().begin();
10403 tu != abi_corpus.get_translation_units().end();
10404 ++tu)
10405 if ((result = lookup_enum_type(type_name, **tu)))
10406 break;
10407
10408 return result;
10409 }
10410
10411 /// Lookup a typedef type definition in all the translation units of a
10412 /// given ABI corpus.
10413 ///
10414 /// @param @param qn the fully qualified name of the typedef type to lookup.
10415 ///
10416 /// @param abi_corpus the ABI corpus which to look the type up in.
10417 ///
10418 /// @return the type definition if any was found, or a NULL pointer.
10419 static typedef_decl_sptr
lookup_typedef_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10420 lookup_typedef_type_through_translation_units(const interned_string& type_name,
10421 const corpus & abi_corpus)
10422 {
10423 typedef_decl_sptr result;
10424
10425 for (translation_units::const_iterator tu =
10426 abi_corpus.get_translation_units().begin();
10427 tu != abi_corpus.get_translation_units().end();
10428 ++tu)
10429 if ((result = lookup_typedef_type(type_name, **tu)))
10430 break;
10431
10432 return result;
10433 }
10434
10435 /// Lookup a qualified type definition in all the translation units of a
10436 /// given ABI corpus.
10437 ///
10438 /// @param @param qn the fully qualified name of the qualified type to
10439 /// lookup.
10440 ///
10441 /// @param abi_corpus the ABI corpus which to look the type up in.
10442 ///
10443 /// @return the type definition if any was found, or a NULL pointer.
10444 static qualified_type_def_sptr
lookup_qualified_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)10445 lookup_qualified_type_through_translation_units(const interned_string& t_name,
10446 const corpus & abi_corpus)
10447 {
10448 qualified_type_def_sptr result;
10449
10450 for (translation_units::const_iterator tu =
10451 abi_corpus.get_translation_units().begin();
10452 tu != abi_corpus.get_translation_units().end();
10453 ++tu)
10454 if ((result = lookup_qualified_type(t_name, **tu)))
10455 break;
10456
10457 return result;
10458 }
10459
10460 /// Lookup a pointer type definition in all the translation units of a
10461 /// given ABI corpus.
10462 ///
10463 /// @param @param qn the fully qualified name of the pointer type to
10464 /// lookup.
10465 ///
10466 /// @param abi_corpus the ABI corpus which to look the type up in.
10467 ///
10468 /// @return the type definition if any was found, or a NULL pointer.
10469 static pointer_type_def_sptr
lookup_pointer_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10470 lookup_pointer_type_through_translation_units(const interned_string& type_name,
10471 const corpus & abi_corpus)
10472 {
10473 pointer_type_def_sptr result;
10474
10475 for (translation_units::const_iterator tu =
10476 abi_corpus.get_translation_units().begin();
10477 tu != abi_corpus.get_translation_units().end();
10478 ++tu)
10479 if ((result = lookup_pointer_type(type_name, **tu)))
10480 break;
10481
10482 return result;
10483 }
10484
10485 /// Lookup a reference type definition in all the translation units of a
10486 /// given ABI corpus.
10487 ///
10488 /// @param @param qn the fully qualified name of the reference type to
10489 /// lookup.
10490 ///
10491 /// @param abi_corpus the ABI corpus which to look the type up in.
10492 ///
10493 /// @return the type definition if any was found, or a NULL pointer.
10494 static reference_type_def_sptr
lookup_reference_type_through_translation_units(const interned_string & t_name,const corpus & abi_corpus)10495 lookup_reference_type_through_translation_units(const interned_string& t_name,
10496 const corpus & abi_corpus)
10497 {
10498 reference_type_def_sptr result;
10499
10500 for (translation_units::const_iterator tu =
10501 abi_corpus.get_translation_units().begin();
10502 tu != abi_corpus.get_translation_units().end();
10503 ++tu)
10504 if ((result = lookup_reference_type(t_name, **tu)))
10505 break;
10506
10507 return result;
10508 }
10509
10510 /// Lookup a array type definition in all the translation units of a
10511 /// given ABI corpus.
10512 ///
10513 /// @param @param qn the fully qualified name of the array type to
10514 /// lookup.
10515 ///
10516 /// @param abi_corpus the ABI corpus which to look the type up in.
10517 ///
10518 /// @return the type definition if any was found, or a NULL pointer.
10519 static array_type_def_sptr
lookup_array_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10520 lookup_array_type_through_translation_units(const interned_string& type_name,
10521 const corpus & abi_corpus)
10522 {
10523 array_type_def_sptr result;
10524
10525 for (translation_units::const_iterator tu =
10526 abi_corpus.get_translation_units().begin();
10527 tu != abi_corpus.get_translation_units().end();
10528 ++tu)
10529 if ((result = lookup_array_type(type_name, **tu)))
10530 break;
10531
10532 return result;
10533 }
10534
10535 /// Lookup a function type definition in all the translation units of
10536 /// a given ABI corpus.
10537 ///
10538 /// @param @param qn the fully qualified name of the function type to
10539 /// lookup.
10540 ///
10541 /// @param abi_corpus the ABI corpus which to look the type up in.
10542 ///
10543 /// @return the type definition if any was found, or a NULL pointer.
10544 static function_type_sptr
lookup_function_type_through_translation_units(const interned_string & type_name,const corpus & abi_corpus)10545 lookup_function_type_through_translation_units(const interned_string& type_name,
10546 const corpus & abi_corpus)
10547 {
10548 function_type_sptr result;
10549
10550 for (translation_units::const_iterator tu =
10551 abi_corpus.get_translation_units().begin();
10552 tu != abi_corpus.get_translation_units().end();
10553 ++tu)
10554 if ((result = lookup_function_type(type_name, **tu)))
10555 break;
10556
10557 return result;
10558 }
10559
10560 /// Lookup a type definition in all the translation units of a given
10561 /// ABI corpus.
10562 ///
10563 /// @param @param qn the fully qualified name of the type to lookup.
10564 ///
10565 /// @param abi_corpus the ABI corpus which to look the type up in.
10566 ///
10567 /// @return the type definition if any was found, or a NULL pointer.
10568 type_base_sptr
lookup_type_through_translation_units(const string & qn,const corpus & abi_corpus)10569 lookup_type_through_translation_units(const string& qn,
10570 const corpus& abi_corpus)
10571 {
10572 type_base_sptr result;
10573
10574 for (translation_units::const_iterator tu =
10575 abi_corpus.get_translation_units().begin();
10576 tu != abi_corpus.get_translation_units().end();
10577 ++tu)
10578 if ((result = lookup_type(qn, **tu)))
10579 break;
10580
10581 return result;
10582 }
10583
10584 /// Lookup a type from a given translation unit present in a give corpus.
10585 ///
10586 /// @param type_name the name of the type to look for.
10587 ///
10588 /// @parm tu_path the path of the translation unit to consider.
10589 ///
10590 /// @param corp the corpus to consider.
10591 ///
10592 /// @return the resulting type, if any.
10593 type_base_sptr
lookup_type_from_translation_unit(const string & type_name,const string & tu_path,const corpus & corp)10594 lookup_type_from_translation_unit(const string& type_name,
10595 const string& tu_path,
10596 const corpus& corp)
10597 {
10598 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
10599 if (i == corp.priv_->path_tu_map.end())
10600 return type_base_sptr();
10601
10602 translation_unit_sptr tu = i->second;
10603 ABG_ASSERT(tu);
10604
10605 type_base_sptr t = lookup_type(type_name, *tu);
10606 return t;
10607 }
10608
10609 /// Look into an ABI corpus for a function type.
10610 ///
10611 /// @param fn_type the function type to be looked for in the ABI
10612 /// corpus.
10613 ///
10614 /// @param corpus the ABI corpus into which to look for the function
10615 /// type.
10616 ///
10617 /// @return the function type found in the corpus.
10618 function_type_sptr
lookup_or_synthesize_fn_type(const function_type_sptr & fn_t,const corpus & corpus)10619 lookup_or_synthesize_fn_type(const function_type_sptr& fn_t,
10620 const corpus& corpus)
10621 {
10622 ABG_ASSERT(fn_t);
10623
10624 function_type_sptr result;
10625
10626 if ((result = lookup_function_type(fn_t, corpus)))
10627 return result;
10628
10629 for (translation_units::const_iterator i =
10630 corpus.get_translation_units().begin();
10631 i != corpus.get_translation_units().end();
10632 ++i)
10633 if ((result = synthesize_function_type_from_translation_unit(*fn_t,
10634 **i)))
10635 return result;
10636
10637 return result;
10638 }
10639
10640 /// Look into a given corpus to find a type which has the same
10641 /// qualified name as a giventype.
10642 ///
10643 /// If the per-corpus type map is non-empty (because the corpus allows
10644 /// the One Definition Rule) then the type islooked up in that
10645 /// per-corpus type map. Otherwise, the type is looked-up in each
10646 /// translation unit.
10647 ///
10648 /// @param t the type which has the same qualified name as the type we
10649 /// are looking for.
10650 ///
10651 /// @param corp the ABI corpus to look into for the type.
10652 type_decl_sptr
lookup_basic_type(const type_decl & t,const corpus & corp)10653 lookup_basic_type(const type_decl& t, const corpus& corp)
10654 {return lookup_basic_type(t.get_name(), corp);}
10655
10656 /// Look into a given corpus to find a basic type which has a given
10657 /// qualified name.
10658 ///
10659 /// If the per-corpus type map is non-empty (because the corpus allows
10660 /// the One Definition Rule) then the type islooked up in that
10661 /// per-corpus type map. Otherwise, the type is looked-up in each
10662 /// translation unit.
10663 ///
10664 /// @param qualified_name the qualified name of the basic type to look
10665 /// for.
10666 ///
10667 /// @param corp the corpus to look into.
10668 type_decl_sptr
lookup_basic_type(const interned_string & qualified_name,const corpus & corp)10669 lookup_basic_type(const interned_string &qualified_name, const corpus& corp)
10670 {
10671 const istring_type_base_wptrs_map_type& m = corp.get_types().basic_types();
10672 type_decl_sptr result;
10673
10674 if (!m.empty())
10675 result = lookup_type_in_map<type_decl>(qualified_name, m);
10676 else
10677 result = lookup_basic_type_through_translation_units(qualified_name, corp);
10678
10679 return result;
10680 }
10681
10682 /// Lookup a @ref type_decl type from a given corpus, by its location.
10683 ///
10684 /// @param loc the location to consider.
10685 ///
10686 /// @param corp the corpus to consider.
10687 ///
10688 /// @return the resulting basic type, if any.
10689 type_decl_sptr
lookup_basic_type_per_location(const interned_string & loc,const corpus & corp)10690 lookup_basic_type_per_location(const interned_string &loc,
10691 const corpus &corp)
10692 {
10693 const istring_type_base_wptrs_map_type& m =
10694 corp.get_type_per_loc_map().basic_types();
10695 type_decl_sptr result;
10696
10697 result = lookup_type_in_map<type_decl>(loc, m);
10698
10699 return result;
10700 }
10701
10702 /// Lookup a @ref type_decl type from a given corpus, by its location.
10703 ///
10704 /// @param loc the location to consider.
10705 ///
10706 /// @param corp the corpus to consider.
10707 ///
10708 /// @return the resulting basic type, if any.
10709 type_decl_sptr
lookup_basic_type_per_location(const string & loc,const corpus & corp)10710 lookup_basic_type_per_location(const string &loc, const corpus &corp)
10711 {
10712 const environment* env = corp.get_environment();
10713 ABG_ASSERT(env);
10714
10715 return lookup_basic_type_per_location(env->intern(loc), corp);
10716 }
10717
10718 /// Look into a given corpus to find a basic type which has a given
10719 /// qualified name.
10720 ///
10721 /// If the per-corpus type map is non-empty (because the corpus allows
10722 /// the One Definition Rule) then the type islooked up in that
10723 /// per-corpus type map. Otherwise, the type is looked-up in each
10724 /// translation unit.
10725 ///
10726 /// @param qualified_name the qualified name of the basic type to look
10727 /// for.
10728 ///
10729 /// @param corp the corpus to look into.
10730 type_decl_sptr
lookup_basic_type(const string & qualified_name,const corpus & corp)10731 lookup_basic_type(const string& qualified_name, const corpus& corp)
10732 {
10733 return lookup_basic_type(corp.get_environment()->intern(qualified_name),
10734 corp);
10735 }
10736
10737 /// Look into a given corpus to find a class type which has the same
10738 /// qualified name as a given type.
10739 ///
10740 /// If the per-corpus type map is non-empty (because the corpus allows
10741 /// the One Definition Rule) then the type islooked up in that
10742 /// per-corpus type map. Otherwise, the type is looked-up in each
10743 /// translation unit.
10744 ///
10745 /// @param t the class decl type which has the same qualified name as
10746 /// the type we are looking for.
10747 ///
10748 /// @param corp the corpus to look into.
10749 class_decl_sptr
lookup_class_type(const class_decl & t,const corpus & corp)10750 lookup_class_type(const class_decl& t, const corpus& corp)
10751 {
10752 interned_string s = get_type_name(t);
10753 return lookup_class_type(s, corp);
10754 }
10755
10756 /// Look into a given corpus to find a class type which has a given
10757 /// qualified name.
10758 ///
10759 /// If the per-corpus type map is non-empty (because the corpus allows
10760 /// the One Definition Rule) then the type islooked up in that
10761 /// per-corpus type map. Otherwise, the type is looked-up in each
10762 /// translation unit.
10763 ///
10764 /// @param qualified_name the qualified name of the type to look for.
10765 ///
10766 /// @param corp the corpus to look into.
10767 class_decl_sptr
lookup_class_type(const string & qualified_name,const corpus & corp)10768 lookup_class_type(const string& qualified_name, const corpus& corp)
10769 {
10770 interned_string s = corp.get_environment()->intern(qualified_name);
10771 return lookup_class_type(s, corp);
10772 }
10773
10774 /// Look into a given corpus to find a class type which has a given
10775 /// qualified name.
10776 ///
10777 /// If the per-corpus type map is non-empty (because the corpus allows
10778 /// the One Definition Rule) then the type islooked up in that
10779 /// per-corpus type map. Otherwise, the type is looked-up in each
10780 /// translation unit.
10781 ///
10782 /// @param qualified_name the qualified name of the type to look for.
10783 ///
10784 /// @param corp the corpus to look into.
10785 class_decl_sptr
lookup_class_type(const interned_string & qualified_name,const corpus & corp)10786 lookup_class_type(const interned_string& qualified_name, const corpus& corp)
10787 {
10788 const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
10789
10790 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
10791
10792 return result;
10793 }
10794
10795 /// Look into a given corpus to find the class type*s* that have a
10796 /// given qualified name.
10797 ///
10798 /// @param qualified_name the qualified name of the type to look for.
10799 ///
10800 /// @param corp the corpus to look into.
10801 ///
10802 /// @return the vector of class types named @p qualified_name.
10803 const type_base_wptrs_type *
lookup_class_types(const interned_string & qualified_name,const corpus & corp)10804 lookup_class_types(const interned_string& qualified_name, const corpus& corp)
10805 {
10806 const istring_type_base_wptrs_map_type& m = corp.get_types().class_types();
10807
10808 return lookup_types_in_map(qualified_name, m);
10809 }
10810
10811 /// Look into a given corpus to find the class type*s* that have a
10812 /// given qualified name.
10813 ///
10814 /// @param qualified_name the qualified name of the type to look for.
10815 ///
10816 /// @param corp the corpus to look into.
10817 ///
10818 /// @return the vector of class types that which name is @p qualified_name.
10819 const type_base_wptrs_type*
lookup_class_types(const string & qualified_name,const corpus & corp)10820 lookup_class_types(const string& qualified_name, const corpus& corp)
10821 {
10822 interned_string s = corp.get_environment()->intern(qualified_name);
10823 return lookup_class_types(s, corp);
10824 }
10825
10826 /// Look up a @ref class_decl from a given corpus by its location.
10827 ///
10828 /// @param loc the location to consider.
10829 ///
10830 /// @param corp the corpus to consider.
10831 ///
10832 /// @return the resulting class decl, if any.
10833 class_decl_sptr
lookup_class_type_per_location(const interned_string & loc,const corpus & corp)10834 lookup_class_type_per_location(const interned_string& loc,
10835 const corpus& corp)
10836 {
10837 const istring_type_base_wptrs_map_type& m =
10838 corp.get_type_per_loc_map().class_types();
10839 class_decl_sptr result = lookup_type_in_map<class_decl>(loc, m);
10840
10841 return result;
10842 }
10843
10844 /// Look up a @ref class_decl from a given corpus by its location.
10845 ///
10846 /// @param loc the location to consider.
10847 ///
10848 /// @param corp the corpus to consider.
10849 ///
10850 /// @return the resulting class decl, if any.
10851 class_decl_sptr
lookup_class_type_per_location(const string & loc,const corpus & corp)10852 lookup_class_type_per_location(const string &loc, const corpus &corp)
10853 {
10854 const environment* env = corp.get_environment();
10855 ABG_ASSERT(env);
10856
10857 return lookup_class_type_per_location(env->intern(loc), corp);
10858 }
10859
10860 /// Look into a given corpus to find a union type which has a given
10861 /// qualified name.
10862 ///
10863 /// If the per-corpus type map is non-empty (because the corpus allows
10864 /// the One Definition Rule) then the type islooked up in that
10865 /// per-corpus type map. Otherwise, the type is looked-up in each
10866 /// translation unit.
10867 ///
10868 /// @param qualified_name the qualified name of the type to look for.
10869 ///
10870 /// @param corp the corpus to look into.
10871 union_decl_sptr
lookup_union_type(const interned_string & type_name,const corpus & corp)10872 lookup_union_type(const interned_string& type_name, const corpus& corp)
10873 {
10874 const istring_type_base_wptrs_map_type& m = corp.get_types().union_types();
10875
10876 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
10877 if (!result)
10878 result = lookup_union_type_through_translation_units(type_name, corp);
10879
10880 return result;
10881 }
10882
10883 /// Look into a given corpus to find a union type which has a given
10884 /// qualified name.
10885 ///
10886 /// If the per-corpus type map is non-empty (because the corpus allows
10887 /// the One Definition Rule) then the type islooked up in that
10888 /// per-corpus type map. Otherwise, the type is looked-up in each
10889 /// translation unit.
10890 ///
10891 /// @param qualified_name the qualified name of the type to look for.
10892 ///
10893 /// @param corp the corpus to look into.
10894 union_decl_sptr
lookup_union_type(const string & type_name,const corpus & corp)10895 lookup_union_type(const string& type_name, const corpus& corp)
10896 {
10897 interned_string s = corp.get_environment()->intern(type_name);
10898 return lookup_union_type(s, corp);
10899 }
10900
10901 /// Look into a given corpus to find an enum type which has the same
10902 /// qualified name as a given enum type.
10903 ///
10904 /// If the per-corpus type map is non-empty (because the corpus allows
10905 /// the One Definition Rule) then the type islooked up in that
10906 /// per-corpus type map. Otherwise, the type is looked-up in each
10907 /// translation unit.
10908 ///
10909 /// @param t the enum type which has the same qualified name as the
10910 /// type we are looking for.
10911 ///
10912 /// @param corp the corpus to look into.
10913 enum_type_decl_sptr
lookup_enum_type(const enum_type_decl & t,const corpus & corp)10914 lookup_enum_type(const enum_type_decl& t, const corpus& corp)
10915 {
10916 interned_string s = get_type_name(t);
10917 return lookup_enum_type(s, corp);
10918 }
10919
10920 /// Look into a given corpus to find an enum type which has a given
10921 /// qualified name.
10922 ///
10923 /// If the per-corpus type map is non-empty (because the corpus allows
10924 /// the One Definition Rule) then the type islooked up in that
10925 /// per-corpus type map. Otherwise, the type is looked-up in each
10926 /// translation unit.
10927 ///
10928 /// @param qualified_name the qualified name of the enum type to look
10929 /// for.
10930 ///
10931 /// @param corp the corpus to look into.
10932 enum_type_decl_sptr
lookup_enum_type(const string & qualified_name,const corpus & corp)10933 lookup_enum_type(const string& qualified_name, const corpus& corp)
10934 {
10935 interned_string s = corp.get_environment()->intern(qualified_name);
10936 return lookup_enum_type(s, corp);
10937 }
10938
10939 /// Look into a given corpus to find an enum type which has a given
10940 /// qualified name.
10941 ///
10942 /// If the per-corpus type map is non-empty (because the corpus allows
10943 /// the One Definition Rule) then the type islooked up in that
10944 /// per-corpus type map. Otherwise, the type is looked-up in each
10945 /// translation unit.
10946 ///
10947 /// @param qualified_name the qualified name of the enum type to look
10948 /// for.
10949 ///
10950 /// @param corp the corpus to look into.
10951 enum_type_decl_sptr
lookup_enum_type(const interned_string & qualified_name,const corpus & corp)10952 lookup_enum_type(const interned_string& qualified_name, const corpus& corp)
10953 {
10954 const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
10955
10956 enum_type_decl_sptr result =
10957 lookup_type_in_map<enum_type_decl>(qualified_name, m);
10958 if (!result)
10959 result = lookup_enum_type_through_translation_units(qualified_name, corp);
10960
10961 return result;
10962 }
10963
10964 /// Look into a given corpus to find the enum type*s* that have a
10965 /// given qualified name.
10966 ///
10967 /// @param qualified_name the qualified name of the type to look for.
10968 ///
10969 /// @param corp the corpus to look into.
10970 ///
10971 /// @return the vector of enum types that which name is @p qualified_name.
10972 const type_base_wptrs_type *
lookup_enum_types(const interned_string & qualified_name,const corpus & corp)10973 lookup_enum_types(const interned_string& qualified_name, const corpus& corp)
10974 {
10975 const istring_type_base_wptrs_map_type& m = corp.get_types().enum_types();
10976
10977 return lookup_types_in_map(qualified_name, m);
10978 }
10979
10980 /// Look into a given corpus to find the enum type*s* that have a
10981 /// given qualified name.
10982 ///
10983 /// @param qualified_name the qualified name of the type to look for.
10984 ///
10985 /// @param corp the corpus to look into.
10986 ///
10987 /// @return the vector of enum types that which name is @p qualified_name.
10988 const type_base_wptrs_type*
lookup_enum_types(const string & qualified_name,const corpus & corp)10989 lookup_enum_types(const string& qualified_name, const corpus& corp)
10990 {
10991 interned_string s = corp.get_environment()->intern(qualified_name);
10992 return lookup_enum_types(s, corp);
10993 }
10994
10995 /// Look up an @ref enum_type_decl from a given corpus, by its location.
10996 ///
10997 /// @param loc the location to consider.
10998 ///
10999 /// @param corp the corpus to look the type from.
11000 ///
11001 /// @return the resulting enum type, if any.
11002 enum_type_decl_sptr
lookup_enum_type_per_location(const interned_string & loc,const corpus & corp)11003 lookup_enum_type_per_location(const interned_string &loc, const corpus& corp)
11004 {
11005 const istring_type_base_wptrs_map_type& m =
11006 corp.get_type_per_loc_map().enum_types();
11007 enum_type_decl_sptr result = lookup_type_in_map<enum_type_decl>(loc, m);
11008
11009 return result;
11010 }
11011
11012 /// Look up an @ref enum_type_decl from a given corpus, by its location.
11013 ///
11014 /// @param loc the location to consider.
11015 ///
11016 /// @param corp the corpus to look the type from.
11017 ///
11018 /// @return the resulting enum type, if any.
11019 enum_type_decl_sptr
lookup_enum_type_per_location(const string & loc,const corpus & corp)11020 lookup_enum_type_per_location(const string &loc, const corpus &corp)
11021 {
11022 const environment* env = corp.get_environment();
11023 ABG_ASSERT(env);
11024
11025 return lookup_enum_type_per_location(env->intern(loc), corp);
11026 }
11027
11028 /// Look into a given corpus to find a typedef type which has the
11029 /// same qualified name as a given typedef type.
11030 ///
11031 /// If the per-corpus type map is non-empty (because the corpus allows
11032 /// the One Definition Rule) then the type islooked up in that
11033 /// per-corpus type map. Otherwise, the type is looked-up in each
11034 /// translation unit.
11035 ///
11036 /// @param t the typedef type which has the same qualified name as the
11037 /// typedef type we are looking for.
11038 ///
11039 /// @param corp the corpus to look into.
11040 typedef_decl_sptr
lookup_typedef_type(const typedef_decl & t,const corpus & corp)11041 lookup_typedef_type(const typedef_decl& t, const corpus& corp)
11042 {
11043 interned_string s = get_type_name(t);
11044 return lookup_typedef_type(s, corp);
11045 }
11046
11047 /// Look into a given corpus to find a typedef type which has the
11048 /// same qualified name as a given typedef type.
11049 ///
11050 /// If the per-corpus type map is non-empty (because the corpus allows
11051 /// the One Definition Rule) then the type islooked up in that
11052 /// per-corpus type map. Otherwise, the type is looked-up in each
11053 /// translation unit.
11054 ///
11055 /// @param t the typedef type which has the same qualified name as the
11056 /// typedef type we are looking for.
11057 ///
11058 /// @param corp the corpus to look into.
11059 typedef_decl_sptr
lookup_typedef_type(const string & qualified_name,const corpus & corp)11060 lookup_typedef_type(const string& qualified_name, const corpus& corp)
11061 {
11062 interned_string s = corp.get_environment()->intern(qualified_name);
11063 return lookup_typedef_type(s, corp);
11064 }
11065
11066 /// Look into a given corpus to find a typedef type which has a
11067 /// given qualified name.
11068 ///
11069 /// If the per-corpus type map is non-empty (because the corpus allows
11070 /// the One Definition Rule) then the type islooked up in that
11071 /// per-corpus type map. Otherwise, the type is looked-up in each
11072 /// translation unit.
11073 ///
11074 /// @param qualified_name the qualified name of the typedef type to
11075 /// look for.
11076 ///
11077 /// @param corp the corpus to look into.
11078 typedef_decl_sptr
lookup_typedef_type(const interned_string & qualified_name,const corpus & corp)11079 lookup_typedef_type(const interned_string& qualified_name, const corpus& corp)
11080 {
11081 const istring_type_base_wptrs_map_type& m = corp.get_types().typedef_types();
11082
11083 typedef_decl_sptr result =
11084 lookup_type_in_map<typedef_decl>(qualified_name, m);
11085 if (!result)
11086 result = lookup_typedef_type_through_translation_units(qualified_name,
11087 corp);
11088
11089 return result;
11090 }
11091
11092 /// Lookup a @ref typedef_decl from a corpus, by its location.
11093 ///
11094 /// @param loc the location to consider.
11095 ///
11096 /// @param corp the corpus to consider.
11097 ///
11098 /// @return the typedef_decl found, if any.
11099 typedef_decl_sptr
lookup_typedef_type_per_location(const interned_string & loc,const corpus & corp)11100 lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
11101 {
11102 const istring_type_base_wptrs_map_type& m =
11103 corp.get_type_per_loc_map().typedef_types();
11104 typedef_decl_sptr result = lookup_type_in_map<typedef_decl>(loc, m);
11105
11106 return result;
11107 }
11108
11109 /// Lookup a @ref typedef_decl from a corpus, by its location.
11110 ///
11111 /// @param loc the location to consider.
11112 ///
11113 /// @param corp the corpus to consider.
11114 ///
11115 /// @return the typedef_decl found, if any.
11116 typedef_decl_sptr
lookup_typedef_type_per_location(const string & loc,const corpus & corp)11117 lookup_typedef_type_per_location(const string &loc, const corpus &corp)
11118 {
11119 const environment* env = corp.get_environment();
11120 ABG_ASSERT(env);
11121
11122 return lookup_typedef_type_per_location(env->intern(loc), corp);
11123 }
11124
11125 /// Look into a corpus to find a class, union or typedef type which
11126 /// has a given qualified name.
11127 ///
11128 /// If the per-corpus type map is non-empty (because the corpus allows
11129 /// the One Definition Rule) then the type islooked up in that
11130 /// per-corpus type map. Otherwise, the type is looked-up in each
11131 /// translation unit.
11132 ///
11133 /// @param qualified_name the name of the type to find.
11134 ///
11135 /// @param corp the corpus to look into.
11136 ///
11137 /// @return the typedef or class type found.
11138 type_base_sptr
lookup_class_or_typedef_type(const string & qualified_name,const corpus & corp)11139 lookup_class_or_typedef_type(const string& qualified_name, const corpus& corp)
11140 {
11141 type_base_sptr result = lookup_class_type(qualified_name, corp);
11142 if (!result)
11143 result = lookup_union_type(qualified_name, corp);
11144
11145 if (!result)
11146 result = lookup_typedef_type(qualified_name, corp);
11147 return result;
11148 }
11149
11150 /// Look into a corpus to find a class, typedef or enum type which has
11151 /// a given qualified name.
11152 ///
11153 /// If the per-corpus type map is non-empty (because the corpus allows
11154 /// the One Definition Rule) then the type islooked up in that
11155 /// per-corpus type map. Otherwise, the type is looked-up in each
11156 /// translation unit.
11157 ///
11158 /// @param qualified_name the qualified name of the type to look for.
11159 ///
11160 /// @param corp the corpus to look into.
11161 ///
11162 /// @return the typedef, class or enum type found.
11163 type_base_sptr
lookup_class_typedef_or_enum_type(const string & qualified_name,const corpus & corp)11164 lookup_class_typedef_or_enum_type(const string& qualified_name,
11165 const corpus& corp)
11166 {
11167 type_base_sptr result = lookup_class_or_typedef_type(qualified_name, corp);
11168 if (!result)
11169 result = lookup_enum_type(qualified_name, corp);
11170
11171 return result;
11172 }
11173
11174 /// Look into a given corpus to find a qualified type which has the
11175 /// same qualified name as a given type.
11176 ///
11177 /// @param t the type which has the same qualified name as the
11178 /// qualified type we are looking for.
11179 ///
11180 /// @param corp the corpus to look into.
11181 ///
11182 /// @return the qualified type found.
11183 qualified_type_def_sptr
lookup_qualified_type(const qualified_type_def & t,const corpus & corp)11184 lookup_qualified_type(const qualified_type_def& t, const corpus& corp)
11185 {
11186 interned_string s = get_type_name(t);
11187 return lookup_qualified_type(s, corp);
11188 }
11189
11190 /// Look into a given corpus to find a qualified type which has a
11191 /// given qualified name.
11192 ///
11193 /// @param qualified_name the qualified name of the type to look for.
11194 ///
11195 /// @param corp the corpus to look into.
11196 ///
11197 /// @return the type found.
11198 qualified_type_def_sptr
lookup_qualified_type(const interned_string & qualified_name,const corpus & corp)11199 lookup_qualified_type(const interned_string& qualified_name, const corpus& corp)
11200 {
11201 const istring_type_base_wptrs_map_type& m =
11202 corp.get_types().qualified_types();
11203
11204 qualified_type_def_sptr result =
11205 lookup_type_in_map<qualified_type_def>(qualified_name, m);
11206
11207 if (!result)
11208 result = lookup_qualified_type_through_translation_units(qualified_name,
11209 corp);
11210
11211 return result;
11212 }
11213
11214 /// Look into a given corpus to find a pointer type which has the same
11215 /// qualified name as a given pointer type.
11216 ///
11217 /// @param t the pointer type which has the same qualified name as the
11218 /// type we are looking for.
11219 ///
11220 /// @param corp the corpus to look into.
11221 ///
11222 /// @return the pointer type found.
11223 pointer_type_def_sptr
lookup_pointer_type(const pointer_type_def & t,const corpus & corp)11224 lookup_pointer_type(const pointer_type_def& t, const corpus& corp)
11225 {
11226 interned_string s = get_type_name(t);
11227 return lookup_pointer_type(s, corp);
11228 }
11229
11230 /// Look into a given corpus to find a pointer type which has a given
11231 /// qualified name.
11232 ///
11233 /// If the per-corpus type map is non-empty (because the corpus allows
11234 /// the One Definition Rule) then the type islooked up in that
11235 /// per-corpus type map. Otherwise, the type is looked-up in each
11236 /// translation unit.
11237 ///
11238 /// @param qualified_name the qualified name of the pointer type to
11239 /// look for.
11240 ///
11241 /// @param corp the corpus to look into.
11242 ///
11243 /// @return the pointer type found.
11244 pointer_type_def_sptr
lookup_pointer_type(const interned_string & qualified_name,const corpus & corp)11245 lookup_pointer_type(const interned_string& qualified_name, const corpus& corp)
11246 {
11247 const istring_type_base_wptrs_map_type& m = corp.get_types().pointer_types();
11248
11249 pointer_type_def_sptr result =
11250 lookup_type_in_map<pointer_type_def>(qualified_name, m);
11251 if (!result)
11252 result = lookup_pointer_type_through_translation_units(qualified_name,
11253 corp);
11254
11255 return result;
11256 }
11257
11258 /// Look into a given corpus to find a reference type which has the
11259 /// same qualified name as a given reference type.
11260 ///
11261 /// If the per-corpus type map is non-empty (because the corpus allows
11262 /// the One Definition Rule) then the type islooked up in that
11263 /// per-corpus type map. Otherwise, the type is looked-up in each
11264 /// translation unit.
11265 ///
11266 /// @param t the reference type which has the same qualified name as
11267 /// the reference type we are looking for.
11268 ///
11269 /// @param corp the corpus to look into.
11270 ///
11271 /// @return the reference type found.
11272 reference_type_def_sptr
lookup_reference_type(const reference_type_def & t,const corpus & corp)11273 lookup_reference_type(const reference_type_def& t, const corpus& corp)
11274 {
11275 interned_string s = get_type_name(t);
11276 return lookup_reference_type(s, corp);
11277 }
11278
11279 /// Look into a given corpus to find a reference type which has a
11280 /// given qualified name.
11281 ///
11282 /// If the per-corpus type map is non-empty (because the corpus allows
11283 /// the One Definition Rule) then the type islooked up in that
11284 /// per-corpus type map. Otherwise, the type is looked-up in each
11285 /// translation unit.
11286 ///
11287 /// @param qualified_name the qualified name of the reference type to
11288 /// look for.
11289 ///
11290 /// @param corp the corpus to look into.
11291 ///
11292 /// @return the reference type found.
11293 reference_type_def_sptr
lookup_reference_type(const interned_string & qualified_name,const corpus & corp)11294 lookup_reference_type(const interned_string& qualified_name, const corpus& corp)
11295 {
11296 const istring_type_base_wptrs_map_type& m =
11297 corp.get_types().reference_types();
11298
11299 reference_type_def_sptr result =
11300 lookup_type_in_map<reference_type_def>(qualified_name, m);
11301 if (!result)
11302 result = lookup_reference_type_through_translation_units(qualified_name,
11303 corp);
11304
11305 return result;
11306 }
11307
11308 /// Look into a given corpus to find an array type which has a given
11309 /// qualified name.
11310 ///
11311 /// If the per-corpus type map is non-empty (because the corpus allows
11312 /// the One Definition Rule) then the type islooked up in that
11313 /// per-corpus type map. Otherwise, the type is looked-up in each
11314 /// translation unit.
11315 ///
11316 /// @param qualified_name the qualified name of the array type to look
11317 /// for.
11318 ///
11319 /// @param corp the corpus to look into.
11320 ///
11321 /// @return the array type found.
11322 array_type_def_sptr
lookup_array_type(const array_type_def & t,const corpus & corp)11323 lookup_array_type(const array_type_def& t, const corpus& corp)
11324 {
11325 interned_string s = get_type_name(t);
11326 return lookup_array_type(s, corp);
11327 }
11328
11329 /// Look into a given corpus to find an array type which has the same
11330 /// qualified name as a given array type.
11331 ///
11332 /// If the per-corpus type map is non-empty (because the corpus allows
11333 /// the One Definition Rule) then the type islooked up in that
11334 /// per-corpus type map. Otherwise, the type is looked-up in each
11335 /// translation unit.
11336 ///
11337 /// @param t the type which has the same qualified name as the type we
11338 /// are looking for.
11339 ///
11340 /// @param corp the corpus to look into.
11341 ///
11342 /// @return the type found.
11343 array_type_def_sptr
lookup_array_type(const interned_string & qualified_name,const corpus & corp)11344 lookup_array_type(const interned_string& qualified_name, const corpus& corp)
11345 {
11346 const istring_type_base_wptrs_map_type& m = corp.get_types().array_types();
11347
11348 array_type_def_sptr result =
11349 lookup_type_in_map<array_type_def>(qualified_name, m);
11350 if (!result)
11351 result = lookup_array_type_through_translation_units(qualified_name, corp);
11352
11353 return result;
11354 }
11355
11356 /// Look into a given corpus to find a function type which has the same
11357 /// qualified name as a given function type.
11358 ///
11359 /// If the per-corpus type map is non-empty (because the corpus allows
11360 /// the One Definition Rule) then the type islooked up in that
11361 /// per-corpus type map. Otherwise, the type is looked-up in each
11362 /// translation unit.
11363 ///
11364 /// @param t the function type which has the same qualified name as
11365 /// the function type we are looking for.
11366 ///
11367 /// @param corp the corpus to look into.
11368 ///
11369 /// @return the function type found.
11370 function_type_sptr
lookup_function_type(const function_type & t,const corpus & corp)11371 lookup_function_type(const function_type&t, const corpus& corp)
11372 {
11373 interned_string type_name = get_type_name(t);
11374 return lookup_function_type(type_name, corp);
11375 }
11376
11377 /// Look into a given corpus to find a function type which has the same
11378 /// qualified name as a given function type.
11379 ///
11380 /// If the per-corpus type map is non-empty (because the corpus allows
11381 /// the One Definition Rule) then the type islooked up in that
11382 /// per-corpus type map. Otherwise, the type is looked-up in each
11383 /// translation unit.
11384 ///
11385 /// @param t the function type which has the same qualified name as
11386 /// the function type we are looking for.
11387 ///
11388 /// @param corp the corpus to look into.
11389 ///
11390 /// @return the function type found.
11391 function_type_sptr
lookup_function_type(const function_type_sptr & fn_t,const corpus & corpus)11392 lookup_function_type(const function_type_sptr& fn_t,
11393 const corpus& corpus)
11394 {
11395 if (fn_t)
11396 return lookup_function_type(*fn_t, corpus);
11397 return function_type_sptr();
11398 }
11399
11400 /// Look into a given corpus to find a function type which has a given
11401 /// qualified name.
11402 ///
11403 /// If the per-corpus type map is non-empty (because the corpus allows
11404 /// the One Definition Rule) then the type islooked up in that
11405 /// per-corpus type map. Otherwise, the type is looked-up in each
11406 /// translation unit.
11407 ///
11408 /// @param qualified_name the qualified name of the function type to
11409 /// look for.
11410 ///
11411 /// @param corp the corpus to look into.
11412 ///
11413 /// @return the function type found.
11414 function_type_sptr
lookup_function_type(const interned_string & qualified_name,const corpus & corp)11415 lookup_function_type(const interned_string& qualified_name, const corpus& corp)
11416 {
11417 const istring_type_base_wptrs_map_type& m = corp.get_types().function_types();
11418
11419 function_type_sptr result =
11420 lookup_type_in_map<function_type>(qualified_name, m);
11421 if (!result)
11422 result = lookup_function_type_through_translation_units(qualified_name,
11423 corp);
11424
11425 return result;
11426 }
11427
11428 /// Look into a given corpus to find a type which has a given
11429 /// qualified name.
11430 ///
11431 /// If the per-corpus type map is non-empty (because the corpus allows
11432 /// the One Definition Rule) then the type islooked up in that
11433 /// per-corpus type map. Otherwise, the type is looked-up in each
11434 /// translation unit.
11435 ///
11436 /// @param qualified_name the qualified name of the function type to
11437 /// look for.
11438 ///
11439 /// @param corp the corpus to look into.
11440 ///
11441 /// @return the function type found.
11442 type_base_sptr
lookup_type(const interned_string & n,const corpus & corp)11443 lookup_type(const interned_string& n, const corpus& corp)
11444 {
11445 type_base_sptr result;
11446
11447 ((result = lookup_basic_type(n, corp))
11448 || (result = lookup_class_type(n, corp))
11449 || (result = lookup_union_type(n, corp))
11450 || (result = lookup_enum_type(n, corp))
11451 || (result = lookup_typedef_type(n, corp))
11452 || (result = lookup_qualified_type(n, corp))
11453 || (result = lookup_pointer_type(n, corp))
11454 || (result = lookup_reference_type(n, corp))
11455 || (result = lookup_array_type(n, corp))
11456 || (result= lookup_function_type(n, corp)));
11457
11458 return result;
11459 }
11460
11461 /// Lookup a type from a corpus, by its location.
11462 ///
11463 /// @param loc the location to consider.
11464 ///
11465 /// @param corp the corpus to look the type from.
11466 ///
11467 /// @return the resulting type, if any found.
11468 type_base_sptr
lookup_type_per_location(const interned_string & loc,const corpus & corp)11469 lookup_type_per_location(const interned_string& loc, const corpus& corp)
11470 {
11471 // TODO: finish this.
11472
11473 //TODO: when we fully support types indexed by their location, this
11474 //function should return a vector of types because at each location,
11475 //there can be several types that are defined (yay, C and C++,
11476 //*sigh*).
11477
11478 type_base_sptr result;
11479 ((result = lookup_basic_type_per_location(loc, corp))
11480 || (result = lookup_class_type_per_location(loc, corp))
11481 || (result = lookup_union_type_per_location(loc, corp))
11482 || (result = lookup_enum_type_per_location(loc, corp))
11483 || (result = lookup_typedef_type_per_location(loc, corp)));
11484
11485 return result;
11486 }
11487
11488 /// Look into a given corpus to find a type
11489 ///
11490 /// If the per-corpus type map is non-empty (because the corpus allows
11491 /// the One Definition Rule) then the type islooked up in that
11492 /// per-corpus type map. Otherwise, the type is looked-up in each
11493 /// translation unit.
11494 ///
11495 /// @param qualified_name the qualified name of the function type to
11496 /// look for.
11497 ///
11498 /// @param corp the corpus to look into.
11499 ///
11500 /// @return the function type found.
11501 type_base_sptr
lookup_type(const type_base & t,const corpus & corp)11502 lookup_type(const type_base&t, const corpus& corp)
11503 {
11504 interned_string n = get_type_name(t);
11505 return lookup_type(n, corp);
11506 }
11507
11508 /// Look into a given corpus to find a type
11509 ///
11510 /// If the per-corpus type map is non-empty (because the corpus allows
11511 /// the One Definition Rule) then the type islooked up in that
11512 /// per-corpus type map. Otherwise, the type is looked-up in each
11513 /// translation unit.
11514 ///
11515 /// @param qualified_name the qualified name of the function type to
11516 /// look for.
11517 ///
11518 /// @param corp the corpus to look into.
11519 ///
11520 /// @return the function type found.
11521 type_base_sptr
lookup_type(const type_base_sptr & t,const corpus & corp)11522 lookup_type(const type_base_sptr&t, const corpus& corp)
11523 {
11524 if (t)
11525 return lookup_type(*t, corp);
11526 return type_base_sptr();
11527 }
11528
11529 /// Update the map that associates a fully qualified name of a given
11530 /// type to that type.
11531 ///
11532 ///
11533 /// @param type the type we are considering.
11534 ///
11535 /// @param types_map the map to update. It's a map that assciates a
11536 /// fully qualified name of a type to the type itself.
11537 ///
11538 /// @param use_type_name_as_key if true, use the name of the type as
11539 /// the key to look it up later. If false, then use the location of
11540 /// the type as a key to look it up later.
11541 ///
11542 /// @return true iff the type was added to the map.
11543 template<typename TypeKind>
11544 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)11545 maybe_update_types_lookup_map(const shared_ptr<TypeKind>& type,
11546 istring_type_base_wptrs_map_type& types_map,
11547 bool use_type_name_as_key = true)
11548 {
11549 interned_string s;
11550
11551 if (use_type_name_as_key)
11552 s = get_type_name(type);
11553 else if (location l = type->get_location())
11554 {
11555 string str = l.expand();
11556 s = type->get_environment()->intern(str);
11557 }
11558
11559 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
11560 bool result = false;
11561
11562 if (i == types_map.end())
11563 {
11564 types_map[s].push_back(type);
11565 result = true;
11566 }
11567 else
11568 i->second.push_back(type);
11569
11570 return result;
11571 }
11572
11573 /// This is the specialization for type @ref class_decl of the
11574 /// function template:
11575 ///
11576 /// maybe_update_types_lookup_map<T>(scope_decl*,
11577 /// const shared_ptr<T>&,
11578 /// istring_type_base_wptrs_map_type&)
11579 ///
11580 /// @param class_type the type to consider.
11581 ///
11582 /// @param types_map the type map to update.
11583 ///
11584 /// @return true iff the type was added to the map.
11585 template<>
11586 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)11587 maybe_update_types_lookup_map<class_decl>(const class_decl_sptr& class_type,
11588 istring_type_base_wptrs_map_type& map,
11589 bool use_type_name_as_key)
11590 {
11591 class_decl_sptr type = class_type;
11592
11593 bool update_qname_map = true;
11594 if (type->get_is_declaration_only())
11595 {
11596 if (class_decl_sptr def =
11597 is_class_type(class_type->get_definition_of_declaration()))
11598 type = def;
11599 else
11600 update_qname_map = false;
11601 }
11602
11603 if (!update_qname_map)
11604 return false;
11605
11606 interned_string s;
11607 if (use_type_name_as_key)
11608 {
11609 string qname = type->get_qualified_name();
11610 s = type->get_environment()->intern(qname);
11611 }
11612 else if (location l = type->get_location())
11613 {
11614 string str = l.expand();
11615 s = type->get_environment()->intern(str);
11616 }
11617
11618 bool result = false;
11619 istring_type_base_wptrs_map_type::iterator i = map.find(s);
11620 if (i == map.end())
11621 {
11622 map[s].push_back(type);
11623 result = true;
11624 }
11625 else
11626 i->second.push_back(type);
11627
11628 return result;
11629 }
11630
11631 /// This is the specialization for type @ref function_type of the
11632 /// function template:
11633 ///
11634 /// maybe_update_types_lookup_map<T>(scope_decl*,
11635 /// const shared_ptr<T>&,
11636 /// istring_type_base_wptrs_map_type&)
11637 ///
11638 /// @param scope the scope of the type to consider.
11639 ///
11640 /// @param class_type the type to consider.
11641 ///
11642 /// @param types_map the type map to update.
11643 ///
11644 /// @return true iff the type was added to the map.
11645 template<>
11646 bool
maybe_update_types_lookup_map(const function_type_sptr & type,istring_type_base_wptrs_map_type & types_map,bool)11647 maybe_update_types_lookup_map<function_type>
11648 (const function_type_sptr& type,
11649 istring_type_base_wptrs_map_type& types_map,
11650 bool /*use_type_name_as_key*/)
11651 {
11652 bool result = false;
11653 interned_string s = get_type_name(type);
11654 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
11655 if (i == types_map.end())
11656 {
11657 types_map[s].push_back(type);
11658 result = true;
11659 }
11660 else
11661 i->second.push_back(type);
11662
11663 return result;
11664 }
11665
11666 /// Update the map that associates the fully qualified name of a basic
11667 /// type with the type itself.
11668 ///
11669 /// The per-translation unit type map is updated if no type with this
11670 /// name was already existing in that map.
11671 ///
11672 /// If no type with this name did already exist in the per-corpus type
11673 /// map, then that per-corpus type map is updated. Otherwise, that
11674 /// type is erased from that per-corpus map.
11675 ///
11676 /// @param basic_type the basic type to consider.
11677 void
maybe_update_types_lookup_map(const type_decl_sptr & basic_type)11678 maybe_update_types_lookup_map(const type_decl_sptr& basic_type)
11679 {
11680 if (translation_unit *tu = basic_type->get_translation_unit())
11681 maybe_update_types_lookup_map<type_decl>
11682 (basic_type, tu->get_types().basic_types());
11683
11684 if (corpus *type_corpus = basic_type->get_corpus())
11685 {
11686 maybe_update_types_lookup_map<type_decl>
11687 (basic_type,
11688 type_corpus->priv_->get_types().basic_types());
11689
11690 maybe_update_types_lookup_map<type_decl>
11691 (basic_type,
11692 type_corpus->get_type_per_loc_map().basic_types(),
11693 /*use_type_name_as_key*/false);
11694
11695 if (corpus *group = type_corpus->get_group())
11696 {
11697 maybe_update_types_lookup_map<type_decl>
11698 (basic_type,
11699 group->priv_->get_types().basic_types());
11700
11701 maybe_update_types_lookup_map<type_decl>
11702 (basic_type,
11703 group->get_type_per_loc_map().basic_types(),
11704 /*use_type_name_as_key*/false);
11705 }
11706 }
11707
11708 }
11709
11710 /// Update the map that associates the fully qualified name of a class
11711 /// type with the type itself.
11712 ///
11713 /// The per-translation unit type map is updated if no type with this
11714 /// name was already existing in that map.
11715 ///
11716 /// If no type with this name did already exist in the per-corpus type
11717 /// map, then that per-corpus type map is updated. Otherwise, that
11718 /// type is erased from that per-corpus map.
11719 ///
11720 /// @param class_type the class type to consider.
11721 void
maybe_update_types_lookup_map(const class_decl_sptr & class_type)11722 maybe_update_types_lookup_map(const class_decl_sptr& class_type)
11723 {
11724 if (translation_unit *tu = class_type->get_translation_unit())
11725 maybe_update_types_lookup_map<class_decl>
11726 (class_type, tu->get_types().class_types());
11727
11728 if (corpus *type_corpus = class_type->get_corpus())
11729 {
11730 maybe_update_types_lookup_map<class_decl>
11731 (class_type,
11732 type_corpus->priv_->get_types().class_types());
11733
11734 maybe_update_types_lookup_map<class_decl>
11735 (class_type,
11736 type_corpus->get_type_per_loc_map().class_types(),
11737 /*use_type_name_as_key*/false);
11738
11739 if (corpus *group = type_corpus->get_group())
11740 {
11741 maybe_update_types_lookup_map<class_decl>
11742 (class_type,
11743 group->priv_->get_types().class_types());
11744
11745 maybe_update_types_lookup_map<class_decl>
11746 (class_type,
11747 group->get_type_per_loc_map().class_types(),
11748 /*use_type_name_as_key*/false);
11749 }
11750 }
11751 }
11752
11753 /// Update the map that associates the fully qualified name of a union
11754 /// type with the type itself.
11755 ///
11756 /// The per-translation unit type map is updated if no type with this
11757 /// name was already existing in that map.
11758 ///
11759 /// If no type with this name did already exist in the per-corpus type
11760 /// map, then that per-corpus type map is updated. Otherwise, that
11761 /// type is erased from that per-corpus map.
11762 ///
11763 /// @param union_type the union type to consider.
11764 void
maybe_update_types_lookup_map(const union_decl_sptr & union_type)11765 maybe_update_types_lookup_map(const union_decl_sptr& union_type)
11766 {
11767 if (translation_unit *tu = union_type->get_translation_unit())
11768 maybe_update_types_lookup_map<union_decl>
11769 (union_type, tu->get_types().union_types());
11770
11771 if (corpus *type_corpus = union_type->get_corpus())
11772 {
11773 maybe_update_types_lookup_map<union_decl>
11774 (union_type,
11775 type_corpus->priv_->get_types().union_types());
11776
11777 maybe_update_types_lookup_map<union_decl>
11778 (union_type,
11779 type_corpus->get_type_per_loc_map().union_types(),
11780 /*use_type_name_as_key*/false);
11781
11782 if (corpus *group = type_corpus->get_group())
11783 {
11784 maybe_update_types_lookup_map<union_decl>
11785 (union_type,
11786 group->priv_->get_types().union_types());
11787
11788 maybe_update_types_lookup_map<union_decl>
11789 (union_type,
11790 group->get_type_per_loc_map().union_types(),
11791 /*use_type_name_as_key*/false);
11792 }
11793 }
11794 }
11795
11796 /// Update the map that associates the fully qualified name of an enum
11797 /// type with the type itself.
11798 ///
11799 /// The per-translation unit type map is updated if no type with this
11800 /// name was already existing in that map.
11801 ///
11802 /// If no type with this name did already exist in the per-corpus type
11803 /// map, then that per-corpus type map is updated. Otherwise, that
11804 /// type is erased from that per-corpus map.
11805 ///
11806 /// @param enum_type the type to consider.
11807 void
maybe_update_types_lookup_map(const enum_type_decl_sptr & enum_type)11808 maybe_update_types_lookup_map(const enum_type_decl_sptr& enum_type)
11809 {
11810 if (translation_unit *tu = enum_type->get_translation_unit())
11811 maybe_update_types_lookup_map<enum_type_decl>
11812 (enum_type, tu->get_types().enum_types());
11813
11814 if (corpus *type_corpus = enum_type->get_corpus())
11815 {
11816 maybe_update_types_lookup_map<enum_type_decl>
11817 (enum_type,
11818 type_corpus->priv_->get_types().enum_types());
11819
11820 maybe_update_types_lookup_map<enum_type_decl>
11821 (enum_type,
11822 type_corpus->get_type_per_loc_map().enum_types(),
11823 /*use_type_name_as_key*/false);
11824
11825 if (corpus *group = type_corpus->get_group())
11826 {
11827 maybe_update_types_lookup_map<enum_type_decl>
11828 (enum_type,
11829 group->priv_->get_types().enum_types());
11830
11831 maybe_update_types_lookup_map<enum_type_decl>
11832 (enum_type,
11833 group->get_type_per_loc_map().enum_types(),
11834 /*use_type_name_as_key*/false);
11835 }
11836 }
11837
11838 }
11839
11840 /// Update the map that associates the fully qualified name of a
11841 /// typedef type with the type itself.
11842 ///
11843 /// The per-translation unit type map is updated if no type with this
11844 /// name was already existing in that map.
11845 ///
11846 /// If no type with this name did already exist in the per-corpus type
11847 /// map, then that per-corpus type map is updated. Otherwise, that
11848 /// type is erased from that per-corpus map.
11849 ///
11850 /// @param typedef_type the type to consider.
11851 void
maybe_update_types_lookup_map(const typedef_decl_sptr & typedef_type)11852 maybe_update_types_lookup_map(const typedef_decl_sptr& typedef_type)
11853 {
11854 if (translation_unit *tu = typedef_type->get_translation_unit())
11855 maybe_update_types_lookup_map<typedef_decl>
11856 (typedef_type, tu->get_types().typedef_types());
11857
11858 if (corpus *type_corpus = typedef_type->get_corpus())
11859 {
11860 maybe_update_types_lookup_map<typedef_decl>
11861 (typedef_type,
11862 type_corpus->priv_->get_types().typedef_types());
11863
11864 maybe_update_types_lookup_map<typedef_decl>
11865 (typedef_type,
11866 type_corpus->get_type_per_loc_map().typedef_types(),
11867 /*use_type_name_as_key*/false);
11868
11869 if (corpus *group = type_corpus->get_group())
11870 {
11871 maybe_update_types_lookup_map<typedef_decl>
11872 (typedef_type,
11873 group->priv_->get_types().typedef_types());
11874
11875 maybe_update_types_lookup_map<typedef_decl>
11876 (typedef_type,
11877 group->get_type_per_loc_map().typedef_types(),
11878 /*use_type_name_as_key*/false);
11879 }
11880 }
11881 }
11882
11883 /// Update the map that associates the fully qualified name of a
11884 /// qualified type with the type itself.
11885 ///
11886 /// The per-translation unit type map is updated if no type with this
11887 /// name was already existing in that map.
11888 ///
11889 /// If no type with this name did already exist in the per-corpus type
11890 /// map, then that per-corpus type map is updated. Otherwise, that
11891 /// type is erased from that per-corpus map.
11892 ///
11893 /// @param qualified_type the type to consider.
11894 void
maybe_update_types_lookup_map(const qualified_type_def_sptr & qualified_type)11895 maybe_update_types_lookup_map(const qualified_type_def_sptr& qualified_type)
11896 {
11897 if (translation_unit *tu = qualified_type->get_translation_unit())
11898 maybe_update_types_lookup_map<qualified_type_def>
11899 (qualified_type, tu->get_types().qualified_types());
11900
11901 if (corpus *type_corpus = qualified_type->get_corpus())
11902 {
11903 maybe_update_types_lookup_map<qualified_type_def>
11904 (qualified_type,
11905 type_corpus->priv_->get_types().qualified_types());
11906
11907 if (corpus *group = type_corpus->get_group())
11908 {
11909 maybe_update_types_lookup_map<qualified_type_def>
11910 (qualified_type,
11911 group->priv_->get_types().qualified_types());
11912 }
11913 }
11914 }
11915
11916 /// Update the map that associates the fully qualified name of a
11917 /// pointer type with the type itself.
11918 ///
11919 /// The per-translation unit type map is updated if no type with this
11920 /// name was already existing in that map.
11921 ///
11922 /// If no type with this name did already exist in the per-corpus type
11923 /// map, then that per-corpus type map is updated. Otherwise, that
11924 /// type is erased from that per-corpus map.
11925 ///
11926 /// @param pointer_type the type to consider.
11927 void
maybe_update_types_lookup_map(const pointer_type_def_sptr & pointer_type)11928 maybe_update_types_lookup_map(const pointer_type_def_sptr& pointer_type)
11929 {
11930 if (translation_unit *tu = pointer_type->get_translation_unit())
11931 maybe_update_types_lookup_map<pointer_type_def>
11932 (pointer_type, tu->get_types().pointer_types());
11933
11934 if (corpus *type_corpus = pointer_type->get_corpus())
11935 {
11936 maybe_update_types_lookup_map<pointer_type_def>
11937 (pointer_type,
11938 type_corpus->priv_->get_types().pointer_types());
11939
11940 if (corpus *group = type_corpus->get_group())
11941 {
11942 maybe_update_types_lookup_map<pointer_type_def>
11943 (pointer_type,
11944 group->priv_->get_types().pointer_types());
11945 }
11946 }
11947 }
11948
11949 /// Update the map that associates the fully qualified name of a
11950 /// reference type with the type itself.
11951 ///
11952 /// The per-translation unit type map is updated if no type with this
11953 /// name was already existing in that map.
11954 ///
11955 /// If no type with this name did already exist in the per-corpus type
11956 /// map, then that per-corpus type map is updated. Otherwise, that
11957 /// type is erased from that per-corpus map.
11958 ///
11959 /// @param reference_type the type to consider.
11960 void
maybe_update_types_lookup_map(const reference_type_def_sptr & reference_type)11961 maybe_update_types_lookup_map(const reference_type_def_sptr& reference_type)
11962 {
11963 if (translation_unit *tu = reference_type->get_translation_unit())
11964 maybe_update_types_lookup_map<reference_type_def>
11965 (reference_type, tu->get_types().reference_types());
11966
11967 if (corpus *type_corpus = reference_type->get_corpus())
11968 {
11969 maybe_update_types_lookup_map<reference_type_def>
11970 (reference_type,
11971 type_corpus->priv_->get_types().reference_types());
11972
11973 if (corpus *group = type_corpus->get_group())
11974 {
11975 maybe_update_types_lookup_map<reference_type_def>
11976 (reference_type,
11977 group->priv_->get_types().reference_types());
11978 }
11979 }
11980 }
11981
11982 /// Update the map that associates the fully qualified name of a type
11983 /// with the type itself.
11984 ///
11985 /// The per-translation unit type map is updated if no type with this
11986 /// name was already existing in that map.
11987 ///
11988 /// If no type with this name did already exist in the per-corpus type
11989 /// map, then that per-corpus type map is updated. Otherwise, that
11990 /// type is erased from that per-corpus map.
11991 ///
11992 /// @param array_type the type to consider.
11993 void
maybe_update_types_lookup_map(const array_type_def_sptr & array_type)11994 maybe_update_types_lookup_map(const array_type_def_sptr& array_type)
11995 {
11996 if (translation_unit *tu = array_type->get_translation_unit())
11997 maybe_update_types_lookup_map<array_type_def>
11998 (array_type, tu->get_types().array_types());
11999
12000 if (corpus *type_corpus = array_type->get_corpus())
12001 {
12002 maybe_update_types_lookup_map<array_type_def>
12003 (array_type,
12004 type_corpus->priv_->get_types().array_types());
12005
12006 maybe_update_types_lookup_map<array_type_def>
12007 (array_type,
12008 type_corpus->get_type_per_loc_map().array_types(),
12009 /*use_type_name_as_key*/false);
12010
12011 if (corpus *group = type_corpus->get_group())
12012 {
12013 maybe_update_types_lookup_map<array_type_def>
12014 (array_type,
12015 group->priv_->get_types().array_types());
12016
12017 maybe_update_types_lookup_map<array_type_def>
12018 (array_type,
12019 group->get_type_per_loc_map().array_types(),
12020 /*use_type_name_as_key*/false);
12021 }
12022 }
12023 }
12024
12025 /// Update the map that associates the fully qualified name of a type
12026 /// with the type itself.
12027 ///
12028 /// The per-translation unit type map is updated if no type with this
12029 /// name was already existing in that map.
12030 ///
12031 /// If no type with this name did already exist in the per-corpus type
12032 /// map, then that per-corpus type map is updated. Otherwise, that
12033 /// type is erased from that per-corpus map.
12034 ///
12035 /// @param subrange_type the type to consider.
12036 void
maybe_update_types_lookup_map(const array_type_def::subrange_sptr & subrange_type)12037 maybe_update_types_lookup_map
12038 (const array_type_def::subrange_sptr& subrange_type)
12039 {
12040 if (translation_unit *tu = subrange_type->get_translation_unit())
12041 maybe_update_types_lookup_map<array_type_def::subrange_type>
12042 (subrange_type, tu->get_types().subrange_types());
12043
12044 if (corpus *type_corpus = subrange_type->get_corpus())
12045 {
12046 maybe_update_types_lookup_map<array_type_def::subrange_type>
12047 (subrange_type,
12048 type_corpus->priv_->get_types().subrange_types());
12049
12050 maybe_update_types_lookup_map<array_type_def::subrange_type>
12051 (subrange_type,
12052 type_corpus->get_type_per_loc_map().subrange_types(),
12053 /*use_type_name_as_key*/false);
12054
12055 if (corpus *group = subrange_type->get_corpus())
12056 {
12057 maybe_update_types_lookup_map<array_type_def::subrange_type>
12058 (subrange_type,
12059 group->priv_->get_types().subrange_types());
12060
12061 maybe_update_types_lookup_map<array_type_def::subrange_type>
12062 (subrange_type,
12063 group->get_type_per_loc_map().subrange_types(),
12064 /*use_type_name_as_key*/false);
12065 }
12066 }
12067 }
12068
12069 /// Update the map that associates the fully qualified name of a
12070 /// function type with the type itself.
12071 ///
12072 /// The per-translation unit type map is updated if no type with this
12073 /// name was already existing in that map.
12074 ///
12075 /// If no type with this name did already exist in the per-corpus type
12076 /// map, then that per-corpus type map is updated. Otherwise, that
12077 /// type is erased from that per-corpus map.
12078 ///
12079 /// @param scope the scope of the function type.
12080 /// @param fn_type the type to consider.
12081 void
maybe_update_types_lookup_map(const function_type_sptr & fn_type)12082 maybe_update_types_lookup_map(const function_type_sptr& fn_type)
12083 {
12084 if (translation_unit *tu = fn_type->get_translation_unit())
12085 maybe_update_types_lookup_map<function_type>
12086 (fn_type, tu->get_types().function_types());
12087
12088 if (corpus *type_corpus = fn_type->get_corpus())
12089 {
12090 maybe_update_types_lookup_map<function_type>
12091 (fn_type,
12092 type_corpus->priv_->get_types().function_types());
12093
12094 if (corpus *group = fn_type->get_corpus())
12095 {
12096 maybe_update_types_lookup_map<function_type>
12097 (fn_type,
12098 group->priv_->get_types().function_types());
12099 }
12100 }
12101 }
12102
12103 /// Update the map that associates the fully qualified name of a type
12104 /// declaration with the type itself.
12105 ///
12106 /// The per-translation unit type map is updated if no type with this
12107 /// name was already existing in that map.
12108 ///
12109 /// If no type with this name did already exist in the per-corpus type
12110 /// map, then that per-corpus type map is updated. Otherwise, that
12111 /// type is erased from that per-corpus map.
12112 ///
12113 /// @param decl the declaration of the type to consider.
12114 void
maybe_update_types_lookup_map(const decl_base_sptr & decl)12115 maybe_update_types_lookup_map(const decl_base_sptr& decl)
12116 {
12117 if (!is_type(decl))
12118 return;
12119
12120 if (type_decl_sptr basic_type = is_type_decl(decl))
12121 maybe_update_types_lookup_map(basic_type);
12122 else if (class_decl_sptr class_type = is_class_type(decl))
12123 maybe_update_types_lookup_map(class_type);
12124 else if (union_decl_sptr union_type = is_union_type(decl))
12125 maybe_update_types_lookup_map(union_type);
12126 else if (enum_type_decl_sptr enum_type = is_enum_type(decl))
12127 maybe_update_types_lookup_map(enum_type);
12128 else if (typedef_decl_sptr typedef_type = is_typedef(decl))
12129 maybe_update_types_lookup_map(typedef_type);
12130 else if (qualified_type_def_sptr qualified_type = is_qualified_type(decl))
12131 maybe_update_types_lookup_map(qualified_type);
12132 else if (pointer_type_def_sptr pointer_type = is_pointer_type(decl))
12133 maybe_update_types_lookup_map(pointer_type);
12134 else if (reference_type_def_sptr reference_type = is_reference_type(decl))
12135 maybe_update_types_lookup_map(reference_type);
12136 else if (array_type_def_sptr array_type = is_array_type(decl))
12137 maybe_update_types_lookup_map(array_type);
12138 else if (array_type_def::subrange_sptr subrange_type = is_subrange_type(decl))
12139 maybe_update_types_lookup_map(subrange_type);
12140 else
12141 ABG_ASSERT_NOT_REACHED;
12142 }
12143
12144 /// Update the map that associates the fully qualified name of a type
12145 /// with the type itself.
12146 ///
12147 /// The per-translation unit type map is updated if no type with this
12148 /// name was already existing in that map.
12149 ///
12150 /// If no type with this name did already exist in the per-corpus type
12151 /// map, then that per-corpus type map is updated. Otherwise, that
12152 /// type is erased from that per-corpus map.
12153 ///
12154 /// @param type the type to consider.
12155 void
maybe_update_types_lookup_map(const type_base_sptr & type)12156 maybe_update_types_lookup_map(const type_base_sptr& type)
12157 {
12158 if (decl_base_sptr decl = get_type_declaration(type))
12159 maybe_update_types_lookup_map(decl);
12160 else
12161 ABG_ASSERT_NOT_REACHED;
12162 }
12163
12164 //--------------------------------
12165 // </type and decls lookup stuff>
12166 // ------------------------------
12167
12168 /// In a translation unit, lookup a given type or synthesize it if
12169 /// it's a qualified type.
12170 ///
12171 /// So this function first looks the type up in the translation unit.
12172 /// If it's found, then OK, it's returned. Otherwise, if it's a
12173 /// qualified, reference or pointer or function type (a composite
12174 /// type), lookup the underlying type, synthesize the type we want
12175 /// from it and return it.
12176 ///
12177 /// If the underlying types is not not found, then give up and return
12178 /// nil.
12179 ///
12180 /// @return the type that was found or the synthesized type.
12181 type_base_sptr
synthesize_type_from_translation_unit(const type_base_sptr & type,translation_unit & tu)12182 synthesize_type_from_translation_unit(const type_base_sptr& type,
12183 translation_unit& tu)
12184 {
12185 type_base_sptr result;
12186
12187 result = lookup_type(type, tu);
12188
12189 if (!result)
12190 {
12191 if (qualified_type_def_sptr qual = is_qualified_type(type))
12192 {
12193 type_base_sptr underlying_type =
12194 synthesize_type_from_translation_unit(qual->get_underlying_type(),
12195 tu);
12196 if (underlying_type)
12197 {
12198 result.reset(new qualified_type_def(underlying_type,
12199 qual->get_cv_quals(),
12200 qual->get_location()));
12201 }
12202 }
12203 else if (pointer_type_def_sptr p = is_pointer_type(type))
12204 {
12205 type_base_sptr pointed_to_type =
12206 synthesize_type_from_translation_unit(p->get_pointed_to_type(),
12207 tu);
12208 if (pointed_to_type)
12209 {
12210 result.reset(new pointer_type_def(pointed_to_type,
12211 p->get_size_in_bits(),
12212 p->get_alignment_in_bits(),
12213 p->get_location()));
12214 result->set_environment(pointed_to_type->get_environment());
12215 }
12216 }
12217 else if (reference_type_def_sptr r = is_reference_type(type))
12218 {
12219 type_base_sptr pointed_to_type =
12220 synthesize_type_from_translation_unit(r->get_pointed_to_type(), tu);
12221 if (pointed_to_type)
12222 {
12223 result.reset(new reference_type_def(pointed_to_type,
12224 r->is_lvalue(),
12225 r->get_size_in_bits(),
12226 r->get_alignment_in_bits(),
12227 r->get_location()));
12228 result->set_environment(pointed_to_type->get_environment());
12229 }
12230 }
12231 else if (function_type_sptr f = is_function_type(type))
12232 result = synthesize_function_type_from_translation_unit(*f, tu);
12233
12234 if (result)
12235 {
12236 add_decl_to_scope(is_decl(result), tu.get_global_scope());
12237 canonicalize(result);
12238 }
12239 }
12240
12241 if (result)
12242 tu.priv_->synthesized_types_.push_back(result);
12243
12244 return result;
12245 }
12246
12247 /// In a translation unit, lookup the sub-types that make up a given
12248 /// function type and if the sub-types are all found, synthesize and
12249 /// return a function_type with them.
12250 ///
12251 /// This function is like lookup_function_type_in_translation_unit()
12252 /// execept that it constructs the function type from the sub-types
12253 /// found in the translation, rather than just looking for the
12254 /// function types held by the translation unit. This can be useful
12255 /// if the translation unit doesnt hold the function type we are
12256 /// looking for (i.e, lookup_function_type_in_translation_unit()
12257 /// returned NULL) but we still want to see if the sub-types of the
12258 /// function types are present in the translation unit.
12259 ///
12260 /// @param fn_type the function type to consider.
12261 ///
12262 /// @param tu the translation unit to look into.
12263 ///
12264 /// @return the resulting synthesized function type if all its
12265 /// sub-types have been found, NULL otherwise.
12266 function_type_sptr
synthesize_function_type_from_translation_unit(const function_type & fn_type,translation_unit & tu)12267 synthesize_function_type_from_translation_unit(const function_type& fn_type,
12268 translation_unit& tu)
12269 {
12270 function_type_sptr nil = function_type_sptr();
12271
12272 environment* env = tu.get_environment();
12273 ABG_ASSERT(env);
12274
12275 type_base_sptr return_type = fn_type.get_return_type();
12276 type_base_sptr result_return_type;
12277 if (!return_type || env->is_void_type(return_type))
12278 result_return_type = env->get_void_type();
12279 else
12280 result_return_type = synthesize_type_from_translation_unit(return_type, tu);
12281 if (!result_return_type)
12282 return nil;
12283
12284 function_type::parameters parms;
12285 type_base_sptr parm_type;
12286 function_decl::parameter_sptr parm;
12287 for (function_type::parameters::const_iterator i =
12288 fn_type.get_parameters().begin();
12289 i != fn_type.get_parameters().end();
12290 ++i)
12291 {
12292 type_base_sptr t = (*i)->get_type();
12293 parm_type = synthesize_type_from_translation_unit(t, tu);
12294 if (!parm_type)
12295 return nil;
12296 parm.reset(new function_decl::parameter(parm_type,
12297 (*i)->get_index(),
12298 (*i)->get_name(),
12299 (*i)->get_location(),
12300 (*i)->get_variadic_marker(),
12301 (*i)->get_is_artificial()));
12302 parms.push_back(parm);
12303 }
12304
12305 class_or_union_sptr class_type;
12306 const method_type* method = is_method_type(&fn_type);
12307 if (method)
12308 {
12309 class_type = is_class_or_union_type
12310 (synthesize_type_from_translation_unit(method->get_class_type(), tu));
12311 ABG_ASSERT(class_type);
12312 }
12313
12314 function_type_sptr result_fn_type;
12315
12316 if (class_type)
12317 result_fn_type.reset(new method_type(result_return_type,
12318 class_type,
12319 parms,
12320 method->get_is_const(),
12321 fn_type.get_size_in_bits(),
12322 fn_type.get_alignment_in_bits()));
12323 else
12324 result_fn_type.reset(new function_type(result_return_type,
12325 parms,
12326 fn_type.get_size_in_bits(),
12327 fn_type.get_alignment_in_bits()));
12328
12329 tu.priv_->synthesized_types_.push_back(result_fn_type);
12330 // The new synthesized type must be in the same environment as its
12331 // translation unit.
12332 result_fn_type->set_environment(tu.get_environment());
12333 tu.bind_function_type_life_time(result_fn_type);
12334
12335 canonicalize(result_fn_type);
12336 return result_fn_type;
12337 }
12338
12339 /// Demangle a C++ mangled name and return the resulting string
12340 ///
12341 /// @param mangled_name the C++ mangled name to demangle.
12342 ///
12343 /// @return the resulting mangled name.
12344 string
demangle_cplus_mangled_name(const string & mangled_name)12345 demangle_cplus_mangled_name(const string& mangled_name)
12346 {
12347 if (mangled_name.empty())
12348 return "";
12349
12350 size_t l = 0;
12351 int status = 0;
12352 char * str = abi::__cxa_demangle(mangled_name.c_str(),
12353 NULL, &l, &status);
12354 string demangled_name = mangled_name;
12355 if (str)
12356 {
12357 ABG_ASSERT(status == 0);
12358 demangled_name = str;
12359 free(str);
12360 str = 0;
12361 }
12362 return demangled_name;
12363 }
12364
12365 /// Return either the type given in parameter if it's non-null, or the
12366 /// void type.
12367 ///
12368 /// @param t the type to consider.
12369 ///
12370 /// @param env the environment to use. If NULL, just abort the
12371 /// process.
12372 ///
12373 /// @return either @p t if it is non-null, or the void type.
12374 type_base_sptr
type_or_void(const type_base_sptr t,const environment * env)12375 type_or_void(const type_base_sptr t, const environment* env)
12376 {
12377 type_base_sptr r;
12378
12379 if (t)
12380 r = t;
12381 else
12382 {
12383 ABG_ASSERT(env);
12384 r = type_base_sptr(env->get_void_type());
12385 }
12386
12387 return r;
12388 }
12389
~global_scope()12390 global_scope::~global_scope()
12391 {
12392 }
12393
12394 // <type_base definitions>
12395
12396 /// Definition of the private data of @ref type_base.
12397 struct type_base::priv
12398 {
12399 size_t size_in_bits;
12400 size_t alignment_in_bits;
12401 type_base_wptr canonical_type;
12402 // The data member below holds the canonical type that is managed by
12403 // the smart pointer referenced by the canonical_type data member
12404 // above. We are storing this underlying (naked) pointer here, so
12405 // that users can access it *fast*. Otherwise, accessing
12406 // canonical_type above implies creating a shared_ptr, and that has
12407 // been measured to be slow for some performance hot spots.
12408 type_base* naked_canonical_type;
12409 // Computing the representation of a type again and again can be
12410 // costly. So we cache the internal and non-internal type
12411 // representation strings here.
12412 interned_string internal_cached_repr_;
12413 interned_string cached_repr_;
12414
privabigail::ir::type_base::priv12415 priv()
12416 : size_in_bits(),
12417 alignment_in_bits(),
12418 naked_canonical_type()
12419 {}
12420
privabigail::ir::type_base::priv12421 priv(size_t s,
12422 size_t a,
12423 type_base_sptr c = type_base_sptr())
12424 : size_in_bits(s),
12425 alignment_in_bits(a),
12426 canonical_type(c),
12427 naked_canonical_type(c.get())
12428 {}
12429 }; // end struct type_base::priv
12430
12431 static void
12432 maybe_propagate_canonical_type(const type_base& lhs_type,
12433 const type_base& rhs_type);
12434
12435 /// Test if two types are eligible to the "Linux Kernel Fast Type
12436 /// Comparison Optimization", a.k.a LKFTCO.
12437 ///
12438 /// Two types T1 and T2 (who are presumably of the same name and kind)
12439 /// are eligible to the LKFTCO if they fulfill the following criteria/
12440 ///
12441 /// 1/ T1 and T2 come from the same Linux Kernel Corpus and they are
12442 /// either class, union or enums.
12443 ///
12444 /// 2/ They are defined in the same translation unit.
12445 ///
12446 /// @param t1 the first type to consider.
12447 ///
12448 /// @param t2 the second type to consider.
12449 ///
12450 /// @return true iff t1 and t2 are eligible to the LKFTCO.
12451 static bool
types_defined_same_linux_kernel_corpus_public(const type_base & t1,const type_base & t2)12452 types_defined_same_linux_kernel_corpus_public(const type_base& t1,
12453 const type_base& t2)
12454 {
12455 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
12456 string t1_file_path, t2_file_path;
12457
12458 /// If the t1 (and t2) are classes/unions/enums from the same linux
12459 /// kernel corpus, let's move on. Otherwise bail out.
12460 if (!(t1_corpus && t2_corpus
12461 && t1_corpus == t2_corpus
12462 && (t1_corpus->get_origin() == corpus::LINUX_KERNEL_BINARY_ORIGIN)
12463 && (is_class_or_union_type(&t1)
12464 || is_enum_type(&t1))))
12465 return false;
12466
12467 class_or_union *c1 = 0, *c2 = 0;
12468 c1 = is_class_or_union_type(&t1);
12469 c2 = is_class_or_union_type(&t2);
12470
12471 // Two anonymous class types with no naming typedefs cannot be
12472 // eligible to this optimization.
12473 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
12474 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
12475 return false;
12476
12477 // Two anonymous enum types cannot be eligible to this optimization.
12478 if (const enum_type_decl *e1 = is_enum_type(&t1))
12479 if (const enum_type_decl *e2 = is_enum_type(&t2))
12480 if (e1->get_is_anonymous() || e2->get_is_anonymous())
12481 return false;
12482
12483 // Look through declaration-only types. That is, get the associated
12484 // definition type.
12485 c1 = look_through_decl_only_class(c1);
12486 c2 = look_through_decl_only_class(c2);
12487
12488 if (c1 && c2)
12489 {
12490 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
12491 {
12492 if (c1->get_environment()->decl_only_class_equals_definition())
12493 // At least one of classes/union is declaration-only.
12494 // Because we are in a context in which a declaration-only
12495 // class/union is equal to all definitions of that
12496 // class/union, we can assume that the two types are
12497 // equal.
12498 return true;
12499 }
12500 }
12501
12502 if (t1.get_size_in_bits() != t2.get_size_in_bits())
12503 return false;
12504
12505 // Look at the file names of the locations of t1 and t2. If they
12506 // are equal, then t1 and t2 are defined in the same file.
12507 {
12508 location l;
12509
12510 if (c1)
12511 l = c1->get_location();
12512 else
12513 l = dynamic_cast<const decl_base&>(t1).get_location();
12514
12515 unsigned line = 0, col = 0;
12516 if (l)
12517 l.expand(t1_file_path, line, col);
12518 if (c2)
12519 l = c2->get_location();
12520 else
12521 l = dynamic_cast<const decl_base&>(t2).get_location();
12522 if (l)
12523 l.expand(t2_file_path, line, col);
12524 }
12525
12526 if (t1_file_path.empty() || t2_file_path.empty())
12527 return false;
12528
12529 if (t1_file_path == t2_file_path)
12530 return true;
12531
12532 return false;
12533 }
12534
12535 /// Compute the canonical type for a given instance of @ref type_base.
12536 ///
12537 /// Consider two types T and T'. The canonical type of T, denoted
12538 /// C(T) is a type such as T == T' if and only if C(T) == C(T'). Said
12539 /// otherwise, to compare two types, one just needs to compare their
12540 /// canonical types using pointer equality. That makes type
12541 /// comparison faster than the structural comparison performed by the
12542 /// abigail::ir::equals() overloads.
12543 ///
12544 /// If there is not yet any canonical type for @p t, then @p t is its
12545 /// own canonical type. Otherwise, this function returns the
12546 /// canonical type of @p t which is the canonical type that has the
12547 /// same hash value as @p t and that structurally equals @p t. Note
12548 /// that after invoking this function, the life time of the returned
12549 /// canonical time is then equals to the life time of the current
12550 /// process.
12551 ///
12552 /// @param t a smart pointer to instance of @ref type_base we want to
12553 /// compute a canonical type for.
12554 ///
12555 /// @return the canonical type for the current instance of @ref
12556 /// type_base.
12557 type_base_sptr
get_canonical_type_for(type_base_sptr t)12558 type_base::get_canonical_type_for(type_base_sptr t)
12559 {
12560 if (!t)
12561 return t;
12562
12563 environment* env = t->get_environment();
12564 ABG_ASSERT(env);
12565
12566 bool decl_only_class_equals_definition =
12567 (odr_is_relevant(*t) || env->decl_only_class_equals_definition());
12568
12569 class_or_union_sptr class_or_union = is_class_or_union_type(t);
12570
12571 // Look through declaration-only classes when we are dealing with
12572 // C++ or languages where we assume the "One Definition Rule". In
12573 // that context, we assume that a declaration-only non-anonymous
12574 // class equals all fully defined classes of the same name.
12575 //
12576 // Otherwise, all classes, including declaration-only classes are
12577 // canonicalized and only canonical comparison is going to be used
12578 // in the system.
12579 if (decl_only_class_equals_definition)
12580 if (class_or_union)
12581 {
12582 class_or_union = look_through_decl_only_class(class_or_union);
12583 if (class_or_union->get_is_declaration_only())
12584 return type_base_sptr();
12585 else
12586 t = class_or_union;
12587 }
12588
12589 class_decl_sptr is_class = is_class_type(t);
12590 if (t->get_canonical_type())
12591 return t->get_canonical_type();
12592
12593 // For classes and union, ensure that an anonymous class doesn't
12594 // have a linkage name. If it does in the future, then me must be
12595 // mindful that the linkage name respects the type identity
12596 // constraints which states that "if two linkage names are different
12597 // then the two types are different".
12598 ABG_ASSERT(!class_or_union
12599 || !class_or_union->get_is_anonymous()
12600 || class_or_union->get_linkage_name().empty());
12601
12602 // We want the pretty representation of the type, but for an
12603 // internal use, not for a user-facing purpose.
12604 //
12605 // If two classe types Foo are declared, one as a class and the
12606 // other as a struct, but are otherwise equivalent, we want their
12607 // pretty representation to be the same. Hence the 'internal'
12608 // argument of ir::get_pretty_representation() is set to true here.
12609 // So in this case, the pretty representation of Foo is going to be
12610 // "class Foo", regardless of its struct-ness. This also applies to
12611 // composite types which would have "class Foo" as a sub-type.
12612 string repr = t->get_cached_pretty_representation(/*internal=*/true);
12613
12614 // If 't' already has a canonical type 'inside' its corpus
12615 // (t_corpus), then this variable is going to contain that canonical
12616 // type.
12617 type_base_sptr canonical_type_present_in_corpus;
12618 environment::canonical_types_map_type& types =
12619 env->get_canonical_types_map();
12620
12621 type_base_sptr result;
12622 environment::canonical_types_map_type::iterator i = types.find(repr);
12623 if (i == types.end())
12624 {
12625 vector<type_base_sptr> v;
12626 v.push_back(t);
12627 types[repr] = v;
12628 result = t;
12629 }
12630 else
12631 {
12632 vector<type_base_sptr> &v = i->second;
12633 // Let's compare 't' structurally (i.e, compare its sub-types
12634 // recursively) against the canonical types of the system. If it
12635 // equals a given canonical type C, then it means C is the
12636 // canonical type of 't'. Otherwise, if 't' is different from
12637 // all the canonical types of the system, then it means 't' is a
12638 // canonical type itself.
12639 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
12640 it != v.rend();
12641 ++it)
12642 {
12643 // Before the "*it == it" comparison below is done, let's
12644 // perform on-the-fly-canonicalization. For C types, let's
12645 // consider that an unresolved struct declaration 'struct S'
12646 // is different from a definition 'struct S'. This is
12647 // because normally, at this point all the declarations of
12648 // struct S that are compatible with the definition of
12649 // struct S have already been resolved to that definition,
12650 // during the DWARF parsing. The remaining unresolved
12651 // declaration are thus considered different. With this
12652 // setup we can properly handle cases of two *different*
12653 // struct S being defined in the same binary (in different
12654 // translation units), and a third struct S being only
12655 // declared as an opaque type in a third translation unit of
12656 // its own, with no definition in there. In that case, the
12657 // declaration-only struct S should be left alone and not
12658 // resolved to any of the two definitions of struct S.
12659 bool saved_decl_only_class_equals_definition =
12660 env->decl_only_class_equals_definition();
12661 env->do_on_the_fly_canonicalization(true);
12662 // Compare types by considering that decl-only classes don't
12663 // equal their definition.
12664 env->decl_only_class_equals_definition(false);
12665 bool equal = types_defined_same_linux_kernel_corpus_public(**it, *t)
12666 || *it == t;
12667 // Restore the state of the on-the-fly-canonicalization and
12668 // the decl-only-class-being-equal-to-a-matching-definition
12669 // flags.
12670 env->do_on_the_fly_canonicalization(false);
12671 env->decl_only_class_equals_definition
12672 (saved_decl_only_class_equals_definition);
12673 if (equal)
12674 {
12675 result = *it;
12676 break;
12677 }
12678 }
12679 if (!result)
12680 {
12681 v.push_back(t);
12682 result = t;
12683 }
12684 }
12685
12686 return result;
12687 }
12688
12689 /// This method is invoked automatically right after the current
12690 /// instance of @ref class_decl has been canonicalized.
12691 void
on_canonical_type_set()12692 type_base::on_canonical_type_set()
12693 {}
12694
12695 /// This is a subroutine of the canonicalize() function.
12696 ///
12697 /// When the canonical type C of type T has just been computed, there
12698 /// can be cases where T has member functions that C doesn't have.
12699 ///
12700 /// This is possible because non virtual member functions are not
12701 /// taken in account when comparing two types.
12702 ///
12703 /// In that case, this function updates C so that it contains the
12704 /// member functions.
12705 ///
12706 /// There can also be cases where C has a method M which is not linked
12707 /// to any underlying symbol, whereas in T, M is to link to an
12708 /// underlying symbol. In that case, this function updates M in C so
12709 /// that it's linked to the same underlying symbol as for M in T.
12710 static void
maybe_adjust_canonical_type(const type_base_sptr & canonical,const type_base_sptr & type)12711 maybe_adjust_canonical_type(const type_base_sptr& canonical,
12712 const type_base_sptr& type)
12713 {
12714 if (// If 'type' is *NOT* a newly canonicalized type ...
12715 type->get_naked_canonical_type()
12716 // ... or if 'type' is it's own canonical type, then get out.
12717 || type.get() == canonical.get())
12718 return;
12719
12720 if (class_decl_sptr cl = is_class_type(type))
12721 {
12722 class_decl_sptr canonical_class = is_class_type(canonical);
12723
12724 if (canonical_class)
12725 {
12726 // Set symbols of member functions that might be missing
12727 // theirs.
12728 for (class_decl::member_functions::const_iterator i =
12729 cl->get_member_functions().begin();
12730 i != cl->get_member_functions().end();
12731 ++i)
12732 if ((*i)->get_symbol())
12733 {
12734 if (method_decl *m = canonical_class->
12735 find_member_function((*i)->get_linkage_name()))
12736 {
12737 elf_symbol_sptr s1 = (*i)->get_symbol();
12738 if (s1 && !m->get_symbol())
12739 // Method 'm' in the canonical type is not
12740 // linked to the underlying symbol of '*i'.
12741 // Let's link it now. have th
12742 m->set_symbol(s1);
12743 }
12744 else
12745 // There is a member function defined and publicly
12746 // exported in the other class, and the canonical
12747 // class doesn't have that member function. Let's
12748 // copy that member function to the canonical class
12749 // then.
12750 copy_member_function (canonical_class, *i);
12751 }
12752 }
12753 }
12754 }
12755
12756 /// Compute the canonical type of a given type.
12757 ///
12758 /// It means that after invoking this function, comparing the intance
12759 /// instance @ref type_base and another one (on which
12760 /// type_base::enable_canonical_equality() would have been invoked as
12761 /// well) is performed by just comparing the pointer values of the
12762 /// canonical types of both types. That equality comparison is
12763 /// supposedly faster than structural comparison of the types.
12764 ///
12765 /// @param t a smart pointer to the instance of @ref type_base for
12766 /// which to compute the canonical type. After this call,
12767 /// t->get_canonical_type() will return the newly computed canonical
12768 /// type.
12769 ///
12770 /// @return the canonical type computed for @p t.
12771 type_base_sptr
canonicalize(type_base_sptr t)12772 canonicalize(type_base_sptr t)
12773 {
12774 if (!t)
12775 return t;
12776
12777 if (t->get_canonical_type())
12778 return t->get_canonical_type();
12779
12780 type_base_sptr canonical = type_base::get_canonical_type_for(t);
12781 maybe_adjust_canonical_type(canonical, t);
12782
12783 t->priv_->canonical_type = canonical;
12784 t->priv_->naked_canonical_type = canonical.get();
12785
12786 if (class_decl_sptr cl = is_class_type(t))
12787 if (type_base_sptr d = is_type(cl->get_earlier_declaration()))
12788 if ((canonical = d->get_canonical_type()))
12789 {
12790 d->priv_->canonical_type = canonical;
12791 d->priv_->naked_canonical_type = canonical.get();
12792 }
12793
12794 if (canonical)
12795 if (decl_base_sptr d = is_decl_slow(canonical))
12796 {
12797 scope_decl *scope = d->get_scope();
12798 // Add the canonical type to the set of canonical types
12799 // belonging to its scope.
12800 if (scope)
12801 scope->get_canonical_types().insert(canonical);
12802 //else, if the type doesn't have a scope, it's doesn't meant
12803 // to be emitted. This can be the case for the result of the
12804 // function strip_typedef, for instance.
12805 }
12806
12807 t->on_canonical_type_set();
12808 return canonical;
12809 }
12810
12811
12812 /// Set the definition of this declaration-only @ref decl_base.
12813 ///
12814 /// @param d the new definition to set.
12815 void
set_definition_of_declaration(const decl_base_sptr & d)12816 decl_base::set_definition_of_declaration(const decl_base_sptr& d)
12817 {
12818 ABG_ASSERT(get_is_declaration_only());
12819 priv_->definition_of_declaration_ = d;
12820 if (type_base *t = is_type(this))
12821 if (type_base_sptr canonical_type = is_type(d)->get_canonical_type())
12822 t->priv_->canonical_type = canonical_type;
12823
12824 priv_->naked_definition_of_declaration_ = const_cast<decl_base*>(d.get());
12825 }
12826
12827 /// The constructor of @ref type_base.
12828 ///
12829 /// @param s the size of the type, in bits.
12830 ///
12831 /// @param a the alignment of the type, in bits.
type_base(const environment * e,size_t s,size_t a)12832 type_base::type_base(const environment* e, size_t s, size_t a)
12833 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
12834 priv_(new priv(s, a))
12835 {}
12836
12837 /// Getter of the canonical type of the current instance of @ref
12838 /// type_base.
12839 ///
12840 /// @return a smart pointer to the canonical type of the current
12841 /// intance of @ref type_base, or an empty smart pointer if the
12842 /// current instance of @ref type_base doesn't have any canonical
12843 /// type.
12844 type_base_sptr
get_canonical_type() const12845 type_base::get_canonical_type() const
12846 {return priv_->canonical_type.lock();}
12847
12848 /// Getter of the canonical type pointer.
12849 ///
12850 /// Note that this function doesn't return a smart pointer, but rather
12851 /// the underlying pointer managed by the smart pointer. So it's as
12852 /// fast as possible. This getter is to be used in code paths that
12853 /// are proven to be performance hot spots; especially, when comparing
12854 /// sensitive types like class, function, pointers and reference
12855 /// types. Those are compared extremely frequently and thus, their
12856 /// accessing the canonical type must be fast.
12857 ///
12858 /// @return the canonical type pointer, not managed by a smart
12859 /// pointer.
12860 type_base*
get_naked_canonical_type() const12861 type_base::get_naked_canonical_type() const
12862 {return priv_->naked_canonical_type;}
12863
12864 /// Get the pretty representation of the current type.
12865 ///
12866 /// The pretty representation is retrieved from a cache. If the cache
12867 /// is empty, this function computes the pretty representation, put it
12868 /// in the cache and returns it.
12869 ///
12870 /// Note that if the type is *NOT* canonicalized, the pretty
12871 /// representation is never cached.
12872 ///
12873 /// @param internal if true, then the pretty representation is to be
12874 /// used for purpuses that are internal to the libabigail library
12875 /// itself. If you don't know what this means, then you probably
12876 /// should set this parameter to "false".
12877 const interned_string&
get_cached_pretty_representation(bool internal) const12878 type_base::get_cached_pretty_representation(bool internal) const
12879 {
12880 if (internal)
12881 {
12882 if (!get_naked_canonical_type() || priv_->internal_cached_repr_.empty())
12883 {
12884 string r = ir::get_pretty_representation(this, internal);
12885 priv_->internal_cached_repr_ = get_environment()->intern(r);
12886 }
12887 return priv_->internal_cached_repr_;
12888 }
12889
12890 if (!get_naked_canonical_type() || priv_->cached_repr_.empty())
12891 {
12892 string r = ir::get_pretty_representation(this, internal);
12893 priv_->cached_repr_ = get_environment()->intern(r);
12894 }
12895
12896 return priv_->cached_repr_;
12897 }
12898
12899 /// Compares two instances of @ref type_base.
12900 ///
12901 /// If the two intances are different, set a bitfield to give some
12902 /// insight about the kind of differences there are.
12903 ///
12904 /// @param l the first artifact of the comparison.
12905 ///
12906 /// @param r the second artifact of the comparison.
12907 ///
12908 /// @param k a pointer to a bitfield that gives information about the
12909 /// kind of changes there are between @p l and @p r. This one is set
12910 /// iff @p is non-null and if the function returns false.
12911 ///
12912 /// Please note that setting k to a non-null value does have a
12913 /// negative performance impact because even if @p l and @p r are not
12914 /// equal, the function keeps up the comparison in order to determine
12915 /// the different kinds of ways in which they are different.
12916 ///
12917 /// @return true if @p l equals @p r, false otherwise.
12918 bool
equals(const type_base & l,const type_base & r,change_kind * k)12919 equals(const type_base& l, const type_base& r, change_kind* k)
12920 {
12921 bool result = (l.get_size_in_bits() == r.get_size_in_bits()
12922 && l.get_alignment_in_bits() == r.get_alignment_in_bits());
12923 if (!result)
12924 if (k)
12925 *k |= LOCAL_TYPE_CHANGE_KIND;
12926 return result;
12927 }
12928
12929 /// Return true iff both type declarations are equal.
12930 ///
12931 /// Note that this doesn't test if the scopes of both types are equal.
12932 bool
operator ==(const type_base & other) const12933 type_base::operator==(const type_base& other) const
12934 {return equals(*this, other, 0);}
12935
12936 /// Inequality operator.
12937 ///
12938 ///@param other the instance of @ref type_base to compare the current
12939 /// instance against.
12940 ///
12941 /// @return true iff the current instance is different from @p other.
12942 bool
operator !=(const type_base & other) const12943 type_base::operator!=(const type_base& other) const
12944 {return !operator==(other);}
12945
12946 /// Setter for the size of the type.
12947 ///
12948 /// @param s the new size -- in bits.
12949 void
set_size_in_bits(size_t s)12950 type_base::set_size_in_bits(size_t s)
12951 {priv_->size_in_bits = s;}
12952
12953 /// Getter for the size of the type.
12954 ///
12955 /// @return the size in bits of the type.
12956 size_t
get_size_in_bits() const12957 type_base::get_size_in_bits() const
12958 {return priv_->size_in_bits;}
12959
12960 /// Setter for the alignment of the type.
12961 ///
12962 /// @param a the new alignment -- in bits.
12963 void
set_alignment_in_bits(size_t a)12964 type_base::set_alignment_in_bits(size_t a)
12965 {priv_->alignment_in_bits = a;}
12966
12967 /// Getter for the alignment of the type.
12968 ///
12969 /// @return the alignment of the type in bits.
12970 size_t
get_alignment_in_bits() const12971 type_base::get_alignment_in_bits() const
12972 {return priv_->alignment_in_bits;}
12973
12974 /// Default implementation of traversal for types. This function does
12975 /// nothing. It must be implemented by every single new type that is
12976 /// written.
12977 ///
12978 /// Please look at e.g, class_decl::traverse() for an example of how
12979 /// to implement this.
12980 ///
12981 /// @param v the visitor used to visit the type.
12982 bool
traverse(ir_node_visitor & v)12983 type_base::traverse(ir_node_visitor& v)
12984 {
12985 if (v.type_node_has_been_visited(this))
12986 return true;
12987
12988 v.visit_begin(this);
12989 bool result = v.visit_end(this);
12990 v.mark_type_node_as_visited(this);
12991
12992 return result;
12993 }
12994
~type_base()12995 type_base::~type_base()
12996 {delete priv_;}
12997
12998 // </type_base definitions>
12999
13000 // <integral_type definitions>
13001
13002 /// Bitwise OR operator for integral_type::modifiers_type.
13003 ///
13004 /// @param l the left-hand side operand.
13005 ///
13006 /// @param r the right-hand side operand.
13007 ///
13008 /// @return the result of the bitwise OR.
13009 integral_type::modifiers_type
operator |(integral_type::modifiers_type l,integral_type::modifiers_type r)13010 operator|(integral_type::modifiers_type l, integral_type::modifiers_type r)
13011 {
13012 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
13013 |static_cast<unsigned>(r));
13014 }
13015
13016 /// Bitwise AND operator for integral_type::modifiers_type.
13017 ///
13018 /// @param l the left-hand side operand.
13019 ///
13020 /// @param r the right-hand side operand.
13021 ///
13022 /// @return the result of the bitwise AND.
13023 integral_type::modifiers_type
operator &(integral_type::modifiers_type l,integral_type::modifiers_type r)13024 operator&(integral_type::modifiers_type l, integral_type::modifiers_type r)
13025 {
13026 return static_cast<integral_type::modifiers_type>(static_cast<unsigned>(l)
13027 &static_cast<unsigned>(r));
13028 }
13029
13030 /// Bitwise |= operator for integral_type::modifiers_type.
13031 ///
13032 /// @param l the left-hand side operand.
13033 ///
13034 /// @param r the right-hand side operand.
13035 ///
13036 /// @return the result of the bitwise |=.
13037 integral_type::modifiers_type&
operator |=(integral_type::modifiers_type & l,integral_type::modifiers_type r)13038 operator|=(integral_type::modifiers_type& l, integral_type::modifiers_type r)
13039 {
13040 l = l | r;
13041 return l;
13042 }
13043
13044 /// Parse a word containing one integral type modifier.
13045 ///
13046 /// A word is considered to be a string of characters that doesn't
13047 /// contain any white space.
13048 ///
13049 /// @param word the word to parse. It is considered to be a string of
13050 /// characters that doesn't contain any white space.
13051 ///
13052 /// @param modifiers out parameter. It's set by this function to the
13053 /// parsed modifier iff the function returned true.
13054 ///
13055 /// @return true iff @word was successfully parsed.
13056 static bool
parse_integral_type_modifier(const string & word,integral_type::modifiers_type & modifiers)13057 parse_integral_type_modifier(const string& word,
13058 integral_type::modifiers_type &modifiers)
13059 {
13060 if (word == "signed")
13061 modifiers |= integral_type::SIGNED_MODIFIER;
13062 else if (word == "unsigned")
13063 modifiers |= integral_type::UNSIGNED_MODIFIER;
13064 else if (word == "short")
13065 modifiers |= integral_type::SHORT_MODIFIER;
13066 else if (word == "long")
13067 modifiers |= integral_type::LONG_MODIFIER;
13068 else if (word == "long long")
13069 modifiers |= integral_type::LONG_LONG_MODIFIER;
13070 else
13071 return false;
13072
13073 return true;
13074 }
13075
13076 /// Parse a base type of an integral type from a string.
13077 ///
13078 /// @param type_name the type name to parse.
13079 ///
13080 /// @param base out parameter. This is set to the resulting base type
13081 /// parsed, iff the function returned true.
13082 ///
13083 /// @return true iff the function could successfully parse the base
13084 /// type.
13085 static bool
parse_base_integral_type(const string & type_name,integral_type::base_type & base)13086 parse_base_integral_type(const string& type_name,
13087 integral_type::base_type& base)
13088 {
13089 if (type_name == "int")
13090 base = integral_type::INT_BASE_TYPE;
13091 else if (type_name == "char")
13092 base = integral_type::CHAR_BASE_TYPE;
13093 else if (type_name == "bool" || type_name == "_Bool")
13094 base = integral_type::BOOL_BASE_TYPE;
13095 else if (type_name == "double")
13096 base = integral_type::DOUBLE_BASE_TYPE;
13097 else if (type_name =="float")
13098 base = integral_type::FLOAT_BASE_TYPE;
13099 else if (type_name == "char16_t")
13100 base = integral_type::CHAR16_T_BASE_TYPE;
13101 else if (type_name == "char32_t")
13102 base = integral_type::CHAR32_T_BASE_TYPE;
13103 else if (type_name == "wchar_t")
13104 base = integral_type::WCHAR_T_BASE_TYPE;
13105 else
13106 return false;
13107
13108 return true;
13109 }
13110
13111 /// Parse an integral type from a string.
13112 ///
13113 /// @param type_name the string containing the integral type to parse.
13114 ///
13115 /// @param base out parameter. Is set by this function to the base
13116 /// type of the integral type, iff the function returned true.
13117 ///
13118 /// @param modifiers out parameter If set by this function to the
13119 /// modifier of the integral type, iff the function returned true.
13120 ///
13121 /// @return true iff the function could parse an integral type from @p
13122 /// type_name.
13123 static bool
parse_integral_type(const string & type_name,integral_type::base_type & base,integral_type::modifiers_type & modifiers)13124 parse_integral_type(const string& type_name,
13125 integral_type::base_type& base,
13126 integral_type::modifiers_type& modifiers)
13127 {
13128 string input = type_name;
13129 string::size_type len = input.length();
13130 string::size_type cur_pos = 0, prev_pos = 0;
13131 string cur_word, prev_word;
13132 bool ok = false;
13133
13134 while (cur_pos < len)
13135 {
13136 prev_pos = cur_pos;
13137 cur_pos = input.find(' ', prev_pos);
13138 prev_word = cur_word;
13139 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
13140
13141 if (cur_pos < len && isspace(input[cur_pos]))
13142 do
13143 ++cur_pos;
13144 while (cur_pos < len && isspace(input[cur_pos]));
13145
13146 if (cur_pos < len
13147 && cur_word == "long"
13148 && prev_word != "long")
13149 {
13150 prev_pos = cur_pos;
13151 cur_pos = input.find(' ', prev_pos);
13152 string saved_prev_word = prev_word;
13153 prev_word = cur_word;
13154 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
13155 if (cur_word == "long")
13156 cur_word = "long long";
13157 else
13158 {
13159 cur_pos = prev_pos;
13160 cur_word = prev_word;
13161 prev_word = saved_prev_word;
13162 }
13163 }
13164
13165 if (!parse_integral_type_modifier(cur_word, modifiers))
13166 {
13167 if (!parse_base_integral_type(cur_word, base))
13168 return false;
13169 else
13170 ok = true;
13171 }
13172 else
13173 ok = true;
13174 }
13175
13176 return ok;
13177 }
13178
13179 /// Parse an integral type from a string.
13180 ///
13181 /// @param str the string containing the integral type to parse.
13182 ///
13183 ///@param type the resulting @ref integral_type. Is set to the result
13184 ///of the parse, iff the function returns true.
13185 ///
13186 /// @return true iff the function could parse an integral type from @p
13187 /// str.
13188 bool
parse_integral_type(const string & str,integral_type & type)13189 parse_integral_type(const string& str, integral_type& type)
13190 {
13191 integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
13192 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
13193
13194 if (!parse_integral_type(str, base_type, modifiers))
13195 return false;
13196
13197 // So this is an integral type.
13198 integral_type int_type(base_type, modifiers);
13199 type = int_type;
13200 return true;
13201 }
13202
13203 /// Default constructor of the @ref integral_type.
integral_type()13204 integral_type::integral_type()
13205 : base_(INT_BASE_TYPE),
13206 modifiers_(NO_MODIFIER)
13207 {}
13208
13209 /// Constructor of the @ref integral_type.
13210 ///
13211 /// @param b the base type of the integral type.
13212 ///
13213 /// @param m the modifiers of the integral type.
integral_type(base_type b,modifiers_type m)13214 integral_type::integral_type(base_type b, modifiers_type m)
13215 : base_(b), modifiers_(m)
13216 {}
13217
13218 /// Constructor of the @ref integral_type.
13219 ///
13220 /// @param the name of the integral type to parse to initialize the
13221 /// current instance of @ref integral_type.
integral_type(const string & type_name)13222 integral_type::integral_type(const string& type_name)
13223 : base_(INT_BASE_TYPE),
13224 modifiers_(NO_MODIFIER)
13225 {
13226 bool could_parse = parse_integral_type(type_name, base_, modifiers_);
13227 ABG_ASSERT(could_parse);
13228 }
13229
13230 /// Getter of the base type of the @ref integral_type.
13231 ///
13232 /// @return the base type of the @ref integral_type.
13233 integral_type::base_type
get_base_type() const13234 integral_type::get_base_type() const
13235 {return base_;}
13236
13237 /// Getter of the modifiers bitmap of the @ref integral_type.
13238 ///
13239 /// @return the modifiers bitmap of the @ref integral_type.
13240 integral_type::modifiers_type
get_modifiers() const13241 integral_type::get_modifiers() const
13242 {return modifiers_;}
13243
13244 /// Equality operator for the @ref integral_type.
13245 ///
13246 /// @param other the other integral type to compare against.
13247 ///
13248 /// @return true iff @p other equals the current instance of @ref
13249 /// integral_type.
13250 bool
operator ==(const integral_type & other) const13251 integral_type::operator==(const integral_type&other) const
13252 {return base_ == other.base_ && modifiers_ == other.modifiers_;}
13253
13254 /// Return the string representation of the current instance of @ref
13255 /// integral_type.
13256 ///
13257 /// @return the string representation of the current instance of @ref
13258 /// integral_type.
13259 string
to_string() const13260 integral_type::to_string() const
13261 {
13262 string result;
13263
13264 // Look at modifiers ...
13265 if (modifiers_ & SIGNED_MODIFIER)
13266 result += "signed ";
13267 if (modifiers_ & UNSIGNED_MODIFIER)
13268 result += "unsigned ";
13269 if (modifiers_ & SHORT_MODIFIER)
13270 result += "short ";
13271 if (modifiers_ & LONG_MODIFIER)
13272 result += "long ";
13273 if (modifiers_ & LONG_LONG_MODIFIER)
13274 result += "long long ";
13275
13276 // ... and look at base types.
13277 if (base_ == INT_BASE_TYPE)
13278 result += "int";
13279 else if (base_ == CHAR_BASE_TYPE)
13280 result += "char";
13281 else if (base_ == BOOL_BASE_TYPE)
13282 result += "bool";
13283 else if (base_ == DOUBLE_BASE_TYPE)
13284 result += "double";
13285 else if (base_ == FLOAT_BASE_TYPE)
13286 result += "float";
13287 else if (base_ == CHAR16_T_BASE_TYPE)
13288 result += "char16_t";
13289 else if (base_ == CHAR32_T_BASE_TYPE)
13290 result += "char32_t";
13291 else if (base_ == WCHAR_T_BASE_TYPE)
13292 result += "wchar_t";
13293
13294 return result;
13295 }
13296
13297 /// Convert the current instance of @ref integral_type into its string
13298 /// representation.
13299 ///
13300 /// @return the string representation of the current instance of @ref
13301 /// integral_type.
operator string() const13302 integral_type::operator string() const
13303 {return to_string();}
13304
13305 // </integral_type definitions>
13306
13307 //<type_decl definitions>
13308
13309 /// Constructor.
13310 ///
13311 /// @param env the environment we are operating from.
13312 ///
13313 /// @param name the name of the type declaration.
13314 ///
13315 /// @param size_in_bits the size of the current type_decl, in bits.
13316 ///
13317 /// @param alignment_in_bits the alignment of the current typ, in
13318 /// bits.
13319 ///
13320 /// @param locus the source location of the current type declaration.
13321 ///
13322 /// @param linkage_name the linkage_name of the current type declaration.
13323 ///
13324 /// @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)13325 type_decl::type_decl(const environment* env,
13326 const string& name,
13327 size_t size_in_bits,
13328 size_t alignment_in_bits,
13329 const location& locus,
13330 const string& linkage_name,
13331 visibility vis)
13332
13333 : type_or_decl_base(env,
13334 BASIC_TYPE
13335 | ABSTRACT_TYPE_BASE
13336 | ABSTRACT_DECL_BASE),
13337 decl_base(env, name, locus, linkage_name, vis),
13338 type_base(env, size_in_bits, alignment_in_bits)
13339 {
13340 runtime_type_instance(this);
13341
13342 integral_type::base_type base_type = integral_type::INT_BASE_TYPE;
13343 integral_type::modifiers_type modifiers = integral_type::NO_MODIFIER;
13344 integral_type int_type(base_type, modifiers);
13345 if (parse_integral_type(name, int_type))
13346 {
13347 // Convert the integral_type into its canonical string
13348 // representation.
13349 string integral_type_name = int_type;
13350
13351 // Set the name of this type_decl to the canonical string
13352 // representation above
13353 set_name(integral_type_name);
13354 set_qualified_name(get_name());
13355
13356 if (!get_linkage_name().empty())
13357 set_linkage_name(integral_type_name);
13358 }
13359 }
13360
13361 /// Compares two instances of @ref type_decl.
13362 ///
13363 /// If the two intances are different, set a bitfield to give some
13364 /// insight about the kind of differences there are.
13365 ///
13366 /// @param l the first artifact of the comparison.
13367 ///
13368 /// @param r the second artifact of the comparison.
13369 ///
13370 /// @param k a pointer to a bitfield that gives information about the
13371 /// kind of changes there are between @p l and @p r. This one is set
13372 /// iff @p k is non-null and the function returns false.
13373 ///
13374 /// Please note that setting k to a non-null value does have a
13375 /// negative performance impact because even if @p l and @p r are not
13376 /// equal, the function keeps up the comparison in order to determine
13377 /// the different kinds of ways in which they are different.
13378 ///
13379 /// @return true if @p l equals @p r, false otherwise.
13380 bool
equals(const type_decl & l,const type_decl & r,change_kind * k)13381 equals(const type_decl& l, const type_decl& r, change_kind* k)
13382 {
13383 bool result = equals(static_cast<const decl_base&>(l),
13384 static_cast<const decl_base&>(r),
13385 k);
13386 if (!k && !result)
13387 return false;
13388
13389 result &= equals(static_cast<const type_base&>(l),
13390 static_cast<const type_base&>(r),
13391 k);
13392 return result;
13393 }
13394
13395 /// Return true if both types equals.
13396 ///
13397 /// This operator re-uses the overload that takes a decl_base.
13398 ///
13399 /// Note that this does not check the scopes of any of the types.
13400 ///
13401 /// @param o the other type_decl to check agains.
13402 bool
operator ==(const type_base & o) const13403 type_decl::operator==(const type_base& o) const
13404 {
13405 const decl_base* other = dynamic_cast<const decl_base*>(&o);
13406 if (!other)
13407 return false;
13408 return *this == *other;
13409 }
13410
13411 /// Return true if both types equals.
13412 ///
13413 /// Note that this does not check the scopes of any of the types.
13414 ///
13415 /// @param o the other type_decl to check against.
13416 bool
operator ==(const decl_base & o) const13417 type_decl::operator==(const decl_base& o) const
13418 {
13419 const type_decl* other = dynamic_cast<const type_decl*>(&o);
13420 if (!other)
13421 return false;
13422 return try_canonical_compare(this, other);
13423 }
13424
13425 /// Return true if both types equals.
13426 ///
13427 /// Note that this does not check the scopes of any of the types.
13428 ///
13429 /// @param o the other type_decl to check against.
13430 ///
13431 /// @return true iff the current isntance equals @p o
13432 bool
operator ==(const type_decl & o) const13433 type_decl::operator==(const type_decl& o) const
13434 {
13435 const decl_base& other = o;
13436 return *this == other;
13437 }
13438
13439 /// Inequality operator.
13440 ///
13441 /// @param o the other type to compare against.
13442 ///
13443 /// @return true iff the current instance is different from @p o.
13444 bool
operator !=(const type_decl & o) const13445 type_decl::operator!=(const type_decl& o) const
13446 {return !operator==(o);}
13447
13448 /// Equality operator for @ref type_decl_sptr.
13449 ///
13450 /// @param l the first operand to compare.
13451 ///
13452 /// @param r the second operand to compare.
13453 ///
13454 /// @return true iff @p l equals @p r.
13455 bool
operator ==(const type_decl_sptr & l,const type_decl_sptr & r)13456 operator==(const type_decl_sptr& l, const type_decl_sptr& r)
13457 {
13458 if (!!l != !!r)
13459 return false;
13460 if (l.get() == r.get())
13461 return true;
13462 return *l == *r;
13463 }
13464
13465 /// Inequality operator for @ref type_decl_sptr.
13466 ///
13467 /// @param l the first operand to compare.
13468 ///
13469 /// @param r the second operand to compare.
13470 ///
13471 /// @return true iff @p l is different from @p r.
13472 bool
operator !=(const type_decl_sptr & l,const type_decl_sptr & r)13473 operator!=(const type_decl_sptr& l, const type_decl_sptr& r)
13474 {return !operator==(l, r);}
13475
13476 /// Get the pretty representation of the current instance of @ref
13477 /// type_decl.
13478 ///
13479 /// @param internal set to true if the call is intended for an
13480 /// internal use (for technical use inside the library itself), false
13481 /// otherwise. If you don't know what this is for, then set it to
13482 /// false.
13483 ///
13484 /// @param qualified_name if true, names emitted in the pretty
13485 /// representation are fully qualified.
13486 ///
13487 /// @return the pretty representatin of the @ref type_decl.
13488 string
get_pretty_representation(bool internal,bool qualified_name) const13489 type_decl::get_pretty_representation(bool internal,
13490 bool qualified_name) const
13491 {
13492 if (qualified_name)
13493 return get_qualified_name(internal);
13494 return get_name();
13495 }
13496
13497 /// This implements the ir_traversable_base::traverse pure virtual
13498 /// function.
13499 ///
13500 /// @param v the visitor used on the current instance.
13501 ///
13502 /// @return true if the entire IR node tree got traversed, false
13503 /// otherwise.
13504 bool
traverse(ir_node_visitor & v)13505 type_decl::traverse(ir_node_visitor& v)
13506 {
13507 if (v.type_node_has_been_visited(this))
13508 return true;
13509
13510 v.visit_begin(this);
13511 bool result = v.visit_end(this);
13512 v.mark_type_node_as_visited(this);
13513
13514 return result;
13515 }
13516
~type_decl()13517 type_decl::~type_decl()
13518 {}
13519 //</type_decl definitions>
13520
13521 // <scope_type_decl definitions>
13522
13523 /// Constructor.
13524 ///
13525 /// @param env the environment we are operating from.
13526 ///
13527 /// @param name the name of the type.
13528 ///
13529 /// @param size_in_bits the size of the type, in bits.
13530 ///
13531 /// @param alignment_in_bits the alignment of the type, in bits.
13532 ///
13533 /// @param locus the source location where the type is defined.
13534 ///
13535 /// @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)13536 scope_type_decl::scope_type_decl(const environment* env,
13537 const string& name,
13538 size_t size_in_bits,
13539 size_t alignment_in_bits,
13540 const location& locus,
13541 visibility vis)
13542 : type_or_decl_base(env,
13543 ABSTRACT_SCOPE_TYPE_DECL
13544 | ABSTRACT_TYPE_BASE
13545 | ABSTRACT_DECL_BASE),
13546 decl_base(env, name, locus, "", vis),
13547 type_base(env, size_in_bits, alignment_in_bits),
13548 scope_decl(env, name, locus)
13549 {}
13550
13551 /// Compares two instances of @ref scope_type_decl.
13552 ///
13553 /// If the two intances are different, set a bitfield to give some
13554 /// insight about the kind of differences there are.
13555 ///
13556 /// @param l the first artifact of the comparison.
13557 ///
13558 /// @param r the second artifact of the comparison.
13559 ///
13560 /// @param k a pointer to a bitfield that gives information about the
13561 /// kind of changes there are between @p l and @p r. This one is set
13562 /// iff @p k is non-null and the function returns false.
13563 ///
13564 /// Please note that setting k to a non-null value does have a
13565 /// negative performance impact because even if @p l and @p r are not
13566 /// equal, the function keeps up the comparison in order to determine
13567 /// the different kinds of ways in which they are different.
13568 ///
13569 /// @return true if @p l equals @p r, false otherwise.
13570 bool
equals(const scope_type_decl & l,const scope_type_decl & r,change_kind * k)13571 equals(const scope_type_decl& l, const scope_type_decl& r, change_kind* k)
13572 {
13573 bool result = equals(static_cast<const scope_decl&>(l),
13574 static_cast<const scope_decl&>(r),
13575 k);
13576
13577 if (!k && !result)
13578 return false;
13579
13580 result &= equals(static_cast<const type_base&>(l),
13581 static_cast<const type_base&>(r),
13582 k);
13583
13584 return result;
13585 }
13586
13587 /// Equality operator between two scope_type_decl.
13588 ///
13589 /// Note that this function does not consider the scope of the scope
13590 /// types themselves.
13591 ///
13592 /// @return true iff both scope types are equal.
13593 bool
operator ==(const decl_base & o) const13594 scope_type_decl::operator==(const decl_base& o) const
13595 {
13596 const scope_type_decl* other = dynamic_cast<const scope_type_decl*>(&o);
13597 if (!other)
13598 return false;
13599 return try_canonical_compare(this, other);
13600 }
13601
13602 /// Equality operator between two scope_type_decl.
13603 ///
13604 /// This re-uses the equality operator that takes a decl_base.
13605 ///
13606 /// @param o the other scope_type_decl to compare against.
13607 ///
13608 /// @return true iff both scope types are equal.
13609 bool
operator ==(const type_base & o) const13610 scope_type_decl::operator==(const type_base& o) const
13611 {
13612 const decl_base* other = dynamic_cast<const decl_base*>(&o);
13613 if (!other)
13614 return false;
13615
13616 return *this == *other;
13617 }
13618
13619 /// Traverses an instance of @ref scope_type_decl, visiting all the
13620 /// sub-types and decls that it might contain.
13621 ///
13622 /// @param v the visitor that is used to visit every IR sub-node of
13623 /// the current node.
13624 ///
13625 /// @return true if either
13626 /// - all the children nodes of the current IR node were traversed
13627 /// and the calling code should keep going with the traversing.
13628 /// - or the current IR node is already being traversed.
13629 /// Otherwise, returning false means that the calling code should not
13630 /// keep traversing the tree.
13631 bool
traverse(ir_node_visitor & v)13632 scope_type_decl::traverse(ir_node_visitor& v)
13633 {
13634 if (visiting())
13635 return true;
13636
13637 if (v.type_node_has_been_visited(this))
13638 return true;
13639
13640 if (v.visit_begin(this))
13641 {
13642 visiting(true);
13643 for (scope_decl::declarations::const_iterator i =
13644 get_member_decls().begin();
13645 i != get_member_decls ().end();
13646 ++i)
13647 if (!(*i)->traverse(v))
13648 break;
13649 visiting(false);
13650 }
13651
13652 bool result = v.visit_end(this);
13653 v.mark_type_node_as_visited(this);
13654
13655 return result;
13656 }
13657
~scope_type_decl()13658 scope_type_decl::~scope_type_decl()
13659 {}
13660 // </scope_type_decl definitions>
13661
13662 // <namespace_decl>
13663
13664 /// Constructor.
13665 ///
13666 /// @param the environment we are operatin from.
13667 ///
13668 /// @param name the name of the namespace.
13669 ///
13670 /// @param locus the source location where the namespace is defined.
13671 ///
13672 /// @param vis the visibility of the namespace.
namespace_decl(const environment * env,const string & name,const location & locus,visibility vis)13673 namespace_decl::namespace_decl(const environment* env,
13674 const string& name,
13675 const location& locus,
13676 visibility vis)
13677 // We need to call the constructor of decl_base directly here
13678 // because it is virtually inherited by scope_decl. Note that we
13679 // just implicitely call the default constructor for scope_decl
13680 // here, as what we really want is to initialize the decl_base
13681 // subobject. Wow, virtual inheritance is useful, but setting it
13682 // up is ugly.
13683 : type_or_decl_base(env,
13684 NAMESPACE_DECL
13685 | ABSTRACT_DECL_BASE
13686 | ABSTRACT_SCOPE_DECL),
13687 decl_base(env, name, locus, "", vis),
13688 scope_decl(env, name, locus)
13689 {
13690 runtime_type_instance(this);
13691 }
13692
13693 /// Build and return a copy of the pretty representation of the
13694 /// namespace.
13695 ///
13696 /// @param internal set to true if the call is intended for an
13697 /// internal use (for technical use inside the library itself), false
13698 /// otherwise. If you don't know what this is for, then set it to
13699 /// false.
13700 ///
13701 /// @param qualified_name if true, names emitted in the pretty
13702 /// representation are fully qualified.
13703 ///
13704 /// @return a copy of the pretty representation of the namespace.
13705 string
get_pretty_representation(bool internal,bool qualified_name) const13706 namespace_decl::get_pretty_representation(bool internal,
13707 bool qualified_name) const
13708 {
13709 string r =
13710 "namespace " + scope_decl::get_pretty_representation(internal,
13711 qualified_name);
13712 return r;
13713 }
13714
13715 /// Return true iff both namespaces and their members are equal.
13716 ///
13717 /// Note that this function does not check if the scope of these
13718 /// namespaces are equal.
13719 bool
operator ==(const decl_base & o) const13720 namespace_decl::operator==(const decl_base& o) const
13721 {
13722 const namespace_decl* other = dynamic_cast<const namespace_decl*>(&o);
13723 if (!other)
13724 return false;
13725 return scope_decl::operator==(*other);
13726 }
13727
13728 /// Test if the current namespace_decl is empty or contains empty
13729 /// namespaces itself.
13730 ///
13731 /// @return true iff the current namespace_decl is empty or contains
13732 /// empty itself.
13733 bool
is_empty_or_has_empty_sub_namespaces() const13734 namespace_decl::is_empty_or_has_empty_sub_namespaces() const
13735 {
13736 if (is_empty())
13737 return true;
13738
13739 for (declarations::const_iterator i = get_member_decls().begin();
13740 i != get_member_decls().end();
13741 ++i)
13742 {
13743 if (!is_namespace(*i))
13744 return false;
13745
13746 namespace_decl_sptr ns = is_namespace(*i);
13747 ABG_ASSERT(ns);
13748
13749 if (!ns->is_empty_or_has_empty_sub_namespaces())
13750 return false;
13751 }
13752
13753 return true;
13754 }
13755
13756 /// This implements the ir_traversable_base::traverse pure virtual
13757 /// function.
13758 ///
13759 /// @param v the visitor used on the current instance and on its
13760 /// member nodes.
13761 ///
13762 /// @return true if the entire IR node tree got traversed, false
13763 /// otherwise.
13764 bool
traverse(ir_node_visitor & v)13765 namespace_decl::traverse(ir_node_visitor& v)
13766 {
13767 if (visiting())
13768 return true;
13769
13770 if (v.visit_begin(this))
13771 {
13772 visiting(true);
13773 scope_decl::declarations::const_iterator i;
13774 for (i = get_member_decls().begin();
13775 i != get_member_decls ().end();
13776 ++i)
13777 {
13778 ir_traversable_base_sptr t =
13779 dynamic_pointer_cast<ir_traversable_base>(*i);
13780 if (t)
13781 if (!t->traverse (v))
13782 break;
13783 }
13784 visiting(false);
13785 }
13786 return v.visit_end(this);
13787 }
13788
~namespace_decl()13789 namespace_decl::~namespace_decl()
13790 {
13791 }
13792
13793 // </namespace_decl>
13794
13795 // <qualified_type_def>
13796
13797 /// Type of the private data of qualified_type_def.
13798 class qualified_type_def::priv
13799 {
13800 friend class qualified_type_def;
13801
13802 qualified_type_def::CV cv_quals_;
13803 // Before the type is canonicalized, this is used as a temporary
13804 // internal name.
13805 interned_string temporary_internal_name_;
13806 // Once the type is canonicalized, this is used as the internal
13807 // name.
13808 interned_string internal_name_;
13809 weak_ptr<type_base> underlying_type_;
13810
priv()13811 priv()
13812 : cv_quals_(CV_NONE)
13813 {}
13814
priv(qualified_type_def::CV quals,type_base_sptr t)13815 priv(qualified_type_def::CV quals,
13816 type_base_sptr t)
13817 : cv_quals_(quals),
13818 underlying_type_(t)
13819 {}
13820 };// end class qualified_type_def::priv
13821
13822 /// Build the name of the current instance of qualified type.
13823 ///
13824 /// @param fully_qualified if true, build a fully qualified name.
13825 ///
13826 /// @param internal set to true if the call is intended for an
13827 /// internal use (for technical use inside the library itself), false
13828 /// otherwise. If you don't know what this is for, then set it to
13829 /// false.
13830 ///
13831 /// @return a copy of the newly-built name.
13832 string
build_name(bool fully_qualified,bool internal) const13833 qualified_type_def::build_name(bool fully_qualified, bool internal) const
13834 {
13835 ABG_ASSERT(get_underlying_type());
13836
13837 return get_name_of_qualified_type(get_underlying_type(),
13838 get_cv_quals(),
13839 fully_qualified, internal);
13840 }
13841
13842 /// This function is automatically invoked whenever an instance of
13843 /// this type is canonicalized.
13844 ///
13845 /// It's an overload of the virtual type_base::on_canonical_type_set.
13846 ///
13847 /// We put here what is thus meant to be executed only at the point of
13848 /// type canonicalization.
13849 void
on_canonical_type_set()13850 qualified_type_def::on_canonical_type_set()
13851 {clear_qualified_name();}
13852
13853 /// Constructor of the qualified_type_def
13854 ///
13855 /// @param type the underlying type
13856 ///
13857 /// @param quals a bitfield representing the const/volatile qualifiers
13858 ///
13859 /// @param locus the location of the qualified type definition
qualified_type_def(type_base_sptr type,CV quals,const location & locus)13860 qualified_type_def::qualified_type_def(type_base_sptr type,
13861 CV quals,
13862 const location& locus)
13863 : type_or_decl_base(type->get_environment(),
13864 QUALIFIED_TYPE
13865 | ABSTRACT_TYPE_BASE
13866 | ABSTRACT_DECL_BASE),
13867 type_base(type->get_environment(), type->get_size_in_bits(),
13868 type->get_alignment_in_bits()),
13869 decl_base(type->get_environment(), "", locus, "",
13870 dynamic_pointer_cast<decl_base>(type)->get_visibility()),
13871 priv_(new priv(quals, type))
13872 {
13873 runtime_type_instance(this);
13874 interned_string name = type->get_environment()->intern(build_name(false));
13875 set_name(name);
13876 }
13877
13878 /// Get the size of the qualified type def.
13879 ///
13880 /// This is an overload for type_base::get_size_in_bits().
13881 ///
13882 /// @return the size of the qualified type.
13883 size_t
get_size_in_bits() const13884 qualified_type_def::get_size_in_bits() const
13885 {
13886 size_t s = get_underlying_type()->get_size_in_bits();
13887 if (s != type_base::get_size_in_bits())
13888 const_cast<qualified_type_def*>(this)->set_size_in_bits(s);
13889 return type_base::get_size_in_bits();
13890 }
13891
13892 /// Compares two instances of @ref qualified_type_def.
13893 ///
13894 /// If the two intances are different, set a bitfield to give some
13895 /// insight about the kind of differences there are.
13896 ///
13897 /// @param l the first artifact of the comparison.
13898 ///
13899 /// @param r the second artifact of the comparison.
13900 ///
13901 /// @param k a pointer to a bitfield that gives information about the
13902 /// kind of changes there are between @p l and @p r. This one is set
13903 /// iff @p k is non-null and the function returns false.
13904 ///
13905 /// Please note that setting k to a non-null value does have a
13906 /// negative performance impact because even if @p l and @p r are not
13907 /// equal, the function keeps up the comparison in order to determine
13908 /// the different kinds of ways in which they are different.
13909 ///
13910 /// @return true if @p l equals @p r, false otherwise.
13911 bool
equals(const qualified_type_def & l,const qualified_type_def & r,change_kind * k)13912 equals(const qualified_type_def& l, const qualified_type_def& r, change_kind* k)
13913 {
13914 bool result = true;
13915 if (l.get_cv_quals() != r.get_cv_quals())
13916 {
13917 result = false;
13918 if (k)
13919 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
13920 else
13921 return false;
13922 }
13923
13924 if (l.get_underlying_type() != r.get_underlying_type())
13925 {
13926 result = false;
13927 if (k)
13928 {
13929 if (!types_have_similar_structure(l.get_underlying_type().get(),
13930 r.get_underlying_type().get()))
13931 // Underlying type changes in which the structure of the
13932 // type changed are considered local changes to the
13933 // qualified type.
13934 *k |= LOCAL_TYPE_CHANGE_KIND;
13935 else
13936 *k |= SUBTYPE_CHANGE_KIND;
13937 }
13938 else
13939 // okay strictly speaking this is not necessary, but I am
13940 // putting it here to maintenance; that is, so that adding
13941 // subsequent clauses needed to compare two qualified types
13942 // later still works.
13943 return false;
13944 }
13945
13946 return result;
13947 }
13948
13949 /// Equality operator for qualified types.
13950 ///
13951 /// Note that this function does not check for equality of the scopes.
13952 ///
13953 ///@param o the other qualified type to compare against.
13954 ///
13955 /// @return true iff both qualified types are equal.
13956 bool
operator ==(const decl_base & o) const13957 qualified_type_def::operator==(const decl_base& o) const
13958 {
13959 const qualified_type_def* other =
13960 dynamic_cast<const qualified_type_def*>(&o);
13961 if (!other)
13962 return false;
13963 return try_canonical_compare(this, other);
13964 }
13965
13966 /// Equality operator for qualified types.
13967 ///
13968 /// Note that this function does not check for equality of the scopes.
13969 /// Also, this re-uses the equality operator above that takes a
13970 /// decl_base.
13971 ///
13972 ///@param o the other qualified type to compare against.
13973 ///
13974 /// @return true iff both qualified types are equal.
13975 bool
operator ==(const type_base & o) const13976 qualified_type_def::operator==(const type_base& o) const
13977 {
13978 const decl_base* other = dynamic_cast<const decl_base*>(&o);
13979 if (!other)
13980 return false;
13981 return *this == *other;
13982 }
13983
13984 /// Equality operator for qualified types.
13985 ///
13986 /// Note that this function does not check for equality of the scopes.
13987 /// Also, this re-uses the equality operator above that takes a
13988 /// decl_base.
13989 ///
13990 ///@param o the other qualified type to compare against.
13991 ///
13992 /// @return true iff both qualified types are equal.
13993 bool
operator ==(const qualified_type_def & o) const13994 qualified_type_def::operator==(const qualified_type_def& o) const
13995 {
13996 const decl_base* other = dynamic_cast<const decl_base*>(&o);
13997 if (!other)
13998 return false;
13999 return *this == *other;
14000 }
14001
14002 /// Implementation for the virtual qualified name builder for @ref
14003 /// qualified_type_def.
14004 ///
14005 /// @param qualified_name the output parameter to hold the resulting
14006 /// qualified name.
14007 ///
14008 /// @param internal set to true if the call is intended for an
14009 /// internal use (for technical use inside the library itself), false
14010 /// otherwise. If you don't know what this is for, then set it to
14011 /// false.
14012 void
get_qualified_name(interned_string & qualified_name,bool internal) const14013 qualified_type_def::get_qualified_name(interned_string& qualified_name,
14014 bool internal) const
14015 {qualified_name = get_qualified_name(internal);}
14016
14017 /// Implementation of the virtual qualified name builder/getter.
14018 ///
14019 /// @param internal set to true if the call is intended for an
14020 /// internal use (for technical use inside the library itself), false
14021 /// otherwise. If you don't know what this is for, then set it to
14022 /// false.
14023 ///
14024 /// @return the resulting qualified name.
14025 const interned_string&
get_qualified_name(bool internal) const14026 qualified_type_def::get_qualified_name(bool internal) const
14027 {
14028 const environment* env = get_environment();
14029 ABG_ASSERT(env);
14030
14031 if (!get_canonical_type())
14032 {
14033 // The type hasn't been canonicalized yet. We want to return a
14034 // temporary name that is not cached because the structure of
14035 // this type (and so its name) can change until its
14036 // canonicalized.
14037 if (internal)
14038 {
14039 // We are asked to return a temporary *internal* name.
14040 // Lets compute it and return a reference to where it's
14041 // stored.
14042 priv_->temporary_internal_name_ =
14043 env->intern(build_name(true, /*internal=*/true));
14044 return priv_->temporary_internal_name_;
14045 }
14046 else
14047 {
14048 // We are asked to return a temporary non-internal name.
14049 set_temporary_qualified_name
14050 (env->intern(build_name(true, /*internal=*/false)));
14051 return peek_temporary_qualified_name();
14052 }
14053 }
14054 else
14055 {
14056 // The type has already been canonicalized. We want to return
14057 // the definitive name and cache it.
14058 if (internal)
14059 {
14060 if (priv_->internal_name_.empty())
14061 priv_->internal_name_ =
14062 env->intern(build_name(/*qualified=*/true,
14063 /*internal=*/true));
14064 return priv_->internal_name_;
14065 }
14066 else
14067 {
14068 if (peek_qualified_name().empty())
14069 set_qualified_name
14070 (env->intern(build_name(/*qualified=*/true,
14071 /*internal=*/false)));
14072 return peek_qualified_name();
14073 }
14074 }
14075 }
14076
14077 /// This implements the ir_traversable_base::traverse pure virtual
14078 /// function.
14079 ///
14080 /// @param v the visitor used on the current instance.
14081 ///
14082 /// @return true if the entire IR node tree got traversed, false
14083 /// otherwise.
14084 bool
traverse(ir_node_visitor & v)14085 qualified_type_def::traverse(ir_node_visitor& v)
14086 {
14087 if (v.type_node_has_been_visited(this))
14088 return true;
14089
14090 if (visiting())
14091 return true;
14092
14093 if (v.visit_begin(this))
14094 {
14095 visiting(true);
14096 if (type_base_sptr t = get_underlying_type())
14097 t->traverse(v);
14098 visiting(false);
14099 }
14100 bool result = v.visit_end(this);
14101 v.mark_type_node_as_visited(this);
14102 return result;
14103 }
14104
~qualified_type_def()14105 qualified_type_def::~qualified_type_def()
14106 {
14107 }
14108
14109 /// Getter of the const/volatile qualifier bit field
14110 qualified_type_def::CV
get_cv_quals() const14111 qualified_type_def::get_cv_quals() const
14112 {return priv_->cv_quals_;}
14113
14114 /// Setter of the const/value qualifiers bit field
14115 void
set_cv_quals(CV cv_quals)14116 qualified_type_def::set_cv_quals(CV cv_quals)
14117 {priv_->cv_quals_ = cv_quals;}
14118
14119 /// Compute and return the string prefix or suffix representing the
14120 /// qualifiers hold by the current instance of @ref
14121 /// qualified_type_def.
14122 ///
14123 /// @return the newly-built cv string.
14124 string
get_cv_quals_string_prefix() const14125 qualified_type_def::get_cv_quals_string_prefix() const
14126 {return get_string_representation_of_cv_quals(priv_->cv_quals_);}
14127
14128 /// Getter of the underlying type
14129 type_base_sptr
get_underlying_type() const14130 qualified_type_def::get_underlying_type() const
14131 {return priv_->underlying_type_.lock();}
14132
14133 /// Setter of the underlying type.
14134 ///
14135 /// @param t the new underlying type.
14136 void
set_underlying_type(const type_base_sptr & t)14137 qualified_type_def::set_underlying_type(const type_base_sptr& t)
14138 {priv_->underlying_type_ = t;}
14139
14140 /// Non-member equality operator for @ref qualified_type_def
14141 ///
14142 /// @param l the left-hand side of the equality operator
14143 ///
14144 /// @param r the right-hand side of the equality operator
14145 ///
14146 /// @return true iff @p l and @p r equals.
14147 bool
operator ==(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)14148 operator==(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
14149 {
14150 if (l.get() == r.get())
14151 return true;
14152 if (!!l != !!r)
14153 return false;
14154
14155 return *l == *r;
14156 }
14157
14158 /// Non-member inequality operator for @ref qualified_type_def
14159 ///
14160 /// @param l the left-hand side of the equality operator
14161 ///
14162 /// @param r the right-hand side of the equality operator
14163 ///
14164 /// @return true iff @p l and @p r equals.
14165 bool
operator !=(const qualified_type_def_sptr & l,const qualified_type_def_sptr & r)14166 operator!=(const qualified_type_def_sptr& l, const qualified_type_def_sptr& r)
14167 {return ! operator==(l, r);}
14168
14169 /// Overloaded bitwise OR operator for cv qualifiers.
14170 qualified_type_def::CV
operator |(qualified_type_def::CV lhs,qualified_type_def::CV rhs)14171 operator|(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
14172 {
14173 return static_cast<qualified_type_def::CV>
14174 (static_cast<unsigned>(lhs) | static_cast<unsigned>(rhs));
14175 }
14176
14177 /// Overloaded bitwise |= operator for cv qualifiers.
14178 qualified_type_def::CV&
operator |=(qualified_type_def::CV & l,qualified_type_def::CV r)14179 operator|=(qualified_type_def::CV& l, qualified_type_def::CV r)
14180 {
14181 l = l | r;
14182 return l;
14183 }
14184
14185 /// Overloaded bitwise AND operator for CV qualifiers.
14186 qualified_type_def::CV
operator &(qualified_type_def::CV lhs,qualified_type_def::CV rhs)14187 operator&(qualified_type_def::CV lhs, qualified_type_def::CV rhs)
14188 {
14189 return static_cast<qualified_type_def::CV>
14190 (static_cast<unsigned>(lhs) & static_cast<unsigned>(rhs));
14191 }
14192
14193 /// Overloaded bitwise inverting operator for CV qualifiers.
14194 qualified_type_def::CV
operator ~(qualified_type_def::CV q)14195 operator~(qualified_type_def::CV q)
14196 {return static_cast<qualified_type_def::CV>(~static_cast<unsigned>(q));}
14197
14198 /// Streaming operator for qualified_type_decl::CV
14199 ///
14200 /// @param o the output stream to serialize the cv qualifier to.
14201 ///
14202 /// @param cv the cv qualifier to serialize.
14203 ///
14204 /// @return the output stream used.
14205 std::ostream&
operator <<(std::ostream & o,qualified_type_def::CV cv)14206 operator<<(std::ostream& o, qualified_type_def::CV cv)
14207 {
14208 string str;
14209
14210 switch (cv)
14211 {
14212 case qualified_type_def::CV_NONE:
14213 str = "none";
14214 break;
14215 case qualified_type_def::CV_CONST:
14216 str = "const";
14217 break;
14218 case qualified_type_def::CV_VOLATILE:
14219 str = "volatile";
14220 break;
14221 case qualified_type_def::CV_RESTRICT:
14222 str = "restrict";
14223 break;
14224 }
14225
14226 o << str;
14227 return o;
14228 }
14229
14230 // </qualified_type_def>
14231
14232 //<pointer_type_def definitions>
14233
14234 /// Private data structure of the @ref pointer_type_def.
14235 struct pointer_type_def::priv
14236 {
14237 type_base_wptr pointed_to_type_;
14238 type_base* naked_pointed_to_type_;
14239 interned_string internal_qualified_name_;
14240 interned_string temp_internal_qualified_name_;
14241
privabigail::ir::pointer_type_def::priv14242 priv(const type_base_sptr& t)
14243 : pointed_to_type_(type_or_void(t, 0)),
14244 naked_pointed_to_type_(t.get())
14245 {}
14246
privabigail::ir::pointer_type_def::priv14247 priv()
14248 : naked_pointed_to_type_()
14249 {}
14250 }; //end struct pointer_type_def
14251
14252 /// This function is automatically invoked whenever an instance of
14253 /// this type is canonicalized.
14254 ///
14255 /// It's an overload of the virtual type_base::on_canonical_type_set.
14256 ///
14257 /// We put here what is thus meant to be executed only at the point of
14258 /// type canonicalization.
14259 void
on_canonical_type_set()14260 pointer_type_def::on_canonical_type_set()
14261 {clear_qualified_name();}
14262
pointer_type_def(const type_base_sptr & pointed_to,size_t size_in_bits,size_t align_in_bits,const location & locus)14263 pointer_type_def::pointer_type_def(const type_base_sptr& pointed_to,
14264 size_t size_in_bits,
14265 size_t align_in_bits,
14266 const location& locus)
14267 : type_or_decl_base(pointed_to->get_environment(),
14268 POINTER_TYPE
14269 | ABSTRACT_TYPE_BASE
14270 | ABSTRACT_DECL_BASE),
14271 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
14272 decl_base(pointed_to->get_environment(), "", locus, ""),
14273 priv_(new priv(pointed_to))
14274 {
14275 runtime_type_instance(this);
14276 try
14277 {
14278 ABG_ASSERT(pointed_to);
14279 const environment* env = pointed_to->get_environment();
14280 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
14281 string name = (pto ? pto->get_name() : string("void")) + "*";
14282 set_name(env->intern(name));
14283 if (pto)
14284 set_visibility(pto->get_visibility());
14285 }
14286 catch (...)
14287 {}
14288 }
14289
14290 /// Compares two instances of @ref pointer_type_def.
14291 ///
14292 /// If the two intances are different, set a bitfield to give some
14293 /// insight about the kind of differences there are.
14294 ///
14295 /// @param l the first artifact of the comparison.
14296 ///
14297 /// @param r the second artifact of the comparison.
14298 ///
14299 /// @param k a pointer to a bitfield that gives information about the
14300 /// kind of changes there are between @p l and @p r. This one is set
14301 /// iff @p k is non-null and the function returns false.
14302 ///
14303 /// Please note that setting k to a non-null value does have a
14304 /// negative performance impact because even if @p l and @p r are not
14305 /// equal, the function keeps up the comparison in order to determine
14306 /// the different kinds of ways in which they are different.
14307 ///
14308 /// @return true if @p l equals @p r, false otherwise.
14309 bool
equals(const pointer_type_def & l,const pointer_type_def & r,change_kind * k)14310 equals(const pointer_type_def& l, const pointer_type_def& r, change_kind* k)
14311 {
14312 // Compare the pointed-to-types modulo the typedefs they might have
14313 bool result = (peel_typedef_type(l.get_pointed_to_type())
14314 == peel_typedef_type(r.get_pointed_to_type()));
14315 if (!result)
14316 if (k)
14317 {
14318 if (!types_have_similar_structure(&l, &r))
14319 // pointed-to type changes in which the structure of the
14320 // type changed are considered local changes to the pointer
14321 // type.
14322 *k |= LOCAL_TYPE_CHANGE_KIND;
14323 *k |= SUBTYPE_CHANGE_KIND;
14324 }
14325
14326 return result;
14327 }
14328
14329 /// Return true iff both instances of pointer_type_def are equal.
14330 ///
14331 /// Note that this function does not check for the scopes of the this
14332 /// types.
14333 bool
operator ==(const decl_base & o) const14334 pointer_type_def::operator==(const decl_base& o) const
14335 {
14336 const pointer_type_def* other = is_pointer_type(&o);
14337 if (!other)
14338 return false;
14339 return try_canonical_compare(this, other);
14340 }
14341
14342 /// Return true iff both instances of pointer_type_def are equal.
14343 ///
14344 /// Note that this function does not check for the scopes of the
14345 /// types.
14346 ///
14347 /// @param other the other type to compare against.
14348 ///
14349 /// @return true iff @p other equals the current instance.
14350 bool
operator ==(const type_base & other) const14351 pointer_type_def::operator==(const type_base& other) const
14352 {
14353 const decl_base* o = is_decl(&other);
14354 if (!o)
14355 return false;
14356 return *this == *o;
14357 }
14358
14359 /// Return true iff both instances of pointer_type_def are equal.
14360 ///
14361 /// Note that this function does not check for the scopes of the
14362 /// types.
14363 ///
14364 /// @param other the other type to compare against.
14365 ///
14366 /// @return true iff @p other equals the current instance.
14367 bool
operator ==(const pointer_type_def & other) const14368 pointer_type_def::operator==(const pointer_type_def& other) const
14369 {
14370 const decl_base& o = other;
14371 return *this == o;
14372 }
14373
14374 /// Getter of the pointed-to type.
14375 ///
14376 /// @return the pointed-to type.
14377 const type_base_sptr
get_pointed_to_type() const14378 pointer_type_def::get_pointed_to_type() const
14379 {return priv_->pointed_to_type_.lock();}
14380
14381 /// Getter of a naked pointer to the pointed-to type.
14382 ///
14383 /// @return a naked pointed to the pointed-to type.
14384 type_base*
get_naked_pointed_to_type() const14385 pointer_type_def::get_naked_pointed_to_type() const
14386 {return priv_->naked_pointed_to_type_;}
14387
14388 /// Build and return the qualified name of the current instance of
14389 /// @ref pointer_type_def.
14390 ///
14391 /// @param qn output parameter. The resulting qualified name.
14392 ///
14393 /// @param internal set to true if the call is intended for an
14394 /// internal use (for technical use inside the library itself), false
14395 /// otherwise. If you don't know what this is for, then set it to
14396 /// false.
14397 void
get_qualified_name(interned_string & qn,bool internal) const14398 pointer_type_def::get_qualified_name(interned_string& qn, bool internal) const
14399 {qn = get_qualified_name(internal);}
14400
14401 /// Build, cache and return the qualified name of the current instance
14402 /// of @ref pointer_type_def. Subsequent invocations of this function
14403 /// return the cached value.
14404 ///
14405 /// @param internal set to true if the call is intended for an
14406 /// internal use (for technical use inside the library itself), false
14407 /// otherwise. If you don't know what this is for, then set it to
14408 /// false.
14409 ///
14410 /// @return the resulting qualified name.
14411 const interned_string&
get_qualified_name(bool internal) const14412 pointer_type_def::get_qualified_name(bool internal) const
14413 {
14414 type_base* pointed_to_type = get_naked_pointed_to_type();
14415
14416 if (internal)
14417 {
14418 if (get_canonical_type())
14419 {
14420 if (priv_->internal_qualified_name_.empty())
14421 priv_->internal_qualified_name_ =
14422 get_name_of_pointer_to_type(*pointed_to_type,
14423 /*qualified_name=*/true,
14424 /*internal=*/true);
14425 return priv_->internal_qualified_name_;
14426 }
14427 else
14428 {
14429 // As the type hasn't yet been canonicalized, its structure
14430 // (and so its name) can change. So let's invalidate the
14431 // cache where we store its name at each invocation of this
14432 // function.
14433 priv_->temp_internal_qualified_name_ =
14434 get_name_of_pointer_to_type(*pointed_to_type,
14435 /*qualified_name=*/true,
14436 /*internal=*/true);
14437 return priv_->temp_internal_qualified_name_;
14438 }
14439 }
14440 else
14441 {
14442 if (get_naked_canonical_type())
14443 {
14444 if (decl_base::peek_qualified_name().empty())
14445 set_qualified_name
14446 (get_name_of_pointer_to_type(*pointed_to_type,
14447 /*qualified_name=*/true,
14448 /*internal=*/false));
14449 return decl_base::peek_qualified_name();
14450 }
14451 else
14452 {
14453 // As the type hasn't yet been canonicalized, its structure
14454 // (and so its name) can change. So let's invalidate the
14455 // cache where we store its name at each invocation of this
14456 // function.
14457 set_qualified_name
14458 (get_name_of_pointer_to_type(*pointed_to_type,
14459 /*qualified_name=*/true,
14460 /*internal=*/false));
14461 return decl_base::peek_qualified_name();
14462 }
14463 }
14464 }
14465
14466 /// This implements the ir_traversable_base::traverse pure virtual
14467 /// function.
14468 ///
14469 /// @param v the visitor used on the current instance.
14470 ///
14471 /// @return true if the entire IR node tree got traversed, false
14472 /// otherwise.
14473 bool
traverse(ir_node_visitor & v)14474 pointer_type_def::traverse(ir_node_visitor& v)
14475 {
14476 if (v.type_node_has_been_visited(this))
14477 return true;
14478
14479 if (visiting())
14480 return true;
14481
14482 if (v.visit_begin(this))
14483 {
14484 visiting(true);
14485 if (type_base_sptr t = get_pointed_to_type())
14486 t->traverse(v);
14487 visiting(false);
14488 }
14489
14490 bool result = v.visit_end(this);
14491 v.mark_type_node_as_visited(this);
14492 return result;
14493 }
14494
~pointer_type_def()14495 pointer_type_def::~pointer_type_def()
14496 {}
14497
14498 /// Turn equality of shared_ptr of @ref pointer_type_def into a deep
14499 /// equality; that is, make it compare the pointed to objects too.
14500 ///
14501 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
14502 /// of the equality.
14503 ///
14504 /// @param r the shared_ptr of @ref pointer_type_def on
14505 /// right-hand-side of the equality.
14506 ///
14507 /// @return true if the @ref pointer_type_def pointed to by the
14508 /// shared_ptrs are equal, false otherwise.
14509 bool
operator ==(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)14510 operator==(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
14511 {
14512 if (l.get() == r.get())
14513 return true;
14514 if (!!l != !!r)
14515 return false;
14516
14517 return *l == *r;
14518 }
14519
14520 /// Turn inequality of shared_ptr of @ref pointer_type_def into a deep
14521 /// equality; that is, make it compare the pointed to objects too.
14522 ///
14523 /// @param l the shared_ptr of @ref pointer_type_def on left-hand-side
14524 /// of the equality.
14525 ///
14526 /// @param r the shared_ptr of @ref pointer_type_def on
14527 /// right-hand-side of the equality.
14528 ///
14529 /// @return true iff the @ref pointer_type_def pointed to by the
14530 /// shared_ptrs are different.
14531 bool
operator !=(const pointer_type_def_sptr & l,const pointer_type_def_sptr & r)14532 operator!=(const pointer_type_def_sptr& l, const pointer_type_def_sptr& r)
14533 {return !operator==(l, r);}
14534
14535 // </pointer_type_def definitions>
14536
14537 // <reference_type_def definitions>
14538
14539 /// This function is automatically invoked whenever an instance of
14540 /// this type is canonicalized.
14541 ///
14542 /// It's an overload of the virtual type_base::on_canonical_type_set.
14543 ///
14544 /// We put here what is thus meant to be executed only at the point of
14545 /// type canonicalization.
14546 void
on_canonical_type_set()14547 reference_type_def::on_canonical_type_set()
14548 {clear_qualified_name();}
14549
reference_type_def(const type_base_sptr pointed_to,bool lvalue,size_t size_in_bits,size_t align_in_bits,const location & locus)14550 reference_type_def::reference_type_def(const type_base_sptr pointed_to,
14551 bool lvalue,
14552 size_t size_in_bits,
14553 size_t align_in_bits,
14554 const location& locus)
14555 : type_or_decl_base(pointed_to->get_environment(),
14556 REFERENCE_TYPE
14557 | ABSTRACT_TYPE_BASE
14558 | ABSTRACT_DECL_BASE),
14559 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
14560 decl_base(pointed_to->get_environment(), "", locus, ""),
14561 is_lvalue_(lvalue)
14562 {
14563 runtime_type_instance(this);
14564
14565 try
14566 {
14567 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
14568 string name;
14569 if (pto)
14570 {
14571 set_visibility(pto->get_visibility());
14572 name = string(pto->get_name()) + "&";
14573 }
14574 else
14575 name = string(get_type_name(is_function_type(pointed_to),
14576 /*qualified_name=*/true)) + "&";
14577
14578 if (!is_lvalue())
14579 name += "&";
14580 environment* env = pointed_to->get_environment();
14581 ABG_ASSERT(env);
14582 set_name(env->intern(name));
14583
14584 pointed_to_type_ = type_base_wptr(type_or_void(pointed_to, 0));
14585 }
14586 catch (...)
14587 {}
14588 }
14589
14590 /// Compares two instances of @ref reference_type_def.
14591 ///
14592 /// If the two intances are different, set a bitfield to give some
14593 /// insight about the kind of differences there are.
14594 ///
14595 /// @param l the first artifact of the comparison.
14596 ///
14597 /// @param r the second artifact of the comparison.
14598 ///
14599 /// @param k a pointer to a bitfield that gives information about the
14600 /// kind of changes there are between @p l and @p r. This one is set
14601 /// iff @p k is non-null and the function returns false.
14602 ///
14603 /// Please note that setting k to a non-null value does have a
14604 /// negative performance impact because even if @p l and @p r are not
14605 /// equal, the function keeps up the comparison in order to determine
14606 /// the different kinds of ways in which they are different.
14607 ///
14608 /// @return true if @p l equals @p r, false otherwise.
14609 bool
equals(const reference_type_def & l,const reference_type_def & r,change_kind * k)14610 equals(const reference_type_def& l, const reference_type_def& r, change_kind* k)
14611 {
14612 if (l.is_lvalue() != r.is_lvalue())
14613 {
14614 if (k)
14615 *k |= LOCAL_TYPE_CHANGE_KIND;
14616 return false;
14617 }
14618
14619 // Compare the pointed-to-types modulo the typedefs they might have
14620 bool result = (peel_typedef_type(l.get_pointed_to_type())
14621 == (peel_typedef_type(r.get_pointed_to_type())));
14622 if (!result)
14623 if (k)
14624 {
14625 if (!types_have_similar_structure(&l, &r))
14626 *k |= LOCAL_TYPE_CHANGE_KIND;
14627 *k |= SUBTYPE_CHANGE_KIND;
14628 }
14629 return result;
14630 }
14631
14632 /// Equality operator of the @ref reference_type_def type.
14633 ///
14634 /// @param o the other instance of @ref reference_type_def to compare
14635 /// against.
14636 ///
14637 /// @return true iff the two instances are equal.
14638 bool
operator ==(const decl_base & o) const14639 reference_type_def::operator==(const decl_base& o) const
14640 {
14641 const reference_type_def* other =
14642 dynamic_cast<const reference_type_def*>(&o);
14643 if (!other)
14644 return false;
14645 return try_canonical_compare(this, other);
14646 }
14647
14648 /// Equality operator of the @ref reference_type_def type.
14649 ///
14650 /// @param o the other instance of @ref reference_type_def to compare
14651 /// against.
14652 ///
14653 /// @return true iff the two instances are equal.
14654 bool
operator ==(const type_base & o) const14655 reference_type_def::operator==(const type_base& o) const
14656 {
14657 const decl_base* other = dynamic_cast<const decl_base*>(&o);
14658 if (!other)
14659 return false;
14660 return *this == *other;
14661 }
14662
14663 /// Equality operator of the @ref reference_type_def type.
14664 ///
14665 /// @param o the other instance of @ref reference_type_def to compare
14666 /// against.
14667 ///
14668 /// @return true iff the two instances are equal.
14669 bool
operator ==(const reference_type_def & o) const14670 reference_type_def::operator==(const reference_type_def& o) const
14671 {
14672 const decl_base* other = dynamic_cast<const decl_base*>(&o);
14673 if (!other)
14674 return false;
14675 return *this == *other;
14676 }
14677
14678 type_base_sptr
get_pointed_to_type() const14679 reference_type_def::get_pointed_to_type() const
14680 {return pointed_to_type_.lock();}
14681
14682 bool
is_lvalue() const14683 reference_type_def::is_lvalue() const
14684 {return is_lvalue_;}
14685
14686 /// Build and return the qualified name of the current instance of the
14687 /// @ref reference_type_def.
14688 ///
14689 /// @param qn output parameter. Is set to the newly-built qualified
14690 /// name of the current instance of @ref reference_type_def.
14691 ///
14692 /// @param internal set to true if the call is intended for an
14693 /// internal use (for technical use inside the library itself), false
14694 /// otherwise. If you don't know what this is for, then set it to
14695 /// false.
14696 void
get_qualified_name(interned_string & qn,bool internal) const14697 reference_type_def::get_qualified_name(interned_string& qn, bool internal) const
14698 {qn = get_qualified_name(internal);}
14699
14700 /// Build, cache and return the qualified name of the current instance
14701 /// of the @ref reference_type_def. Subsequent invocations of this
14702 /// function return the cached value.
14703 ///
14704 /// @param internal set to true if the call is intended for an
14705 /// internal use (for technical use inside the library itself), false
14706 /// otherwise. If you don't know what this is for, then set it to
14707 /// false.
14708 ///
14709 /// @return the newly-built qualified name of the current instance of
14710 /// @ref reference_type_def.
14711 const interned_string&
get_qualified_name(bool internal) const14712 reference_type_def::get_qualified_name(bool internal) const
14713 {
14714 if (peek_qualified_name().empty()
14715 || !get_canonical_type())
14716 set_qualified_name(get_name_of_reference_to_type(*get_pointed_to_type(),
14717 is_lvalue(),
14718 /*qualified_name=*/true,
14719 internal));
14720 return peek_qualified_name();
14721 }
14722
14723 /// This implements the ir_traversable_base::traverse pure virtual
14724 /// function.
14725 ///
14726 /// @param v the visitor used on the current instance.
14727 ///
14728 /// @return true if the entire IR node tree got traversed, false
14729 /// otherwise.
14730 bool
traverse(ir_node_visitor & v)14731 reference_type_def::traverse(ir_node_visitor& v)
14732 {
14733 if (v.type_node_has_been_visited(this))
14734 return true;
14735
14736 if (visiting())
14737 return true;
14738
14739 if (v.visit_begin(this))
14740 {
14741 visiting(true);
14742 if (type_base_sptr t = get_pointed_to_type())
14743 t->traverse(v);
14744 visiting(false);
14745 }
14746
14747 bool result = v.visit_end(this);
14748 v.mark_type_node_as_visited(this);
14749 return result;
14750 }
14751
~reference_type_def()14752 reference_type_def::~reference_type_def()
14753 {}
14754
14755 /// Turn equality of shared_ptr of @ref reference_type_def into a deep
14756 /// equality; that is, make it compare the pointed to objects too.
14757 ///
14758 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
14759 /// of the equality.
14760 ///
14761 /// @param r the shared_ptr of @ref reference_type_def on
14762 /// right-hand-side of the equality.
14763 ///
14764 /// @return true if the @ref reference_type_def pointed to by the
14765 /// shared_ptrs are equal, false otherwise.
14766 bool
operator ==(const reference_type_def_sptr & l,const reference_type_def_sptr & r)14767 operator==(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
14768 {
14769 if (l.get() == r.get())
14770 return true;
14771 if (!!l != !!r)
14772 return false;
14773
14774 return *l == *r;
14775 }
14776
14777 /// Turn inequality of shared_ptr of @ref reference_type_def into a deep
14778 /// equality; that is, make it compare the pointed to objects too.
14779 ///
14780 /// @param l the shared_ptr of @ref reference_type_def on left-hand-side
14781 /// of the equality.
14782 ///
14783 /// @param r the shared_ptr of @ref reference_type_def on
14784 /// right-hand-side of the equality.
14785 ///
14786 /// @return true iff the @ref reference_type_def pointed to by the
14787 /// shared_ptrs are different.
14788 bool
operator !=(const reference_type_def_sptr & l,const reference_type_def_sptr & r)14789 operator!=(const reference_type_def_sptr& l, const reference_type_def_sptr& r)
14790 {return !operator==(l, r);}
14791
14792 // </reference_type_def definitions>
14793
14794 // <array_type_def definitions>
14795
14796 // <array_type_def::subrange_type>
14797
14798 // <array_type_def::subrante_type::bound_value>
14799
14800 /// Default constructor of the @ref
14801 /// array_type_def::subrange_type::bound_value class.
14802 ///
14803 /// Constructs an unsigned bound_value of value zero.
bound_value()14804 array_type_def::subrange_type::bound_value::bound_value()
14805 : s_(UNSIGNED_SIGNEDNESS)
14806 {
14807 v_.unsigned_ = 0;
14808 }
14809
14810 /// Initialize an unsigned bound_value with a given value.
14811 ///
14812 /// @param v the initial bound value.
bound_value(uint64_t v)14813 array_type_def::subrange_type::bound_value::bound_value(uint64_t v)
14814 : s_(UNSIGNED_SIGNEDNESS)
14815 {
14816 v_.unsigned_ = v;
14817 }
14818
14819 /// Initialize a signed bound_value with a given value.
14820 ///
14821 /// @param v the initial bound value.
bound_value(int64_t v)14822 array_type_def::subrange_type::bound_value::bound_value(int64_t v)
14823 : s_(SIGNED_SIGNEDNESS)
14824 {
14825 v_.signed_ = v;
14826 }
14827
14828 /// Getter of the signedness (unsigned VS signed) of the bound value.
14829 ///
14830 /// @return the signedness of the bound value.
14831 enum array_type_def::subrange_type::bound_value::signedness
get_signedness() const14832 array_type_def::subrange_type::bound_value::get_signedness() const
14833 {return s_;}
14834
14835 /// Setter of the signedness (unsigned VS signed) of the bound value.
14836 ///
14837 /// @param s the new signedness of the bound value.
14838 void
set_signedness(enum signedness s)14839 array_type_def::subrange_type::bound_value::set_signedness(enum signedness s)
14840 { s_ = s;}
14841
14842 /// Getter of the bound value as a signed value.
14843 ///
14844 /// @return the bound value as signed.
14845 int64_t
get_signed_value() const14846 array_type_def::subrange_type::bound_value::get_signed_value() const
14847 {return v_.signed_;
14848 }
14849
14850 /// Getter of the bound value as an unsigned value.
14851 ///
14852 /// @return the bound value as unsigned.
14853 uint64_t
get_unsigned_value()14854 array_type_def::subrange_type::bound_value::get_unsigned_value()
14855 {return v_.unsigned_;}
14856
14857 /// Setter of the bound value as unsigned.
14858 ///
14859 /// @param v the new unsigned value.
14860 void
set_unsigned(uint64_t v)14861 array_type_def::subrange_type::bound_value::set_unsigned(uint64_t v)
14862 {
14863 s_ = UNSIGNED_SIGNEDNESS;
14864 v_.unsigned_ = v;
14865 }
14866
14867 /// Setter of the bound value as signed.
14868 ///
14869 /// @param v the new signed value.
14870 void
set_signed(int64_t v)14871 array_type_def::subrange_type::bound_value::set_signed(int64_t v)
14872 {
14873 s_ = SIGNED_SIGNEDNESS;
14874 v_.signed_ = v;
14875 }
14876
14877 /// Equality operator of the bound value.
14878 ///
14879 /// @param v the other bound value to compare with.
14880 ///
14881 /// @return true iff the current bound value equals @p v.
14882 bool
operator ==(const bound_value & v) const14883 array_type_def::subrange_type::bound_value::operator==(const bound_value& v) const
14884 {
14885 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
14886 }
14887
14888 // </array_type_def::subrante_type::bound_value>
14889
14890 struct array_type_def::subrange_type::priv
14891 {
14892 bound_value lower_bound_;
14893 bound_value upper_bound_;
14894 type_base_wptr underlying_type_;
14895 translation_unit::language language_;
14896 bool infinite_;
14897
privabigail::ir::array_type_def::subrange_type::priv14898 priv(bound_value ub,
14899 translation_unit::language l = translation_unit::LANG_C11)
14900 : upper_bound_(ub), language_(l), infinite_(false)
14901 {}
14902
privabigail::ir::array_type_def::subrange_type::priv14903 priv(bound_value lb, bound_value ub,
14904 translation_unit::language l = translation_unit::LANG_C11)
14905 : lower_bound_(lb), upper_bound_(ub),
14906 language_(l), infinite_(false)
14907 {}
14908
privabigail::ir::array_type_def::subrange_type::priv14909 priv(bound_value lb, bound_value ub, const type_base_sptr &u,
14910 translation_unit::language l = translation_unit::LANG_C11)
14911 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
14912 language_(l), infinite_(false)
14913 {}
14914 };
14915
14916 /// Constructor of an array_type_def::subrange_type type.
14917 ///
14918 /// @param env the environment this type was created from.
14919 ///
14920 /// @param name the name of the subrange type.
14921 ///
14922 /// @param lower_bound the lower bound of the array. This is
14923 /// generally zero (at least for C and C++).
14924 ///
14925 /// @param upper_bound the upper bound of the array.
14926 ///
14927 /// @param underlying_type the underlying type of the subrange type.
14928 ///
14929 /// @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)14930 array_type_def::subrange_type::subrange_type(const environment* env,
14931 const string& name,
14932 bound_value lower_bound,
14933 bound_value upper_bound,
14934 const type_base_sptr& utype,
14935 const location& loc,
14936 translation_unit::language l)
14937 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
14938 type_base(env,
14939 upper_bound.get_unsigned_value()
14940 - lower_bound.get_unsigned_value(),
14941 0),
14942 decl_base(env, name, loc, ""),
14943 priv_(new priv(lower_bound, upper_bound, utype, l))
14944 {
14945 runtime_type_instance(this);
14946 }
14947
14948 /// Constructor of the array_type_def::subrange_type type.
14949 ///
14950 /// @param env the environment this type is being created in.
14951 ///
14952 /// @param name the name of the subrange type.
14953 ///
14954 /// @param lower_bound the lower bound of the array. This is
14955 /// generally zero (at least for C and C++).
14956 ///
14957 /// @param upper_bound the upper bound of the array.
14958 ///
14959 /// @param loc the source location where the type is defined.
14960 ///
14961 /// @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)14962 array_type_def::subrange_type::subrange_type(const environment* env,
14963 const string& name,
14964 bound_value lower_bound,
14965 bound_value upper_bound,
14966 const location& loc,
14967 translation_unit::language l)
14968 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
14969 type_base(env,
14970 upper_bound.get_unsigned_value()
14971 - lower_bound.get_unsigned_value(), 0),
14972 decl_base(env, name, loc, ""),
14973 priv_(new priv(lower_bound, upper_bound, l))
14974 {
14975 runtime_type_instance(this);
14976 }
14977
14978 /// Constructor of the array_type_def::subrange_type type.
14979 ///
14980 /// @param env the environment this type is being created from.
14981 ///
14982 /// @param name of the name of type.
14983 ///
14984 /// @param upper_bound the upper bound of the array. The lower bound
14985 /// is considered to be zero.
14986 ///
14987 /// @param loc the source location of the type.
14988 ///
14989 /// @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)14990 array_type_def::subrange_type::subrange_type(const environment* env,
14991 const string& name,
14992 bound_value upper_bound,
14993 const location& loc,
14994 translation_unit::language l)
14995 : type_or_decl_base(env, ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
14996 type_base(env, upper_bound.get_unsigned_value(), 0),
14997 decl_base(env, name, loc, ""),
14998 priv_(new priv(upper_bound, l))
14999 {
15000 runtime_type_instance(this);
15001 }
15002
15003 /// Getter of the underlying type of the subrange, that is, the type
15004 /// that defines the range.
15005 ///
15006 /// @return the underlying type.
15007 type_base_sptr
get_underlying_type() const15008 array_type_def::subrange_type::get_underlying_type() const
15009 {return priv_->underlying_type_.lock();}
15010
15011 /// Setter of the underlying type of the subrange, that is, the type
15012 /// that defines the range.
15013 ///
15014 /// @param u the new underlying type.
15015 void
set_underlying_type(const type_base_sptr & u)15016 array_type_def::subrange_type::set_underlying_type(const type_base_sptr &u)
15017 {
15018 ABG_ASSERT(priv_->underlying_type_.expired());
15019 priv_->underlying_type_ = u;
15020 }
15021
15022 /// Getter of the upper bound of the subrange type.
15023 ///
15024 /// @return the upper bound of the subrange type.
15025 int64_t
get_upper_bound() const15026 array_type_def::subrange_type::get_upper_bound() const
15027 {return priv_->upper_bound_.get_signed_value();}
15028
15029 /// Getter of the lower bound of the subrange type.
15030 ///
15031 /// @return the lower bound of the subrange type.
15032 int64_t
get_lower_bound() const15033 array_type_def::subrange_type::get_lower_bound() const
15034 {return priv_->lower_bound_.get_signed_value();}
15035
15036 /// Setter of the upper bound of the subrange type.
15037 ///
15038 /// @param ub the new value of the upper bound.
15039 void
set_upper_bound(int64_t ub)15040 array_type_def::subrange_type::set_upper_bound(int64_t ub)
15041 {priv_->upper_bound_ = ub;}
15042
15043 /// Setter of the lower bound.
15044 ///
15045 /// @param lb the new value of the lower bound.
15046 void
set_lower_bound(int64_t lb)15047 array_type_def::subrange_type::set_lower_bound(int64_t lb)
15048 {priv_->lower_bound_ = lb;}
15049
15050 /// Getter of the length of the subrange type.
15051 ///
15052 /// Note that a length of zero means the array has an infinite (or
15053 /// rather a non-known) size.
15054 ///
15055 /// @return the length of the subrange type.
15056 uint64_t
get_length() const15057 array_type_def::subrange_type::get_length() const
15058 {
15059 if (is_infinite())
15060 return 0;
15061
15062 ABG_ASSERT(get_upper_bound() >= get_lower_bound());
15063 return get_upper_bound() - get_lower_bound() + 1;
15064 }
15065
15066 /// Test if the length of the subrange type is infinite.
15067 ///
15068 /// @return true iff the length of the subrange type is infinite.
15069 bool
is_infinite() const15070 array_type_def::subrange_type::is_infinite() const
15071 {return priv_->infinite_;}
15072
15073 /// Set the infinite-ness status of the subrange type.
15074 ///
15075 /// @param f true iff the length of the subrange type should be set to
15076 /// being infinite.
15077 void
is_infinite(bool f)15078 array_type_def::subrange_type::is_infinite(bool f)
15079 {priv_->infinite_ = f;}
15080
15081 /// Getter of the language that generated this type.
15082 ///
15083 /// @return the language of this type.
15084 translation_unit::language
get_language() const15085 array_type_def::subrange_type::get_language() const
15086 {return priv_->language_;}
15087
15088 /// Return a string representation of the sub range.
15089 ///
15090 /// @return the string representation of the sub range.
15091 string
as_string() const15092 array_type_def::subrange_type::as_string() const
15093 {
15094 std::ostringstream o;
15095
15096 if (is_ada_language(get_language()))
15097 {
15098 type_base_sptr underlying_type = get_underlying_type();
15099 if (underlying_type)
15100 o << ir::get_pretty_representation(underlying_type, false) << " ";
15101 o << "range "<< get_lower_bound() << " .. " << get_upper_bound();
15102 }
15103 else if (is_infinite())
15104 o << "[]";
15105 else
15106 o << "[" << get_length() << "]";
15107
15108 return o.str();
15109 }
15110
15111 /// Return a string representation of a vector of subranges
15112 ///
15113 /// @return the string representation of a vector of sub ranges.
15114 string
vector_as_string(const vector<subrange_sptr> & v)15115 array_type_def::subrange_type::vector_as_string(const vector<subrange_sptr>& v)
15116 {
15117 if (v.empty())
15118 return "[]";
15119
15120 string r;
15121 for (vector<subrange_sptr>::const_iterator i = v.begin();
15122 i != v.end();
15123 ++i)
15124 r += (*i)->as_string();
15125
15126 return r;
15127 }
15128
15129 /// Compares two isntances of @ref array_type_def::subrange_type.
15130 ///
15131 /// If the two intances are different, set a bitfield to give some
15132 /// insight about the kind of differences there are.
15133 ///
15134 /// @param l the first artifact of the comparison.
15135 ///
15136 /// @param r the second artifact of the comparison.
15137 ///
15138 /// @param k a pointer to a bitfield that gives information about the
15139 /// kind of changes there are between @p l and @p r. This one is set
15140 /// iff @p k is non-null and the function returns false.
15141 ///
15142 /// Please note that setting k to a non-null value does have a
15143 /// negative performance impact because even if @p l and @p r are not
15144 /// equal, the function keeps up the comparison in order to determine
15145 /// the different kinds of ways in which they are different.
15146 ///
15147 /// @return true if @p l equals @p r, false otherwise.
15148 bool
equals(const array_type_def::subrange_type & l,const array_type_def::subrange_type & r,change_kind * k)15149 equals(const array_type_def::subrange_type& l,
15150 const array_type_def::subrange_type& r,
15151 change_kind* k)
15152 {
15153 bool result = true;
15154
15155 if (l.get_lower_bound() != r.get_lower_bound()
15156 || l.get_upper_bound() != r.get_upper_bound()
15157 || l.get_name() != r.get_name())
15158 {
15159 result = false;
15160 if (k)
15161 *k |= LOCAL_TYPE_CHANGE_KIND;
15162 else
15163 return result;
15164 }
15165
15166 #if 0
15167 // If we enable this, we need to update the reporting code too, to
15168 // report changes about range underlying types too.
15169 if (l.get_underlying_type() != r.get_underlying_type())
15170 {
15171 result = false;
15172 if (k)
15173 {
15174 if (!types_have_similar_structure(l.get_underlying_type().get(),
15175 r.get_underlying_type().get()))
15176 *k |= LOCAL_TYPE_CHANGE_KIND;
15177 else
15178 *k |= SUBTYPE_CHANGE_KIND;
15179 }
15180 else
15181 return result;
15182 }
15183 #endif
15184 return result;
15185 }
15186
15187 /// Equality operator.
15188 ///
15189 /// @param o the other subrange to test against.
15190 ///
15191 /// @return true iff @p o equals the current instance of
15192 /// array_type_def::subrange_type.
15193 bool
operator ==(const decl_base & o) const15194 array_type_def::subrange_type::operator==(const decl_base& o) const
15195 {
15196 const subrange_type* other =
15197 dynamic_cast<const subrange_type*>(&o);
15198 if (!other)
15199 return false;
15200 return try_canonical_compare(this, other);
15201 }
15202
15203 /// Equality operator.
15204 ///
15205 /// @param o the other subrange to test against.
15206 ///
15207 /// @return true iff @p o equals the current instance of
15208 /// array_type_def::subrange_type.
15209 bool
operator ==(const type_base & o) const15210 array_type_def::subrange_type::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.
15219 ///
15220 /// @param o the other subrange to test against.
15221 ///
15222 /// @return true iff @p o equals the current instance of
15223 /// array_type_def::subrange_type.
15224 bool
operator ==(const subrange_type & o) const15225 array_type_def::subrange_type::operator==(const subrange_type& o) const
15226 {
15227 const type_base &t = o;
15228 return operator==(t);
15229 }
15230
15231 /// Inequality operator.
15232 ///
15233 /// @param o the other subrange to test against.
15234 ///
15235 /// @return true iff @p o is different from the current instance of
15236 /// array_type_def::subrange_type.
15237 bool
operator !=(const subrange_type & o) const15238 array_type_def::subrange_type::operator!=(const subrange_type& o) const
15239 {return !operator==(o);}
15240
15241 /// Build a pretty representation for an
15242 /// array_type_def::subrange_type.
15243 ///
15244 /// @param internal set to true if the call is intended for an
15245 /// internal use (for technical use inside the library itself), false
15246 /// otherwise. If you don't know what this is for, then set it to
15247 /// false.
15248 ///
15249 /// @return a copy of the pretty representation of the current
15250 /// instance of typedef_decl.
15251 string
get_pretty_representation(bool,bool) const15252 array_type_def::subrange_type::get_pretty_representation(bool, bool) const
15253 {
15254 string name = get_name();
15255 string repr;
15256
15257 if (name.empty())
15258 repr += "<anonymous range>";
15259 else
15260 repr += "<range " + get_name() + ">";
15261 repr += as_string();
15262
15263 return repr;
15264 }
15265
15266 /// This implements the ir_traversable_base::traverse pure virtual
15267 /// function.
15268 ///
15269 /// @param v the visitor used on the current instance.
15270 ///
15271 /// @return true if the entire IR node tree got traversed, false
15272 /// otherwise.
15273 bool
traverse(ir_node_visitor & v)15274 array_type_def::subrange_type::traverse(ir_node_visitor& v)
15275 {
15276 if (v.type_node_has_been_visited(this))
15277 return true;
15278
15279 if (v.visit_begin(this))
15280 {
15281 visiting(true);
15282 if (type_base_sptr u = get_underlying_type())
15283 u->traverse(v);
15284 visiting(false);
15285 }
15286
15287 bool result = v.visit_end(this);
15288 v.mark_type_node_as_visited(this);
15289 return result;
15290 }
15291
15292 // </array_type_def::subrange_type>
15293
15294 struct array_type_def::priv
15295 {
15296 type_base_wptr element_type_;
15297 subranges_type subranges_;
15298 interned_string temp_internal_qualified_name_;
15299 interned_string internal_qualified_name_;
15300
privabigail::ir::array_type_def::priv15301 priv(type_base_sptr t)
15302 : element_type_(t) {}
privabigail::ir::array_type_def::priv15303 priv(type_base_sptr t, subranges_type subs)
15304 : element_type_(t), subranges_(subs) {}
15305 };
15306
15307 /// Constructor for the type array_type_def
15308 ///
15309 /// Note how the constructor expects a vector of subrange
15310 /// objects. Parsing of the array information always entails
15311 /// parsing the subrange info as well, thus the class subrange_type
15312 /// is defined inside class array_type_def and also parsed
15313 /// simultaneously.
15314 ///
15315 /// @param e_type the type of the elements contained in the array
15316 ///
15317 /// @param subs a vector of the array's subranges(dimensions)
15318 ///
15319 /// @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)15320 array_type_def::array_type_def(const type_base_sptr e_type,
15321 const std::vector<subrange_sptr>& subs,
15322 const location& locus)
15323 : type_or_decl_base(e_type->get_environment(),
15324 ARRAY_TYPE
15325 | ABSTRACT_TYPE_BASE
15326 | ABSTRACT_DECL_BASE),
15327 type_base(e_type->get_environment(), 0, e_type->get_alignment_in_bits()),
15328 decl_base(e_type->get_environment(), locus),
15329 priv_(new priv(e_type))
15330 {
15331 runtime_type_instance(this);
15332 append_subranges(subs);
15333 }
15334
15335 string
get_subrange_representation() const15336 array_type_def::get_subrange_representation() const
15337 {
15338 string r = subrange_type::vector_as_string(get_subranges());
15339 return r;
15340 }
15341
15342 /// Get the string representation of an @ref array_type_def.
15343 ///
15344 /// @param a the array type to consider.
15345 ///
15346 /// @param internal set to true if the call is intended for an
15347 /// internal use (for technical use inside the library itself), false
15348 /// otherwise. If you don't know what this is for, then set it to
15349 /// false.
15350 static string
get_type_representation(const array_type_def & a,bool internal)15351 get_type_representation(const array_type_def& a, bool internal)
15352 {
15353 type_base_sptr e_type = a.get_element_type();
15354 decl_base_sptr d = get_type_declaration(e_type);
15355 string r;
15356
15357 if (is_ada_language(a.get_language()))
15358 {
15359 std::ostringstream o;
15360 o << "array ("
15361 << a.get_subrange_representation()
15362 << ") of "
15363 << e_type->get_pretty_representation(internal);
15364 }
15365 else
15366 {
15367 if (internal)
15368 r = get_type_name(e_type, /*qualified=*/true, /*internal=*/true)
15369 + a.get_subrange_representation();
15370 else
15371 r = get_type_name(e_type, /*qualified=*/false, /*internal=*/false)
15372 + a.get_subrange_representation();
15373 }
15374
15375 return r;
15376 }
15377
15378 /// Get the pretty representation of the current instance of @ref
15379 /// array_type_def.
15380 ///
15381 /// @param internal set to true if the call is intended for an
15382 /// internal use (for technical use inside the library itself), false
15383 /// otherwise. If you don't know what this is for, then set it to
15384 /// false.
15385 string
get_pretty_representation(bool internal,bool) const15386 array_type_def::get_pretty_representation(bool internal,
15387 bool /*qualified_name*/) const
15388 {return get_type_representation(*this, internal);}
15389
15390 /// Compares two instances of @ref array_type_def.
15391 ///
15392 /// If the two intances are different, set a bitfield to give some
15393 /// insight about the kind of differences there are.
15394 ///
15395 /// @param l the first artifact of the comparison.
15396 ///
15397 /// @param r the second artifact of the comparison.
15398 ///
15399 /// @param k a pointer to a bitfield that gives information about the
15400 /// kind of changes there are between @p l and @p r. This one is set
15401 /// iff @p k is non-null and the function returns false.
15402 ///
15403 /// Please note that setting k to a non-null value does have a
15404 /// negative performance impact because even if @p l and @p r are not
15405 /// equal, the function keeps up the comparison in order to determine
15406 /// the different kinds of ways in which they are different.
15407 ///
15408 /// @return true if @p l equals @p r, false otherwise.
15409 bool
equals(const array_type_def & l,const array_type_def & r,change_kind * k)15410 equals(const array_type_def& l, const array_type_def& r, change_kind* k)
15411 {
15412 std::vector<array_type_def::subrange_sptr > this_subs = l.get_subranges();
15413 std::vector<array_type_def::subrange_sptr > other_subs = r.get_subranges();
15414
15415 bool result = true;
15416 if (this_subs.size() != other_subs.size())
15417 {
15418 result = false;
15419 if (k)
15420 *k |= LOCAL_TYPE_CHANGE_KIND;
15421 else
15422 return false;
15423 }
15424
15425 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
15426 for (i = this_subs.begin(), j = other_subs.begin();
15427 i != this_subs.end() && j != other_subs.end();
15428 ++i, ++j)
15429 if (**i != **j)
15430 {
15431 result = false;
15432 if (k)
15433 {
15434 *k |= LOCAL_TYPE_CHANGE_KIND;
15435 break;
15436 }
15437 else
15438 return false;
15439 }
15440
15441 // Compare the element types modulo the typedefs they might have
15442 if (peel_typedef_type(l.get_element_type())
15443 != peel_typedef_type(r.get_element_type()))
15444 {
15445 result = false;
15446 if (k)
15447 *k |= SUBTYPE_CHANGE_KIND;
15448 else
15449 return false;
15450 }
15451
15452 return result;
15453 }
15454
15455 /// Test if two variables are equals modulo CV qualifiers.
15456 ///
15457 /// @param l the first array of the comparison.
15458 ///
15459 /// @param r the second array of the comparison.
15460 ///
15461 /// @return true iff @p l equals @p r or, if they are different, the
15462 /// difference between the too is just a matter of CV qualifiers.
15463 bool
equals_modulo_cv_qualifier(const array_type_def * l,const array_type_def * r)15464 equals_modulo_cv_qualifier(const array_type_def* l, const array_type_def* r)
15465 {
15466 if (l == r)
15467 return true;
15468
15469 if (!l || !r)
15470 return false;
15471
15472 l = is_array_type(peel_qualified_or_typedef_type(l));
15473 r = is_array_type(peel_qualified_or_typedef_type(r));
15474
15475 std::vector<array_type_def::subrange_sptr > this_subs = l->get_subranges();
15476 std::vector<array_type_def::subrange_sptr > other_subs = r->get_subranges();
15477
15478 if (this_subs.size() != other_subs.size())
15479 return false;
15480
15481 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
15482 for (i = this_subs.begin(), j = other_subs.begin();
15483 i != this_subs.end() && j != other_subs.end();
15484 ++i, ++j)
15485 if (**i != **j)
15486 return false;
15487
15488 type_base *first_element_type =
15489 peel_qualified_or_typedef_type(l->get_element_type().get());
15490 type_base *second_element_type =
15491 peel_qualified_or_typedef_type(r->get_element_type().get());
15492
15493 if (*first_element_type != *second_element_type)
15494 return false;
15495
15496 return true;
15497 }
15498
15499 /// Get the language of the array.
15500 ///
15501 /// @return the language of the array.
15502 translation_unit::language
get_language() const15503 array_type_def::get_language() const
15504 {
15505 const std::vector<subrange_sptr>& subranges =
15506 get_subranges();
15507
15508 if (subranges.empty())
15509 return translation_unit::LANG_C11;
15510 return subranges.front()->get_language();
15511 }
15512
15513 bool
operator ==(const decl_base & o) const15514 array_type_def::operator==(const decl_base& o) const
15515 {
15516 const array_type_def* other =
15517 dynamic_cast<const array_type_def*>(&o);
15518 if (!other)
15519 return false;
15520 return try_canonical_compare(this, other);
15521 }
15522
15523 bool
operator ==(const type_base & o) const15524 array_type_def::operator==(const type_base& o) const
15525 {
15526 const decl_base* other = dynamic_cast<const decl_base*>(&o);
15527 if (!other)
15528 return false;
15529 return *this == *other;
15530 }
15531
15532 /// Getter of the type of an array element.
15533 ///
15534 /// @return the type of an array element.
15535 const type_base_sptr
get_element_type() const15536 array_type_def::get_element_type() const
15537 {return priv_->element_type_.lock();}
15538
15539 /// Setter of the type of array element.
15540 ///
15541 /// Beware that after using this function, one might want to
15542 /// re-compute the canonical type of the array, if one has already
15543 /// been computed.
15544 ///
15545 /// The intended use of this method is to permit in-place adjustment
15546 /// of the element type's qualifiers. In particular, the size of the
15547 /// element type should not be changed.
15548 ///
15549 /// @param element_type the new element type to set.
15550 void
set_element_type(const type_base_sptr & element_type)15551 array_type_def::set_element_type(const type_base_sptr& element_type)
15552 {
15553 priv_->element_type_ = element_type;
15554 }
15555
15556 /// Append subranges from the vector @param subs to the current
15557 /// vector of subranges.
15558 void
append_subranges(const std::vector<subrange_sptr> & subs)15559 array_type_def::append_subranges(const std::vector<subrange_sptr>& subs)
15560 {
15561 size_t s = get_element_type()->get_size_in_bits();
15562
15563 for (std::vector<shared_ptr<subrange_type> >::const_iterator i = subs.begin();
15564 i != subs.end();
15565 ++i)
15566 {
15567 priv_->subranges_.push_back(*i);
15568 s *= (*i)->get_length();
15569 }
15570
15571 const environment* env = get_environment();
15572 ABG_ASSERT(env);
15573 set_name(env->intern(get_pretty_representation()));
15574 set_size_in_bits(s);
15575 }
15576
15577 /// @return true if one of the sub-ranges of the array is infinite, or
15578 /// if the array has no sub-range at all, also meaning that the size
15579 /// of the array is infinite.
15580 bool
is_infinite() const15581 array_type_def::is_infinite() const
15582 {
15583 if (priv_->subranges_.empty())
15584 return true;
15585
15586 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
15587 priv_->subranges_.begin();
15588 i != priv_->subranges_.end();
15589 ++i)
15590 if ((*i)->is_infinite())
15591 return true;
15592
15593 return false;
15594 }
15595
15596 int
get_dimension_count() const15597 array_type_def::get_dimension_count() const
15598 {return priv_->subranges_.size();}
15599
15600 /// Build and return the qualified name of the current instance of the
15601 /// @ref array_type_def.
15602 ///
15603 /// @param qn output parameter. Is set to the newly-built qualified
15604 /// name of the current instance of @ref array_type_def.
15605 ///
15606 /// @param internal set to true if the call is intended for an
15607 /// internal use (for technical use inside the library itself), false
15608 /// otherwise. If you don't know what this is for, then set it to
15609 /// false.
15610 void
get_qualified_name(interned_string & qn,bool internal) const15611 array_type_def::get_qualified_name(interned_string& qn, bool internal) const
15612 {qn = get_qualified_name(internal);}
15613
15614 /// Compute the qualified name of the array.
15615 ///
15616 /// @param internal set to true if the call is intended for an
15617 /// internal use (for technical use inside the library itself), false
15618 /// otherwise. If you don't know what this is for, then set it to
15619 /// false.
15620 ///
15621 /// @return the resulting qualified name.
15622 const interned_string&
get_qualified_name(bool internal) const15623 array_type_def::get_qualified_name(bool internal) const
15624 {
15625 const environment* env = get_environment();
15626 ABG_ASSERT(env);
15627
15628 if (internal)
15629 {
15630 if (get_canonical_type())
15631 {
15632 if (priv_->internal_qualified_name_.empty())
15633 priv_->internal_qualified_name_ =
15634 env->intern(get_type_representation(*this, /*internal=*/true));
15635 return priv_->internal_qualified_name_;
15636 }
15637 else
15638 {
15639 priv_->temp_internal_qualified_name_ =
15640 env->intern(get_type_representation(*this, /*internal=*/true));
15641 return priv_->temp_internal_qualified_name_;
15642 }
15643 }
15644 else
15645 {
15646 if (get_canonical_type())
15647 {
15648 if (decl_base::peek_qualified_name().empty())
15649 set_qualified_name(env->intern(get_type_representation
15650 (*this, /*internal=*/false)));
15651 return decl_base::peek_qualified_name();
15652 }
15653 else
15654 {
15655 set_qualified_name(env->intern(get_type_representation
15656 (*this, /*internal=*/false)));
15657 return decl_base::peek_qualified_name();
15658 }
15659 }
15660 }
15661
15662 /// This implements the ir_traversable_base::traverse pure virtual
15663 /// function.
15664 ///
15665 /// @param v the visitor used on the current instance.
15666 ///
15667 /// @return true if the entire IR node tree got traversed, false
15668 /// otherwise.
15669 bool
traverse(ir_node_visitor & v)15670 array_type_def::traverse(ir_node_visitor& v)
15671 {
15672 if (v.type_node_has_been_visited(this))
15673 return true;
15674
15675 if (visiting())
15676 return true;
15677
15678 if (v.visit_begin(this))
15679 {
15680 visiting(true);
15681 if (type_base_sptr t = get_element_type())
15682 t->traverse(v);
15683 visiting(false);
15684 }
15685
15686 bool result = v.visit_end(this);
15687 v.mark_type_node_as_visited(this);
15688 return result;
15689 }
15690
15691 const location&
get_location() const15692 array_type_def::get_location() const
15693 {return decl_base::get_location();}
15694
15695 /// Get the array's subranges
15696 const std::vector<array_type_def::subrange_sptr>&
get_subranges() const15697 array_type_def::get_subranges() const
15698 {return priv_->subranges_;}
15699
~array_type_def()15700 array_type_def::~array_type_def()
15701 {}
15702
15703 // </array_type_def definitions>
15704
15705 // <enum_type_decl definitions>
15706
15707 class enum_type_decl::priv
15708 {
15709 type_base_sptr underlying_type_;
15710 enumerators enumerators_;
15711
15712 friend class enum_type_decl;
15713
15714 priv();
15715
15716 public:
priv(type_base_sptr underlying_type,enumerators & enumerators)15717 priv(type_base_sptr underlying_type,
15718 enumerators& enumerators)
15719 : underlying_type_(underlying_type),
15720 enumerators_(enumerators)
15721 {}
15722 }; // end class enum_type_decl::priv
15723
15724 /// Constructor.
15725 ///
15726 /// @param name the name of the type declaration.
15727 ///
15728 /// @param locus the source location where the type was defined.
15729 ///
15730 /// @param underlying_type the underlying type of the enum.
15731 ///
15732 /// @param enums the enumerators of this enum type.
15733 ///
15734 /// @param linkage_name the linkage name of the enum.
15735 ///
15736 /// @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)15737 enum_type_decl::enum_type_decl(const string& name,
15738 const location& locus,
15739 type_base_sptr underlying_type,
15740 enumerators& enums,
15741 const string& linkage_name,
15742 visibility vis)
15743 : type_or_decl_base(underlying_type->get_environment(),
15744 ENUM_TYPE
15745 | ABSTRACT_TYPE_BASE
15746 | ABSTRACT_DECL_BASE),
15747 type_base(underlying_type->get_environment(),
15748 underlying_type->get_size_in_bits(),
15749 underlying_type->get_alignment_in_bits()),
15750 decl_base(underlying_type->get_environment(),
15751 name, locus, linkage_name, vis),
15752 priv_(new priv(underlying_type, enums))
15753 {
15754 runtime_type_instance(this);
15755 for (enumerators::iterator e = get_enumerators().begin();
15756 e != get_enumerators().end();
15757 ++e)
15758 e->set_enum_type(this);
15759 }
15760
15761 /// Return the underlying type of the enum.
15762 type_base_sptr
get_underlying_type() const15763 enum_type_decl::get_underlying_type() const
15764 {return priv_->underlying_type_;}
15765
15766 /// @return the list of enumerators of the enum.
15767 const enum_type_decl::enumerators&
get_enumerators() const15768 enum_type_decl::get_enumerators() const
15769 {return priv_->enumerators_;}
15770
15771 /// @return the list of enumerators of the enum.
15772 enum_type_decl::enumerators&
get_enumerators()15773 enum_type_decl::get_enumerators()
15774 {return priv_->enumerators_;}
15775
15776 /// Get the pretty representation of the current instance of @ref
15777 /// enum_type_decl.
15778 ///
15779 /// @param internal set to true if the call is intended for an
15780 /// internal use (for technical use inside the library itself), false
15781 /// otherwise. If you don't know what this is for, then set it to
15782 /// false.
15783 ///
15784 /// @param qualified_name if true, names emitted in the pretty
15785 /// representation are fully qualified.
15786 ///
15787 /// @return the pretty representation of the enum type.
15788 string
get_pretty_representation(bool internal,bool qualified_name) const15789 enum_type_decl::get_pretty_representation(bool internal,
15790 bool qualified_name) const
15791 {
15792 string r = "enum " + decl_base::get_pretty_representation(internal,
15793 qualified_name);
15794 return r;
15795 }
15796
15797 /// This implements the ir_traversable_base::traverse pure virtual
15798 /// function.
15799 ///
15800 /// @param v the visitor used on the current instance.
15801 ///
15802 /// @return true if the entire IR node tree got traversed, false
15803 /// otherwise.
15804 bool
traverse(ir_node_visitor & v)15805 enum_type_decl::traverse(ir_node_visitor &v)
15806 {
15807 if (v.type_node_has_been_visited(this))
15808 return true;
15809
15810 if (visiting())
15811 return true;
15812
15813 if (v.visit_begin(this))
15814 {
15815 visiting(true);
15816 if (type_base_sptr t = get_underlying_type())
15817 t->traverse(v);
15818 visiting(false);
15819 }
15820
15821 bool result = v.visit_end(this);
15822 v.mark_type_node_as_visited(this);
15823 return result;
15824 }
15825
15826 /// Destructor for the enum type declaration.
~enum_type_decl()15827 enum_type_decl::~enum_type_decl()
15828 {}
15829
15830 /// Test if two enums differ, but not by a name change.
15831 ///
15832 /// @param l the first enum to consider.
15833 ///
15834 /// @param r the second enum to consider.
15835 ///
15836 /// @return true iff @p l differs from @p r by anything but a name
15837 /// change.
15838 bool
enum_has_non_name_change(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)15839 enum_has_non_name_change(const enum_type_decl& l,
15840 const enum_type_decl& r,
15841 change_kind* k)
15842 {
15843 bool result = false;
15844 if (*l.get_underlying_type() != *r.get_underlying_type())
15845 {
15846 result = true;
15847 if (k)
15848 *k |= SUBTYPE_CHANGE_KIND;
15849 else
15850 return true;
15851 }
15852
15853 enum_type_decl::enumerators::const_iterator i, j;
15854 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
15855 i != l.get_enumerators().end() && j != r.get_enumerators().end();
15856 ++i, ++j)
15857 if (*i != *j)
15858 {
15859 result = true;
15860 if (k)
15861 {
15862 *k |= LOCAL_TYPE_CHANGE_KIND;
15863 break;
15864 }
15865 else
15866 return true;
15867 }
15868
15869 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
15870 {
15871 result = true;
15872 if (k)
15873 *k |= LOCAL_TYPE_CHANGE_KIND;
15874 else
15875 return true;
15876 }
15877
15878 enum_type_decl &local_r = const_cast<enum_type_decl&>(r);
15879 interned_string qn_r = l.get_environment()->intern(r.get_qualified_name());
15880 interned_string qn_l = l.get_environment()->intern(l.get_qualified_name());
15881 string n_l = l.get_name();
15882 string n_r = r.get_name();
15883 local_r.set_qualified_name(qn_l);
15884 local_r.set_name(n_l);
15885
15886 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
15887 {
15888 result = true;
15889 if (k)
15890 {
15891 if (!l.decl_base::operator==(r))
15892 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
15893 if (!l.type_base::operator==(r))
15894 *k |= LOCAL_TYPE_CHANGE_KIND;
15895 }
15896 else
15897 {
15898 local_r.set_name(n_r);
15899 local_r.set_qualified_name(qn_r);
15900 return true;
15901 }
15902 }
15903 local_r.set_qualified_name(qn_r);
15904 local_r.set_name(n_r);
15905
15906 return result;
15907 }
15908
15909 /// Compares two instances of @ref enum_type_decl.
15910 ///
15911 /// If the two intances are different, set a bitfield to give some
15912 /// insight about the kind of differences there are.
15913 ///
15914 /// @param l the first artifact of the comparison.
15915 ///
15916 /// @param r the second artifact of the comparison.
15917 ///
15918 /// @param k a pointer to a bitfield that gives information about the
15919 /// kind of changes there are between @p l and @p r. This one is set
15920 /// iff @p k is non-null and the function returns false.
15921 ///
15922 /// Please note that setting k to a non-null value does have a
15923 /// negative performance impact because even if @p l and @p r are not
15924 /// equal, the function keeps up the comparison in order to determine
15925 /// the different kinds of ways in which they are different.
15926 ///
15927 /// @return true if @p l equals @p r, false otherwise.
15928 bool
equals(const enum_type_decl & l,const enum_type_decl & r,change_kind * k)15929 equals(const enum_type_decl& l, const enum_type_decl& r, change_kind* k)
15930 {
15931 bool result = true;
15932 if (*l.get_underlying_type() != *r.get_underlying_type())
15933 {
15934 result = false;
15935 if (k)
15936 *k |= SUBTYPE_CHANGE_KIND;
15937 else
15938 return false;
15939 }
15940
15941 enum_type_decl::enumerators::const_iterator i, j;
15942 for (i = l.get_enumerators().begin(), j = r.get_enumerators().begin();
15943 i != l.get_enumerators().end() && j != r.get_enumerators().end();
15944 ++i, ++j)
15945 if (*i != *j)
15946 {
15947 result = false;
15948 if (k)
15949 {
15950 *k |= LOCAL_TYPE_CHANGE_KIND;
15951 break;
15952 }
15953 else
15954 return false;
15955 }
15956
15957 if (i != l.get_enumerators().end() || j != r.get_enumerators().end())
15958 {
15959 result = false;
15960 if (k)
15961 *k |= LOCAL_TYPE_CHANGE_KIND;
15962 else
15963 return false;
15964 }
15965
15966 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
15967 {
15968 result = false;
15969 if (k)
15970 {
15971 if (!l.decl_base::operator==(r))
15972 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
15973 if (!l.type_base::operator==(r))
15974 *k |= LOCAL_TYPE_CHANGE_KIND;
15975 }
15976 else
15977 return false;
15978 }
15979
15980 return result;
15981 }
15982
15983 /// Equality operator.
15984 ///
15985 /// @param o the other enum to test against.
15986 ///
15987 /// @return true iff @p o equals the current instance of enum type
15988 /// decl.
15989 bool
operator ==(const decl_base & o) const15990 enum_type_decl::operator==(const decl_base& o) const
15991 {
15992 const enum_type_decl* op = dynamic_cast<const enum_type_decl*>(&o);
15993 if (!op)
15994 return false;
15995 return try_canonical_compare(this, op);
15996 }
15997
15998 /// Equality operator.
15999 ///
16000 /// @param o the other enum to test against.
16001 ///
16002 /// @return true iff @p o is equals the current instance of enum type
16003 /// decl.
16004 bool
operator ==(const type_base & o) const16005 enum_type_decl::operator==(const type_base& o) const
16006 {
16007 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16008 if (!other)
16009 return false;
16010 return *this == *other;
16011 }
16012
16013 /// Equality operator for @ref enum_type_decl_sptr.
16014 ///
16015 /// @param l the first operand to compare.
16016 ///
16017 /// @param r the second operand to compare.
16018 ///
16019 /// @return true iff @p l equals @p r.
16020 bool
operator ==(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)16021 operator==(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
16022 {
16023 if (!!l != !!r)
16024 return false;
16025 if (l.get() == r.get())
16026 return true;
16027 decl_base_sptr o = r;
16028 return *l == *o;
16029 }
16030
16031 /// Inequality operator for @ref enum_type_decl_sptr.
16032 ///
16033 /// @param l the first operand to compare.
16034 ///
16035 /// @param r the second operand to compare.
16036 ///
16037 /// @return true iff @p l equals @p r.
16038 bool
operator !=(const enum_type_decl_sptr & l,const enum_type_decl_sptr & r)16039 operator!=(const enum_type_decl_sptr& l, const enum_type_decl_sptr& r)
16040 {return !operator==(l, r);}
16041
16042 /// The type of the private data of an @ref
16043 /// enum_type_decl::enumerator.
16044 class enum_type_decl::enumerator::priv
16045 {
16046 const environment* env_;
16047 interned_string name_;
16048 int64_t value_;
16049 interned_string qualified_name_;
16050 enum_type_decl* enum_type_;
16051
16052 friend class enum_type_decl::enumerator;
16053
16054 public:
16055
priv()16056 priv()
16057 : env_(),
16058 enum_type_()
16059 {}
16060
priv(const environment * env,const string & name,int64_t value,enum_type_decl * e=0)16061 priv(const environment* env,
16062 const string& name,
16063 int64_t value,
16064 enum_type_decl* e = 0)
16065 : env_(env),
16066 name_(env ? env->intern(name) : interned_string()),
16067 value_(value),
16068 enum_type_(e)
16069 {}
16070 }; // end class enum_type_def::enumerator::priv
16071
16072 /// Default constructor of the @ref enum_type_decl::enumerator type.
enumerator()16073 enum_type_decl::enumerator::enumerator()
16074 : priv_(new priv)
16075 {}
16076
16077 /// Constructor of the @ref enum_type_decl::enumerator type.
16078 ///
16079 /// @param env the environment we are operating from.
16080 ///
16081 /// @param name the name of the enumerator.
16082 ///
16083 /// @param value the value of the enumerator.
enumerator(const environment * env,const string & name,int64_t value)16084 enum_type_decl::enumerator::enumerator(const environment* env,
16085 const string& name,
16086 int64_t value)
16087 : priv_(new priv(env, name, value))
16088 {}
16089
16090 /// Copy constructor of the @ref enum_type_decl::enumerator type.
16091 ///
16092 /// @param other enumerator to copy.
enumerator(const enumerator & other)16093 enum_type_decl::enumerator::enumerator(const enumerator& other)
16094 : priv_(new priv(other.get_environment(),
16095 other.get_name(),
16096 other.get_value(),
16097 other.get_enum_type()))
16098 {}
16099
16100 /// Assignment operator of the @ref enum_type_decl::enumerator type.
16101 ///
16102 /// @param o
16103 enum_type_decl::enumerator&
operator =(const enumerator & o)16104 enum_type_decl::enumerator::operator=(const enumerator& o)
16105 {
16106 priv_->env_ = o.get_environment();
16107 priv_->name_ = o.get_name();
16108 priv_->value_ = o.get_value();
16109 priv_->enum_type_ = o.get_enum_type();
16110 return *this;
16111 }
16112 /// Equality operator
16113 ///
16114 /// @param other the enumerator to compare to the current instance of
16115 /// enum_type_decl::enumerator.
16116 ///
16117 /// @return true if @p other equals the current instance of
16118 /// enum_type_decl::enumerator.
16119 bool
operator ==(const enumerator & other) const16120 enum_type_decl::enumerator::operator==(const enumerator& other) const
16121 {return (get_name() == other.get_name()
16122 && get_value() == other.get_value());}
16123
16124 /// Inequality operator.
16125 ///
16126 /// @param other the other instance to compare against.
16127 ///
16128 /// @return true iff @p other is different from the current instance.
16129 bool
operator !=(const enumerator & other) const16130 enum_type_decl::enumerator::operator!=(const enumerator& other) const
16131 {return !operator==(other);}
16132
16133 /// Getter of the environment of this enumerator.
16134 ///
16135 /// @return the environment of this enumerator.
16136 const environment*
get_environment() const16137 enum_type_decl::enumerator::get_environment() const
16138 {return priv_->env_;}
16139
16140 /// Getter for the name of the current instance of
16141 /// enum_type_decl::enumerator.
16142 ///
16143 /// @return a reference to the name of the current instance of
16144 /// enum_type_decl::enumerator.
16145 const interned_string&
get_name() const16146 enum_type_decl::enumerator::get_name() const
16147 {return priv_->name_;}
16148
16149 /// Getter for the qualified name of the current instance of
16150 /// enum_type_decl::enumerator. The first invocation of the method
16151 /// builds the qualified name, caches it and return a reference to the
16152 /// cached qualified name. Subsequent invocations just return the
16153 /// cached value.
16154 ///
16155 /// @param internal set to true if the call is intended for an
16156 /// internal use (for technical use inside the library itself), false
16157 /// otherwise. If you don't know what this is for, then set it to
16158 /// false.
16159 ///
16160 /// @return the qualified name of the current instance of
16161 /// enum_type_decl::enumerator.
16162 const interned_string&
get_qualified_name(bool internal) const16163 enum_type_decl::enumerator::get_qualified_name(bool internal) const
16164 {
16165 if (priv_->qualified_name_.empty())
16166 {
16167 const environment* env = priv_->enum_type_->get_environment();
16168 ABG_ASSERT(env);
16169 priv_->qualified_name_ =
16170 env->intern(get_enum_type()->get_qualified_name(internal)
16171 + "::"
16172 + get_name());
16173 }
16174 return priv_->qualified_name_;
16175 }
16176
16177 /// Setter for the name of @ref enum_type_decl::enumerator.
16178 ///
16179 /// @param n the new name.
16180 void
set_name(const string & n)16181 enum_type_decl::enumerator::set_name(const string& n)
16182 {
16183 const environment* env = get_environment();
16184 ABG_ASSERT(env);
16185 priv_->name_ = env->intern(n);
16186 }
16187
16188 /// Getter for the value of @ref enum_type_decl::enumerator.
16189 ///
16190 /// @return the value of the current instance of
16191 /// enum_type_decl::enumerator.
16192 int64_t
get_value() const16193 enum_type_decl::enumerator::get_value() const
16194 {return priv_->value_;}
16195
16196 /// Setter for the value of @ref enum_type_decl::enumerator.
16197 ///
16198 /// @param v the new value of the enum_type_decl::enumerator.
16199 void
set_value(int64_t v)16200 enum_type_decl::enumerator::set_value(int64_t v)
16201 {priv_->value_= v;}
16202
16203 /// Getter for the enum type that this enumerator is for.
16204 ///
16205 /// @return the enum type that this enumerator is for.
16206 enum_type_decl*
get_enum_type() const16207 enum_type_decl::enumerator::get_enum_type() const
16208 {return priv_->enum_type_;}
16209
16210 /// Setter for the enum type that this enumerator is for.
16211 ///
16212 /// @param e the new enum type.
16213 void
set_enum_type(enum_type_decl * e)16214 enum_type_decl::enumerator::set_enum_type(enum_type_decl* e)
16215 {priv_->enum_type_ = e;}
16216 // </enum_type_decl definitions>
16217
16218 // <typedef_decl definitions>
16219
16220 /// Private data structure of the @ref typedef_decl.
16221 struct typedef_decl::priv
16222 {
16223 type_base_wptr underlying_type_;
16224 string internal_qualified_name_;
16225 string temp_internal_qualified_name_;
16226
privabigail::ir::typedef_decl::priv16227 priv(const type_base_sptr& t)
16228 : underlying_type_(t)
16229 {}
16230 }; // end struct typedef_decl::priv
16231
16232 /// Constructor of the typedef_decl type.
16233 ///
16234 /// @param name the name of the typedef.
16235 ///
16236 /// @param underlying_type the underlying type of the typedef.
16237 ///
16238 /// @param locus the source location of the typedef declaration.
16239 ///
16240 /// @param linkage_name the mangled name of the typedef.
16241 ///
16242 /// @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)16243 typedef_decl::typedef_decl(const string& name,
16244 const type_base_sptr underlying_type,
16245 const location& locus,
16246 const string& linkage_name,
16247 visibility vis)
16248 : type_or_decl_base(underlying_type->get_environment(),
16249 TYPEDEF_TYPE
16250 | ABSTRACT_TYPE_BASE
16251 | ABSTRACT_DECL_BASE),
16252 type_base(underlying_type->get_environment(),
16253 underlying_type->get_size_in_bits(),
16254 underlying_type->get_alignment_in_bits()),
16255 decl_base(underlying_type->get_environment(),
16256 name, locus, linkage_name, vis),
16257 priv_(new priv(underlying_type))
16258 {
16259 runtime_type_instance(this);
16260 }
16261
16262 /// Return the size of the typedef.
16263 ///
16264 /// This function looks at the size of the underlying type and ensures
16265 /// that it's the same as the size of the typedef.
16266 ///
16267 /// @return the size of the typedef.
16268 size_t
get_size_in_bits() const16269 typedef_decl::get_size_in_bits() const
16270 {
16271 size_t s = get_underlying_type()->get_size_in_bits();
16272 if (s != type_base::get_size_in_bits())
16273 const_cast<typedef_decl*>(this)->set_size_in_bits(s);
16274 return type_base::get_size_in_bits();
16275 }
16276
16277 /// Return the alignment of the typedef.
16278 ///
16279 /// This function looks at the alignment of the underlying type and
16280 /// ensures that it's the same as the alignment of the typedef.
16281 ///
16282 /// @return the size of the typedef.
16283 size_t
get_alignment_in_bits() const16284 typedef_decl::get_alignment_in_bits() const
16285 {
16286 size_t s = get_underlying_type()->get_alignment_in_bits();
16287 if (s != type_base::get_alignment_in_bits())
16288 const_cast<typedef_decl*>(this)->set_alignment_in_bits(s);
16289 return type_base::get_alignment_in_bits();
16290 }
16291
16292 /// Compares two instances of @ref typedef_decl.
16293 ///
16294 /// If the two intances are different, set a bitfield to give some
16295 /// insight about the kind of differences there are.
16296 ///
16297 /// @param l the first artifact of the comparison.
16298 ///
16299 /// @param r the second artifact of the comparison.
16300 ///
16301 /// @param k a pointer to a bitfield that gives information about the
16302 /// kind of changes there are between @p l and @p r. This one is set
16303 /// iff @p k is non-null and the function returns false.
16304 ///
16305 /// Please note that setting k to a non-null value does have a
16306 /// negative performance impact because even if @p l and @p r are not
16307 /// equal, the function keeps up the comparison in order to determine
16308 /// the different kinds of ways in which they are different.
16309 ///
16310 /// @return true if @p l equals @p r, false otherwise.
16311 bool
equals(const typedef_decl & l,const typedef_decl & r,change_kind * k)16312 equals(const typedef_decl& l, const typedef_decl& r, change_kind* k)
16313 {
16314 bool result = true;
16315 // Compare the properties of the 'is-a-member-decl" relation of this
16316 // decl. For typedefs of a C program, this always return true as
16317 // there is no "member typedef type" in C.
16318 //
16319 // In other words, in C, Only the underlying types of typedefs are
16320 // compared. In C++ however, the properties of the
16321 // 'is-a-member-decl' relation of the typedef are compared.
16322 if (!maybe_compare_as_member_decls(l, r, k))
16323 {
16324 result = false;
16325 if (k)
16326 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
16327 else
16328 return false;
16329 }
16330
16331 if (*l.get_underlying_type() != *r.get_underlying_type())
16332 {
16333 // Changes to the underlying type of a typedef are considered
16334 // local, a bit like for pointers.
16335 result = false;
16336 if (k)
16337 *k |= LOCAL_TYPE_CHANGE_KIND;
16338 else
16339 return false;
16340 }
16341
16342 return result;
16343 }
16344
16345 /// Equality operator
16346 ///
16347 /// @param o the other typedef_decl to test against.
16348 bool
operator ==(const decl_base & o) const16349 typedef_decl::operator==(const decl_base& o) const
16350 {
16351 const typedef_decl* other = dynamic_cast<const typedef_decl*>(&o);
16352 if (!other)
16353 return false;
16354 return try_canonical_compare(this, other);
16355 }
16356
16357 /// Equality operator
16358 ///
16359 /// @param o the other typedef_decl to test against.
16360 ///
16361 /// @return true if the current instance of @ref typedef_decl equals
16362 /// @p o.
16363 bool
operator ==(const type_base & o) const16364 typedef_decl::operator==(const type_base& o) const
16365 {
16366 const decl_base* other = dynamic_cast<const decl_base*>(&o);
16367 if (!other)
16368 return false;
16369 return *this == *other;
16370 }
16371
16372 /// Build a pretty representation for a typedef_decl.
16373 ///
16374 /// @param internal set to true if the call is intended for an
16375 /// internal use (for technical use inside the library itself), false
16376 /// otherwise. If you don't know what this is for, then set it to
16377 /// false.
16378 ///
16379 /// @param qualified_name if true, names emitted in the pretty
16380 /// representation are fully qualified.
16381 ///
16382 /// @return a copy of the pretty representation of the current
16383 /// instance of typedef_decl.
16384 string
get_pretty_representation(bool internal,bool qualified_name) const16385 typedef_decl::get_pretty_representation(bool internal,
16386 bool qualified_name) const
16387 {
16388
16389 string result = "typedef ";
16390 if (qualified_name)
16391 result += get_qualified_name(internal);
16392 else
16393 result += get_name();
16394
16395 return result;
16396 }
16397
16398 /// Getter of the underlying type of the typedef.
16399 ///
16400 /// @return the underlying_type.
16401 type_base_sptr
get_underlying_type() const16402 typedef_decl::get_underlying_type() const
16403 {return priv_->underlying_type_.lock();}
16404
16405 /// Setter ofthe underlying type of the typedef.
16406 ///
16407 /// @param t the new underlying type of the typedef.
16408 void
set_underlying_type(const type_base_sptr & t)16409 typedef_decl::set_underlying_type(const type_base_sptr& t)
16410 {priv_->underlying_type_ = t;}
16411
16412 /// This implements the ir_traversable_base::traverse pure virtual
16413 /// function.
16414 ///
16415 /// @param v the visitor used on the current instance.
16416 ///
16417 /// @return true if the entire IR node tree got traversed, false
16418 /// otherwise.
16419 bool
traverse(ir_node_visitor & v)16420 typedef_decl::traverse(ir_node_visitor& v)
16421 {
16422 if (v.type_node_has_been_visited(this))
16423 return true;
16424
16425 if (visiting())
16426 return true;
16427
16428 if (v.visit_begin(this))
16429 {
16430 visiting(true);
16431 if (type_base_sptr t = get_underlying_type())
16432 t->traverse(v);
16433 visiting(false);
16434 }
16435
16436 bool result = v.visit_end(this);
16437 v.mark_type_node_as_visited(this);
16438 return result;
16439 }
16440
~typedef_decl()16441 typedef_decl::~typedef_decl()
16442 {}
16443 // </typedef_decl definitions>
16444
16445 // <var_decl definitions>
16446
16447 struct var_decl::priv
16448 {
16449 type_base_wptr type_;
16450 type_base* naked_type_;
16451 decl_base::binding binding_;
16452 elf_symbol_sptr symbol_;
16453 interned_string id_;
16454
privabigail::ir::var_decl::priv16455 priv()
16456 : naked_type_(),
16457 binding_(decl_base::BINDING_GLOBAL)
16458 {}
16459
privabigail::ir::var_decl::priv16460 priv(type_base_sptr t,
16461 decl_base::binding b)
16462 : type_(t),
16463 naked_type_(t.get()),
16464 binding_(b)
16465 {}
16466 }; // end struct var_decl::priv
16467
16468 /// Constructor
16469 ///
16470 /// @param name the name of the variable declaration
16471 ///
16472 /// @param name the type of the variable declaration
16473 ///
16474 /// @param locus the source location where the variable was defined.
16475 ///
16476 /// @param linkage_name the linkage name of the variable.
16477 ///
16478 /// @param vis the visibility of of the variable.
16479 ///
16480 /// @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)16481 var_decl::var_decl(const string& name,
16482 type_base_sptr type,
16483 const location& locus,
16484 const string& linkage_name,
16485 visibility vis,
16486 binding bind)
16487 : type_or_decl_base(type->get_environment(),
16488 VAR_DECL | ABSTRACT_DECL_BASE),
16489 decl_base(type->get_environment(), name, locus, linkage_name, vis),
16490 priv_(new priv(type, bind))
16491 {
16492 runtime_type_instance(this);
16493 }
16494
16495 /// Getter of the type of the variable.
16496 ///
16497 /// @return the type of the variable.
16498 const type_base_sptr
get_type() const16499 var_decl::get_type() const
16500 {return priv_->type_.lock();}
16501
16502 /// Getter of the type of the variable.
16503 ///
16504 /// This getter returns a bare pointer, as opposed to a smart pointer.
16505 /// It's to be used on performance sensitive code paths identified by
16506 /// careful profiling.
16507 ///
16508 /// @return the type of the variable, as a bare pointer.
16509 const type_base*
get_naked_type() const16510 var_decl::get_naked_type() const
16511 {return priv_->naked_type_;}
16512
16513 /// Getter of the binding of the variable.
16514 ///
16515 /// @return the biding of the variable.
16516 decl_base::binding
get_binding() const16517 var_decl::get_binding() const
16518 {return priv_->binding_;}
16519
16520 /// Setter of the binding of the variable.
16521 ///
16522 /// @param b the new binding value.
16523 void
set_binding(decl_base::binding b)16524 var_decl::set_binding(decl_base::binding b)
16525 {priv_->binding_ = b;}
16526
16527 /// Sets the underlying ELF symbol for the current variable.
16528 ///
16529 /// And underlyin$g ELF symbol for the current variable might exist
16530 /// only if the corpus that this variable originates from was
16531 /// constructed from an ELF binary file.
16532 ///
16533 /// Note that comparing two variables that have underlying ELF symbols
16534 /// involves comparing their underlying elf symbols. The decl name
16535 /// for the variable thus becomes irrelevant in the comparison.
16536 ///
16537 /// @param sym the new ELF symbol for this variable decl.
16538 void
set_symbol(const elf_symbol_sptr & sym)16539 var_decl::set_symbol(const elf_symbol_sptr& sym)
16540 {
16541 priv_->symbol_ = sym;
16542 // The variable id cache that depends on the symbol must be
16543 // invalidated because the symbol changed.
16544 priv_->id_ = get_environment()->intern("");
16545 }
16546
16547 /// Gets the the underlying ELF symbol for the current variable,
16548 /// that was set using var_decl::set_symbol(). Please read the
16549 /// documentation for that member function for more information about
16550 /// "underlying ELF symbols".
16551 ///
16552 /// @return sym the underlying ELF symbol for this variable decl, if
16553 /// one exists.
16554 const elf_symbol_sptr&
get_symbol() const16555 var_decl::get_symbol() const
16556 {return priv_->symbol_;}
16557
16558 /// Create a new var_decl that is a clone of the current one.
16559 ///
16560 /// @return the cloned var_decl.
16561 var_decl_sptr
clone() const16562 var_decl::clone() const
16563 {
16564 var_decl_sptr v(new var_decl(get_name(),
16565 get_type(),
16566 get_location(),
16567 get_linkage_name(),
16568 get_visibility(),
16569 get_binding()));
16570
16571 v->set_symbol(get_symbol());
16572
16573 if (is_member_decl(*this))
16574 {
16575 class_decl* scope = dynamic_cast<class_decl*>(get_scope());
16576 scope->add_data_member(v, get_member_access_specifier(*this),
16577 get_data_member_is_laid_out(*this),
16578 get_member_is_static(*this),
16579 get_data_member_offset(*this));
16580 }
16581 else
16582 add_decl_to_scope(v, get_scope());
16583
16584 return v;
16585 }
16586 /// Setter of the scope of the current var_decl.
16587 ///
16588 /// Note that the decl won't hold a reference on the scope. It's
16589 /// rather the scope that holds a reference on its members.
16590 ///
16591 /// @param scope the new scope.
16592 void
set_scope(scope_decl * scope)16593 var_decl::set_scope(scope_decl* scope)
16594 {
16595 if (!get_context_rel())
16596 set_context_rel(new dm_context_rel(scope));
16597 else
16598 get_context_rel()->set_scope(scope);
16599 }
16600
16601 /// Compares two instances of @ref var_decl.
16602 ///
16603 /// If the two intances are different, set a bitfield to give some
16604 /// insight about the kind of differences there are.
16605 ///
16606 /// @param l the first artifact of the comparison.
16607 ///
16608 /// @param r the second artifact of the comparison.
16609 ///
16610 /// @param k a pointer to a bitfield that gives information about the
16611 /// kind of changes there are between @p l and @p r. This one is set
16612 /// iff @p k is non-null and the function returns false.
16613 ///
16614 /// Please note that setting k to a non-null value does have a
16615 /// negative performance impact because even if @p l and @p r are not
16616 /// equal, the function keeps up the comparison in order to determine
16617 /// the different kinds of ways in which they are different.
16618 ///
16619 /// @return true if @p l equals @p r, false otherwise.
16620 bool
equals(const var_decl & l,const var_decl & r,change_kind * k)16621 equals(const var_decl& l, const var_decl& r, change_kind* k)
16622 {
16623 bool result = true;
16624
16625 // First test types of variables. This should be fast because in
16626 // the general case, most types should be canonicalized.
16627 if (*l.get_naked_type() != *r.get_naked_type())
16628 {
16629 result = false;
16630 if (k)
16631 {
16632 if (!types_have_similar_structure(l.get_naked_type(),
16633 r.get_naked_type()))
16634 *k |= (LOCAL_TYPE_CHANGE_KIND);
16635 else
16636 *k |= SUBTYPE_CHANGE_KIND;
16637 }
16638 else
16639 return false;
16640 }
16641
16642 // If there are underlying elf symbols for these variables,
16643 // compare them. And then compare the other parts.
16644 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
16645 if (!!s0 != !!s1)
16646 {
16647 result = false;
16648 if (k)
16649 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
16650 else
16651 return false;
16652 }
16653 else if (s0 && s0 != s1)
16654 {
16655 result = false;
16656 if (k)
16657 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
16658 else
16659 return false;
16660 }
16661 bool symbols_are_equal = (s0 && s1 && result);
16662
16663 if (symbols_are_equal)
16664 {
16665 // The variables have underlying elf symbols that are equal, so
16666 // now, let's compare the decl_base part of the variables w/o
16667 // considering their decl names.
16668 const interned_string &n1 = l.get_name(), &n2 = r.get_name();
16669 const_cast<var_decl&>(l).set_name("");
16670 const_cast<var_decl&>(r).set_name("");
16671 bool decl_bases_different = !l.decl_base::operator==(r);
16672 const_cast<var_decl&>(l).set_name(n1);
16673 const_cast<var_decl&>(r).set_name(n2);
16674
16675 if (decl_bases_different)
16676 {
16677 result = false;
16678 if (k)
16679 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
16680 else
16681 return false;
16682 }
16683 }
16684 else
16685 if (!l.decl_base::operator==(r))
16686 {
16687 result = false;
16688 if (k)
16689 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
16690 else
16691 return false;
16692 }
16693
16694 const dm_context_rel* c0 =
16695 dynamic_cast<const dm_context_rel*>(l.get_context_rel());
16696 const dm_context_rel* c1 =
16697 dynamic_cast<const dm_context_rel*>(r.get_context_rel());
16698 ABG_ASSERT(c0 && c1);
16699
16700 if (*c0 != *c1)
16701 {
16702 result = false;
16703 if (k)
16704 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
16705 else
16706 return false;
16707 }
16708
16709 return result;
16710 }
16711
16712 /// Comparison operator of @ref var_decl.
16713 ///
16714 /// @param o the instance of @ref var_decl to compare against.
16715 ///
16716 /// @return true iff the current instance of @ref var_decl equals @p o.
16717 bool
operator ==(const decl_base & o) const16718 var_decl::operator==(const decl_base& o) const
16719 {
16720 const var_decl* other = dynamic_cast<const var_decl*>(&o);
16721 if (!other)
16722 return false;
16723
16724 return equals(*this, *other, 0);
16725 }
16726
16727 /// Return an ID that tries to uniquely identify the variable inside a
16728 /// program or a library.
16729 ///
16730 /// So if the variable has an underlying elf symbol, the ID is the
16731 /// concatenation of the symbol name and its version. Otherwise, the
16732 /// ID is the linkage name if its non-null. Otherwise, it's the
16733 /// pretty representation of the variable.
16734 ///
16735 /// @return the ID.
16736 interned_string
get_id() const16737 var_decl::get_id() const
16738 {
16739 if (priv_->id_.empty())
16740 {
16741 string repr = get_name();
16742 string sym_str;
16743 if (elf_symbol_sptr s = get_symbol())
16744 sym_str = s->get_id_string();
16745 else if (!get_linkage_name().empty())
16746 sym_str = get_linkage_name();
16747 const environment* env = get_type()->get_environment();
16748 ABG_ASSERT(env);
16749 priv_->id_ = env->intern(repr);
16750 if (!sym_str.empty())
16751 priv_->id_ = env->intern(priv_->id_ + "{" + sym_str + "}");
16752 }
16753 return priv_->id_;
16754 }
16755
16756 /// Return the hash value for the current instance.
16757 ///
16758 /// @return the hash value.
16759 size_t
get_hash() const16760 var_decl::get_hash() const
16761 {
16762 var_decl::hash hash_var;
16763 return hash_var(this);
16764 }
16765
16766 /// Get the qualified name of a given variable or data member.
16767 ///
16768 ///
16769 /// Note that if the current instance of @ref var_decl is an anonymous
16770 /// data member, then the qualified name is actually the flat
16771 /// representation (the definition) of the type of the anonymous data
16772 /// member. We chose the flat representation because otherwise, the
16773 /// name of an *anonymous* data member is empty, by construction, e.g:
16774 ///
16775 /// struct foo {
16776 /// int a;
16777 /// union {
16778 /// char b;
16779 /// char c;
16780 /// }; // <---- this data member is anonymous.
16781 /// int d;
16782 /// }
16783 ///
16784 /// The string returned for the anonymous member here is going to be:
16785 ///
16786 /// "union {char b; char c}"
16787 ///
16788 /// @param internal if true then this is for a purpose to the library,
16789 /// otherwise, it's for being displayed to users.
16790 ///
16791 /// @return the resulting qualified name.
16792 const interned_string&
get_qualified_name(bool internal) const16793 var_decl::get_qualified_name(bool internal) const
16794 {
16795 if (is_anonymous_data_member(this)
16796 && decl_base::get_qualified_name().empty())
16797 {
16798 // Display the anonymous data member in a way that makes sense.
16799 string r = get_pretty_representation(internal);
16800 set_qualified_name(get_environment()->intern(r));
16801 }
16802
16803 return decl_base::get_qualified_name(internal);
16804 }
16805
16806 /// Build and return the pretty representation of this variable.
16807 ///
16808 /// @param internal set to true if the call is intended for an
16809 /// internal use (for technical use inside the library itself), false
16810 /// otherwise. If you don't know what this is for, then set it to
16811 /// false.
16812 ///
16813 /// @param qualified_name if true, names emitted in the pretty
16814 /// representation are fully qualified.
16815 ///
16816 /// @return a copy of the pretty representation of this variable.
16817 string
get_pretty_representation(bool internal,bool qualified_name) const16818 var_decl::get_pretty_representation(bool internal, bool qualified_name) const
16819 {
16820 string result;
16821
16822 if (is_member_decl(this) && get_member_is_static(this))
16823 result = "static ";
16824
16825 // Detect if the current instance of var_decl is a member of
16826 // an anonymous class or union.
16827 bool member_of_anonymous_class = false;
16828 if (class_or_union* scope = is_at_class_scope(this))
16829 if (scope->get_is_anonymous())
16830 member_of_anonymous_class = true;
16831
16832 if (array_type_def_sptr t = is_array_type(get_type()))
16833 {
16834 string name;
16835 if (member_of_anonymous_class || !qualified_name)
16836 name = get_name();
16837 else
16838 name = get_qualified_name(internal);
16839
16840 result +=
16841 get_type_declaration(t->get_element_type())->get_qualified_name(internal)
16842 + " " + name + t->get_subrange_representation();
16843 }
16844 else
16845 {
16846 if (/*The current var_decl is to be used as an anonymous data
16847 member. */
16848 get_name().empty())
16849 {
16850 // Display the anonymous data member in a way that
16851 // makes sense.
16852 result +=
16853 get_class_or_union_flat_representation
16854 (is_class_or_union_type(get_type()),
16855 "", /*one_line=*/true, internal);
16856 }
16857 else if (data_member_has_anonymous_type(this))
16858 {
16859 result += get_class_or_union_flat_representation
16860 (is_class_or_union_type(get_type()),
16861 "", /*one_line=*/true, internal);
16862 result += " ";
16863 if (member_of_anonymous_class || !qualified_name)
16864 // It doesn't make sense to name the member of an
16865 // anonymous class or union like:
16866 // "__anonymous__::data_member_name". So let's just use
16867 // its non-qualified name.
16868 result += get_name();
16869 else
16870 result += get_qualified_name(internal);
16871 }
16872 else
16873 {
16874 result +=
16875 get_type_declaration(get_type())->get_qualified_name(internal)
16876 + " ";
16877
16878 if (member_of_anonymous_class || !qualified_name)
16879 // It doesn't make sense to name the member of an
16880 // anonymous class or union like:
16881 // "__anonymous__::data_member_name". So let's just use
16882 // its non-qualified name.
16883 result += get_name();
16884 else
16885 result += get_qualified_name(internal);
16886 }
16887 }
16888 return result;
16889 }
16890
16891 /// Get a name that is valid even for an anonymous data member.
16892 ///
16893 /// If the current @ref var_decl is an anonymous data member, then
16894 /// return its pretty representation. As of now, that pretty
16895 /// representation is actually its flat representation as returned by
16896 /// get_class_or_union_flat_representation().
16897 ///
16898 /// Otherwise, just return the name of the current @ref var_decl.
16899 ///
16900 /// @param qualified if true, return the qualified name. This doesn't
16901 /// have an effet if the current @ref var_decl represents an anonymous
16902 /// data member.
16903 string
get_anon_dm_reliable_name(bool qualified) const16904 var_decl::get_anon_dm_reliable_name(bool qualified) const
16905 {
16906 string name;
16907 if (is_anonymous_data_member(this))
16908 name = get_pretty_representation(true, qualified);
16909 else
16910 name = get_name();
16911
16912 return name;
16913 }
16914
16915 /// This implements the ir_traversable_base::traverse pure virtual
16916 /// function.
16917 ///
16918 /// @param v the visitor used on the current instance.
16919 ///
16920 /// @return true if the entire IR node tree got traversed, false
16921 /// otherwise.
16922 bool
traverse(ir_node_visitor & v)16923 var_decl::traverse(ir_node_visitor& v)
16924 {
16925 if (visiting())
16926 return true;
16927
16928 if (v.visit_begin(this))
16929 {
16930 visiting(true);
16931 if (type_base_sptr t = get_type())
16932 t->traverse(v);
16933 visiting(false);
16934 }
16935 return v.visit_end(this);
16936 }
16937
~var_decl()16938 var_decl::~var_decl()
16939 {}
16940
16941 // </var_decl definitions>
16942
16943 // <function_type>
16944
16945 /// The type of the private data of the @ref function_type type.
16946 struct function_type::priv
16947 {
16948 parameters parms_;
16949 type_base_wptr return_type_;
16950 interned_string cached_name_;
16951 interned_string internal_cached_name_;
16952
privabigail::ir::function_type::priv16953 priv()
16954 {}
16955
privabigail::ir::function_type::priv16956 priv(const parameters& parms,
16957 type_base_sptr return_type)
16958 : parms_(parms),
16959 return_type_(return_type)
16960 {}
16961
privabigail::ir::function_type::priv16962 priv(type_base_sptr return_type)
16963 : return_type_(return_type)
16964 {}
16965
16966 /// Mark a given @ref function_type as being compared.
16967 ///
16968 /// @param type the @ref function_type to mark as being compared.
16969 void
mark_as_being_comparedabigail::ir::function_type::priv16970 mark_as_being_compared(const function_type& type) const
16971 {
16972 const environment* env = type.get_environment();
16973 ABG_ASSERT(env);
16974 env->priv_->fn_types_being_compared_.insert(&type);
16975 }
16976
16977 /// If a given @ref function_type was marked as being compared, this
16978 /// function unmarks it.
16979 ///
16980 /// @param type the @ref function_type to mark as *NOT* being
16981 /// compared.
16982 void
unmark_as_being_comparedabigail::ir::function_type::priv16983 unmark_as_being_compared(const function_type& type) const
16984 {
16985 const environment* env = type.get_environment();
16986 ABG_ASSERT(env);
16987 env->priv_->fn_types_being_compared_.erase(&type);
16988 }
16989
16990 /// Tests if a @ref function_type is currently being compared.
16991 ///
16992 /// @param type the function type to take into account.
16993 ///
16994 /// @return true if @p type is being compared.
16995 bool
comparison_startedabigail::ir::function_type::priv16996 comparison_started(const function_type& type) const
16997 {
16998 const environment* env = type.get_environment();
16999 ABG_ASSERT(env);
17000 return env->priv_->fn_types_being_compared_.count(&type);
17001 }
17002 };// end struc function_type::priv
17003
17004 /// This function is automatically invoked whenever an instance of
17005 /// this type is canonicalized.
17006 ///
17007 /// It's an overload of the virtual type_base::on_canonical_type_set.
17008 ///
17009 /// We put here what is thus meant to be executed only at the point of
17010 /// type canonicalization.
17011 void
on_canonical_type_set()17012 function_type::on_canonical_type_set()
17013 {
17014 priv_->cached_name_.clear();
17015 priv_->internal_cached_name_.clear();
17016 }
17017
17018 /// The most straightforward constructor for the function_type class.
17019 ///
17020 /// @param return_type the return type of the function type.
17021 ///
17022 /// @param parms the list of parameters of the function type.
17023 /// Stricto sensu, we just need a list of types; we are using a list
17024 /// of parameters (where each parameter also carries the name of the
17025 /// parameter and its source location) to try and provide better
17026 /// diagnostics whenever it makes sense. If it appears that this
17027 /// wasts too many resources, we can fall back to taking just a
17028 /// vector of types here.
17029 ///
17030 /// @param size_in_bits the size of this type, in bits.
17031 ///
17032 /// @param alignment_in_bits the alignment of this type, in bits.
17033 ///
17034 /// @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)17035 function_type::function_type(type_base_sptr return_type,
17036 const parameters& parms,
17037 size_t size_in_bits,
17038 size_t alignment_in_bits)
17039 : type_or_decl_base(return_type->get_environment(),
17040 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
17041 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
17042 priv_(new priv(parms, return_type))
17043 {
17044 runtime_type_instance(this);
17045
17046 for (parameters::size_type i = 0, j = 1;
17047 i < priv_->parms_.size();
17048 ++i, ++j)
17049 {
17050 if (i == 0 && priv_->parms_[i]->get_is_artificial())
17051 // If the first parameter is artificial, then it certainly
17052 // means that this is a member function, and the first
17053 // parameter is the implicit this pointer. In that case, set
17054 // the index of that implicit parameter to zero. Otherwise,
17055 // the index of the first parameter starts at one.
17056 j = 0;
17057 priv_->parms_[i]->set_index(j);
17058 }
17059 }
17060
17061 /// A constructor for a function_type that takes no parameters.
17062 ///
17063 /// @param return_type the return type of this function_type.
17064 ///
17065 /// @param size_in_bits the size of this type, in bits.
17066 ///
17067 /// @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)17068 function_type::function_type(type_base_sptr return_type,
17069 size_t size_in_bits, size_t alignment_in_bits)
17070 : type_or_decl_base(return_type->get_environment(),
17071 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
17072 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
17073 priv_(new priv(return_type))
17074 {
17075 runtime_type_instance(this);
17076 }
17077
17078 /// A constructor for a function_type that takes no parameter and
17079 /// that has no return_type yet. These missing parts can (and must)
17080 /// be added later.
17081 ///
17082 /// @param env the environment we are operating from.
17083 ///
17084 /// @param size_in_bits the size of this type, in bits.
17085 ///
17086 /// @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)17087 function_type::function_type(const environment* env,
17088 size_t size_in_bits,
17089 size_t alignment_in_bits)
17090 : type_or_decl_base(env, FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
17091 type_base(env, size_in_bits, alignment_in_bits),
17092 priv_(new priv)
17093 {
17094 runtime_type_instance(this);
17095 }
17096
17097 /// Getter for the return type of the current instance of @ref
17098 /// function_type.
17099 ///
17100 /// @return the return type.
17101 type_base_sptr
get_return_type() const17102 function_type::get_return_type() const
17103 {return priv_->return_type_.lock();}
17104
17105 /// Setter of the return type of the current instance of @ref
17106 /// function_type.
17107 ///
17108 /// @param t the new return type to set.
17109 void
set_return_type(type_base_sptr t)17110 function_type::set_return_type(type_base_sptr t)
17111 {priv_->return_type_ = t;}
17112
17113 /// Getter for the set of parameters of the current intance of @ref
17114 /// function_type.
17115 ///
17116 /// @return the parameters of the current instance of @ref
17117 /// function_type.
17118 const function_decl::parameters&
get_parameters() const17119 function_type::get_parameters() const
17120 {return priv_->parms_;}
17121
17122 /// Get the Ith parameter of the vector of parameters of the current
17123 /// instance of @ref function_type.
17124 ///
17125 /// Note that the first parameter is at index 0. That parameter is
17126 /// the first parameter that comes after the possible implicit "this"
17127 /// parameter, when the current instance @ref function_type is for a
17128 /// member function. Otherwise, if the current instance of @ref
17129 /// function_type is for a non-member function, the parameter at index
17130 /// 0 is the first parameter of the function.
17131 ///
17132 ///
17133 /// @param i the index of the parameter to return. If i is greater
17134 /// than the index of the last parameter, then this function returns
17135 /// an empty parameter (smart) pointer.
17136 ///
17137 /// @return the @p i th parameter that is not implicit.
17138 const function_decl::parameter_sptr
get_parm_at_index_from_first_non_implicit_parm(size_t i) const17139 function_type::get_parm_at_index_from_first_non_implicit_parm(size_t i) const
17140 {
17141 parameter_sptr result;
17142 if (dynamic_cast<const method_type*>(this))
17143 {
17144 if (i + 1 < get_parameters().size())
17145 result = get_parameters()[i + 1];
17146 }
17147 else
17148 {
17149 if (i < get_parameters().size())
17150 result = get_parameters()[i];
17151 }
17152 return result;
17153 }
17154
17155 /// Setter for the parameters of the current instance of @ref
17156 /// function_type.
17157 ///
17158 /// @param p the new vector of parameters to set.
17159 void
set_parameters(const parameters & p)17160 function_type::set_parameters(const parameters &p)
17161 {
17162 priv_->parms_ = p;
17163 for (parameters::size_type i = 0, j = 1;
17164 i < priv_->parms_.size();
17165 ++i, ++j)
17166 {
17167 if (i == 0 && priv_->parms_[i]->get_is_artificial())
17168 // If the first parameter is artificial, then it certainly
17169 // means that this is a member function, and the first
17170 // parameter is the implicit this pointer. In that case, set
17171 // the index of that implicit parameter to zero. Otherwise,
17172 // the index of the first parameter starts at one.
17173 j = 0;
17174 priv_->parms_[i]->set_index(j);
17175 }
17176 }
17177
17178 /// Append a new parameter to the vector of parameters of the current
17179 /// instance of @ref function_type.
17180 ///
17181 /// @param parm the parameter to append.
17182 void
append_parameter(parameter_sptr parm)17183 function_type::append_parameter(parameter_sptr parm)
17184 {
17185 parm->set_index(priv_->parms_.size());
17186 priv_->parms_.push_back(parm);
17187 }
17188
17189 /// Test if the current instance of @ref function_type is for a
17190 /// variadic function.
17191 ///
17192 /// A variadic function is a function that takes a variable number of
17193 /// arguments.
17194 ///
17195 /// @return true iff the current instance of @ref function_type is for
17196 /// a variadic function.
17197 bool
is_variadic() const17198 function_type::is_variadic() const
17199 {
17200 return (!priv_->parms_.empty()
17201 && priv_->parms_.back()->get_variadic_marker());
17202 }
17203
17204 /// Compare two function types.
17205 ///
17206 /// In case these function types are actually method types, this
17207 /// function avoids comparing two parameters (of the function types)
17208 /// if the types of the parameters are actually the types of the
17209 /// classes of the method types. This prevents infinite recursion
17210 /// during the comparison of two classes that are structurally
17211 /// identical.
17212 ///
17213 /// This is a subroutine of the equality operator of function_type.
17214 ///
17215 /// @param lhs the first function type to consider
17216 ///
17217 /// @param rhs the second function type to consider
17218 ///
17219 /// @param k a pointer to a bitfield set by the function to give
17220 /// information about the kind of changes carried by @p lhs and @p
17221 /// rhs. It is set iff @p k is non-null and the function returns
17222 /// false.
17223 ///
17224 /// Please note that setting k to a non-null value does have a
17225 /// negative performance impact because even if @p l and @p r are not
17226 /// equal, the function keeps up the comparison in order to determine
17227 /// the different kinds of ways in which they are different.
17228 ///
17229 ///@return true if lhs == rhs, false otherwise.
17230 bool
equals(const function_type & lhs,const function_type & rhs,change_kind * k)17231 equals(const function_type& lhs,
17232 const function_type& rhs,
17233 change_kind* k)
17234 {
17235 #define RETURN(value) \
17236 do { \
17237 lhs.priv_->unmark_as_being_compared(lhs); \
17238 lhs.priv_->unmark_as_being_compared(rhs); \
17239 if (value == true) \
17240 maybe_propagate_canonical_type(lhs, rhs); \
17241 return value; \
17242 } while(0)
17243
17244 if (lhs.priv_->comparison_started(lhs)
17245 || lhs.priv_->comparison_started(rhs))
17246 return true;
17247
17248 lhs.priv_->mark_as_being_compared(lhs);
17249 lhs.priv_->mark_as_being_compared(rhs);
17250
17251 bool result = true;
17252
17253 if (!lhs.type_base::operator==(rhs))
17254 {
17255 result = false;
17256 if (k)
17257 *k |= LOCAL_TYPE_CHANGE_KIND;
17258 else
17259 RETURN(result);
17260 }
17261
17262 class_or_union* lhs_class = 0, *rhs_class = 0;
17263 if (const method_type* m = dynamic_cast<const method_type*>(&lhs))
17264 lhs_class = m->get_class_type().get();
17265
17266 if (const method_type* m = dynamic_cast<const method_type*>(&rhs))
17267 rhs_class = m->get_class_type().get();
17268
17269 // Compare the names of the class of the method
17270
17271 if (!!lhs_class != !!rhs_class)
17272 {
17273 result = false;
17274 if (k)
17275 *k |= LOCAL_TYPE_CHANGE_KIND;
17276 else
17277 RETURN(result);
17278 }
17279 else if (lhs_class
17280 && (lhs_class->get_qualified_name()
17281 != rhs_class->get_qualified_name()))
17282 {
17283 result = false;
17284 if (k)
17285 *k |= LOCAL_TYPE_CHANGE_KIND;
17286 else
17287 RETURN(result);
17288 }
17289
17290 // Then compare the return type; Beware if it's t's a class type
17291 // that is the same as the method class name; we can recurse for
17292 // ever in that case.
17293
17294 decl_base* lhs_return_type_decl =
17295 get_type_declaration(lhs.get_return_type()).get();
17296 decl_base* rhs_return_type_decl =
17297 get_type_declaration(rhs.get_return_type()).get();
17298 bool compare_result_types = true;
17299 string lhs_rt_name = lhs_return_type_decl
17300 ? lhs_return_type_decl->get_qualified_name()
17301 : string();
17302 string rhs_rt_name = rhs_return_type_decl
17303 ? rhs_return_type_decl->get_qualified_name()
17304 : string();
17305
17306 if ((lhs_class && (lhs_class->get_qualified_name() == lhs_rt_name))
17307 ||
17308 (rhs_class && (rhs_class->get_qualified_name() == rhs_rt_name)))
17309 compare_result_types = false;
17310
17311 if (compare_result_types)
17312 {
17313 if (lhs.get_return_type() != rhs.get_return_type())
17314 {
17315 result = false;
17316 if (k)
17317 {
17318 if (!types_have_similar_structure(lhs.get_return_type(),
17319 rhs.get_return_type()))
17320 *k |= LOCAL_TYPE_CHANGE_KIND;
17321 else
17322 *k |= SUBTYPE_CHANGE_KIND;
17323 }
17324 else
17325 RETURN(result);
17326 }
17327 }
17328 else
17329 if (lhs_rt_name != rhs_rt_name)
17330 {
17331 result = false;
17332 if (k)
17333 *k |= SUBTYPE_CHANGE_KIND;
17334 else
17335 RETURN(result);
17336 }
17337
17338 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
17339 for (i = lhs.get_first_parm(), j = rhs.get_first_parm();
17340 i != lhs.get_parameters().end() && j != rhs.get_parameters().end();
17341 ++i, ++j)
17342 {
17343 if (**i != **j)
17344 {
17345 result = false;
17346 if (k)
17347 {
17348 if (!types_have_similar_structure((*i)->get_type(),
17349 (*j)->get_type()))
17350 *k |= LOCAL_TYPE_CHANGE_KIND;
17351 else
17352 *k |= SUBTYPE_CHANGE_KIND;
17353 }
17354 else
17355 RETURN(result);
17356 }
17357 }
17358
17359 if ((i != lhs.get_parameters().end()
17360 || j != rhs.get_parameters().end()))
17361 {
17362 result = false;
17363 if (k)
17364 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
17365 else
17366 RETURN(result);
17367 }
17368
17369 RETURN(result);
17370 #undef RETURN
17371 }
17372
17373 /// Get the first parameter of the function.
17374 ///
17375 /// If the function is a non-static member function, the parameter
17376 /// returned is the first one following the implicit 'this' parameter.
17377 ///
17378 /// @return the first non implicit parameter of the function.
17379 function_type::parameters::const_iterator
get_first_non_implicit_parm() const17380 function_type::get_first_non_implicit_parm() const
17381 {
17382 if (get_parameters().empty())
17383 return get_parameters().end();
17384
17385 bool is_method = dynamic_cast<const method_type*>(this);
17386
17387 parameters::const_iterator i = get_parameters().begin();
17388
17389 if (is_method)
17390 ++i;
17391
17392 return i;
17393 }
17394
17395 /// Get the first parameter of the function.
17396 ///
17397 /// Note that if the function is a non-static member function, the
17398 /// parameter returned is the implicit 'this' parameter.
17399 ///
17400 /// @return the first parameter of the function.
17401 function_type::parameters::const_iterator
get_first_parm() const17402 function_type::get_first_parm() const
17403 {return get_parameters().begin();}
17404
17405 /// Get the name of the current @ref function_type.
17406 ///
17407 /// The name is retrieved from a cache. If the cache is empty, this
17408 /// function computes the name of the type, stores it in the cache and
17409 /// returns it. Subsequent invocation of the function are going to
17410 /// just hit the cache.
17411 ///
17412 /// Note that if the type is *NOT* canonicalized then function type
17413 /// name is never cached.
17414 ///
17415 /// @param internal if true then it means the function type name is
17416 /// going to be used for purposes that are internal to libabigail
17417 /// itself. If you don't know what this is then you probably should
17418 /// set this parameter to 'false'.
17419 ///
17420 /// @return the name of the function type.
17421 const interned_string&
get_cached_name(bool internal) const17422 function_type::get_cached_name(bool internal) const
17423 {
17424 if (internal)
17425 {
17426 if (!get_naked_canonical_type() || priv_->internal_cached_name_.empty())
17427 priv_->internal_cached_name_ = get_function_type_name(this, internal);
17428
17429 return priv_->internal_cached_name_;
17430 }
17431
17432 if (!get_naked_canonical_type() || priv_->cached_name_.empty())
17433 priv_->cached_name_ = get_function_type_name(this, internal);
17434
17435 return priv_->cached_name_;
17436 }
17437
17438 /// Equality operator for function_type.
17439 ///
17440 /// @param o the other function_type to compare against.
17441 ///
17442 /// @return true iff the two function_type are equal.
17443 bool
operator ==(const type_base & other) const17444 function_type::operator==(const type_base& other) const
17445 {
17446 const function_type* o = dynamic_cast<const function_type*>(&other);
17447 if (!o)
17448 return false;
17449 return try_canonical_compare(this, o);
17450 }
17451
17452 /// Return a copy of the pretty representation of the current @ref
17453 /// function_type.
17454 ///
17455 /// @param internal set to true if the call is intended for an
17456 /// internal use (for technical use inside the library itself), false
17457 /// otherwise. If you don't know what this is for, then set it to
17458 /// false.
17459 ///
17460 /// @return a copy of the pretty representation of the current @ref
17461 /// function_type.
17462 string
get_pretty_representation(bool internal,bool) const17463 function_type::get_pretty_representation(bool internal,
17464 bool /*qualified_name*/) const
17465 {return ir::get_pretty_representation(this, internal);}
17466
17467 /// Traverses an instance of @ref function_type, visiting all the
17468 /// sub-types and decls that it might contain.
17469 ///
17470 /// @param v the visitor that is used to visit every IR sub-node of
17471 /// the current node.
17472 ///
17473 /// @return true if either
17474 /// - all the children nodes of the current IR node were traversed
17475 /// and the calling code should keep going with the traversing.
17476 /// - or the current IR node is already being traversed.
17477 /// Otherwise, returning false means that the calling code should not
17478 /// keep traversing the tree.
17479 bool
traverse(ir_node_visitor & v)17480 function_type::traverse(ir_node_visitor& v)
17481 {
17482 // TODO: should we allow the walker to avoid visiting function type
17483 // twice? I think that if we do, then ir_node_visitor needs an
17484 // option to specifically disallow this feature for function types.
17485
17486 if (visiting())
17487 return true;
17488
17489 if (v.visit_begin(this))
17490 {
17491 visiting(true);
17492 bool keep_going = true;
17493
17494 if (type_base_sptr t = get_return_type())
17495 {
17496 if (!t->traverse(v))
17497 keep_going = false;
17498 }
17499
17500 if (keep_going)
17501 for (parameters::const_iterator i = get_parameters().begin();
17502 i != get_parameters().end();
17503 ++i)
17504 if (type_base_sptr parm_type = (*i)->get_type())
17505 if (!parm_type->traverse(v))
17506 break;
17507
17508 visiting(false);
17509 }
17510 return v.visit_end(this);
17511 }
17512
~function_type()17513 function_type::~function_type()
17514 {}
17515 // </function_type>
17516
17517 // <method_type>
17518
17519 struct method_type::priv
17520 {
17521 class_or_union_wptr class_type_;
17522 bool is_const;
17523
privabigail::ir::method_type::priv17524 priv()
17525 : is_const()
17526 {}
17527 }; // end struct method_type::priv
17528
17529 /// Constructor for instances of method_type.
17530 ///
17531 /// Instances of method_decl must be of type method_type.
17532 ///
17533 /// @param return_type the type of the return value of the method.
17534 ///
17535 /// @param class_type the base type of the method type. That is, the
17536 /// type of the class the method belongs to.
17537 ///
17538 /// @param p the vector of the parameters of the method.
17539 ///
17540 /// @param is_const whether this method type is for a const method.
17541 /// Note that const-ness is a property of the method *type* and of the
17542 /// relationship between a method *declaration* and its scope.
17543 ///
17544 /// @param size_in_bits the size of an instance of method_type,
17545 /// expressed in bits.
17546 ///
17547 /// @param alignment_in_bits the alignment of an instance of
17548 /// 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)17549 method_type::method_type (type_base_sptr return_type,
17550 class_or_union_sptr class_type,
17551 const std::vector<function_decl::parameter_sptr>& p,
17552 bool is_const,
17553 size_t size_in_bits,
17554 size_t alignment_in_bits)
17555 : type_or_decl_base(class_type->get_environment(),
17556 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
17557 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
17558 function_type(return_type, p, size_in_bits, alignment_in_bits),
17559 priv_(new priv)
17560 {
17561 runtime_type_instance(this);
17562 set_class_type(class_type);
17563 set_is_const(is_const);
17564 }
17565
17566 /// Constructor of instances of method_type.
17567 ///
17568 ///Instances of method_decl must be of type method_type.
17569 ///
17570 /// @param return_type the type of the return value of the method.
17571 ///
17572 /// @param class_type the type of the class the method belongs to.
17573 /// The actual (dynamic) type of class_type must be a pointer
17574 /// class_type. We are setting it to pointer to type_base here to
17575 /// help client code that is compiled without rtti and thus cannot
17576 /// perform dynamic casts.
17577 ///
17578 /// @param p the vector of the parameters of the method type.
17579 ///
17580 /// @param is_const whether this method type is for a const method.
17581 /// Note that const-ness is a property of the method *type* and of the
17582 /// relationship between a method *declaration* and its scope.
17583 ///
17584 /// @param size_in_bits the size of an instance of method_type,
17585 /// expressed in bits.
17586 ///
17587 /// @param alignment_in_bits the alignment of an instance of
17588 /// 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)17589 method_type::method_type(type_base_sptr return_type,
17590 type_base_sptr class_type,
17591 const std::vector<function_decl::parameter_sptr>& p,
17592 bool is_const,
17593 size_t size_in_bits,
17594 size_t alignment_in_bits)
17595 : type_or_decl_base(class_type->get_environment(),
17596 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
17597 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
17598 function_type(return_type, p, size_in_bits, alignment_in_bits),
17599 priv_(new priv)
17600 {
17601 runtime_type_instance(this);
17602 set_class_type(is_class_type(class_type));
17603 set_is_const(is_const);
17604 }
17605
17606 /// Constructor of the qualified_type_def
17607 ///
17608 /// @param env the environment we are operating from.
17609 ///
17610 /// @param size_in_bits the size of the type, expressed in bits.
17611 ///
17612 /// @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)17613 method_type::method_type(const environment* env,
17614 size_t size_in_bits,
17615 size_t alignment_in_bits)
17616 : type_or_decl_base(env, METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
17617 type_base(env, size_in_bits, alignment_in_bits),
17618 function_type(env, size_in_bits, alignment_in_bits),
17619 priv_(new priv)
17620 {
17621 runtime_type_instance(this);
17622 }
17623
17624 /// Constructor of instances of method_type.
17625 ///
17626 /// When constructed with this constructor, and instane of method_type
17627 /// must set a return type using method_type::set_return_type
17628 ///
17629 /// @param class_typ the base type of the method type. That is, the
17630 /// type of the class (or union) the method belongs to.
17631 ///
17632 /// @param size_in_bits the size of an instance of method_type,
17633 /// expressed in bits.
17634 ///
17635 /// @param alignment_in_bits the alignment of an instance of
17636 /// 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)17637 method_type::method_type(class_or_union_sptr class_type,
17638 bool is_const,
17639 size_t size_in_bits,
17640 size_t alignment_in_bits)
17641 : type_or_decl_base(class_type->get_environment(),
17642 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
17643 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
17644 function_type(class_type->get_environment(),
17645 size_in_bits,
17646 alignment_in_bits),
17647 priv_(new priv)
17648 {
17649 runtime_type_instance(this);
17650 set_class_type(class_type);
17651 set_is_const(is_const);
17652 }
17653
17654 /// Get the class type this method belongs to.
17655 ///
17656 /// @return the class type.
17657 class_or_union_sptr
get_class_type() const17658 method_type::get_class_type() const
17659 {return class_or_union_sptr(priv_->class_type_);}
17660
17661 /// Sets the class type of the current instance of method_type.
17662 ///
17663 /// The class type is the type of the class the method belongs to.
17664 ///
17665 /// @param t the new class type to set.
17666 void
set_class_type(const class_or_union_sptr & t)17667 method_type::set_class_type(const class_or_union_sptr& t)
17668 {
17669 if (!t)
17670 return;
17671
17672 priv_->class_type_ = t;
17673 }
17674
17675 /// Return a copy of the pretty representation of the current @ref
17676 /// method_type.
17677 ///
17678 /// @param internal set to true if the call is intended for an
17679 /// internal use (for technical use inside the library itself), false
17680 /// otherwise. If you don't know what this is for, then set it to
17681 /// false.
17682 ///
17683 /// @return a copy of the pretty representation of the current @ref
17684 /// method_type.
17685 string
get_pretty_representation(bool internal,bool) const17686 method_type::get_pretty_representation(bool internal,
17687 bool /*qualified_name*/) const
17688 {return ir::get_pretty_representation(*this, internal);}
17689
17690 /// Setter of the "is-const" property of @ref method_type.
17691 ///
17692 /// @param the new value of the "is-const" property.
17693 void
set_is_const(bool f)17694 method_type::set_is_const(bool f)
17695 {priv_->is_const = f;}
17696
17697 /// Getter of the "is-const" property of @ref method_type.
17698 ///
17699 /// @return true iff the "is-const" property was set.
17700 bool
get_is_const() const17701 method_type::get_is_const() const
17702 {return priv_->is_const;}
17703
17704 /// The destructor of method_type
~method_type()17705 method_type::~method_type()
17706 {}
17707
17708 // </method_type>
17709
17710 // <function_decl definitions>
17711
17712 struct function_decl::priv
17713 {
17714 bool declared_inline_;
17715 decl_base::binding binding_;
17716 function_type_wptr type_;
17717 function_type* naked_type_;
17718 elf_symbol_sptr symbol_;
17719 interned_string id_;
17720
privabigail::ir::function_decl::priv17721 priv()
17722 : declared_inline_(false),
17723 binding_(decl_base::BINDING_GLOBAL),
17724 naked_type_()
17725 {}
17726
privabigail::ir::function_decl::priv17727 priv(function_type_sptr t,
17728 bool declared_inline,
17729 decl_base::binding binding)
17730 : declared_inline_(declared_inline),
17731 binding_(binding),
17732 type_(t),
17733 naked_type_(t.get())
17734 {}
17735
privabigail::ir::function_decl::priv17736 priv(function_type_sptr t,
17737 bool declared_inline,
17738 decl_base::binding binding,
17739 elf_symbol_sptr s)
17740 : declared_inline_(declared_inline),
17741 binding_(binding),
17742 type_(t),
17743 naked_type_(t.get()),
17744 symbol_(s)
17745 {}
17746 }; // end sruct function_decl::priv
17747
function_decl(const string & name,function_type_sptr function_type,bool declared_inline,const location & locus,const string & mangled_name,visibility vis,binding bind)17748 function_decl::function_decl(const string& name,
17749 function_type_sptr function_type,
17750 bool declared_inline,
17751 const location& locus,
17752 const string& mangled_name,
17753 visibility vis,
17754 binding bind)
17755 : type_or_decl_base(function_type->get_environment(),
17756 FUNCTION_DECL | ABSTRACT_DECL_BASE),
17757 decl_base(function_type->get_environment(), name, locus, mangled_name, vis),
17758 priv_(new priv(function_type, declared_inline, bind))
17759 {
17760 runtime_type_instance(this);
17761 }
17762
17763 /// Constructor of the function_decl type.
17764 ///
17765 /// This flavour of constructor is for when the pointer to the
17766 /// instance of function_type that the client code has is presented as
17767 /// a pointer to type_base. In that case, this constructor saves the
17768 /// client code from doing a dynamic_cast to get the function_type
17769 /// pointer.
17770 ///
17771 /// @param name the name of the function declaration.
17772 ///
17773 /// @param fn_type the type of the function declaration. The dynamic
17774 /// type of this parameter should be 'pointer to function_type'
17775 ///
17776 /// @param declared_inline whether this function was declared inline
17777 ///
17778 /// @param locus the source location of the function declaration.
17779 ///
17780 /// @param linkage_name the mangled name of the function declaration.
17781 ///
17782 /// @param vis the visibility of the function declaration.
17783 ///
17784 /// @param bind the kind of the binding of the function
17785 /// 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)17786 function_decl::function_decl(const string& name,
17787 type_base_sptr fn_type,
17788 bool declared_inline,
17789 const location& locus,
17790 const string& linkage_name,
17791 visibility vis,
17792 binding bind)
17793 : type_or_decl_base(fn_type->get_environment(),
17794 FUNCTION_DECL | ABSTRACT_DECL_BASE),
17795 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
17796 priv_(new priv(dynamic_pointer_cast<function_type>(fn_type),
17797 declared_inline,
17798 bind))
17799 {
17800 runtime_type_instance(this);
17801 }
17802
17803 /// Get the pretty representation of the current instance of @ref function_decl.
17804 ///
17805 /// @param internal set to true if the call is intended for an
17806 /// internal use (for technical use inside the library itself), false
17807 /// otherwise. If you don't know what this is for, then set it to
17808 /// false.
17809 ///
17810 /// @return the pretty representation for a function.
17811 string
get_pretty_representation(bool internal,bool) const17812 function_decl::get_pretty_representation(bool internal,
17813 bool /*qualified_name*/) const
17814 {
17815 const method_decl* mem_fn =
17816 dynamic_cast<const method_decl*>(this);
17817
17818 string result = mem_fn ? "method ": "function ";
17819
17820 if (mem_fn
17821 && is_member_function(mem_fn)
17822 && get_member_function_is_virtual(mem_fn))
17823 result += "virtual ";
17824
17825 decl_base_sptr type;
17826 if ((mem_fn
17827 && is_member_function(mem_fn)
17828 && (get_member_function_is_dtor(*mem_fn)
17829 || get_member_function_is_ctor(*mem_fn))))
17830 /*cdtors do not have return types. */;
17831 else
17832 type = mem_fn
17833 ? get_type_declaration(mem_fn->get_type()->get_return_type())
17834 : get_type_declaration(get_type()->get_return_type());
17835
17836 if (type)
17837 result += type->get_qualified_name(internal) + " ";
17838
17839 result += get_pretty_representation_of_declarator(internal);
17840
17841 return result;
17842 }
17843
17844 /// Compute and return the pretty representation for the part of the
17845 /// function declaration that starts at the declarator. That is, the
17846 /// return type and the other specifiers of the beginning of the
17847 /// function's declaration ar omitted.
17848 ///
17849 /// @param internal set to true if the call is intended for an
17850 /// internal use (for technical use inside the library itself), false
17851 /// otherwise. If you don't know what this is for, then set it to
17852 /// false.
17853 ///
17854 /// @return the pretty representation for the part of the function
17855 /// declaration that starts at the declarator.
17856 string
get_pretty_representation_of_declarator(bool internal) const17857 function_decl::get_pretty_representation_of_declarator (bool internal) const
17858 {
17859 const method_decl* mem_fn =
17860 dynamic_cast<const method_decl*>(this);
17861
17862 string result;
17863
17864 if (mem_fn)
17865 {
17866 result += mem_fn->get_type()->get_class_type()->get_qualified_name()
17867 + "::" + mem_fn->get_name();
17868 }
17869 else
17870 result += get_qualified_name();
17871
17872 result += "(";
17873
17874 parameters::const_iterator i = get_parameters().begin(),
17875 end = get_parameters().end();
17876
17877 // Skip the first parameter if this is a method.
17878 if (mem_fn && i != end)
17879 ++i;
17880 parameter_sptr parm;
17881 parameter_sptr first_parm;
17882 if (i != end)
17883 first_parm = *i;
17884 for (; i != end; ++i)
17885 {
17886 parm = *i;
17887 if (parm.get() != first_parm.get())
17888 result += ", ";
17889 if (parm->get_variadic_marker()
17890 || get_environment()->is_variadic_parameter_type(parm->get_type()))
17891 result += "...";
17892 else
17893 {
17894 decl_base_sptr type_decl = get_type_declaration(parm->get_type());
17895 result += type_decl->get_qualified_name(internal);
17896 }
17897 }
17898 result += ")";
17899
17900 if (mem_fn
17901 &&((is_member_function(mem_fn) && get_member_function_is_const(*mem_fn))
17902 || is_method_type(mem_fn->get_type())->get_is_const()))
17903 result += " const";
17904
17905 return result;
17906 }
17907
17908 /// Getter for the first non-implicit parameter of a function decl.
17909 ///
17910 /// If the function is a non-static member function, the parameter
17911 /// returned is the first one following the implicit 'this' parameter.
17912 ///
17913 /// @return the first non implicit parm.
17914 function_decl::parameters::const_iterator
get_first_non_implicit_parm() const17915 function_decl::get_first_non_implicit_parm() const
17916 {
17917 if (get_parameters().empty())
17918 return get_parameters().end();
17919
17920 bool is_method = dynamic_cast<const method_decl*>(this);
17921
17922 parameters::const_iterator i = get_parameters().begin();
17923 if (is_method)
17924 ++i;
17925
17926 return i;
17927 }
17928
17929 /// Return the type of the current instance of @ref function_decl.
17930 ///
17931 /// It's either a function_type or method_type.
17932 /// @return the type of the current instance of @ref function_decl.
17933 const shared_ptr<function_type>
get_type() const17934 function_decl::get_type() const
17935 {return priv_->type_.lock();}
17936
17937 /// Fast getter of the type of the current instance of @ref function_decl.
17938 ///
17939 /// Note that this function returns the underlying pointer managed by
17940 /// the smart pointer returned by function_decl::get_type(). It's
17941 /// faster than function_decl::get_type(). This getter is to be used
17942 /// in code paths that are proven to be performance hot spots;
17943 /// especially (for instance) when comparing function types. Those
17944 /// are compared extremely frequently when libabigail is used to
17945 /// handle huge binaries with a lot of functions.
17946 ///
17947 /// @return the type of the current instance of @ref function_decl.
17948 const function_type*
get_naked_type() const17949 function_decl::get_naked_type() const
17950 {return priv_->naked_type_;}
17951
17952 void
set_type(const function_type_sptr & fn_type)17953 function_decl::set_type(const function_type_sptr& fn_type)
17954 {
17955 priv_->type_ = fn_type;
17956 priv_->naked_type_ = fn_type.get();
17957 }
17958
17959 /// This sets the underlying ELF symbol for the current function decl.
17960 ///
17961 /// And underlyin$g ELF symbol for the current function decl might
17962 /// exist only if the corpus that this function decl originates from
17963 /// was constructed from an ELF binary file.
17964 ///
17965 /// Note that comparing two function decls that have underlying ELF
17966 /// symbols involves comparing their underlying elf symbols. The decl
17967 /// name for the function thus becomes irrelevant in the comparison.
17968 ///
17969 /// @param sym the new ELF symbol for this function decl.
17970 void
set_symbol(const elf_symbol_sptr & sym)17971 function_decl::set_symbol(const elf_symbol_sptr& sym)
17972 {
17973 priv_->symbol_ = sym;
17974 // The function id cache that depends on the symbol must be
17975 // invalidated because the symbol changed.
17976 priv_->id_ = get_environment()->intern("");
17977 }
17978
17979 /// Gets the the underlying ELF symbol for the current variable,
17980 /// that was set using function_decl::set_symbol(). Please read the
17981 /// documentation for that member function for more information about
17982 /// "underlying ELF symbols".
17983 ///
17984 /// @return sym the underlying ELF symbol for this function decl, if
17985 /// one exists.
17986 const elf_symbol_sptr&
get_symbol() const17987 function_decl::get_symbol() const
17988 {return priv_->symbol_;}
17989
17990 bool
is_declared_inline() const17991 function_decl::is_declared_inline() const
17992 {return priv_->declared_inline_;}
17993
17994 decl_base::binding
get_binding() const17995 function_decl::get_binding() const
17996 {return priv_->binding_;}
17997
17998 /// @return the return type of the current instance of function_decl.
17999 const shared_ptr<type_base>
get_return_type() const18000 function_decl::get_return_type() const
18001 {return get_type()->get_return_type();}
18002
18003 /// @return the parameters of the function.
18004 const std::vector<shared_ptr<function_decl::parameter> >&
get_parameters() const18005 function_decl::get_parameters() const
18006 {return get_type()->get_parameters();}
18007
18008 /// Append a parameter to the type of this function.
18009 ///
18010 /// @param parm the parameter to append.
18011 void
append_parameter(shared_ptr<parameter> parm)18012 function_decl::append_parameter(shared_ptr<parameter> parm)
18013 {get_type()->append_parameter(parm);}
18014
18015 /// Append a vector of parameters to the type of this function.
18016 ///
18017 /// @param parms the vector of parameters to append.
18018 void
append_parameters(std::vector<shared_ptr<parameter>> & parms)18019 function_decl::append_parameters(std::vector<shared_ptr<parameter> >& parms)
18020 {
18021 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
18022 i != parms.end();
18023 ++i)
18024 get_type()->append_parameter(*i);
18025 }
18026
18027 /// Create a new instance of function_decl that is a clone of the
18028 /// current one.
18029 ///
18030 /// @return the new clone.
18031 function_decl_sptr
clone() const18032 function_decl::clone() const
18033 {
18034 function_decl_sptr f;
18035 if (is_member_function(*this))
18036 {
18037 method_decl_sptr
18038 m(new method_decl(get_name(),
18039 get_type(),
18040 is_declared_inline(),
18041 get_location(),
18042 get_linkage_name(),
18043 get_visibility(),
18044 get_binding()));
18045 class_or_union* scope = is_class_or_union_type(get_scope());
18046 ABG_ASSERT(scope);
18047 scope->add_member_function(m, get_member_access_specifier(*this),
18048 get_member_function_is_virtual(*this),
18049 get_member_function_vtable_offset(*this),
18050 get_member_is_static(*this),
18051 get_member_function_is_ctor(*this),
18052 get_member_function_is_dtor(*this),
18053 get_member_function_is_const(*this));
18054 f = m;
18055 }
18056 else
18057 {
18058 f.reset(new function_decl(get_name(),
18059 get_type(),
18060 is_declared_inline(),
18061 get_location(),
18062 get_linkage_name(),
18063 get_visibility(),
18064 get_binding()));
18065 add_decl_to_scope(f, get_scope());
18066 }
18067 f->set_symbol(get_symbol());
18068
18069 return f;
18070 }
18071
18072 /// Compares two instances of @ref function_decl.
18073 ///
18074 /// If the two intances are different, set a bitfield to give some
18075 /// insight about the kind of differences there are.
18076 ///
18077 /// @param l the first artifact of the comparison.
18078 ///
18079 /// @param r the second artifact of the comparison.
18080 ///
18081 /// @param k a pointer to a bitfield that gives information about the
18082 /// kind of changes there are between @p l and @p r. This one is set
18083 /// iff @p k is non-null and the function returns false.
18084 ///
18085 /// Please note that setting k to a non-null value does have a
18086 /// negative performance impact because even if @p l and @p r are not
18087 /// equal, the function keeps up the comparison in order to determine
18088 /// the different kinds of ways in which they are different.
18089 ///
18090 /// @return true if @p l equals @p r, false otherwise.
18091 bool
equals(const function_decl & l,const function_decl & r,change_kind * k)18092 equals(const function_decl& l, const function_decl& r, change_kind* k)
18093 {
18094 bool result = true;
18095
18096 // Compare function types
18097 const type_base* t0 = l.get_naked_type(), *t1 = r.get_naked_type();
18098 if (t0 == t1 || *t0 == *t1)
18099 ; // the types are equal, let's move on to compare the other
18100 // properties of the functions.
18101 else
18102 {
18103 result = false;
18104 if (k)
18105 {
18106 if (!types_have_similar_structure(t0, t1))
18107 *k |= LOCAL_TYPE_CHANGE_KIND;
18108 else
18109 *k |= SUBTYPE_CHANGE_KIND;
18110 }
18111 else
18112 return false;
18113 }
18114
18115 const elf_symbol_sptr &s0 = l.get_symbol(), &s1 = r.get_symbol();
18116 if (!!s0 != !!s1)
18117 {
18118 result = false;
18119 if (k)
18120 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18121 else
18122 return false;
18123 }
18124 else if (s0 && s0 != s1)
18125 {
18126 if (!elf_symbols_alias(s0, s1))
18127 {
18128 result = false;
18129 if (k)
18130 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18131 else
18132 return false;
18133 }
18134 }
18135 bool symbols_are_equal = (s0 && s1 && result);
18136
18137 if (symbols_are_equal)
18138 {
18139 // The functions have underlying elf symbols that are equal,
18140 // so now, let's compare the decl_base part of the functions
18141 // w/o considering their decl names.
18142 interned_string n1 = l.get_name(), n2 = r.get_name();
18143 interned_string ln1 = l.get_linkage_name(), ln2 = r.get_linkage_name();
18144 const_cast<function_decl&>(l).set_name("");
18145 const_cast<function_decl&>(l).set_linkage_name("");
18146 const_cast<function_decl&>(r).set_name("");
18147 const_cast<function_decl&>(r).set_linkage_name("");
18148
18149 bool decl_bases_different = !l.decl_base::operator==(r);
18150
18151 const_cast<function_decl&>(l).set_name(n1);
18152 const_cast<function_decl&>(l).set_linkage_name(ln1);
18153 const_cast<function_decl&>(r).set_name(n2);
18154 const_cast<function_decl&>(r).set_linkage_name(ln2);
18155
18156 if (decl_bases_different)
18157 {
18158 result = false;
18159 if (k)
18160 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18161 else
18162 return false;
18163 }
18164 }
18165 else
18166 if (!l.decl_base::operator==(r))
18167 {
18168 result = false;
18169 if (k)
18170 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18171 else
18172 return false;
18173 }
18174
18175 // Compare the remaining properties
18176 if (l.is_declared_inline() != r.is_declared_inline()
18177 || l.get_binding() != r.get_binding())
18178 {
18179 result = false;
18180 if (k)
18181 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18182 else
18183 return false;
18184 }
18185
18186 if (is_member_function(l) != is_member_function(r))
18187 {
18188 result = false;
18189 if (k)
18190 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18191 else
18192 return false;
18193 }
18194
18195 if (is_member_function(l) && is_member_function(r))
18196 {
18197 if (!((get_member_function_is_ctor(l)
18198 == get_member_function_is_ctor(r))
18199 && (get_member_function_is_dtor(l)
18200 == get_member_function_is_dtor(r))
18201 && (get_member_is_static(l)
18202 == get_member_is_static(r))
18203 && (get_member_function_is_const(l)
18204 == get_member_function_is_const(r))
18205 && (get_member_function_is_virtual(l)
18206 == get_member_function_is_virtual(r))
18207 && (get_member_function_vtable_offset(l)
18208 == get_member_function_vtable_offset(r))))
18209 {
18210 result = false;
18211 if (k)
18212 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18213 else
18214 return false;
18215 }
18216 }
18217
18218 return result;
18219 }
18220
18221 /// Comparison operator for @ref function_decl.
18222 ///
18223 /// @param other the other instance of @ref function_decl to compare
18224 /// against.
18225 ///
18226 /// @return true iff the current instance of @ref function_decl equals
18227 /// @p other.
18228 bool
operator ==(const decl_base & other) const18229 function_decl::operator==(const decl_base& other) const
18230 {
18231 const function_decl* o = dynamic_cast<const function_decl*>(&other);
18232 if (!o)
18233 return false;
18234 return equals(*this, *o, 0);
18235 }
18236
18237 /// Return true iff the function takes a variable number of
18238 /// parameters.
18239 ///
18240 /// @return true if the function taks a variable number
18241 /// of parameters.
18242 bool
is_variadic() const18243 function_decl::is_variadic() const
18244 {
18245 return (!get_parameters().empty()
18246 && get_parameters().back()->get_variadic_marker());
18247 }
18248
18249 /// The virtual implementation of 'get_hash' for a function_decl.
18250 ///
18251 /// This allows decl_base::get_hash to work for function_decls.
18252 ///
18253 /// @return the hash value for function decl.
18254 size_t
get_hash() const18255 function_decl::get_hash() const
18256 {
18257 function_decl::hash hash_fn;
18258 return hash_fn(*this);
18259 }
18260
18261 /// Return an ID that tries to uniquely identify the function inside a
18262 /// program or a library.
18263 ///
18264 /// So if the function has an underlying elf symbol, the ID is the
18265 /// concatenation of the symbol name and its version. Otherwise, the
18266 /// ID is the linkage name if its non-null. Otherwise, it's the
18267 /// pretty representation of the function.
18268 ///
18269 /// @return the ID.
18270 interned_string
get_id() const18271 function_decl::get_id() const
18272 {
18273 if (priv_->id_.empty())
18274 {
18275 const environment* env = get_type()->get_environment();
18276 if (elf_symbol_sptr s = get_symbol())
18277 {
18278 if (s->has_aliases())
18279 // The symbol has several aliases, so let's use a scheme
18280 // that allows all aliased functions to have different
18281 // IDs.
18282 priv_->id_ = env->intern(get_name() + "/" + s->get_id_string());
18283 else
18284 // Let's use the full symbol name with its version as ID.
18285 priv_->id_ = env->intern(s->get_id_string());
18286 }
18287 else if (!get_linkage_name().empty())
18288 priv_->id_= env->intern(get_linkage_name());
18289 else
18290 priv_->id_ = env->intern(get_pretty_representation());
18291 }
18292 return priv_->id_;
18293 }
18294
18295 /// Test if two function declarations are aliases.
18296 ///
18297 /// Two functions declarations are aliases if their symbols are
18298 /// aliases, in the ELF sense.
18299 ///
18300 /// @param f1 the first function to consider.
18301 ///
18302 /// @param f2 the second function to consider.
18303 ///
18304 /// @return true iff @p f1 is an alias of @p f2
18305 bool
function_decls_alias(const function_decl & f1,const function_decl & f2)18306 function_decls_alias(const function_decl& f1, const function_decl& f2)
18307 {
18308 elf_symbol_sptr s1 = f1.get_symbol(), s2 = f2.get_symbol();
18309
18310 if (!s1 || !s2)
18311 return false;
18312
18313 return elf_symbols_alias(s1, s2);
18314 }
18315
18316 /// This implements the ir_traversable_base::traverse pure virtual
18317 /// function.
18318 ///
18319 /// @param v the visitor used on the current instance.
18320 ///
18321 /// @return true if the entire IR node tree got traversed, false
18322 /// otherwise.
18323 bool
traverse(ir_node_visitor & v)18324 function_decl::traverse(ir_node_visitor& v)
18325 {
18326 if (visiting())
18327 return true;
18328
18329 if (v.visit_begin(this))
18330 {
18331 visiting(true);
18332 if (type_base_sptr t = get_type())
18333 t->traverse(v);
18334 visiting(false);
18335 }
18336 return v.visit_end(this);
18337 }
18338
18339 /// Destructor of the @ref function_decl type.
~function_decl()18340 function_decl::~function_decl()
18341 {delete priv_;}
18342
18343 /// A deep comparison operator for a shared pointer to @ref function_decl
18344 ///
18345 /// This function compares to shared pointers to @ref function_decl by
18346 /// looking at the pointed-to instances of @ref function_dec
18347 /// comparing them too. If the two pointed-to objects are equal then
18348 /// this function returns true.
18349 ///
18350 /// @param l the left-hand side argument of the equality operator.
18351 ///
18352 /// @param r the right-hand side argument of the equality operator.
18353 ///
18354 /// @return true iff @p l equals @p r.
18355 bool
operator ==(const function_decl_sptr & l,const function_decl_sptr & r)18356 operator==(const function_decl_sptr& l, const function_decl_sptr& r)
18357 {
18358 if (l.get() == r.get())
18359 return true;
18360 if (!!l != !!r)
18361 return false;
18362
18363 return *l == *r;
18364 }
18365
18366 /// A deep inequality operator for smart pointers to functions.
18367 ///
18368 /// @param l the left-hand side argument of the inequality operator.
18369 ///
18370 /// @pram r the right-hand side argument of the inequality operator.
18371 ///
18372 /// @return true iff @p is not equal to @p r.
18373 bool
operator !=(const function_decl_sptr & l,const function_decl_sptr & r)18374 operator!=(const function_decl_sptr& l, const function_decl_sptr& r)
18375 {return !operator==(l, r);}
18376
18377 // <function_decl definitions>
18378
18379 // <function_decl::parameter definitions>
18380
18381 struct function_decl::parameter::priv
18382 {
18383 type_base_wptr type_;
18384 unsigned index_;
18385 bool variadic_marker_;
18386
privabigail::ir::function_decl::parameter::priv18387 priv()
18388 : index_(),
18389 variadic_marker_()
18390 {}
18391
privabigail::ir::function_decl::parameter::priv18392 priv(type_base_sptr type,
18393 unsigned index,
18394 bool variadic_marker)
18395 : type_(type),
18396 index_(index),
18397 variadic_marker_(variadic_marker)
18398 {}
18399 };// end struct function_decl::parameter::priv
18400
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic)18401 function_decl::parameter::parameter(const type_base_sptr type,
18402 unsigned index,
18403 const string& name,
18404 const location& loc,
18405 bool is_variadic)
18406 : type_or_decl_base(type->get_environment(),
18407 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
18408 decl_base(type->get_environment(), name, loc),
18409 priv_(new priv(type, index, is_variadic))
18410 {
18411 runtime_type_instance(this);
18412 }
18413
parameter(const type_base_sptr type,unsigned index,const string & name,const location & loc,bool is_variadic,bool is_artificial)18414 function_decl::parameter::parameter(const type_base_sptr type,
18415 unsigned index,
18416 const string& name,
18417 const location& loc,
18418 bool is_variadic,
18419 bool is_artificial)
18420 : type_or_decl_base(type->get_environment(),
18421 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
18422 decl_base(type->get_environment(), name, loc),
18423 priv_(new priv(type, index, is_variadic))
18424 {
18425 runtime_type_instance(this);
18426 set_is_artificial(is_artificial);
18427 }
18428
parameter(const type_base_sptr type,const string & name,const location & loc,bool is_variadic,bool is_artificial)18429 function_decl::parameter::parameter(const type_base_sptr type,
18430 const string& name,
18431 const location& loc,
18432 bool is_variadic,
18433 bool is_artificial)
18434 : type_or_decl_base(type->get_environment(),
18435 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
18436 decl_base(type->get_environment(), name, loc),
18437 priv_(new priv(type, 0, is_variadic))
18438 {
18439 runtime_type_instance(this);
18440 set_is_artificial(is_artificial);
18441 }
18442
parameter(const type_base_sptr type,unsigned index,bool variad)18443 function_decl::parameter::parameter(const type_base_sptr type,
18444 unsigned index,
18445 bool variad)
18446 : type_or_decl_base(type->get_environment(),
18447 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
18448 decl_base(type->get_environment(), "", location()),
18449 priv_(new priv(type, index, variad))
18450 {
18451 runtime_type_instance(this);
18452 }
18453
18454 const type_base_sptr
get_type() const18455 function_decl::parameter::get_type()const
18456 {return priv_->type_.lock();}
18457
18458 /// @return a copy of the type name of the parameter.
18459 interned_string
get_type_name() const18460 function_decl::parameter::get_type_name() const
18461 {
18462 const environment* env = get_environment();
18463 ABG_ASSERT(env);
18464
18465 type_base_sptr t = get_type();
18466 string str;
18467 if (get_variadic_marker() || env->is_variadic_parameter_type(t))
18468 str = "...";
18469 else
18470 {
18471 ABG_ASSERT(t);
18472 str = abigail::ir::get_type_name(t);
18473 }
18474 return env->intern(str);
18475 }
18476
18477 /// @return a copy of the pretty representation of the type of the
18478 /// parameter.
18479 const string
get_type_pretty_representation() const18480 function_decl::parameter::get_type_pretty_representation() const
18481 {
18482 type_base_sptr t = get_type();
18483 string str;
18484 if (get_variadic_marker()
18485 || get_environment()->is_variadic_parameter_type(t))
18486 str = "...";
18487 else
18488 {
18489 ABG_ASSERT(t);
18490 str += get_type_declaration(t)->get_pretty_representation();
18491 }
18492 return str;
18493 }
18494
18495 /// Get a name uniquely identifying the parameter in the function.
18496 ///
18497 ///@return the unique parm name id.
18498 interned_string
get_name_id() const18499 function_decl::parameter::get_name_id() const
18500 {
18501 const environment* env = get_environment();
18502 ABG_ASSERT(env);
18503
18504 std::ostringstream o;
18505 o << "parameter-" << get_index();
18506
18507 return env->intern(o.str());
18508 }
18509
18510 unsigned
get_index() const18511 function_decl::parameter::get_index() const
18512 {return priv_->index_;}
18513
18514 void
set_index(unsigned i)18515 function_decl::parameter::set_index(unsigned i)
18516 {priv_->index_ = i;}
18517
18518
18519 bool
get_variadic_marker() const18520 function_decl::parameter::get_variadic_marker() const
18521 {return priv_->variadic_marker_;}
18522
18523 /// Compares two instances of @ref function_decl::parameter.
18524 ///
18525 /// If the two intances are different, set a bitfield to give some
18526 /// insight about the kind of differences there are.
18527 ///
18528 /// @param l the first artifact of the comparison.
18529 ///
18530 /// @param r the second artifact of the comparison.
18531 ///
18532 /// @param k a pointer to a bitfield that gives information about the
18533 /// kind of changes there are between @p l and @p r. This one is set
18534 /// iff @p k is non-null and the function returns false.
18535 ///
18536 /// Please note that setting k to a non-null value does have a
18537 /// negative performance impact because even if @p l and @p r are not
18538 /// equal, the function keeps up the comparison in order to determine
18539 /// the different kinds of ways in which they are different.
18540 ///
18541 /// @return true if @p l equals @p r, false otherwise.
18542 bool
equals(const function_decl::parameter & l,const function_decl::parameter & r,change_kind * k)18543 equals(const function_decl::parameter& l,
18544 const function_decl::parameter& r,
18545 change_kind* k)
18546 {
18547 bool result = true;
18548
18549 if ((l.get_variadic_marker() != r.get_variadic_marker())
18550 || (l.get_index() != r.get_index())
18551 || (!!l.get_type() != !!r.get_type()))
18552 {
18553 result = false;
18554 if (k)
18555 {
18556 if (l.get_index() != r.get_index())
18557 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
18558 if (l.get_variadic_marker() != r.get_variadic_marker()
18559 || !!l.get_type() != !!r.get_type())
18560 *k |= LOCAL_TYPE_CHANGE_KIND;
18561 }
18562 else
18563 return false;
18564 }
18565
18566
18567 // Sometimes, function parameters can be wrapped into a no-op
18568 // qualifier. Let's strip that qualifier out.
18569 type_base_sptr l_type = look_through_no_op_qualified_type(l.get_type());
18570 type_base_sptr r_type = look_through_no_op_qualified_type(r.get_type());
18571 if (l_type != r_type)
18572 {
18573 result = false;
18574 if (k)
18575 {
18576 if (!types_have_similar_structure(l_type, r_type))
18577 *k |= LOCAL_TYPE_CHANGE_KIND;
18578 else
18579 *k |= SUBTYPE_CHANGE_KIND;
18580 }
18581 else
18582 return false;
18583 }
18584
18585 return result;
18586 }
18587
18588 bool
operator ==(const parameter & o) const18589 function_decl::parameter::operator==(const parameter& o) const
18590 {return equals(*this, o, 0);}
18591
18592 bool
operator ==(const decl_base & o) const18593 function_decl::parameter::operator==(const decl_base& o) const
18594 {
18595 const function_decl::parameter* p =
18596 dynamic_cast<const function_decl::parameter*>(&o);
18597 if (!p)
18598 return false;
18599 return function_decl::parameter::operator==(*p);
18600 }
18601
18602 /// Non-member equality operator for @ref function_decl::parameter.
18603 ///
18604 /// @param l the left-hand side of the equality operator
18605 ///
18606 /// @param r the right-hand side of the equality operator
18607 ///
18608 /// @return true iff @p l and @p r equals.
18609 bool
operator ==(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)18610 operator==(const function_decl::parameter_sptr& l,
18611 const function_decl::parameter_sptr& r)
18612 {
18613 if (!!l != !!r)
18614 return false;
18615 if (!l)
18616 return true;
18617 return *l == *r;
18618 }
18619
18620 /// Non-member inequality operator for @ref function_decl::parameter.
18621 ///
18622 /// @param l the left-hand side of the equality operator
18623 ///
18624 /// @param r the right-hand side of the equality operator
18625 ///
18626 /// @return true iff @p l and @p r different.
18627 bool
operator !=(const function_decl::parameter_sptr & l,const function_decl::parameter_sptr & r)18628 operator!=(const function_decl::parameter_sptr& l,
18629 const function_decl::parameter_sptr& r)
18630 {return !operator==(l, r);}
18631
18632 /// Traverse the diff sub-tree under the current instance
18633 /// function_decl.
18634 ///
18635 /// @param v the visitor to invoke on each diff node of the sub-tree.
18636 ///
18637 /// @return true if the traversing has to keep going on, false
18638 /// otherwise.
18639 bool
traverse(ir_node_visitor & v)18640 function_decl::parameter::traverse(ir_node_visitor& v)
18641 {
18642 if (visiting())
18643 return true;
18644
18645 if (v.visit_begin(this))
18646 {
18647 visiting(true);
18648 if (type_base_sptr t = get_type())
18649 t->traverse(v);
18650 visiting(false);
18651 }
18652 return v.visit_end(this);
18653 }
18654
18655 /// Get the hash of a decl. If the hash hasn't been computed yet,
18656 /// compute it ans store its value; otherwise, just return the hash.
18657 ///
18658 /// @return the hash of the decl.
18659 size_t
get_hash() const18660 function_decl::parameter::get_hash() const
18661 {
18662 function_decl::parameter::hash hash_fn_parm;
18663 return hash_fn_parm(this);
18664 }
18665
18666 /// Compute the qualified name of the parameter.
18667 ///
18668 /// @param internal set to true if the call is intended for an
18669 /// internal use (for technical use inside the library itself), false
18670 /// otherwise. If you don't know what this is for, then set it to
18671 /// false.
18672 ///
18673 /// @param qn the resulting qualified name.
18674 void
get_qualified_name(interned_string & qualified_name,bool) const18675 function_decl::parameter::get_qualified_name(interned_string& qualified_name,
18676 bool /*internal*/) const
18677 {qualified_name = get_name();}
18678
18679 /// Compute and return a copy of the pretty representation of the
18680 /// current function parameter.
18681 ///
18682 /// @param internal set to true if the call is intended for an
18683 /// internal use (for technical use inside the library itself), false
18684 /// otherwise. If you don't know what this is for, then set it to
18685 /// false.
18686 ///
18687 /// @return a copy of the textual representation of the current
18688 /// function parameter.
18689 string
get_pretty_representation(bool internal,bool) const18690 function_decl::parameter::get_pretty_representation(bool internal,
18691 bool /*qualified_name*/) const
18692 {
18693 const environment* env = get_environment();
18694 ABG_ASSERT(env);
18695
18696 string type_repr;
18697 type_base_sptr t = get_type();
18698 if (!t)
18699 type_repr = "void";
18700 else if (env->is_variadic_parameter_type(t))
18701 type_repr = "...";
18702 else
18703 type_repr = ir::get_pretty_representation(t, internal);
18704
18705 string result = type_repr;
18706 string parm_name = get_name_id();
18707
18708 if (!parm_name.empty())
18709 result += " " + parm_name;
18710
18711 return result;
18712 }
18713
18714 // </function_decl::parameter definitions>
18715
18716 // <class_or_union definitions>
18717 struct class_or_union::priv
18718 {
18719 typedef_decl_wptr naming_typedef_;
18720 member_types member_types_;
18721 data_members data_members_;
18722 data_members non_static_data_members_;
18723 member_functions member_functions_;
18724 // A map that associates a linkage name to a member function.
18725 string_mem_fn_sptr_map_type mem_fns_map_;
18726 // A map that associates function signature strings to member
18727 // function.
18728 string_mem_fn_ptr_map_type signature_2_mem_fn_map_;
18729 member_function_templates member_function_templates_;
18730 member_class_templates member_class_templates_;
18731
privabigail::ir::class_or_union::priv18732 priv()
18733 {}
18734
privabigail::ir::class_or_union::priv18735 priv(class_or_union::member_types& mbr_types,
18736 class_or_union::data_members& data_mbrs,
18737 class_or_union::member_functions& mbr_fns)
18738 : member_types_(mbr_types),
18739 data_members_(data_mbrs),
18740 member_functions_(mbr_fns)
18741 {
18742 for (data_members::const_iterator i = data_members_.begin();
18743 i != data_members_.end();
18744 ++i)
18745 if (!get_member_is_static(*i))
18746 non_static_data_members_.push_back(*i);
18747 }
18748
18749 /// Mark a class or union or union as being currently compared using
18750 /// the class_or_union== operator.
18751 ///
18752 /// Note that is marking business is to avoid infinite loop when
18753 /// comparing a class or union or union. If via the comparison of a
18754 /// data member or a member function a recursive re-comparison of
18755 /// the class or union is attempted, the marking business help to
18756 /// detect that infinite loop possibility and avoid it.
18757 ///
18758 /// @param klass the class or union or union to mark as being
18759 /// currently compared.
18760 void
mark_as_being_comparedabigail::ir::class_or_union::priv18761 mark_as_being_compared(const class_or_union& klass) const
18762 {
18763 const environment* env = klass.get_environment();
18764 ABG_ASSERT(env);
18765 env->priv_->classes_being_compared_.insert(&klass);
18766 }
18767
18768 /// Mark a class or union as being currently compared using the
18769 /// class_or_union== operator.
18770 ///
18771 /// Note that is marking business is to avoid infinite loop when
18772 /// comparing a class or union. If via the comparison of a data
18773 /// member or a member function a recursive re-comparison of the
18774 /// class or union is attempted, the marking business help to detect
18775 /// that infinite loop possibility and avoid it.
18776 ///
18777 /// @param klass the class or union to mark as being currently
18778 /// compared.
18779 void
mark_as_being_comparedabigail::ir::class_or_union::priv18780 mark_as_being_compared(const class_or_union* klass) const
18781 {mark_as_being_compared(*klass);}
18782
18783 /// Mark a class or union as being currently compared using the
18784 /// class_or_union== operator.
18785 ///
18786 /// Note that is marking business is to avoid infinite loop when
18787 /// comparing a class or union. If via the comparison of a data
18788 /// member or a member function a recursive re-comparison of the
18789 /// class or union is attempted, the marking business help to detect
18790 /// that infinite loop possibility and avoid it.
18791 ///
18792 /// @param klass the class or union to mark as being currently
18793 /// compared.
18794 void
mark_as_being_comparedabigail::ir::class_or_union::priv18795 mark_as_being_compared(const class_or_union_sptr& klass) const
18796 {mark_as_being_compared(*klass);}
18797
18798 /// If the instance of class_or_union has been previously marked as
18799 /// being compared -- via an invocation of mark_as_being_compared()
18800 /// this method unmarks it. Otherwise is has no effect.
18801 ///
18802 /// This method is not thread safe because it uses the static data
18803 /// member classes_being_compared_. If you wish to use it in a
18804 /// multi-threaded environment you should probably protect the
18805 /// access to that static data member with a mutex or somesuch.
18806 ///
18807 /// @param klass the instance of class_or_union to unmark.
18808 void
unmark_as_being_comparedabigail::ir::class_or_union::priv18809 unmark_as_being_compared(const class_or_union& klass) const
18810 {
18811 const environment* env = klass.get_environment();
18812 ABG_ASSERT(env);
18813 env->priv_->classes_being_compared_.erase(&klass);
18814 }
18815
18816 /// If the instance of class_or_union has been previously marked as
18817 /// being compared -- via an invocation of mark_as_being_compared()
18818 /// this method unmarks it. Otherwise is has no effect.
18819 ///
18820 /// @param klass the instance of class_or_union to unmark.
18821 void
unmark_as_being_comparedabigail::ir::class_or_union::priv18822 unmark_as_being_compared(const class_or_union* klass) const
18823 {
18824 if (klass)
18825 return unmark_as_being_compared(*klass);
18826 }
18827
18828 /// Test if a given instance of class_or_union is being currently
18829 /// compared.
18830 ///
18831 ///@param klass the class or union to test.
18832 ///
18833 /// @return true if @p klass is being compared, false otherwise.
18834 bool
comparison_startedabigail::ir::class_or_union::priv18835 comparison_started(const class_or_union& klass) const
18836 {
18837 const environment* env = klass.get_environment();
18838 ABG_ASSERT(env);
18839 return env->priv_->classes_being_compared_.count(&klass);
18840 }
18841
18842 /// Test if a given instance of class_or_union is being currently
18843 /// compared.
18844 ///
18845 ///@param klass the class or union to test.
18846 ///
18847 /// @return true if @p klass is being compared, false otherwise.
18848 bool
comparison_startedabigail::ir::class_or_union::priv18849 comparison_started(const class_or_union* klass) const
18850 {
18851 if (klass)
18852 return comparison_started(*klass);
18853 return false;
18854 }
18855 }; // end struct class_or_union::priv
18856
18857 /// A Constructor for instances of @ref class_or_union
18858 ///
18859 /// @param env the environment we are operating from.
18860 ///
18861 /// @param name the identifier of the class.
18862 ///
18863 /// @param size_in_bits the size of an instance of @ref
18864 /// class_or_union, expressed in bits
18865 ///
18866 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
18867 /// expressed in bits.
18868 ///
18869 /// @param locus the source location of declaration point this class.
18870 ///
18871 /// @param vis the visibility of instances of @ref class_or_union.
18872 ///
18873 /// @param mem_types the vector of member types of this instance of
18874 /// @ref class_or_union.
18875 ///
18876 /// @param data_members the vector of data members of this instance of
18877 /// @ref class_or_union.
18878 ///
18879 /// @param member_fns the vector of member functions of this instance
18880 /// 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)18881 class_or_union::class_or_union(const environment* env, const string& name,
18882 size_t size_in_bits, size_t align_in_bits,
18883 const location& locus, visibility vis,
18884 member_types& mem_types,
18885 data_members& data_members,
18886 member_functions& member_fns)
18887 : type_or_decl_base(env,
18888 ABSTRACT_TYPE_BASE
18889 | ABSTRACT_DECL_BASE
18890 | ABSTRACT_SCOPE_TYPE_DECL
18891 | ABSTRACT_SCOPE_DECL),
18892 decl_base(env, name, locus, name, vis),
18893 type_base(env, size_in_bits, align_in_bits),
18894 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
18895 priv_(new priv(mem_types, data_members, member_fns))
18896 {
18897 for (member_types::iterator i = mem_types.begin();
18898 i != mem_types.end();
18899 ++i)
18900 if (!has_scope(get_type_declaration(*i)))
18901 add_decl_to_scope(get_type_declaration(*i), this);
18902
18903 for (data_members::iterator i = data_members.begin();
18904 i != data_members.end();
18905 ++i)
18906 if (!has_scope(*i))
18907 add_decl_to_scope(*i, this);
18908
18909 for (member_functions::iterator i = member_fns.begin();
18910 i != member_fns.end();
18911 ++i)
18912 if (!has_scope(static_pointer_cast<decl_base>(*i)))
18913 add_decl_to_scope(*i, this);
18914 }
18915
18916 /// A constructor for instances of @ref class_or_union.
18917 ///
18918 /// @param env the environment we are operating from.
18919 ///
18920 /// @param name the name of the class.
18921 ///
18922 /// @param size_in_bits the size of an instance of @ref
18923 /// class_or_union, expressed in bits
18924 ///
18925 /// @param align_in_bits the alignment of an instance of @ref class_or_union,
18926 /// expressed in bits.
18927 ///
18928 /// @param locus the source location of declaration point this class.
18929 ///
18930 /// @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)18931 class_or_union::class_or_union(const environment* env, const string& name,
18932 size_t size_in_bits, size_t align_in_bits,
18933 const location& locus, visibility vis)
18934 : type_or_decl_base(env,
18935 ABSTRACT_TYPE_BASE
18936 | ABSTRACT_DECL_BASE
18937 | ABSTRACT_SCOPE_TYPE_DECL
18938 | ABSTRACT_SCOPE_DECL),
18939 decl_base(env, name, locus, name, vis),
18940 type_base(env, size_in_bits, align_in_bits),
18941 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
18942 priv_(new priv)
18943 {}
18944
18945 /// Constructor of the @ref class_or_union type.
18946 ///
18947 /// @param env the @ref environment we are operating from.
18948 ///
18949 /// @param name the name of the @ref class_or_union.
18950 ///
18951 /// @param is_declaration_only a boolean saying whether the instance
18952 /// represents a declaration only, or not.
class_or_union(const environment * env,const string & name,bool is_declaration_only)18953 class_or_union::class_or_union(const environment* env, const string& name,
18954 bool is_declaration_only)
18955 : type_or_decl_base(env,
18956 ABSTRACT_TYPE_BASE
18957 | ABSTRACT_DECL_BASE
18958 | ABSTRACT_SCOPE_TYPE_DECL
18959 | ABSTRACT_SCOPE_DECL),
18960 decl_base(env, name, location(), name),
18961 type_base(env, 0, 0),
18962 scope_type_decl(env, name, 0, 0, location()),
18963 priv_(new priv)
18964 {
18965 set_is_declaration_only(is_declaration_only);
18966 }
18967
18968 /// This implements the ir_traversable_base::traverse pure virtual
18969 /// function.
18970 ///
18971 /// @param v the visitor used on the member nodes of the translation
18972 /// unit during the traversal.
18973 ///
18974 /// @return true if the entire IR node tree got traversed, false
18975 /// otherwise.
18976 bool
traverse(ir_node_visitor & v)18977 class_or_union::traverse(ir_node_visitor& v)
18978 {
18979 if (v.type_node_has_been_visited(this))
18980 return true;
18981
18982 if (visiting())
18983 return true;
18984
18985 if (v.visit_begin(this))
18986 {
18987 visiting(true);
18988 bool stop = false;
18989
18990 if (!stop)
18991 for (data_members::const_iterator i = get_data_members().begin();
18992 i != get_data_members().end();
18993 ++i)
18994 if (!(*i)->traverse(v))
18995 {
18996 stop = true;
18997 break;
18998 }
18999
19000 if (!stop)
19001 for (member_functions::const_iterator i= get_member_functions().begin();
19002 i != get_member_functions().end();
19003 ++i)
19004 if (!(*i)->traverse(v))
19005 {
19006 stop = true;
19007 break;
19008 }
19009
19010 if (!stop)
19011 for (member_types::const_iterator i = get_member_types().begin();
19012 i != get_member_types().end();
19013 ++i)
19014 if (!(*i)->traverse(v))
19015 {
19016 stop = true;
19017 break;
19018 }
19019
19020 if (!stop)
19021 for (member_function_templates::const_iterator i =
19022 get_member_function_templates().begin();
19023 i != get_member_function_templates().end();
19024 ++i)
19025 if (!(*i)->traverse(v))
19026 {
19027 stop = true;
19028 break;
19029 }
19030
19031 if (!stop)
19032 for (member_class_templates::const_iterator i =
19033 get_member_class_templates().begin();
19034 i != get_member_class_templates().end();
19035 ++i)
19036 if (!(*i)->traverse(v))
19037 {
19038 stop = true;
19039 break;
19040 }
19041 visiting(false);
19042 }
19043
19044 bool result = v.visit_end(this);
19045 v.mark_type_node_as_visited(this);
19046 return result;
19047 }
19048
19049 /// Destrcutor of the @ref class_or_union type.
~class_or_union()19050 class_or_union::~class_or_union()
19051 {delete priv_;}
19052
19053 /// Add a member declaration to the current instance of class_or_union.
19054 /// The member declaration can be either a member type, data member,
19055 /// member function, or member template.
19056 ///
19057 /// @param d the member declaration to add.
19058 decl_base_sptr
add_member_decl(const decl_base_sptr & d)19059 class_or_union::add_member_decl(const decl_base_sptr& d)
19060 {return insert_member_decl(d, get_member_decls().end());}
19061
19062 /// Remove a given decl from the current @ref class_or_union scope.
19063 ///
19064 /// Note that only type declarations are supported by this method for
19065 /// now. Support for the other kinds of declaration is left as an
19066 /// exercise for the interested reader of the code.
19067 ///
19068 /// @param decl the declaration to remove from this @ref
19069 /// class_or_union scope.
19070 void
remove_member_decl(decl_base_sptr decl)19071 class_or_union::remove_member_decl(decl_base_sptr decl)
19072 {
19073 type_base_sptr t = is_type(decl);
19074
19075 // For now we want to support just removing types from classes. For
19076 // other kinds of IR node, we need more work.
19077 ABG_ASSERT(t);
19078
19079 remove_member_type(t);
19080 }
19081
19082 /// Fixup the members of the type of an anonymous data member.
19083 ///
19084 /// Walk all data members of (the type of) a given anonymous data
19085 /// member and set a particular property of the relationship between
19086 /// each data member and its containing type.
19087 ///
19088 /// That property records the fact that the data member belongs to the
19089 /// anonymous data member we consider.
19090 ///
19091 /// In the future, if there are other properties of this relationship
19092 /// to set in this manner, they ought to be added here.
19093 ///
19094 /// @param anon_dm the anonymous data member to consider.
19095 void
maybe_fixup_members_of_anon_data_member(var_decl_sptr & anon_dm)19096 class_or_union::maybe_fixup_members_of_anon_data_member(var_decl_sptr& anon_dm)
19097 {
19098 class_or_union * anon_dm_type =
19099 anonymous_data_member_to_class_or_union(anon_dm.get());
19100 if (!anon_dm_type)
19101 return;
19102
19103 for (class_or_union::data_members::const_iterator it =
19104 anon_dm_type->get_non_static_data_members().begin();
19105 it != anon_dm_type->get_non_static_data_members().end();
19106 ++it)
19107 {
19108 dm_context_rel *rel =
19109 dynamic_cast<dm_context_rel*>((*it)->get_context_rel());
19110 ABG_ASSERT(rel);
19111 rel->set_anonymous_data_member(anon_dm.get());
19112 }
19113 }
19114
19115 /// Insert a member type.
19116 ///
19117 /// @param t the type to insert in the @ref class_or_union type.
19118 ///
19119 /// @param an iterator right before which @p t has to be inserted.
19120 void
insert_member_type(type_base_sptr t,declarations::iterator before)19121 class_or_union::insert_member_type(type_base_sptr t,
19122 declarations::iterator before)
19123 {
19124 decl_base_sptr d = get_type_declaration(t);
19125 ABG_ASSERT(d);
19126 ABG_ASSERT(!has_scope(d));
19127
19128 priv_->member_types_.push_back(t);
19129 scope_decl::insert_member_decl(d, before);
19130 }
19131
19132 /// Add a member type to the current instance of class_or_union.
19133 ///
19134 /// @param t the member type to add. It must not have been added to a
19135 /// scope, otherwise this will violate an ABG_ASSERTion.
19136 void
add_member_type(type_base_sptr t)19137 class_or_union::add_member_type(type_base_sptr t)
19138 {insert_member_type(t, get_member_decls().end());}
19139
19140 /// Add a member type to the current instance of class_or_union.
19141 ///
19142 /// @param t the type to be added as a member type to the current
19143 /// instance of class_or_union. An instance of class_or_union::member_type
19144 /// will be created out of @p t and and added to the the class.
19145 ///
19146 /// @param a the access specifier for the member type to be created.
19147 type_base_sptr
add_member_type(type_base_sptr t,access_specifier a)19148 class_or_union::add_member_type(type_base_sptr t, access_specifier a)
19149 {
19150 decl_base_sptr d = get_type_declaration(t);
19151 ABG_ASSERT(d);
19152 ABG_ASSERT(!is_member_decl(d));
19153 add_member_type(t);
19154 set_member_access_specifier(d, a);
19155 return t;
19156 }
19157
19158 /// Remove a member type from the current @ref class_or_union scope.
19159 ///
19160 /// @param t the type to remove.
19161 void
remove_member_type(type_base_sptr t)19162 class_or_union::remove_member_type(type_base_sptr t)
19163 {
19164 for (member_types::iterator i = priv_->member_types_.begin();
19165 i != priv_->member_types_.end();
19166 ++i)
19167 {
19168 if (*((*i)) == *t)
19169 {
19170 priv_->member_types_.erase(i);
19171 return;
19172 }
19173 }
19174 }
19175
19176 /// Getter of the alignment of the @ref class_or_union type.
19177 ///
19178 /// If this @ref class_or_union is a declaration of a definition that
19179 /// is elsewhere, then the size of the definition is returned.
19180 ///
19181 /// @return the alignment of the @ref class_or_union type.
19182 size_t
get_alignment_in_bits() const19183 class_or_union::get_alignment_in_bits() const
19184 {
19185 if (get_is_declaration_only() && get_definition_of_declaration())
19186 return is_class_or_union_type
19187 (get_definition_of_declaration())->get_alignment_in_bits();
19188
19189 return type_base::get_alignment_in_bits();
19190 }
19191
19192 /// Setter of the alignment of the class type.
19193 ///
19194 /// If this class is a declaration of a definition that is elsewhere,
19195 /// then the new alignment is set to the definition.
19196 ///
19197 /// @param s the new alignment.
19198 void
set_alignment_in_bits(size_t a)19199 class_or_union::set_alignment_in_bits(size_t a)
19200 {
19201 if (get_is_declaration_only() && get_definition_of_declaration())
19202 is_class_or_union_type
19203 (get_definition_of_declaration()) ->set_alignment_in_bits(a);
19204 else
19205 type_base::set_alignment_in_bits(a);
19206 }
19207
19208 /// Setter of the size of the @ref class_or_union type.
19209 ///
19210 /// If this @ref class_or_union is a declaration of a definition that
19211 /// is elsewhere, then the new size is set to the definition.
19212 ///
19213 /// @param s the new size.
19214 void
set_size_in_bits(size_t s)19215 class_or_union::set_size_in_bits(size_t s)
19216 {
19217 if (get_is_declaration_only() && get_definition_of_declaration())
19218 is_class_or_union_type
19219 (get_definition_of_declaration())->set_size_in_bits(s);
19220 else
19221 type_base::set_size_in_bits(s);
19222 }
19223
19224 /// Getter of the size of the @ref class_or_union type.
19225 ///
19226 /// If this @ref class_or_union is a declaration of a definition that
19227 /// is elsewhere, then the size of the definition is returned.
19228 ///
19229 /// @return the size of the @ref class_or_union type.
19230 size_t
get_size_in_bits() const19231 class_or_union::get_size_in_bits() const
19232 {
19233 if (get_is_declaration_only() && get_definition_of_declaration())
19234 return is_class_or_union_type
19235 (get_definition_of_declaration())->get_size_in_bits();
19236
19237 return type_base::get_size_in_bits();
19238 }
19239
19240
19241 /// Getter for the naming typedef of the current class.
19242 ///
19243 /// Consider the C idiom:
19244 ///
19245 /// typedef struct {int member;} foo_type;
19246 ///
19247 /// In that idiom, foo_type is the naming typedef of the anonymous
19248 /// struct that is declared.
19249 ///
19250 /// @return the naming typedef, if any. Otherwise, returns nil.
19251 typedef_decl_sptr
get_naming_typedef() const19252 class_or_union::get_naming_typedef() const
19253 {return priv_->naming_typedef_.lock();}
19254
19255 /// Set the naming typedef of the current instance of @ref class_decl.
19256 ///
19257 /// Consider the C idiom:
19258 ///
19259 /// typedef struct {int member;} foo_type;
19260 ///
19261 /// In that idiom, foo_type is the naming typedef of the anonymous
19262 /// struct that is declared.
19263 ///
19264 /// @param typedef_type the new naming typedef.
19265 void
set_naming_typedef(const typedef_decl_sptr & typedef_type)19266 class_or_union::set_naming_typedef(const typedef_decl_sptr& typedef_type)
19267 {
19268 priv_->naming_typedef_ = typedef_type;
19269 }
19270
19271 /// Get the member types of this @ref class_or_union.
19272 ///
19273 /// @return a vector of the member types of this ref class_or_union.
19274 const class_or_union::member_types&
get_member_types() const19275 class_or_union::get_member_types() const
19276 {return priv_->member_types_;}
19277
19278 /// Get the number of anonymous member classes contained in this
19279 /// class.
19280 ///
19281 /// @return the number of anonymous member classes contained in this
19282 /// class.
19283 size_t
get_num_anonymous_member_classes() const19284 class_or_union::get_num_anonymous_member_classes() const
19285 {
19286 int result = 0;
19287 for (member_types::const_iterator it = get_member_types().begin();
19288 it != get_member_types().end();
19289 ++it)
19290 if (class_decl_sptr t = is_class_type(*it))
19291 if (t->get_is_anonymous())
19292 ++result;
19293
19294 return result;
19295 }
19296
19297 /// Get the number of anonymous member unions contained in this class.
19298 ///
19299 /// @return the number of anonymous member unions contained in this
19300 /// class.
19301 size_t
get_num_anonymous_member_unions() const19302 class_or_union::get_num_anonymous_member_unions() const
19303 {
19304 int result = 0;
19305 for (member_types::const_iterator it = get_member_types().begin();
19306 it != get_member_types().end();
19307 ++it)
19308 if (union_decl_sptr t = is_union_type(*it))
19309 if (t->get_is_anonymous())
19310 ++result;
19311
19312 return result;
19313 }
19314
19315 /// Get the number of anonymous member enums contained in this class.
19316 ///
19317 /// @return the number of anonymous member enums contained in this
19318 /// class.
19319 size_t
get_num_anonymous_member_enums() const19320 class_or_union::get_num_anonymous_member_enums() const
19321 {
19322 int result = 0;
19323 for (member_types::const_iterator it = get_member_types().begin();
19324 it != get_member_types().end();
19325 ++it)
19326 if (enum_type_decl_sptr t = is_enum_type(*it))
19327 if (t->get_is_anonymous())
19328 ++result;
19329
19330 return result;
19331 }
19332
19333 /// Find a member type of a given name, inside the current @ref
19334 /// class_or_union.
19335 ///
19336 /// @param name the name of the member type to look for.
19337 ///
19338 /// @return a pointer to the @ref type_base that represents the member
19339 /// type of name @p name, for the current class.
19340 type_base_sptr
find_member_type(const string & name) const19341 class_or_union::find_member_type(const string& name) const
19342 {
19343 for (member_types::const_iterator i = get_member_types().begin();
19344 i != get_member_types().end();
19345 ++i)
19346 if (get_type_name(*i, /*qualified*/false) == name)
19347 return *i;
19348 return type_base_sptr();
19349 }
19350
19351 /// Add a data member to the current instance of class_or_union.
19352 ///
19353 /// @param v a var_decl to add as a data member. A proper
19354 /// class_or_union::data_member is created from @p v and added to the
19355 /// class_or_union. This var_decl should not have been already added
19356 /// to a scope.
19357 ///
19358 /// @param access the access specifier for the data member.
19359 ///
19360 /// @param is_laid_out whether the data member was laid out. That is,
19361 /// if its offset has been computed. In the pattern of a class
19362 /// template for instance, this would be set to false.
19363 ///
19364 /// @param is_static whether the data memer is static.
19365 ///
19366 /// @param offset_in_bits if @p is_laid_out is true, this is the
19367 /// offset of the data member, expressed (oh, surprise) in bits.
19368 void
add_data_member(var_decl_sptr v,access_specifier access,bool is_laid_out,bool is_static,size_t offset_in_bits)19369 class_or_union::add_data_member(var_decl_sptr v, access_specifier access,
19370 bool is_laid_out, bool is_static,
19371 size_t offset_in_bits)
19372 {
19373 ABG_ASSERT(!has_scope(v));
19374
19375 priv_->data_members_.push_back(v);
19376 scope_decl::add_member_decl(v);
19377 set_data_member_is_laid_out(v, is_laid_out);
19378 set_data_member_offset(v, offset_in_bits);
19379 set_member_access_specifier(v, access);
19380 set_member_is_static(v, is_static);
19381
19382 if (!is_static)
19383 {
19384 // If this is a non-static variable, add it to the set of
19385 // non-static variables, if it's not only in there.
19386 bool is_already_in = false;
19387 for (data_members::const_iterator i =
19388 priv_->non_static_data_members_.begin();
19389 i != priv_->non_static_data_members_.end();
19390 ++i)
19391 if (*i == v)
19392 {
19393 is_already_in = true;
19394 break;
19395 }
19396 if (!is_already_in)
19397 priv_->non_static_data_members_.push_back(v);
19398 }
19399
19400 // If v is an anonymous data member, then fixup its data members.
19401 // For now, the only thing the fixup does is to make the data
19402 // members of the anonymous data member be aware of their containing
19403 // anonymous data member. That is helpful to compute the absolute
19404 // bit offset of each of the members of the anonymous data member.
19405 maybe_fixup_members_of_anon_data_member(v);
19406 }
19407
19408 /// Get the data members of this @ref class_or_union.
19409 ///
19410 /// @return a vector of the data members of this @ref class_or_union.
19411 const class_or_union::data_members&
get_data_members() const19412 class_or_union::get_data_members() const
19413 {return priv_->data_members_;}
19414
19415 /// Find a data member of a given name in the current @ref class_or_union.
19416 ///
19417 /// @param name the name of the data member to find in the current
19418 /// @ref class_or_union.
19419 ///
19420 /// @return a pointer to the @ref var_decl that represents the data
19421 /// member to find inside the current @ref class_or_union.
19422 const var_decl_sptr
find_data_member(const string & name) const19423 class_or_union::find_data_member(const string& name) const
19424 {
19425 for (data_members::const_iterator i = get_data_members().begin();
19426 i != get_data_members().end();
19427 ++i)
19428 if ((*i)->get_name() == name)
19429 return *i;
19430
19431 // We haven't found a data member with the name 'name'. Let's look
19432 // closer again, this time in our anonymous data members.
19433 for (data_members::const_iterator i = get_data_members().begin();
19434 i != get_data_members().end();
19435 ++i)
19436 if (is_anonymous_data_member(*i))
19437 {
19438 class_or_union_sptr type = is_class_or_union_type((*i)->get_type());
19439 ABG_ASSERT(type);
19440 if (var_decl_sptr data_member = type->find_data_member(name))
19441 return data_member;
19442 }
19443
19444 return var_decl_sptr();
19445 }
19446
19447 /// Find an anonymous data member in the class.
19448 ///
19449 /// @param v the anonymous data member to find.
19450 ///
19451 /// @return the anonymous data member found, or nil if none was found.
19452 const var_decl_sptr
find_anonymous_data_member(const var_decl_sptr & v) const19453 class_or_union::find_anonymous_data_member(const var_decl_sptr& v) const
19454 {
19455 if (!v->get_name().empty())
19456 return var_decl_sptr();
19457
19458 for (data_members::const_iterator it = get_non_static_data_members().begin();
19459 it != get_non_static_data_members().end();
19460 ++it)
19461 {
19462 if (is_anonymous_data_member(*it))
19463 if ((*it)->get_pretty_representation(true, true)
19464 == v->get_pretty_representation(true, true))
19465 return *it;
19466 }
19467
19468 return var_decl_sptr();
19469 }
19470
19471 /// Find a given data member.
19472 ///
19473 /// This function takes a @ref var_decl as an argument. If it has a
19474 /// non-empty name, then it tries to find a data member which has the
19475 /// same name as the argument.
19476 ///
19477 /// If it has an empty name, then the @ref var_decl is considered as
19478 /// an anonymous data member. In that case, this function tries to
19479 /// find an anonymous data member which type equals that of the @ref
19480 /// var_decl argument.
19481 ///
19482 /// @param v this carries either the name of the data member we need
19483 /// to look for, or the type of the anonymous data member we are
19484 /// looking for.
19485 const var_decl_sptr
find_data_member(const var_decl_sptr & v) const19486 class_or_union::find_data_member(const var_decl_sptr& v) const
19487 {
19488 if (!v)
19489 return var_decl_sptr();
19490
19491 if (v->get_name().empty())
19492 return find_anonymous_data_member(v);
19493
19494 return find_data_member(v->get_name());
19495 }
19496
19497
19498 /// Get the non-static data memebers of this @ref class_or_union.
19499 ///
19500 /// @return a vector of the non-static data members of this @ref
19501 /// class_or_union.
19502 const class_or_union::data_members&
get_non_static_data_members() const19503 class_or_union::get_non_static_data_members() const
19504 {return priv_->non_static_data_members_;}
19505
19506 /// Add a member function.
19507 ///
19508 /// @param f the new member function to add.
19509 ///
19510 /// @param a the access specifier to use for the new member function.
19511 ///
19512 /// @param is_static whether the new member function is static.
19513 ///
19514 /// @param is_ctor whether the new member function is a constructor.
19515 ///
19516 /// @param is_dtor whether the new member function is a destructor.
19517 ///
19518 /// @param is_const whether the new member function is const.
19519 void
add_member_function(method_decl_sptr f,access_specifier a,bool is_static,bool is_ctor,bool is_dtor,bool is_const)19520 class_or_union::add_member_function(method_decl_sptr f,
19521 access_specifier a,
19522 bool is_static, bool is_ctor,
19523 bool is_dtor, bool is_const)
19524 {
19525 ABG_ASSERT(!has_scope(f));
19526
19527 scope_decl::add_member_decl(f);
19528
19529 set_member_function_is_ctor(f, is_ctor);
19530 set_member_function_is_dtor(f, is_dtor);
19531 set_member_access_specifier(f, a);
19532 set_member_is_static(f, is_static);
19533 set_member_function_is_const(f, is_const);
19534
19535 priv_->member_functions_.push_back(f);
19536
19537 // Update the map of linkage name -> member functions. It's useful,
19538 // so that class_or_union::find_member_function() can function.
19539 if (!f->get_linkage_name().empty())
19540 priv_->mem_fns_map_[f->get_linkage_name()] = f;
19541 }
19542
19543 /// Get the member functions of this @ref class_or_union.
19544 ///
19545 /// @return a vector of the member functions of this @ref
19546 /// class_or_union.
19547 const class_or_union::member_functions&
get_member_functions() const19548 class_or_union::get_member_functions() const
19549 {return priv_->member_functions_;}
19550
19551 /// Find a method, using its linkage name as a key.
19552 ///
19553 /// @param linkage_name the linkage name of the method to find.
19554 ///
19555 /// @return the method found, or nil if none was found.
19556 const method_decl*
find_member_function(const string & linkage_name) const19557 class_or_union::find_member_function(const string& linkage_name) const
19558 {
19559 return const_cast<class_or_union*>(this)->find_member_function(linkage_name);
19560 }
19561
19562 /// Find a method, using its linkage name as a key.
19563 ///
19564 /// @param linkage_name the linkage name of the method to find.
19565 ///
19566 /// @return the method found, or nil if none was found.
19567 method_decl*
find_member_function(const string & linkage_name)19568 class_or_union::find_member_function(const string& linkage_name)
19569 {
19570 string_mem_fn_sptr_map_type::const_iterator i =
19571 priv_->mem_fns_map_.find(linkage_name);
19572 if (i == priv_->mem_fns_map_.end())
19573 return 0;
19574 return i->second.get();
19575 }
19576
19577 /// Find a method, using its linkage name as a key.
19578 ///
19579 /// @param linkage_name the linkage name of the method to find.
19580 ///
19581 /// @return the method found, or nil if none was found.
19582 method_decl_sptr
find_member_function_sptr(const string & linkage_name)19583 class_or_union::find_member_function_sptr(const string& linkage_name)
19584 {
19585 string_mem_fn_sptr_map_type::const_iterator i =
19586 priv_->mem_fns_map_.find(linkage_name);
19587 if (i == priv_->mem_fns_map_.end())
19588 return 0;
19589 return i->second;
19590 }
19591
19592 /// Find a method (member function) using its signature (pretty
19593 /// representation) as a key.
19594 ///
19595 /// @param s the signature of the method.
19596 ///
19597 /// @return the method found, or nil if none was found.
19598 const method_decl*
find_member_function_from_signature(const string & s) const19599 class_or_union::find_member_function_from_signature(const string& s) const
19600 {
19601 return const_cast<class_or_union*>(this)->find_member_function_from_signature(s);
19602 }
19603
19604 /// Find a method (member function) using its signature (pretty
19605 /// representation) as a key.
19606 ///
19607 /// @param s the signature of the method.
19608 ///
19609 /// @return the method found, or nil if none was found.
19610 method_decl*
find_member_function_from_signature(const string & s)19611 class_or_union::find_member_function_from_signature(const string& s)
19612 {
19613 string_mem_fn_ptr_map_type::const_iterator i =
19614 priv_->signature_2_mem_fn_map_.find(s);
19615 if (i == priv_->signature_2_mem_fn_map_.end())
19616 return 0;
19617 return i->second;
19618 }
19619
19620 /// Get the member function templates of this class.
19621 ///
19622 /// @return a vector of the member function templates of this class.
19623 const member_function_templates&
get_member_function_templates() const19624 class_or_union::get_member_function_templates() const
19625 {return priv_->member_function_templates_;}
19626
19627 /// Get the member class templates of this class.
19628 ///
19629 /// @return a vector of the member class templates of this class.
19630 const member_class_templates&
get_member_class_templates() const19631 class_or_union::get_member_class_templates() const
19632 {return priv_->member_class_templates_;}
19633
19634 /// Append a member function template to the @ref class_or_union.
19635 ///
19636 /// @param m the member function template to append.
19637 void
add_member_function_template(member_function_template_sptr m)19638 class_or_union::add_member_function_template(member_function_template_sptr m)
19639 {
19640 decl_base* c = m->as_function_tdecl()->get_scope();
19641 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
19642 /// error message or something like a structured error.
19643 priv_->member_function_templates_.push_back(m);
19644 if (!c)
19645 scope_decl::add_member_decl(m->as_function_tdecl());
19646 }
19647
19648 /// Append a member class template to the @ref class_or_union.
19649 ///
19650 /// @param m the member function template to append.
19651 void
add_member_class_template(member_class_template_sptr m)19652 class_or_union::add_member_class_template(member_class_template_sptr m)
19653 {
19654 decl_base* c = m->as_class_tdecl()->get_scope();
19655 /// TODO: use our own ABG_ASSERTion facility that adds a meaningful
19656 /// error message or something like a structured error.
19657 m->set_scope(this);
19658 priv_->member_class_templates_.push_back(m);
19659 if (!c)
19660 scope_decl::add_member_decl(m->as_class_tdecl());
19661 }
19662
19663 ///@return true iff the current instance has no member.
19664 bool
has_no_member() const19665 class_or_union::has_no_member() const
19666 {
19667 return (priv_->member_types_.empty()
19668 && priv_->data_members_.empty()
19669 && priv_->member_functions_.empty()
19670 && priv_->member_function_templates_.empty()
19671 && priv_->member_class_templates_.empty());
19672 }
19673
19674 /// Insert a data member to this @ref class_or_union type.
19675 ///
19676 /// @param d the data member to insert.
19677 ///
19678 /// @param before an iterator to the point before which to insert the
19679 /// the data member, in the coontainer that contains all the data
19680 /// members.
19681 decl_base_sptr
insert_member_decl(decl_base_sptr d,declarations::iterator before)19682 class_or_union::insert_member_decl(decl_base_sptr d,
19683 declarations::iterator before)
19684 {
19685 if (type_base_sptr t = dynamic_pointer_cast<type_base>(d))
19686 insert_member_type(t, before);
19687 else if (var_decl_sptr v = dynamic_pointer_cast<var_decl>(d))
19688 {
19689 add_data_member(v, public_access,
19690 /*is_laid_out=*/false,
19691 /*is_static=*/true,
19692 /*offset_in_bits=*/0);
19693 d = v;
19694 }
19695 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
19696 add_member_function(f, public_access,
19697 /*is_static=*/false,
19698 /*is_ctor=*/false,
19699 /*is_dtor=*/false,
19700 /*is_const=*/false);
19701 else if (member_function_template_sptr f =
19702 dynamic_pointer_cast<member_function_template>(d))
19703 add_member_function_template(f);
19704 else if (member_class_template_sptr c =
19705 dynamic_pointer_cast<member_class_template>(d))
19706 add_member_class_template(c);
19707 else
19708 scope_decl::add_member_decl(d);
19709
19710 return d;
19711 }
19712
19713 /// Equality operator.
19714 ///
19715 /// @param other the other @ref class_or_union to compare against.
19716 ///
19717 /// @return true iff @p other equals the current @ref class_or_union.
19718 bool
operator ==(const decl_base & other) const19719 class_or_union::operator==(const decl_base& other) const
19720 {
19721 const class_or_union* op = dynamic_cast<const class_or_union*>(&other);
19722 if (!op)
19723 return false;
19724
19725 // If this is a decl-only type (and thus with no canonical type),
19726 // use the canonical type of the definition, if any.
19727 const class_or_union *l = 0;
19728 if (get_is_declaration_only())
19729 l = dynamic_cast<const class_or_union*>(get_naked_definition_of_declaration());
19730 if (l == 0)
19731 l = this;
19732
19733 // Likewise for the other class.
19734 const class_or_union *r = 0;
19735 if (op->get_is_declaration_only())
19736 r = dynamic_cast<const class_or_union*>(op->get_naked_definition_of_declaration());
19737 if (r == 0)
19738 r = op;
19739
19740 return try_canonical_compare(l, r);
19741 }
19742
19743 /// Equality operator.
19744 ///
19745 /// @param other the other @ref class_or_union to compare against.
19746 ///
19747 /// @return true iff @p other equals the current @ref class_or_union.
19748 bool
operator ==(const type_base & other) const19749 class_or_union::operator==(const type_base& other) const
19750 {
19751 const decl_base* o = dynamic_cast<const decl_base*>(&other);
19752 if (!o)
19753 return false;
19754 return *this == *o;
19755 }
19756
19757 /// Equality operator.
19758 ///
19759 /// @param other the other @ref class_or_union to compare against.
19760 ///
19761 /// @return true iff @p other equals the current @ref class_or_union.
19762 bool
operator ==(const class_or_union & other) const19763 class_or_union::operator==(const class_or_union& other) const
19764 {
19765 const decl_base& o = other;
19766 return class_or_union::operator==(o);
19767 }
19768
19769 /// Compares two instances of @ref class_or_union.
19770 ///
19771 /// If the two intances are different, set a bitfield to give some
19772 /// insight about the kind of differences there are.
19773 ///
19774 /// @param l the first artifact of the comparison.
19775 ///
19776 /// @param r the second artifact of the comparison.
19777 ///
19778 /// @param k a pointer to a bitfield that gives information about the
19779 /// kind of changes there are between @p l and @p r. This one is set
19780 /// iff it's non-null and if the function returns false.
19781 ///
19782 /// Please note that setting k to a non-null value does have a
19783 /// negative performance impact because even if @p l and @p r are not
19784 /// equal, the function keeps up the comparison in order to determine
19785 /// the different kinds of ways in which they are different.
19786 ///
19787 /// @return true if @p l equals @p r, false otherwise.
19788 bool
equals(const class_or_union & l,const class_or_union & r,change_kind * k)19789 equals(const class_or_union& l, const class_or_union& r, change_kind* k)
19790 {
19791 #define RETURN(value) \
19792 do { \
19793 l.priv_->unmark_as_being_compared(l); \
19794 l.priv_->unmark_as_being_compared(r); \
19795 return value; \
19796 } while(0)
19797
19798 // if one of the classes is declaration-only, look through it to
19799 // get its definition.
19800 bool l_is_decl_only = l.get_is_declaration_only();
19801 bool r_is_decl_only = r.get_is_declaration_only();
19802 if (l_is_decl_only || r_is_decl_only)
19803 {
19804 const class_or_union* def1 = l_is_decl_only
19805 ? is_class_or_union_type(l.get_naked_definition_of_declaration())
19806 : &l;
19807
19808 const class_or_union* def2 = r_is_decl_only
19809 ? is_class_or_union_type(r.get_naked_definition_of_declaration())
19810 : &r;
19811
19812 if (!def1 || !def2)
19813 {
19814 if (!l.get_is_anonymous()
19815 && !r.get_is_anonymous()
19816 && l_is_decl_only && r_is_decl_only
19817 && comparison::filtering::is_decl_only_class_with_size_change(l, r))
19818 // The two decl-only classes differ from their size. A
19819 // true decl-only class should not have a size property to
19820 // begin with. This comes from a DWARF oddity and can
19821 // results in a false positive, so let's not consider that
19822 // change.
19823 return true;
19824
19825 if (l.get_environment()->decl_only_class_equals_definition()
19826 && !l.get_is_anonymous()
19827 && !r.get_is_anonymous())
19828 {
19829 const interned_string& q1 = l.get_scoped_name();
19830 const interned_string& q2 = r.get_scoped_name();
19831 if (q1 == q2)
19832 // Not using RETURN(true) here, because that causes
19833 // performance issues. We don't need to do
19834 // l.priv_->unmark_as_being_compared({l,r}) here because
19835 // we haven't marked l or r as being compared yet, and
19836 // doing so has a peformance cost that shows up on
19837 // performance profiles for *big* libraries.
19838 return true;
19839 else
19840 {
19841 if (k)
19842 *k |= LOCAL_TYPE_CHANGE_KIND;
19843 // Not using RETURN(true) here, because that causes
19844 // performance issues. We don't need to do
19845 // l.priv_->unmark_as_being_compared({l,r}) here because
19846 // we haven't marked l or r as being compared yet, and
19847 // doing so has a peformance cost that shows up on
19848 // performance profiles for *big* libraries.
19849 return false;
19850 }
19851 }
19852 else // A decl-only class is considered different from a
19853 // class definition of the same name.
19854 {
19855 if (!!def1 != !!def2)
19856 {
19857 if (k)
19858 *k |= LOCAL_TYPE_CHANGE_KIND;
19859 return false;
19860 }
19861
19862 // both definitions are empty
19863 if (!(l.decl_base::operator==(r)
19864 && l.type_base::operator==(r)))
19865 {
19866 if (k)
19867 *k |= LOCAL_TYPE_CHANGE_KIND;
19868 return false;
19869 }
19870
19871 return true;
19872 }
19873 }
19874
19875 if (l.priv_->comparison_started(l)
19876 || l.priv_->comparison_started(r))
19877 return true;
19878
19879 l.priv_->mark_as_being_compared(l);
19880 l.priv_->mark_as_being_compared(r);
19881
19882 bool val = *def1 == *def2;
19883 if (!val)
19884 if (k)
19885 *k |= LOCAL_TYPE_CHANGE_KIND;
19886 RETURN(val);
19887 }
19888
19889 // No need to go further if the classes have different names or
19890 // different size / alignment.
19891 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
19892 {
19893 if (k)
19894 *k |= LOCAL_TYPE_CHANGE_KIND;
19895 return false;
19896 }
19897
19898 if (types_defined_same_linux_kernel_corpus_public(l, r))
19899 return true;
19900
19901 if (l.priv_->comparison_started(l)
19902 || l.priv_->comparison_started(r))
19903 return true;
19904
19905 l.priv_->mark_as_being_compared(l);
19906 l.priv_->mark_as_being_compared(r);
19907
19908 bool result = true;
19909
19910 //compare data_members
19911 {
19912 if (l.get_non_static_data_members().size()
19913 != r.get_non_static_data_members().size())
19914 {
19915 result = false;
19916 if (k)
19917 *k |= LOCAL_TYPE_CHANGE_KIND;
19918 else
19919 RETURN(result);
19920 }
19921
19922 for (class_or_union::data_members::const_iterator
19923 d0 = l.get_non_static_data_members().begin(),
19924 d1 = r.get_non_static_data_members().begin();
19925 (d0 != l.get_non_static_data_members().end()
19926 && d1 != r.get_non_static_data_members().end());
19927 ++d0, ++d1)
19928 if (**d0 != **d1)
19929 {
19930 result = false;
19931 if (k)
19932 {
19933 // Report any representation change as being local.
19934 if (!types_have_similar_structure((*d0)->get_type(),
19935 (*d1)->get_type())
19936 || (*d0)->get_type() == (*d1)->get_type())
19937 *k |= LOCAL_TYPE_CHANGE_KIND;
19938 else
19939 *k |= SUBTYPE_CHANGE_KIND;
19940 }
19941 else
19942 RETURN(result);
19943 }
19944 }
19945
19946 // Do not compare member functions. DWARF does not necessarily
19947 // all the member functions, be they virtual or not, in all
19948 // translation units. So we cannot have a clear view of them, per
19949 // class
19950
19951 // compare member function templates
19952 {
19953 if (l.get_member_function_templates().size()
19954 != r.get_member_function_templates().size())
19955 {
19956 result = false;
19957 if (k)
19958 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19959 else
19960 RETURN(result);
19961 }
19962
19963 for (member_function_templates::const_iterator
19964 fn_tmpl_it0 = l.get_member_function_templates().begin(),
19965 fn_tmpl_it1 = r.get_member_function_templates().begin();
19966 fn_tmpl_it0 != l.get_member_function_templates().end()
19967 && fn_tmpl_it1 != r.get_member_function_templates().end();
19968 ++fn_tmpl_it0, ++fn_tmpl_it1)
19969 if (**fn_tmpl_it0 != **fn_tmpl_it1)
19970 {
19971 result = false;
19972 if (k)
19973 {
19974 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19975 break;
19976 }
19977 else
19978 RETURN(result);
19979 }
19980 }
19981
19982 // compare member class templates
19983 {
19984 if (l.get_member_class_templates().size()
19985 != r.get_member_class_templates().size())
19986 {
19987 result = false;
19988 if (k)
19989 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
19990 else
19991 RETURN(result);
19992 }
19993
19994 for (member_class_templates::const_iterator
19995 cl_tmpl_it0 = l.get_member_class_templates().begin(),
19996 cl_tmpl_it1 = r.get_member_class_templates().begin();
19997 cl_tmpl_it0 != l.get_member_class_templates().end()
19998 && cl_tmpl_it1 != r.get_member_class_templates().end();
19999 ++cl_tmpl_it0, ++cl_tmpl_it1)
20000 if (**cl_tmpl_it0 != **cl_tmpl_it1)
20001 {
20002 result = false;
20003 if (k)
20004 {
20005 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
20006 break;
20007 }
20008 else
20009 RETURN(result);
20010 }
20011 }
20012
20013 RETURN(result);
20014 #undef RETURN
20015 }
20016
20017
20018 /// Copy a method of a @ref class_or_union into a new @ref
20019 /// class_or_union.
20020 ///
20021 /// @param t the @ref class_or_union into which the method is to be copied.
20022 ///
20023 /// @param method the method to copy into @p t.
20024 ///
20025 /// @return the resulting newly copied method.
20026 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl_sptr & method)20027 copy_member_function(const class_or_union_sptr& t,
20028 const method_decl_sptr& method)
20029 {return copy_member_function(t, method.get());}
20030
20031
20032 /// Copy a method of a @ref class_or_union into a new @ref
20033 /// class_or_union.
20034 ///
20035 /// @param t the @ref class_or_union into which the method is to be copied.
20036 ///
20037 /// @param method the method to copy into @p t.
20038 ///
20039 /// @return the resulting newly copied method.
20040 method_decl_sptr
copy_member_function(const class_or_union_sptr & t,const method_decl * method)20041 copy_member_function(const class_or_union_sptr& t, const method_decl* method)
20042 {
20043 ABG_ASSERT(t);
20044 ABG_ASSERT(method);
20045
20046 method_type_sptr old_type = method->get_type();
20047 ABG_ASSERT(old_type);
20048 method_type_sptr new_type(new method_type(old_type->get_return_type(),
20049 t,
20050 old_type->get_parameters(),
20051 old_type->get_is_const(),
20052 old_type->get_size_in_bits(),
20053 old_type->get_alignment_in_bits()));
20054 new_type->set_environment(t->get_environment());
20055 keep_type_alive(new_type);
20056
20057 method_decl_sptr
20058 new_method(new method_decl(method->get_name(),
20059 new_type,
20060 method->is_declared_inline(),
20061 method->get_location(),
20062 method->get_linkage_name(),
20063 method->get_visibility(),
20064 method->get_binding()));
20065 new_method->set_symbol(method->get_symbol());
20066
20067 if (class_decl_sptr class_type = is_class_type(t))
20068 class_type->add_member_function(new_method,
20069 get_member_access_specifier(*method),
20070 get_member_function_is_virtual(*method),
20071 get_member_function_vtable_offset(*method),
20072 get_member_is_static(*method),
20073 get_member_function_is_ctor(*method),
20074 get_member_function_is_dtor(*method),
20075 get_member_function_is_const(*method));
20076 else
20077 t->add_member_function(new_method,
20078 get_member_access_specifier(*method),
20079 get_member_is_static(*method),
20080 get_member_function_is_ctor(*method),
20081 get_member_function_is_dtor(*method),
20082 get_member_function_is_const(*method));
20083 return new_method;
20084 }
20085
20086 // </class_or_union definitions>
20087
20088 /// Test if two @ref class_decl or @ref function_type are already
20089 /// being compared.
20090 ///
20091 /// @param lhs_type the first type that would be involved in a
20092 /// potential comparison.
20093 ///
20094 /// @param rhs_type the second type that would involved in a potential
20095 /// comparison.
20096 ///
20097 /// @return true iff @p lhs_type and @p rhs_type are being compared.
20098 static bool
types_are_being_compared(const type_base & lhs_type,const type_base & rhs_type)20099 types_are_being_compared(const type_base& lhs_type,
20100 const type_base& rhs_type)
20101 {
20102 type_base *l = &const_cast<type_base&>(lhs_type);
20103 type_base *r = &const_cast<type_base&>(rhs_type);
20104
20105 if (class_or_union *l_cou = is_class_or_union_type(l))
20106 if (class_or_union *r_cou = is_class_or_union_type(r))
20107 return (l_cou->priv_->comparison_started(*l_cou)
20108 || l_cou->priv_->comparison_started(*r_cou));
20109
20110 if (function_type *l_fn_type = is_function_type(l))
20111 if (function_type *r_fn_type = is_function_type(r))
20112 return (l_fn_type->priv_->comparison_started(*l_fn_type)
20113 || l_fn_type->priv_->comparison_started(*r_fn_type));
20114
20115 return false;
20116 }
20117
20118 /// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
20119 /// @{
20120 ///
20121 /// During the canonicalization of a type T (which doesn't yet have a
20122 /// canonical type), T is compared structurally (member-wise) against
20123 /// a type C which already has a canonical type. The comparison
20124 /// expression is C == T.
20125 ///
20126 /// During that structural comparison, if a subtype of C (which also
20127 /// already has a canonical type) is structurally compared to a
20128 /// subtype of T (which doesn't yet have a canonical type) and if they
20129 /// are equal, then we can deduce that the canonical type of the
20130 /// subtype of C is the canonical type of the subtype of C.
20131 ///
20132 /// Thus, we can canonicalize the sub-type of the T, during the
20133 /// canonicalization of T itself. That canonicalization of the
20134 /// sub-type of T is what we call the "on-the-fly canonicalization".
20135 /// It's on the fly because it happens during a comparison -- which
20136 /// itself happens during the canonicalization of T.
20137 ///
20138 /// For now this on-the-fly canonicalization only happens when
20139 /// comparing @ref class_decl and @ref function_type.
20140 ///
20141 /// @}
20142
20143
20144 /// If on-the-fly canonicalization is turned on, then this function
20145 /// sets the canonical type of its second parameter to the canonical
20146 /// type of the first parameter.
20147 ///
20148 /// @param lhs_type the type which canonical type to propagate.
20149 ///
20150 /// @param rhs_type the type which canonical type to set.
20151 static void
maybe_propagate_canonical_type(const type_base & lhs_type,const type_base & rhs_type)20152 maybe_propagate_canonical_type(const type_base& lhs_type,
20153 const type_base& rhs_type)
20154 {
20155
20156 if (const environment *env = lhs_type.get_environment())
20157 if (env->do_on_the_fly_canonicalization())
20158 if (type_base_sptr canonical_type = lhs_type.get_canonical_type())
20159 if (!rhs_type.get_canonical_type()
20160 && !types_are_being_compared(lhs_type, rhs_type))
20161 {
20162 const_cast<type_base&>(rhs_type).priv_->canonical_type =
20163 canonical_type;
20164 const_cast<type_base&>(rhs_type).priv_->naked_canonical_type =
20165 canonical_type.get();
20166 }
20167 }
20168
20169 // <class_decl definitions>
20170
20171 static void
20172 sort_virtual_member_functions(class_decl::member_functions& mem_fns);
20173
20174 /// The private data for the class_decl type.
20175 struct class_decl::priv
20176 {
20177 base_specs bases_;
20178 unordered_map<string, base_spec_sptr> bases_map_;
20179 member_functions virtual_mem_fns_;
20180 virtual_mem_fn_map_type virtual_mem_fns_map_;
20181 bool is_struct_;
20182
privabigail::ir::class_decl::priv20183 priv()
20184 : is_struct_(false)
20185 {}
20186
privabigail::ir::class_decl::priv20187 priv(bool is_struct, class_decl::base_specs& bases)
20188 : bases_(bases),
20189 is_struct_(is_struct)
20190 {
20191 }
20192
privabigail::ir::class_decl::priv20193 priv(bool is_struct)
20194 : is_struct_(is_struct)
20195 {}
20196 };// end struct class_decl::priv
20197
20198 /// A Constructor for instances of \ref class_decl
20199 ///
20200 /// @param env the environment we are operating from.
20201 ///
20202 /// @param name the identifier of the class.
20203 ///
20204 /// @param size_in_bits the size of an instance of class_decl, expressed
20205 /// in bits
20206 ///
20207 /// @param align_in_bits the alignment of an instance of class_decl,
20208 /// expressed in bits.
20209 ///
20210 /// @param locus the source location of declaration point this class.
20211 ///
20212 /// @param vis the visibility of instances of class_decl.
20213 ///
20214 /// @param bases the vector of base classes for this instance of class_decl.
20215 ///
20216 /// @param mbrs the vector of member types of this instance of
20217 /// class_decl.
20218 ///
20219 /// @param data_mbrs the vector of data members of this instance of
20220 /// class_decl.
20221 ///
20222 /// @param mbr_fns the vector of member functions of this instance of
20223 /// 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)20224 class_decl::class_decl(const environment* env, const string& name,
20225 size_t size_in_bits, size_t align_in_bits,
20226 bool is_struct, const location& locus,
20227 visibility vis, base_specs& bases,
20228 member_types& mbr_types,
20229 data_members& data_mbrs,
20230 member_functions& mbr_fns)
20231 : type_or_decl_base(env,
20232 CLASS_TYPE
20233 | ABSTRACT_TYPE_BASE
20234 | ABSTRACT_DECL_BASE
20235 | ABSTRACT_SCOPE_TYPE_DECL
20236 | ABSTRACT_SCOPE_DECL),
20237 decl_base(env, name, locus, name, vis),
20238 type_base(env, size_in_bits, align_in_bits),
20239 class_or_union(env, name, size_in_bits, align_in_bits,
20240 locus, vis, mbr_types, data_mbrs, mbr_fns),
20241 priv_(new priv(is_struct, bases))
20242 {
20243 runtime_type_instance(this);
20244 }
20245
20246 /// A Constructor for instances of @ref class_decl
20247 ///
20248 /// @param env the environment we are operating from.
20249 ///
20250 /// @param name the identifier of the class.
20251 ///
20252 /// @param size_in_bits the size of an instance of class_decl, expressed
20253 /// in bits
20254 ///
20255 /// @param align_in_bits the alignment of an instance of class_decl,
20256 /// expressed in bits.
20257 ///
20258 /// @param locus the source location of declaration point this class.
20259 ///
20260 /// @param vis the visibility of instances of class_decl.
20261 ///
20262 /// @param bases the vector of base classes for this instance of class_decl.
20263 ///
20264 /// @param mbrs the vector of member types of this instance of
20265 /// class_decl.
20266 ///
20267 /// @param data_mbrs the vector of data members of this instance of
20268 /// class_decl.
20269 ///
20270 /// @param mbr_fns the vector of member functions of this instance of
20271 /// class_decl.
20272 ///
20273 /// @param is_anonymous whether the newly created instance is
20274 /// 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)20275 class_decl::class_decl(const environment* env, const string& name,
20276 size_t size_in_bits, size_t align_in_bits,
20277 bool is_struct, const location& locus,
20278 visibility vis, base_specs& bases,
20279 member_types& mbr_types, data_members& data_mbrs,
20280 member_functions& mbr_fns, bool is_anonymous)
20281 : type_or_decl_base(env,
20282 CLASS_TYPE
20283 | ABSTRACT_TYPE_BASE
20284 | ABSTRACT_DECL_BASE
20285 | ABSTRACT_SCOPE_TYPE_DECL
20286 | ABSTRACT_SCOPE_DECL),
20287 decl_base(env, name, locus,
20288 // If the class is anonymous then by default it won't
20289 // have a linkage name. Also, the anonymous class does
20290 // have an internal-only unique name that is generally
20291 // not taken into account when comparing classes; such a
20292 // unique internal-only name, when used as a linkage
20293 // name might introduce spurious comparison false
20294 // negatives.
20295 /*linkage_name=*/is_anonymous ? string() : name,
20296 vis),
20297 type_base(env, size_in_bits, align_in_bits),
20298 class_or_union(env, name, size_in_bits, align_in_bits,
20299 locus, vis, mbr_types, data_mbrs, mbr_fns),
20300 priv_(new priv(is_struct, bases))
20301 {
20302 runtime_type_instance(this);
20303 set_is_anonymous(is_anonymous);
20304 }
20305
20306 /// A constructor for instances of class_decl.
20307 ///
20308 /// @param env the environment we are operating from.
20309 ///
20310 /// @param name the name of the class.
20311 ///
20312 /// @param size_in_bits the size of an instance of class_decl, expressed
20313 /// in bits
20314 ///
20315 /// @param align_in_bits the alignment of an instance of class_decl,
20316 /// expressed in bits.
20317 ///
20318 /// @param locus the source location of declaration point this class.
20319 ///
20320 /// @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)20321 class_decl::class_decl(const environment* env, const string& name,
20322 size_t size_in_bits, size_t align_in_bits,
20323 bool is_struct, const location& locus,
20324 visibility vis)
20325 : type_or_decl_base(env,
20326 CLASS_TYPE
20327 | ABSTRACT_TYPE_BASE
20328 | ABSTRACT_DECL_BASE
20329 | ABSTRACT_SCOPE_TYPE_DECL
20330 | ABSTRACT_SCOPE_DECL),
20331 decl_base(env, name, locus, name, vis),
20332 type_base(env, size_in_bits, align_in_bits),
20333 class_or_union(env, name, size_in_bits, align_in_bits,
20334 locus, vis),
20335 priv_(new priv(is_struct))
20336 {
20337 runtime_type_instance(this);
20338 }
20339
20340 /// A constructor for instances of @ref class_decl.
20341 ///
20342 /// @param env the environment we are operating from.
20343 ///
20344 /// @param name the name of the class.
20345 ///
20346 /// @param size_in_bits the size of an instance of class_decl, expressed
20347 /// in bits
20348 ///
20349 /// @param align_in_bits the alignment of an instance of class_decl,
20350 /// expressed in bits.
20351 ///
20352 /// @param locus the source location of declaration point this class.
20353 ///
20354 /// @param vis the visibility of instances of class_decl.
20355 ///
20356 /// @param is_anonymous whether the newly created instance is
20357 /// 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)20358 class_decl:: class_decl(const environment* env, const string& name,
20359 size_t size_in_bits, size_t align_in_bits,
20360 bool is_struct, const location& locus,
20361 visibility vis, bool is_anonymous)
20362 : type_or_decl_base(env,
20363 CLASS_TYPE
20364 | ABSTRACT_TYPE_BASE
20365 | ABSTRACT_DECL_BASE
20366 | ABSTRACT_SCOPE_TYPE_DECL
20367 | ABSTRACT_SCOPE_DECL),
20368 decl_base(env, name, locus,
20369 // If the class is anonymous then by default it won't
20370 // have a linkage name. Also, the anonymous class does
20371 // have an internal-only unique name that is generally
20372 // not taken into account when comparing classes; such a
20373 // unique internal-only name, when used as a linkage
20374 // name might introduce spurious comparison false
20375 // negatives.
20376 /*linkage_name=*/ is_anonymous ? string() : name,
20377 vis),
20378 type_base(env, size_in_bits, align_in_bits),
20379 class_or_union(env, name, size_in_bits, align_in_bits,
20380 locus, vis),
20381 priv_(new priv(is_struct))
20382 {
20383 runtime_type_instance(this);
20384 set_is_anonymous(is_anonymous);
20385 }
20386
20387 /// A constuctor for instances of class_decl that represent a
20388 /// declaration without definition.
20389 ///
20390 /// @param env the environment we are operating from.
20391 ///
20392 /// @param name the name of the class.
20393 ///
20394 /// @param is_declaration_only a boolean saying whether the instance
20395 /// represents a declaration only, or not.
class_decl(const environment * env,const string & name,bool is_struct,bool is_declaration_only)20396 class_decl::class_decl(const environment* env, const string& name,
20397 bool is_struct, bool is_declaration_only)
20398 : type_or_decl_base(env,
20399 CLASS_TYPE
20400 | ABSTRACT_TYPE_BASE
20401 | ABSTRACT_DECL_BASE
20402 | ABSTRACT_SCOPE_TYPE_DECL
20403 | ABSTRACT_SCOPE_DECL),
20404 decl_base(env, name, location(), name),
20405 type_base(env, 0, 0),
20406 class_or_union(env, name, is_declaration_only),
20407 priv_(new priv(is_struct))
20408 {
20409 runtime_type_instance(this);
20410 }
20411
20412 /// This method is invoked automatically right after the current
20413 /// instance of @ref class_decl has been canonicalized.
20414 ///
20415 /// Currently, the only thing it does is to sort the virtual member
20416 /// functions vector.
20417 void
on_canonical_type_set()20418 class_decl::on_canonical_type_set()
20419 {
20420 sort_virtual_mem_fns();
20421
20422 for (class_decl::virtual_mem_fn_map_type::iterator i =
20423 priv_->virtual_mem_fns_map_.begin();
20424 i != priv_->virtual_mem_fns_map_.end();
20425 ++i)
20426 sort_virtual_member_functions(i->second);
20427 }
20428
20429 /// Set the "is-struct" flag of the class.
20430 ///
20431 /// @param f the new value of the flag.
20432 void
is_struct(bool f)20433 class_decl::is_struct(bool f)
20434 {priv_->is_struct_ = f;}
20435
20436 /// Test if the class is a struct.
20437 ///
20438 /// @return true iff the class is a struct.
20439 bool
is_struct() const20440 class_decl::is_struct() const
20441 {return priv_->is_struct_;}
20442
20443 /// Add a base specifier to this class.
20444 ///
20445 /// @param b the new base specifier.
20446 void
add_base_specifier(base_spec_sptr b)20447 class_decl::add_base_specifier(base_spec_sptr b)
20448 {
20449 ABG_ASSERT(get_environment());
20450 ABG_ASSERT(b->get_environment() == get_environment());
20451 priv_->bases_.push_back(b);
20452 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
20453 if (const environment* env = get_environment())
20454 b->set_environment(env);
20455 }
20456
20457 /// Get the base specifiers for this class.
20458 ///
20459 /// @return a vector of the base specifiers.
20460 const class_decl::base_specs&
get_base_specifiers() const20461 class_decl::get_base_specifiers() const
20462 {return priv_->bases_;}
20463
20464 /// Find a base class of a given qualified name for the current class.
20465 ///
20466 /// @param qualified_name the qualified name of the base class to look for.
20467 ///
20468 /// @return a pointer to the @ref class_decl that represents the base
20469 /// class of name @p qualified_name, if found.
20470 class_decl_sptr
find_base_class(const string & qualified_name) const20471 class_decl::find_base_class(const string& qualified_name) const
20472 {
20473 unordered_map<string, base_spec_sptr>::iterator i =
20474 priv_->bases_map_.find(qualified_name);
20475
20476 if (i != priv_->bases_map_.end())
20477 return i->second->get_base_class();
20478
20479 return class_decl_sptr();
20480 }
20481
20482 /// Get the virtual member functions of this class.
20483 ///
20484 /// @param return a vector of the virtual member functions of this
20485 /// class.
20486 const class_decl::member_functions&
get_virtual_mem_fns() const20487 class_decl::get_virtual_mem_fns() const
20488 {return priv_->virtual_mem_fns_;}
20489
20490 /// Get the map that associates a virtual table offset to the virtual
20491 /// member functions with that virtual table offset.
20492 ///
20493 /// Usually, there should be a 1:1 mapping between a given vtable
20494 /// offset and virtual member functions of that vtable offset. But
20495 /// because of some implementation details, there can be several C++
20496 /// destructor functions that are *generated* by compilers, for a
20497 /// given destructor that is defined in the source code. If the
20498 /// destructor is virtual then those generated functions have some
20499 /// DWARF attributes in common with the constructor that the user
20500 /// actually defined in its source code. Among those attributes are
20501 /// the vtable offset of the destructor.
20502 ///
20503 /// @return the map that associates a virtual table offset to the
20504 /// virtual member functions with that virtual table offset.
20505 const class_decl::virtual_mem_fn_map_type&
get_virtual_mem_fns_map() const20506 class_decl::get_virtual_mem_fns_map() const
20507 {return priv_->virtual_mem_fns_map_;}
20508
20509 /// Sort the virtual member functions by their virtual index.
20510 void
sort_virtual_mem_fns()20511 class_decl::sort_virtual_mem_fns()
20512 {sort_virtual_member_functions(priv_->virtual_mem_fns_);}
20513
20514 /// Getter of the pretty representation of the current instance of
20515 /// @ref class_decl.
20516 ///
20517 /// @param internal set to true if the call is intended for an
20518 /// internal use (for technical use inside the library itself), false
20519 /// otherwise. If you don't know what this is for, then set it to
20520 /// false.
20521 ///
20522 /// @param qualified_name if true, names emitted in the pretty
20523 /// representation are fully qualified.
20524 ///
20525 /// @return the pretty representaion for a class_decl.
20526 string
get_pretty_representation(bool internal,bool qualified_name) const20527 class_decl::get_pretty_representation(bool internal,
20528 bool qualified_name) const
20529 {
20530 string cl = "class ";
20531 if (!internal && is_struct())
20532 cl = "struct ";
20533
20534 // When computing the pretty representation for internal purposes,
20535 // if an anonymous class is named by a typedef, then consider that
20536 // it has a name, which is the typedef name.
20537 if (get_is_anonymous())
20538 return get_class_or_union_flat_representation(this, "",
20539 /*one_line=*/true,
20540 internal);
20541
20542 string result = cl;
20543 if (qualified_name)
20544 result += get_qualified_name(internal);
20545 else
20546 result += get_name();
20547
20548 return result;
20549 }
20550
20551 decl_base_sptr
insert_member_decl(decl_base_sptr d,declarations::iterator before)20552 class_decl::insert_member_decl(decl_base_sptr d,
20553 declarations::iterator before)
20554 {
20555 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
20556 add_member_function(f, public_access,
20557 /*is_virtual=*/false,
20558 /*vtable_offset=*/0,
20559 /*is_static=*/false,
20560 /*is_ctor=*/false,
20561 /*is_dtor=*/false,
20562 /*is_const=*/false);
20563 else
20564 d = class_or_union::insert_member_decl(d, before);
20565
20566 return d;
20567 }
20568
20569 /// The private data structure of class_decl::base_spec.
20570 struct class_decl::base_spec::priv
20571 {
20572 class_decl_wptr base_class_;
20573 long offset_in_bits_;
20574 bool is_virtual_;
20575
privabigail::ir::class_decl::base_spec::priv20576 priv(const class_decl_sptr& cl,
20577 long offset_in_bits,
20578 bool is_virtual)
20579 : base_class_(cl),
20580 offset_in_bits_(offset_in_bits),
20581 is_virtual_(is_virtual)
20582 {}
20583 };
20584
20585 /// Constructor for base_spec instances.
20586 ///
20587 /// @param base the base class to consider
20588 ///
20589 /// @param a the access specifier of the base class.
20590 ///
20591 /// @param offset_in_bits if positive or null, represents the offset
20592 /// of the base in the layout of its containing type.. If negative,
20593 /// means that the current base is not laid out in its containing type.
20594 ///
20595 /// @param is_virtual if true, means that the current base class is
20596 /// virtual in it's containing type.
base_spec(const class_decl_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)20597 class_decl::base_spec::base_spec(const class_decl_sptr& base,
20598 access_specifier a,
20599 long offset_in_bits,
20600 bool is_virtual)
20601 : type_or_decl_base(base->get_environment(),
20602 ABSTRACT_DECL_BASE),
20603 decl_base(base->get_environment(), base->get_name(), base->get_location(),
20604 base->get_linkage_name(), base->get_visibility()),
20605 member_base(a),
20606 priv_(new priv(base, offset_in_bits, is_virtual))
20607 {
20608 runtime_type_instance(this);
20609 }
20610
20611 /// Get the base class referred to by the current base class
20612 /// specifier.
20613 ///
20614 /// @return the base class.
20615 class_decl_sptr
get_base_class() const20616 class_decl::base_spec::get_base_class() const
20617 {return priv_->base_class_.lock();}
20618
20619 /// Getter of the "is-virtual" proprerty of the base class specifier.
20620 ///
20621 /// @return true iff this specifies a virtual base class.
20622 bool
get_is_virtual() const20623 class_decl::base_spec::get_is_virtual() const
20624 {return priv_->is_virtual_;}
20625
20626 /// Getter of the offset of the base.
20627 ///
20628 /// @return the offset of the base.
20629 long
get_offset_in_bits() const20630 class_decl::base_spec::get_offset_in_bits() const
20631 {return priv_->offset_in_bits_;}
20632
20633 /// Calculate the hash value for a class_decl::base_spec.
20634 ///
20635 /// @return the hash value.
20636 size_t
get_hash() const20637 class_decl::base_spec::get_hash() const
20638 {
20639 base_spec::hash h;
20640 return h(*this);
20641 }
20642
20643 /// Traverses an instance of @ref class_decl::base_spec, visiting all
20644 /// the sub-types and decls that it might contain.
20645 ///
20646 /// @param v the visitor that is used to visit every IR sub-node of
20647 /// the current node.
20648 ///
20649 /// @return true if either
20650 /// - all the children nodes of the current IR node were traversed
20651 /// and the calling code should keep going with the traversing.
20652 /// - or the current IR node is already being traversed.
20653 /// Otherwise, returning false means that the calling code should not
20654 /// keep traversing the tree.
20655 bool
traverse(ir_node_visitor & v)20656 class_decl::base_spec::traverse(ir_node_visitor& v)
20657 {
20658 if (visiting())
20659 return true;
20660
20661 if (v.visit_begin(this))
20662 {
20663 visiting(true);
20664 get_base_class()->traverse(v);
20665 visiting(false);
20666 }
20667
20668 return v.visit_end(this);
20669 }
20670
20671 /// Constructor for base_spec instances.
20672 ///
20673 /// Note that this constructor is for clients that don't support RTTI
20674 /// and that have a base class of type_base, but of dynamic type
20675 /// class_decl.
20676 ///
20677 /// @param base the base class to consider. Must be a pointer to an
20678 /// instance of class_decl
20679 ///
20680 /// @param a the access specifier of the base class.
20681 ///
20682 /// @param offset_in_bits if positive or null, represents the offset
20683 /// of the base in the layout of its containing type.. If negative,
20684 /// means that the current base is not laid out in its containing type.
20685 ///
20686 /// @param is_virtual if true, means that the current base class is
20687 /// virtual in it's containing type.
base_spec(const type_base_sptr & base,access_specifier a,long offset_in_bits,bool is_virtual)20688 class_decl::base_spec::base_spec(const type_base_sptr& base,
20689 access_specifier a,
20690 long offset_in_bits,
20691 bool is_virtual)
20692 : type_or_decl_base(base->get_environment(),
20693 ABSTRACT_DECL_BASE),
20694 decl_base(base->get_environment(), get_type_declaration(base)->get_name(),
20695 get_type_declaration(base)->get_location(),
20696 get_type_declaration(base)->get_linkage_name(),
20697 get_type_declaration(base)->get_visibility()),
20698 member_base(a),
20699 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
20700 offset_in_bits,
20701 is_virtual))
20702 {
20703 runtime_type_instance(this);
20704 }
20705
20706 /// Compares two instances of @ref class_decl::base_spec.
20707 ///
20708 /// If the two intances are different, set a bitfield to give some
20709 /// insight about the kind of differences there are.
20710 ///
20711 /// @param l the first artifact of the comparison.
20712 ///
20713 /// @param r the second artifact of the comparison.
20714 ///
20715 /// @param k a pointer to a bitfield that gives information about the
20716 /// kind of changes there are between @p l and @p r. This one is set
20717 /// iff @p k is non-null and the function returns false.
20718 ///
20719 /// Please note that setting k to a non-null value does have a
20720 /// negative performance impact because even if @p l and @p r are not
20721 /// equal, the function keeps up the comparison in order to determine
20722 /// the different kinds of ways in which they are different.
20723 ///
20724 /// @return true if @p l equals @p r, false otherwise.
20725 bool
equals(const class_decl::base_spec & l,const class_decl::base_spec & r,change_kind * k)20726 equals(const class_decl::base_spec& l,
20727 const class_decl::base_spec& r,
20728 change_kind* k)
20729 {
20730 if (!l.member_base::operator==(r))
20731 {
20732 if (k)
20733 *k |= LOCAL_TYPE_CHANGE_KIND;
20734 return false;
20735 }
20736
20737 return (*l.get_base_class() == *r.get_base_class());
20738 }
20739
20740 /// Comparison operator for @ref class_decl::base_spec.
20741 ///
20742 /// @param other the instance of @ref class_decl::base_spec to compare
20743 /// against.
20744 ///
20745 /// @return true if the current instance of @ref class_decl::base_spec
20746 /// equals @p other.
20747 bool
operator ==(const decl_base & other) const20748 class_decl::base_spec::operator==(const decl_base& other) const
20749 {
20750 const class_decl::base_spec* o =
20751 dynamic_cast<const class_decl::base_spec*>(&other);
20752
20753 if (!o)
20754 return false;
20755
20756 return equals(*this, *o, 0);
20757 }
20758
20759 /// Comparison operator for @ref class_decl::base_spec.
20760 ///
20761 /// @param other the instance of @ref class_decl::base_spec to compare
20762 /// against.
20763 ///
20764 /// @return true if the current instance of @ref class_decl::base_spec
20765 /// equals @p other.
20766 bool
operator ==(const member_base & other) const20767 class_decl::base_spec::operator==(const member_base& other) const
20768 {
20769 const class_decl::base_spec* o =
20770 dynamic_cast<const class_decl::base_spec*>(&other);
20771 if (!o)
20772 return false;
20773
20774 return operator==(static_cast<const decl_base&>(*o));
20775 }
20776
~mem_fn_context_rel()20777 mem_fn_context_rel::~mem_fn_context_rel()
20778 {
20779 }
20780
20781 /// A constructor for instances of method_decl.
20782 ///
20783 /// @param name the name of the method.
20784 ///
20785 /// @param type the type of the method.
20786 ///
20787 /// @param declared_inline whether the method was
20788 /// declared inline or not.
20789 ///
20790 /// @param locus the source location of the method.
20791 ///
20792 /// @param linkage_name the mangled name of the method.
20793 ///
20794 /// @param vis the visibility of the method.
20795 ///
20796 /// @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)20797 method_decl::method_decl(const string& name,
20798 method_type_sptr type,
20799 bool declared_inline,
20800 const location& locus,
20801 const string& linkage_name,
20802 visibility vis,
20803 binding bind)
20804 : type_or_decl_base(type->get_environment(),
20805 METHOD_DECL
20806 | ABSTRACT_DECL_BASE
20807 |FUNCTION_DECL),
20808 decl_base(type->get_environment(), name, locus, linkage_name, vis),
20809 function_decl(name, static_pointer_cast<function_type>(type),
20810 declared_inline, locus, linkage_name, vis, bind)
20811 {
20812 runtime_type_instance(this);
20813 set_context_rel(new mem_fn_context_rel(0));
20814 set_member_function_is_const(*this, type->get_is_const());
20815 }
20816
20817 /// A constructor for instances of method_decl.
20818 ///
20819 /// @param name the name of the method.
20820 ///
20821 /// @param type the type of the method. Must be an instance of
20822 /// method_type.
20823 ///
20824 /// @param declared_inline whether the method was
20825 /// declared inline or not.
20826 ///
20827 /// @param locus the source location of the method.
20828 ///
20829 /// @param linkage_name the mangled name of the method.
20830 ///
20831 /// @param vis the visibility of the method.
20832 ///
20833 /// @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)20834 method_decl::method_decl(const string& name,
20835 function_type_sptr type,
20836 bool declared_inline,
20837 const location& locus,
20838 const string& linkage_name,
20839 visibility vis,
20840 binding bind)
20841 : type_or_decl_base(type->get_environment(),
20842 METHOD_DECL
20843 | ABSTRACT_DECL_BASE
20844 | FUNCTION_DECL),
20845 decl_base(type->get_environment(), name, locus, linkage_name, vis),
20846 function_decl(name, static_pointer_cast<function_type>
20847 (dynamic_pointer_cast<method_type>(type)),
20848 declared_inline, locus, linkage_name, vis, bind)
20849 {
20850 runtime_type_instance(this);
20851 set_context_rel(new mem_fn_context_rel(0));
20852 }
20853
20854 /// A constructor for instances of method_decl.
20855 ///
20856 /// @param name the name of the method.
20857 ///
20858 /// @param type the type of the method. Must be an instance of
20859 /// method_type.
20860 ///
20861 /// @param declared_inline whether the method was
20862 /// declared inline or not.
20863 ///
20864 /// @param locus the source location of the method.
20865 ///
20866 /// @param linkage_name the mangled name of the method.
20867 ///
20868 /// @param vis the visibility of the method.
20869 ///
20870 /// @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)20871 method_decl::method_decl(const string& name,
20872 type_base_sptr type,
20873 bool declared_inline,
20874 const location& locus,
20875 const string& linkage_name,
20876 visibility vis,
20877 binding bind)
20878 : type_or_decl_base(type->get_environment(),
20879 METHOD_DECL
20880 | ABSTRACT_DECL_BASE
20881 | FUNCTION_DECL),
20882 decl_base(type->get_environment(), name, locus, linkage_name, vis),
20883 function_decl(name, static_pointer_cast<function_type>
20884 (dynamic_pointer_cast<method_type>(type)),
20885 declared_inline, locus, linkage_name, vis, bind)
20886 {
20887 runtime_type_instance(this);
20888 set_context_rel(new mem_fn_context_rel(0));
20889 }
20890
20891 /// Set the linkage name of the method.
20892 ///
20893 /// @param l the new linkage name of the method.
20894 void
set_linkage_name(const string & l)20895 method_decl::set_linkage_name(const string& l)
20896 {
20897 decl_base::set_linkage_name(l);
20898 // Update the linkage_name -> member function map of the containing
20899 // class declaration.
20900 if (!l.empty())
20901 {
20902 method_type_sptr t = get_type();
20903 class_or_union_sptr cl = t->get_class_type();
20904 method_decl_sptr m(this, sptr_utils::noop_deleter());
20905 cl->priv_->mem_fns_map_[l] = m;
20906 }
20907 }
20908
~method_decl()20909 method_decl::~method_decl()
20910 {}
20911
20912 const method_type_sptr
get_type() const20913 method_decl::get_type() const
20914 {
20915 method_type_sptr result;
20916 if (function_decl::get_type())
20917 result = dynamic_pointer_cast<method_type>(function_decl::get_type());
20918 return result;
20919 }
20920
20921 /// Set the containing class of a method_decl.
20922 ///
20923 /// @param scope the new containing class_decl.
20924 void
set_scope(scope_decl * scope)20925 method_decl::set_scope(scope_decl* scope)
20926 {
20927 if (!get_context_rel())
20928 set_context_rel(new mem_fn_context_rel(scope));
20929 else
20930 get_context_rel()->set_scope(scope);
20931 }
20932
20933 /// Equality operator for @ref method_decl_sptr.
20934 ///
20935 /// This is a deep equality operator, as it compares the @ref
20936 /// method_decl that is pointed-to by the smart pointer.
20937 ///
20938 /// @param l the left-hand side argument of the equality operator.
20939 ///
20940 /// @param r the righ-hand side argument of the equality operator.
20941 ///
20942 /// @return true iff @p l equals @p r.
20943 bool
operator ==(const method_decl_sptr & l,const method_decl_sptr & r)20944 operator==(const method_decl_sptr& l, const method_decl_sptr& r)
20945 {
20946 if (l.get() == r.get())
20947 return true;
20948 if (!!l != !!r)
20949 return false;
20950
20951 return *l == *r;
20952 }
20953
20954 /// Inequality operator for @ref method_decl_sptr.
20955 ///
20956 /// This is a deep equality operator, as it compares the @ref
20957 /// method_decl that is pointed-to by the smart pointer.
20958 ///
20959 /// @param l the left-hand side argument of the equality operator.
20960 ///
20961 /// @param r the righ-hand side argument of the equality operator.
20962 ///
20963 /// @return true iff @p l differs from @p r.
20964 bool
operator !=(const method_decl_sptr & l,const method_decl_sptr & r)20965 operator!=(const method_decl_sptr& l, const method_decl_sptr& r)
20966 {return !operator==(l, r);}
20967
20968 /// Test if a function_decl is actually a method_decl.
20969 ///
20970 ///@param d the @ref function_decl to consider.
20971 ///
20972 /// @return the method_decl sub-object of @p d if inherits
20973 /// a method_decl type.
20974 method_decl*
is_method_decl(const type_or_decl_base * d)20975 is_method_decl(const type_or_decl_base *d)
20976 {
20977 return dynamic_cast<method_decl*>
20978 (const_cast<type_or_decl_base*>(d));
20979 }
20980
20981 /// Test if a function_decl is actually a method_decl.
20982 ///
20983 ///@param d the @ref function_decl to consider.
20984 ///
20985 /// @return the method_decl sub-object of @p d if inherits
20986 /// a method_decl type.
20987 method_decl*
is_method_decl(const type_or_decl_base & d)20988 is_method_decl(const type_or_decl_base&d)
20989 {return is_method_decl(&d);}
20990
20991 /// Test if a function_decl is actually a method_decl.
20992 ///
20993 ///@param d the @ref function_decl to consider.
20994 ///
20995 /// @return the method_decl sub-object of @p d if inherits
20996 /// a method_decl type.
20997 method_decl_sptr
is_method_decl(const type_or_decl_base_sptr & d)20998 is_method_decl(const type_or_decl_base_sptr& d)
20999 {return dynamic_pointer_cast<method_decl>(d);}
21000
21001 /// A "less than" functor to sort a vector of instances of
21002 /// method_decl that are virtual.
21003 struct virtual_member_function_less_than
21004 {
21005 /// The less than operator. First, it sorts the methods by their
21006 /// vtable index. If they have the same vtable index, it sorts them
21007 /// by the name of their ELF symbol. If they don't have elf
21008 /// symbols, it sorts them by considering their pretty
21009 /// representation.
21010 ///
21011 /// Note that this method expects virtual methods.
21012 ///
21013 /// @param f the first method to consider.
21014 ///
21015 /// @param s the second method to consider.
21016 ///
21017 /// @return true if method @p is less than method @s.
21018 bool
operator ()abigail::ir::virtual_member_function_less_than21019 operator()(const method_decl& f,
21020 const method_decl& s)
21021 {
21022 ABG_ASSERT(get_member_function_is_virtual(f));
21023 ABG_ASSERT(get_member_function_is_virtual(s));
21024
21025 ssize_t f_offset = get_member_function_vtable_offset(f);
21026 ssize_t s_offset = get_member_function_vtable_offset(s);
21027 if (f_offset != s_offset) return f_offset < s_offset;
21028
21029 string fn, sn;
21030
21031 // If the functions have symbols, then compare their symbol-id
21032 // string.
21033 elf_symbol_sptr f_sym = f.get_symbol();
21034 elf_symbol_sptr s_sym = s.get_symbol();
21035 if ((!f_sym) != (!s_sym)) return !f_sym;
21036 if (f_sym && s_sym)
21037 {
21038 fn = f_sym->get_id_string();
21039 sn = s_sym->get_id_string();
21040 if (fn != sn) return fn < sn;
21041 }
21042
21043 // Try the linkage names (important for destructors).
21044 fn = f.get_linkage_name();
21045 sn = s.get_linkage_name();
21046 if (fn != sn) return fn < sn;
21047
21048 // None of the functions have symbols or linkage names that
21049 // distinguish them, so compare their pretty representation.
21050 fn = f.get_pretty_representation();
21051 sn = s.get_pretty_representation();
21052 if (fn != sn) return fn < sn;
21053
21054 /// If it's just the file paths that are different then sort them
21055 /// too.
21056 string fn_filepath, sn_filepath;
21057 unsigned line = 0, column = 0;
21058 location fn_loc = f.get_location(), sn_loc = s.get_location();
21059 if (fn_loc)
21060 fn_loc.expand(fn_filepath, line, column);
21061 if (sn_loc)
21062 sn_loc.expand(sn_filepath, line, column);
21063 return fn_filepath < sn_filepath;
21064 }
21065
21066 /// The less than operator. First, it sorts the methods by their
21067 /// vtable index. If they have the same vtable index, it sorts them
21068 /// by the name of their ELF symbol. If they don't have elf
21069 /// symbols, it sorts them by considering their pretty
21070 /// representation.
21071 ///
21072 /// Note that this method expects to take virtual methods.
21073 ///
21074 /// @param f the first method to consider.
21075 ///
21076 /// @param s the second method to consider.
21077 bool
operator ()abigail::ir::virtual_member_function_less_than21078 operator()(const method_decl_sptr f,
21079 const method_decl_sptr s)
21080 {return operator()(*f, *s);}
21081 }; // end struct virtual_member_function_less_than
21082
21083 /// Sort a vector of instances of virtual member functions.
21084 ///
21085 /// @param mem_fns the vector of member functions to sort.
21086 static void
sort_virtual_member_functions(class_decl::member_functions & mem_fns)21087 sort_virtual_member_functions(class_decl::member_functions& mem_fns)
21088 {
21089 virtual_member_function_less_than lt;
21090 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
21091 }
21092
21093 /// Add a member function to the current instance of @ref class_or_union.
21094 ///
21095 /// @param f a method_decl to add to the current class. This function
21096 /// should not have been already added to a scope.
21097 ///
21098 /// @param access the access specifier for the member function to add.
21099 ///
21100 /// @param is_virtual if this is true then it means the function @p f
21101 /// is a virtual function. That also means that the current instance
21102 /// of @ref class_or_union is actually an instance of @ref class_decl.
21103 ///
21104 /// @param vtable_offset the offset of the member function in the
21105 /// virtual table. This parameter is taken into account only if @p
21106 /// is_virtual is true.
21107 ///
21108 /// @param is_static whether the member function is static.
21109 ///
21110 /// @param is_ctor whether the member function is a constructor.
21111 ///
21112 /// @param is_dtor whether the member function is a destructor.
21113 ///
21114 /// @param is_const whether the member function is const.
21115 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)21116 class_or_union::add_member_function(method_decl_sptr f,
21117 access_specifier a,
21118 bool is_virtual,
21119 size_t vtable_offset,
21120 bool is_static, bool is_ctor,
21121 bool is_dtor, bool is_const)
21122 {
21123 add_member_function(f, a, is_static, is_ctor,
21124 is_dtor, is_const);
21125
21126 if (class_decl* klass = is_class_type(this))
21127 {
21128 set_member_function_is_virtual(f, is_virtual);
21129 if (is_virtual)
21130 {
21131 set_member_function_vtable_offset(f, vtable_offset);
21132 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
21133 }
21134 }
21135 }
21136
21137 /// When a virtual member function has seen its virtualness set by
21138 /// set_member_function_is_virtual(), this function ensures that the
21139 /// member function is added to the specific vectors and maps of
21140 /// virtual member function of its class.
21141 ///
21142 /// @param method the method to fixup.
21143 void
fixup_virtual_member_function(method_decl_sptr method)21144 fixup_virtual_member_function(method_decl_sptr method)
21145 {
21146 if (!method || !get_member_function_is_virtual(method))
21147 return;
21148
21149 class_decl_sptr klass = is_class_type(method->get_type()->get_class_type());
21150
21151 class_decl::member_functions::const_iterator m;
21152 for (m = klass->priv_->virtual_mem_fns_.begin();
21153 m != klass->priv_->virtual_mem_fns_.end();
21154 ++m)
21155 if (m->get() == method.get())
21156 break;
21157 if (m == klass->priv_->virtual_mem_fns_.end())
21158 klass->priv_->virtual_mem_fns_.push_back(method);
21159
21160 // Build or udpate the map that associates a vtable offset to the
21161 // number of virtual member functions that "point" to it.
21162 ssize_t voffset = get_member_function_vtable_offset(method);
21163 if (voffset == -1)
21164 return;
21165
21166 class_decl::virtual_mem_fn_map_type::iterator i =
21167 klass->priv_->virtual_mem_fns_map_.find(voffset);
21168 if (i == klass->priv_->virtual_mem_fns_map_.end())
21169 {
21170 class_decl::member_functions virtual_mem_fns_at_voffset;
21171 virtual_mem_fns_at_voffset.push_back(method);
21172 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
21173 }
21174 else
21175 {
21176 for (m = i->second.begin() ; m != i->second.end(); ++m)
21177 if (m->get() == method.get())
21178 break;
21179 if (m == i->second.end())
21180 i->second.push_back(method);
21181 }
21182 }
21183
21184 /// Return true iff the class has no entity in its scope.
21185 bool
has_no_base_nor_member() const21186 class_decl::has_no_base_nor_member() const
21187 {return priv_->bases_.empty() && has_no_member();}
21188
21189 /// Test if the current instance of @ref class_decl has virtual member
21190 /// functions.
21191 ///
21192 /// @return true iff the current instance of @ref class_decl has
21193 /// virtual member functions.
21194 bool
has_virtual_member_functions() const21195 class_decl::has_virtual_member_functions() const
21196 {return !get_virtual_mem_fns().empty();}
21197
21198 /// Test if the current instance of @ref class_decl has at least one
21199 /// virtual base.
21200 ///
21201 /// @return true iff the current instance of @ref class_decl has a
21202 /// virtual member function.
21203 bool
has_virtual_bases() const21204 class_decl::has_virtual_bases() const
21205 {
21206 for (base_specs::const_iterator b = get_base_specifiers().begin();
21207 b != get_base_specifiers().end();
21208 ++b)
21209 if ((*b)->get_is_virtual()
21210 || (*b)->get_base_class()->has_virtual_bases())
21211 return true;
21212
21213 return false;
21214 }
21215
21216 /// Test if the current instance has a vtable.
21217 ///
21218 /// This is only valid for a C++ program.
21219 ///
21220 /// Basically this function checks if the class has either virtual
21221 /// functions, or virtual bases.
21222 bool
has_vtable() const21223 class_decl::has_vtable() const
21224 {
21225 if (has_virtual_member_functions()
21226 || has_virtual_bases())
21227 return true;
21228 return false;
21229 }
21230
21231 /// Get the highest vtable offset of all the virtual methods of the
21232 /// class.
21233 ///
21234 /// @return the highest vtable offset of all the virtual methods of
21235 /// the class.
21236 ssize_t
get_biggest_vtable_offset() const21237 class_decl::get_biggest_vtable_offset() const
21238 {
21239 ssize_t offset = -1;
21240 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
21241 get_virtual_mem_fns_map().begin();
21242 e != get_virtual_mem_fns_map().end();
21243 ++e)
21244 if (e->first > offset)
21245 offset = e->first;
21246
21247 return offset;
21248 }
21249
21250 /// Return the hash value for the current instance.
21251 ///
21252 /// @return the hash value.
21253 size_t
get_hash() const21254 class_decl::get_hash() const
21255 {
21256 class_decl::hash hash_class;
21257 return hash_class(this);
21258 }
21259
21260 /// Test if two methods are equal without taking their symbol or
21261 /// linkage name into account.
21262 ///
21263 /// @param f the first method.
21264 ///
21265 /// @param s the second method.
21266 ///
21267 /// @return true iff @p f equals @p s without taking their linkage
21268 /// name or symbol into account.
21269 static bool
methods_equal_modulo_elf_symbol(const method_decl_sptr & f,const method_decl_sptr & s)21270 methods_equal_modulo_elf_symbol(const method_decl_sptr& f,
21271 const method_decl_sptr& s)
21272 {
21273 method_decl_sptr first = f, second = s;
21274 elf_symbol_sptr saved_first_elf_symbol =
21275 first->get_symbol();
21276 elf_symbol_sptr saved_second_elf_symbol =
21277 second->get_symbol();
21278 interned_string saved_first_linkage_name =
21279 first->get_linkage_name();
21280 interned_string saved_second_linkage_name =
21281 second->get_linkage_name();
21282
21283 first->set_symbol(elf_symbol_sptr());
21284 first->set_linkage_name("");
21285 second->set_symbol(elf_symbol_sptr());
21286 second->set_linkage_name("");
21287
21288 bool equal = *first == *second;
21289
21290 first->set_symbol(saved_first_elf_symbol);
21291 first->set_linkage_name(saved_first_linkage_name);
21292 second->set_symbol(saved_second_elf_symbol);
21293 second->set_linkage_name(saved_second_linkage_name);
21294
21295 return equal;
21296 }
21297
21298 /// Test if a given method is equivalent to at least of other method
21299 /// that is in a vector of methods.
21300 ///
21301 /// Note that "equivalent" here means being equal without taking the
21302 /// linkage name or the symbol of the methods into account.
21303 ///
21304 /// This is a sub-routine of the 'equals' function that compares @ref
21305 /// class_decl.
21306 ///
21307 /// @param method the method to compare.
21308 ///
21309 /// @param fns the vector of functions to compare @p method against.
21310 ///
21311 /// @return true iff @p is equivalent to at least one method in @p
21312 /// fns.
21313 static bool
method_matches_at_least_one_in_vector(const method_decl_sptr & method,const class_decl::member_functions & fns)21314 method_matches_at_least_one_in_vector(const method_decl_sptr& method,
21315 const class_decl::member_functions& fns)
21316 {
21317 for (class_decl::member_functions::const_iterator i = fns.begin();
21318 i != fns.end();
21319 ++i)
21320 if (methods_equal_modulo_elf_symbol(*i, method))
21321 return true;
21322
21323 return false;
21324 }
21325
21326 /// Compares two instances of @ref class_decl.
21327 ///
21328 /// If the two intances are different, set a bitfield to give some
21329 /// insight about the kind of differences there are.
21330 ///
21331 /// @param l the first artifact of the comparison.
21332 ///
21333 /// @param r the second artifact of the comparison.
21334 ///
21335 /// @param k a pointer to a bitfield that gives information about the
21336 /// kind of changes there are between @p l and @p r. This one is set
21337 /// iff @p k is non-null and the function returns false.
21338 ///
21339 /// Please note that setting k to a non-null value does have a
21340 /// negative performance impact because even if @p l and @p r are not
21341 /// equal, the function keeps up the comparison in order to determine
21342 /// the different kinds of ways in which they are different.
21343 ///
21344 /// @return true if @p l equals @p r, false otherwise.
21345 bool
equals(const class_decl & l,const class_decl & r,change_kind * k)21346 equals(const class_decl& l, const class_decl& r, change_kind* k)
21347 {
21348 // if one of the classes is declaration-only then we take a fast
21349 // path here.
21350 if (l.get_is_declaration_only() || r.get_is_declaration_only())
21351 return equals(static_cast<const class_or_union&>(l),
21352 static_cast<const class_or_union&>(r),
21353 k);
21354
21355 if (l.class_or_union::priv_->comparison_started(l)
21356 || l.class_or_union::priv_->comparison_started(r))
21357 return true;
21358
21359 bool result = true;
21360 if (!equals(static_cast<const class_or_union&>(l),
21361 static_cast<const class_or_union&>(r),
21362 k))
21363 {
21364 result = false;
21365 if (!k)
21366 return result;
21367 }
21368
21369 l.class_or_union::priv_->mark_as_being_compared(l);
21370 l.class_or_union::priv_->mark_as_being_compared(r);
21371
21372 #define RETURN(value) \
21373 do { \
21374 l.class_or_union::priv_->unmark_as_being_compared(l); \
21375 l.class_or_union::priv_->unmark_as_being_compared(r); \
21376 if (value == true) \
21377 maybe_propagate_canonical_type(l, r); \
21378 return value; \
21379 } while(0)
21380
21381 // Compare bases.
21382 if (l.get_base_specifiers().size() != r.get_base_specifiers().size())
21383 {
21384 result = false;
21385 if (k)
21386 *k |= LOCAL_TYPE_CHANGE_KIND;
21387 else
21388 RETURN(result);
21389 }
21390
21391 for (class_decl::base_specs::const_iterator
21392 b0 = l.get_base_specifiers().begin(),
21393 b1 = r.get_base_specifiers().begin();
21394 (b0 != l.get_base_specifiers().end()
21395 && b1 != r.get_base_specifiers().end());
21396 ++b0, ++b1)
21397 if (*b0 != *b1)
21398 {
21399 result = false;
21400 if (k)
21401 {
21402 if (!types_have_similar_structure((*b0)->get_base_class().get(),
21403 (*b1)->get_base_class().get()))
21404 *k |= LOCAL_TYPE_CHANGE_KIND;
21405 else
21406 *k |= SUBTYPE_CHANGE_KIND;
21407 break;
21408 }
21409 RETURN(result);
21410 }
21411
21412 // Compare virtual member functions
21413
21414 // We look at the map that associates a given vtable offset to a
21415 // vector of virtual member functions that point to that offset.
21416 //
21417 // This is because there are cases where several functions can
21418 // point to the same virtual table offset.
21419 //
21420 // This is usually the case for virtual destructors. Even though
21421 // there can be only one virtual destructor declared in source
21422 // code, there are actually potentially up to three generated
21423 // functions for that destructor. Some of these generated
21424 // functions can be clones of other functions that are among those
21425 // generated ones. In any cases, they all have the same
21426 // properties, including the vtable offset property.
21427
21428 // So, there should be the same number of different vtable
21429 // offsets, the size of two maps must be equals.
21430 if (l.get_virtual_mem_fns_map().size()
21431 != r.get_virtual_mem_fns_map().size())
21432 {
21433 result = false;
21434 if (k)
21435 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21436 else
21437 RETURN(result);
21438 }
21439
21440 // Then, each virtual member function of a given vtable offset in
21441 // the first class type, must match an equivalent virtual member
21442 // function of a the same vtable offset in the second class type.
21443 //
21444 // By "match", I mean that the two virtual member function should
21445 // be equal if we don't take into account their symbol name or
21446 // their linkage name. This is because two destructor functions
21447 // clones (for instance) might have different linkage name, but
21448 // are still equivalent if their other properties are the same.
21449 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
21450 l.get_virtual_mem_fns_map().begin();
21451 first_v_fn_entry != l.get_virtual_mem_fns_map().end();
21452 ++first_v_fn_entry)
21453 {
21454 unsigned voffset = first_v_fn_entry->first;
21455 const class_decl::member_functions& first_vfns =
21456 first_v_fn_entry->second;
21457
21458 const class_decl::virtual_mem_fn_map_type::const_iterator
21459 second_v_fn_entry = r.get_virtual_mem_fns_map().find(voffset);
21460
21461 if (second_v_fn_entry == r.get_virtual_mem_fns_map().end())
21462 {
21463 result = false;
21464 if (k)
21465 *k |= LOCAL_NON_TYPE_CHANGE_KIND;
21466 RETURN(result);
21467 }
21468
21469 const class_decl::member_functions& second_vfns =
21470 second_v_fn_entry->second;
21471
21472 bool matches = false;
21473 for (class_decl::member_functions::const_iterator i =
21474 first_vfns.begin();
21475 i != first_vfns.end();
21476 ++i)
21477 if (method_matches_at_least_one_in_vector(*i, second_vfns))
21478 {
21479 matches = true;
21480 break;
21481 }
21482
21483 if (!matches)
21484 {
21485 result = false;
21486 if (k)
21487 *k |= SUBTYPE_CHANGE_KIND;
21488 else
21489 RETURN(result);
21490 }
21491 }
21492
21493 RETURN(result);
21494 #undef RETURN
21495 }
21496
21497 /// Copy a method of a class into a new class.
21498 ///
21499 /// @param klass the class into which the method is to be copied.
21500 ///
21501 /// @param method the method to copy into @p klass.
21502 ///
21503 /// @return the resulting newly copied method.
21504 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl_sptr & f)21505 copy_member_function(const class_decl_sptr& clazz, const method_decl_sptr& f)
21506 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
21507
21508 /// Copy a method of a class into a new class.
21509 ///
21510 /// @param klass the class into which the method is to be copied.
21511 ///
21512 /// @param method the method to copy into @p klass.
21513 ///
21514 /// @return the resulting newly copied method.
21515 method_decl_sptr
copy_member_function(const class_decl_sptr & clazz,const method_decl * f)21516 copy_member_function(const class_decl_sptr& clazz, const method_decl* f)
21517 {return copy_member_function(static_pointer_cast<class_or_union>(clazz), f);}
21518
21519 /// Comparison operator for @ref class_decl.
21520 ///
21521 /// @param other the instance of @ref class_decl to compare against.
21522 ///
21523 /// @return true iff the current instance of @ref class_decl equals @p
21524 /// other.
21525 bool
operator ==(const decl_base & other) const21526 class_decl::operator==(const decl_base& other) const
21527 {
21528 const class_decl* op = is_class_type(&other);
21529 if (!op)
21530 return false;
21531
21532 // If this is a decl-only type (and thus with no canonical type),
21533 // use the canonical type of the definition, if any.
21534 const class_decl *l = 0;
21535 if (get_is_declaration_only())
21536 l = dynamic_cast<const class_decl*>(get_naked_definition_of_declaration());
21537 if (l == 0)
21538 l = this;
21539
21540 ABG_ASSERT(l);
21541
21542 // Likewise for the other type.
21543 const class_decl *r = 0;
21544 if (op->get_is_declaration_only())
21545 r = dynamic_cast<const class_decl*>(op->get_naked_definition_of_declaration());
21546 if (r == 0)
21547 r = op;
21548
21549 ABG_ASSERT(r);
21550
21551 return try_canonical_compare(l, r);
21552 }
21553
21554 /// Equality operator for class_decl.
21555 ///
21556 /// Re-uses the equality operator that takes a decl_base.
21557 ///
21558 /// @param other the other class_decl to compare against.
21559 ///
21560 /// @return true iff the current instance equals the other one.
21561 bool
operator ==(const type_base & other) const21562 class_decl::operator==(const type_base& other) const
21563 {
21564 const decl_base* o = is_decl(&other);
21565 if (!o)
21566 return false;
21567 return *this == *o;
21568 }
21569
21570 /// Comparison operator for @ref class_decl.
21571 ///
21572 /// @param other the instance of @ref class_decl to compare against.
21573 ///
21574 /// @return true iff the current instance of @ref class_decl equals @p
21575 /// other.
21576 bool
operator ==(const class_decl & other) const21577 class_decl::operator==(const class_decl& other) const
21578 {
21579 const decl_base& o = other;
21580 return *this == o;
21581 }
21582
21583 /// Turn equality of shared_ptr of class_decl into a deep equality;
21584 /// that is, make it compare the pointed to objects too.
21585 ///
21586 /// @param l the shared_ptr of class_decl on left-hand-side of the
21587 /// equality.
21588 ///
21589 /// @param r the shared_ptr of class_decl on right-hand-side of the
21590 /// equality.
21591 ///
21592 /// @return true if the class_decl pointed to by the shared_ptrs are
21593 /// equal, false otherwise.
21594 bool
operator ==(const class_decl_sptr & l,const class_decl_sptr & r)21595 operator==(const class_decl_sptr& l, const class_decl_sptr& r)
21596 {
21597 if (l.get() == r.get())
21598 return true;
21599 if (!!l != !!r)
21600 return false;
21601
21602 return *l == *r;
21603 }
21604
21605 /// Turn inequality of shared_ptr of class_decl into a deep equality;
21606 /// that is, make it compare the pointed to objects too.
21607 ///
21608 /// @param l the shared_ptr of class_decl on left-hand-side of the
21609 /// equality.
21610 ///
21611 /// @param r the shared_ptr of class_decl on right-hand-side of the
21612 /// equality.
21613 ///
21614 /// @return true if the class_decl pointed to by the shared_ptrs are
21615 /// different, false otherwise.
21616 bool
operator !=(const class_decl_sptr & l,const class_decl_sptr & r)21617 operator!=(const class_decl_sptr& l, const class_decl_sptr& r)
21618 {return !operator==(l, r);}
21619
21620 /// Turn equality of shared_ptr of class_or_union into a deep
21621 /// equality; that is, make it compare the pointed to objects too.
21622 ///
21623 /// @param l the left-hand-side operand of the operator
21624 ///
21625 /// @param r the right-hand-side operand of the operator.
21626 ///
21627 /// @return true iff @p l equals @p r.
21628 bool
operator ==(const class_or_union_sptr & l,const class_or_union_sptr & r)21629 operator==(const class_or_union_sptr& l, const class_or_union_sptr& r)
21630 {
21631 if (l.get() == r.get())
21632 return true;
21633 if (!!l != !!r)
21634 return false;
21635
21636 return *l == *r;
21637 }
21638
21639 /// Turn inequality of shared_ptr of class_or_union into a deep
21640 /// equality; that is, make it compare the pointed to objects too.
21641 ///
21642 /// @param l the left-hand-side operand of the operator
21643 ///
21644 /// @param r the right-hand-side operand of the operator.
21645 ///
21646 /// @return true iff @p l is different from @p r.
21647 bool
operator !=(const class_or_union_sptr & l,const class_or_union_sptr & r)21648 operator!=(const class_or_union_sptr& l, const class_or_union_sptr& r)
21649 {return !operator==(l, r);}
21650
21651 /// This implements the ir_traversable_base::traverse pure virtual
21652 /// function.
21653 ///
21654 /// @param v the visitor used on the current instance and on its
21655 /// members.
21656 ///
21657 /// @return true if the entire IR node tree got traversed, false
21658 /// otherwise.
21659 bool
traverse(ir_node_visitor & v)21660 class_decl::traverse(ir_node_visitor& v)
21661 {
21662 if (v.type_node_has_been_visited(this))
21663 return true;
21664
21665 if (visiting())
21666 return true;
21667
21668 if (v.visit_begin(this))
21669 {
21670 visiting(true);
21671 bool stop = false;
21672
21673 for (base_specs::const_iterator i = get_base_specifiers().begin();
21674 i != get_base_specifiers().end();
21675 ++i)
21676 {
21677 if (!(*i)->traverse(v))
21678 {
21679 stop = true;
21680 break;
21681 }
21682 }
21683
21684 if (!stop)
21685 for (data_members::const_iterator i = get_data_members().begin();
21686 i != get_data_members().end();
21687 ++i)
21688 if (!(*i)->traverse(v))
21689 {
21690 stop = true;
21691 break;
21692 }
21693
21694 if (!stop)
21695 for (member_functions::const_iterator i= get_member_functions().begin();
21696 i != get_member_functions().end();
21697 ++i)
21698 if (!(*i)->traverse(v))
21699 {
21700 stop = true;
21701 break;
21702 }
21703
21704 if (!stop)
21705 for (member_types::const_iterator i = get_member_types().begin();
21706 i != get_member_types().end();
21707 ++i)
21708 if (!(*i)->traverse(v))
21709 {
21710 stop = true;
21711 break;
21712 }
21713
21714 if (!stop)
21715 for (member_function_templates::const_iterator i =
21716 get_member_function_templates().begin();
21717 i != get_member_function_templates().end();
21718 ++i)
21719 if (!(*i)->traverse(v))
21720 {
21721 stop = true;
21722 break;
21723 }
21724
21725 if (!stop)
21726 for (member_class_templates::const_iterator i =
21727 get_member_class_templates().begin();
21728 i != get_member_class_templates().end();
21729 ++i)
21730 if (!(*i)->traverse(v))
21731 {
21732 stop = true;
21733 break;
21734 }
21735 visiting(false);
21736 }
21737
21738 bool result = v.visit_end(this);
21739 v.mark_type_node_as_visited(this);
21740 return result;
21741 }
21742
21743 /// Destructor of the @ref class_decl type.
~class_decl()21744 class_decl::~class_decl()
21745 {delete priv_;}
21746
~context_rel()21747 context_rel::~context_rel()
21748 {}
21749
21750 bool
operator ==(const member_base & o) const21751 member_base::operator==(const member_base& o) const
21752 {
21753 return (get_access_specifier() == o.get_access_specifier()
21754 && get_is_static() == o.get_is_static());
21755 }
21756
21757 /// Equality operator for smart pointers to @ref
21758 /// class_decl::base_specs.
21759 ///
21760 /// This compares the pointed-to objects.
21761 ///
21762 /// @param l the first instance to consider.
21763 ///
21764 /// @param r the second instance to consider.
21765 ///
21766 /// @return true iff @p l equals @p r.
21767 bool
operator ==(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)21768 operator==(const class_decl::base_spec_sptr& l,
21769 const class_decl::base_spec_sptr& r)
21770 {
21771 if (l.get() == r.get())
21772 return true;
21773 if (!!l != !!r)
21774 return false;
21775
21776 return *l == static_cast<const decl_base&>(*r);
21777 }
21778
21779 /// Inequality operator for smart pointers to @ref
21780 /// class_decl::base_specs.
21781 ///
21782 /// This compares the pointed-to objects.
21783 ///
21784 /// @param l the first instance to consider.
21785 ///
21786 /// @param r the second instance to consider.
21787 ///
21788 /// @return true iff @p l is different from @p r.
21789 bool
operator !=(const class_decl::base_spec_sptr & l,const class_decl::base_spec_sptr & r)21790 operator!=(const class_decl::base_spec_sptr& l,
21791 const class_decl::base_spec_sptr& r)
21792 {return !operator==(l, r);}
21793
21794 /// Test if an ABI artifact is a class base specifier.
21795 ///
21796 /// @param tod the ABI artifact to consider.
21797 ///
21798 /// @return a pointer to the @ref class_decl::base_spec sub-object of
21799 /// @p tod iff it's a class base specifier.
21800 class_decl::base_spec*
is_class_base_spec(const type_or_decl_base * tod)21801 is_class_base_spec(const type_or_decl_base* tod)
21802 {
21803 return dynamic_cast<class_decl::base_spec*>
21804 (const_cast<type_or_decl_base*>(tod));
21805 }
21806
21807 /// Test if an ABI artifact is a class base specifier.
21808 ///
21809 /// @param tod the ABI artifact to consider.
21810 ///
21811 /// @return a pointer to the @ref class_decl::base_spec sub-object of
21812 /// @p tod iff it's a class base specifier.
21813 class_decl::base_spec_sptr
is_class_base_spec(type_or_decl_base_sptr tod)21814 is_class_base_spec(type_or_decl_base_sptr tod)
21815 {return dynamic_pointer_cast<class_decl::base_spec>(tod);}
21816
21817 bool
operator ==(const member_base & other) const21818 member_function_template::operator==(const member_base& other) const
21819 {
21820 try
21821 {
21822 const member_function_template& o =
21823 dynamic_cast<const member_function_template&>(other);
21824
21825 if (!(is_constructor() == o.is_constructor()
21826 && is_const() == o.is_const()
21827 && member_base::operator==(o)))
21828 return false;
21829
21830 if (function_tdecl_sptr ftdecl = as_function_tdecl())
21831 {
21832 function_tdecl_sptr other_ftdecl = o.as_function_tdecl();
21833 if (other_ftdecl)
21834 return ftdecl->function_tdecl::operator==(*other_ftdecl);
21835 }
21836 }
21837 catch(...)
21838 {}
21839 return false;
21840 }
21841
21842 /// Equality operator for smart pointers to @ref
21843 /// member_function_template. This is compares the
21844 /// pointed-to instances.
21845 ///
21846 /// @param l the first instance to consider.
21847 ///
21848 /// @param r the second instance to consider.
21849 ///
21850 /// @return true iff @p l equals @p r.
21851 bool
operator ==(const member_function_template_sptr & l,const member_function_template_sptr & r)21852 operator==(const member_function_template_sptr& l,
21853 const member_function_template_sptr& r)
21854 {
21855 if (l.get() == r.get())
21856 return true;
21857 if (!!l != !!r)
21858 return false;
21859
21860 return *l == *r;
21861 }
21862
21863 /// Inequality operator for smart pointers to @ref
21864 /// member_function_template. This is compares the pointed-to
21865 /// instances.
21866 ///
21867 /// @param l the first instance to consider.
21868 ///
21869 /// @param r the second instance to consider.
21870 ///
21871 /// @return true iff @p l equals @p r.
21872 bool
operator !=(const member_function_template_sptr & l,const member_function_template_sptr & r)21873 operator!=(const member_function_template_sptr& l,
21874 const member_function_template_sptr& r)
21875 {return !operator==(l, r);}
21876
21877 /// This implements the ir_traversable_base::traverse pure virtual
21878 /// function.
21879 ///
21880 /// @param v the visitor used on the current instance and on its
21881 /// underlying function template.
21882 ///
21883 /// @return true if the entire IR node tree got traversed, false
21884 /// otherwise.
21885 bool
traverse(ir_node_visitor & v)21886 member_function_template::traverse(ir_node_visitor& v)
21887 {
21888 if (visiting())
21889 return true;
21890
21891 if (v.visit_begin(this))
21892 {
21893 visiting(true);
21894 if (function_tdecl_sptr f = as_function_tdecl())
21895 f->traverse(v);
21896 visiting(false);
21897 }
21898 return v.visit_end(this);
21899 }
21900
21901 /// Equality operator of the the @ref member_class_template class.
21902 ///
21903 /// @param other the other @ref member_class_template to compare against.
21904 ///
21905 /// @return true iff the current instance equals @p other.
21906 bool
operator ==(const member_base & other) const21907 member_class_template::operator==(const member_base& other) const
21908 {
21909 try
21910 {
21911 const member_class_template& o =
21912 dynamic_cast<const member_class_template&>(other);
21913
21914 if (!member_base::operator==(o))
21915 return false;
21916
21917 return as_class_tdecl()->class_tdecl::operator==(o);
21918 }
21919 catch(...)
21920 {return false;}
21921 }
21922
21923 /// Comparison operator for the @ref member_class_template
21924 /// type.
21925 ///
21926 /// @param other the other instance of @ref
21927 /// member_class_template to compare against.
21928 ///
21929 /// @return true iff the two instances are equal.
21930 bool
operator ==(const member_class_template & other) const21931 member_class_template::operator==(const member_class_template& other) const
21932 {
21933 const decl_base* o = dynamic_cast<const decl_base*>(&other);
21934 return *this == *o;
21935 }
21936
21937 /// Comparison operator for the @ref member_class_template
21938 /// type.
21939 ///
21940 /// @param l the first argument of the operator.
21941 ///
21942 /// @param r the second argument of the operator.
21943 ///
21944 /// @return true iff the two instances are equal.
21945 bool
operator ==(const member_class_template_sptr & l,const member_class_template_sptr & r)21946 operator==(const member_class_template_sptr& l,
21947 const member_class_template_sptr& r)
21948 {
21949 if (l.get() == r.get())
21950 return true;
21951 if (!!l != !!r)
21952 return false;
21953
21954 return *l == *r;
21955 }
21956
21957 /// Inequality operator for the @ref member_class_template
21958 /// type.
21959 ///
21960 /// @param l the first argument of the operator.
21961 ///
21962 /// @param r the second argument of the operator.
21963 ///
21964 /// @return true iff the two instances are equal.
21965 bool
operator !=(const member_class_template_sptr & l,const member_class_template_sptr & r)21966 operator!=(const member_class_template_sptr& l,
21967 const member_class_template_sptr& r)
21968 {return !operator==(l, r);}
21969
21970 /// This implements the ir_traversable_base::traverse pure virtual
21971 /// function.
21972 ///
21973 /// @param v the visitor used on the current instance and on the class
21974 /// pattern of the template.
21975 ///
21976 /// @return true if the entire IR node tree got traversed, false
21977 /// otherwise.
21978 bool
traverse(ir_node_visitor & v)21979 member_class_template::traverse(ir_node_visitor& v)
21980 {
21981 if (visiting())
21982 return true;
21983
21984 if (v.visit_begin(this))
21985 {
21986 visiting(true);
21987 if (class_tdecl_sptr t = as_class_tdecl())
21988 t->traverse(v);
21989 visiting(false);
21990 }
21991 return v.visit_end(this);
21992 }
21993
21994 /// Streaming operator for class_decl::access_specifier.
21995 ///
21996 /// @param o the output stream to serialize the access specifier to.
21997 ///
21998 /// @param a the access specifier to serialize.
21999 ///
22000 /// @return the output stream.
22001 std::ostream&
operator <<(std::ostream & o,access_specifier a)22002 operator<<(std::ostream& o, access_specifier a)
22003 {
22004 string r;
22005
22006 switch (a)
22007 {
22008 case no_access:
22009 r = "none";
22010 break;
22011 case private_access:
22012 r = "private";
22013 break;
22014 case protected_access:
22015 r = "protected";
22016 break;
22017 case public_access:
22018 r= "public";
22019 break;
22020 };
22021 o << r;
22022 return o;
22023 }
22024
22025 /// Sets the static-ness property of a class member.
22026 ///
22027 /// @param d the class member to set the static-ness property for.
22028 /// Note that this must be a class member otherwise the function
22029 /// aborts the current process.
22030 ///
22031 /// @param s this must be true if the member is to be static, false
22032 /// otherwise.
22033 void
set_member_is_static(decl_base & d,bool s)22034 set_member_is_static(decl_base& d, bool s)
22035 {
22036 ABG_ASSERT(is_member_decl(d));
22037
22038 context_rel* c = d.get_context_rel();
22039 ABG_ASSERT(c);
22040
22041 c->set_is_static(s);
22042
22043 scope_decl* scope = d.get_scope();
22044
22045 if (class_or_union* cl = is_class_or_union_type(scope))
22046 {
22047 if (var_decl* v = is_var_decl(&d))
22048 {
22049 if (s)
22050 // remove from the non-static data members
22051 for (class_decl::data_members::iterator i =
22052 cl->priv_->non_static_data_members_.begin();
22053 i != cl->priv_->non_static_data_members_.end();
22054 ++i)
22055 {
22056 if ((*i)->get_name() == v->get_name())
22057 {
22058 cl->priv_->non_static_data_members_.erase(i);
22059 break;
22060 }
22061 }
22062 else
22063 {
22064 bool is_already_in_non_static_data_members = false;
22065 for (class_or_union::data_members::iterator i =
22066 cl->priv_->non_static_data_members_.begin();
22067 i != cl->priv_->non_static_data_members_.end();
22068 ++i)
22069 {
22070 if ((*i)->get_name() == v->get_name())
22071 {
22072 is_already_in_non_static_data_members = true;
22073 break;
22074 }
22075 }
22076 if (!is_already_in_non_static_data_members)
22077 {
22078 var_decl_sptr var;
22079 // add to non-static data members.
22080 for (class_or_union::data_members::const_iterator i =
22081 cl->priv_->data_members_.begin();
22082 i != cl->priv_->data_members_.end();
22083 ++i)
22084 {
22085 if ((*i)->get_name() == v->get_name())
22086 {
22087 var = *i;
22088 break;
22089 }
22090 }
22091 ABG_ASSERT(var);
22092 cl->priv_->non_static_data_members_.push_back(var);
22093 }
22094 }
22095 }
22096 }
22097 }
22098
22099 /// Sets the static-ness property of a class member.
22100 ///
22101 /// @param d the class member to set the static-ness property for.
22102 /// Note that this must be a class member otherwise the function
22103 /// aborts the current process.
22104 ///
22105 /// @param s this must be true if the member is to be static, false
22106 /// otherwise.
22107 void
set_member_is_static(const decl_base_sptr & d,bool s)22108 set_member_is_static(const decl_base_sptr& d, bool s)
22109 {set_member_is_static(*d, s);}
22110
22111 // </class_decl>
22112
22113 // <union_decl>
22114
22115 /// Constructor for the @ref union_decl type.
22116 ///
22117 /// @param env the @ref environment we are operating from.
22118 ///
22119 /// @param name the name of the union type.
22120 ///
22121 /// @param size_in_bits the size of the union, in bits.
22122 ///
22123 /// @param locus the location of the type.
22124 ///
22125 /// @param vis the visibility of instances of @ref union_decl.
22126 ///
22127 /// @param mbr_types the member types of the union.
22128 ///
22129 /// @param data_mbrs the data members of the union.
22130 ///
22131 /// @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)22132 union_decl::union_decl(const environment* env, const string& name,
22133 size_t size_in_bits, const location& locus,
22134 visibility vis, member_types& mbr_types,
22135 data_members& data_mbrs, member_functions& member_fns)
22136 : type_or_decl_base(env,
22137 UNION_TYPE
22138 | ABSTRACT_TYPE_BASE
22139 | ABSTRACT_DECL_BASE),
22140 decl_base(env, name, locus, name, vis),
22141 type_base(env, size_in_bits, 0),
22142 class_or_union(env, name, size_in_bits, 0,
22143 locus, vis, mbr_types, data_mbrs, member_fns)
22144 {
22145 runtime_type_instance(this);
22146 }
22147
22148 /// Constructor for the @ref union_decl type.
22149 ///
22150 /// @param env the @ref environment we are operating from.
22151 ///
22152 /// @param name the name of the union type.
22153 ///
22154 /// @param size_in_bits the size of the union, in bits.
22155 ///
22156 /// @param locus the location of the type.
22157 ///
22158 /// @param vis the visibility of instances of @ref union_decl.
22159 ///
22160 /// @param mbr_types the member types of the union.
22161 ///
22162 /// @param data_mbrs the data members of the union.
22163 ///
22164 /// @param member_fns the member functions of the union.
22165 ///
22166 /// @param is_anonymous whether the newly created instance is
22167 /// 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)22168 union_decl::union_decl(const environment* env, const string& name,
22169 size_t size_in_bits, const location& locus,
22170 visibility vis, member_types& mbr_types,
22171 data_members& data_mbrs, member_functions& member_fns,
22172 bool is_anonymous)
22173 : type_or_decl_base(env,
22174 UNION_TYPE
22175 | ABSTRACT_TYPE_BASE
22176 | ABSTRACT_DECL_BASE),
22177 decl_base(env, name, locus,
22178 // If the class is anonymous then by default it won't
22179 // have a linkage name. Also, the anonymous class does
22180 // have an internal-only unique name that is generally
22181 // not taken into account when comparing classes; such a
22182 // unique internal-only name, when used as a linkage
22183 // name might introduce spurious comparison false
22184 // negatives.
22185 /*linkage_name=*/is_anonymous ? string() : name,
22186 vis),
22187 type_base(env, size_in_bits, 0),
22188 class_or_union(env, name, size_in_bits, 0,
22189 locus, vis, mbr_types, data_mbrs, member_fns)
22190 {
22191 runtime_type_instance(this);
22192 set_is_anonymous(is_anonymous);
22193 }
22194
22195 /// Constructor for the @ref union_decl type.
22196 ///
22197 /// @param env the @ref environment we are operating from.
22198 ///
22199 /// @param name the name of the union type.
22200 ///
22201 /// @param size_in_bits the size of the union, in bits.
22202 ///
22203 /// @param locus the location of the type.
22204 ///
22205 /// @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)22206 union_decl::union_decl(const environment* env, const string& name,
22207 size_t size_in_bits, const location& locus,
22208 visibility vis)
22209 : type_or_decl_base(env,
22210 UNION_TYPE
22211 | ABSTRACT_TYPE_BASE
22212 | ABSTRACT_DECL_BASE
22213 | ABSTRACT_SCOPE_TYPE_DECL
22214 | ABSTRACT_SCOPE_DECL),
22215 decl_base(env, name, locus, name, vis),
22216 type_base(env, size_in_bits, 0),
22217 class_or_union(env, name, size_in_bits,
22218 0, locus, vis)
22219 {
22220 runtime_type_instance(this);
22221 }
22222
22223 /// Constructor for the @ref union_decl type.
22224 ///
22225 /// @param env the @ref environment we are operating from.
22226 ///
22227 /// @param name the name of the union type.
22228 ///
22229 /// @param size_in_bits the size of the union, in bits.
22230 ///
22231 /// @param locus the location of the type.
22232 ///
22233 /// @param vis the visibility of instances of @ref union_decl.
22234 ///
22235 /// @param is_anonymous whether the newly created instance is
22236 /// anonymous.
union_decl(const environment * env,const string & name,size_t size_in_bits,const location & locus,visibility vis,bool is_anonymous)22237 union_decl::union_decl(const environment* env, const string& name,
22238 size_t size_in_bits, const location& locus,
22239 visibility vis, bool is_anonymous)
22240 : type_or_decl_base(env,
22241 UNION_TYPE
22242 | ABSTRACT_TYPE_BASE
22243 | ABSTRACT_DECL_BASE
22244 | ABSTRACT_SCOPE_TYPE_DECL
22245 | ABSTRACT_SCOPE_DECL),
22246 decl_base(env, name, locus,
22247 // If the class is anonymous then by default it won't
22248 // have a linkage name. Also, the anonymous class does
22249 // have an internal-only unique name that is generally
22250 // not taken into account when comparing classes; such a
22251 // unique internal-only name, when used as a linkage
22252 // name might introduce spurious comparison false
22253 // negatives.
22254 /*linkage_name=*/is_anonymous ? string() : name,
22255 vis),
22256 type_base(env, size_in_bits, 0),
22257 class_or_union(env, name, size_in_bits,
22258 0, locus, vis)
22259 {
22260 runtime_type_instance(this);
22261 set_is_anonymous(is_anonymous);
22262 }
22263
22264 /// Constructor for the @ref union_decl type.
22265 ///
22266 /// @param env the @ref environment we are operating from.
22267 ///
22268 /// @param name the name of the union type.
22269 ///
22270 /// @param is_declaration_only a boolean saying whether the instance
22271 /// represents a declaration only, or not.
union_decl(const environment * env,const string & name,bool is_declaration_only)22272 union_decl::union_decl(const environment* env,
22273 const string& name,
22274 bool is_declaration_only)
22275 : type_or_decl_base(env,
22276 UNION_TYPE
22277 | ABSTRACT_TYPE_BASE
22278 | ABSTRACT_DECL_BASE
22279 | ABSTRACT_SCOPE_TYPE_DECL
22280 | ABSTRACT_SCOPE_DECL),
22281 decl_base(env, name, location(), name),
22282 type_base(env, 0, 0),
22283 class_or_union(env, name, is_declaration_only)
22284 {
22285 runtime_type_instance(this);
22286 }
22287
22288 /// Getter of the pretty representation of the current instance of
22289 /// @ref union_decl.
22290 ///
22291 /// @param internal set to true if the call is intended for an
22292 /// internal use (for technical use inside the library itself), false
22293 /// otherwise. If you don't know what this is for, then set it to
22294 /// false.
22295 ///
22296 /// @param qualified_name if true, names emitted in the pretty
22297 /// representation are fully qualified.
22298 ///
22299 /// @return the pretty representaion for a union_decl.
22300 string
get_pretty_representation(bool internal,bool qualified_name) const22301 union_decl::get_pretty_representation(bool internal,
22302 bool qualified_name) const
22303 {
22304 string repr;
22305 if (get_is_anonymous())
22306 repr = get_class_or_union_flat_representation(this, "",
22307 /*one_line=*/true,
22308 internal);
22309 else
22310 {
22311 repr = "union ";
22312 if (qualified_name)
22313 repr += get_qualified_name(internal);
22314 else
22315 repr += get_name();
22316 }
22317
22318 return repr;
22319 }
22320
22321 /// Comparison operator for @ref union_decl.
22322 ///
22323 /// @param other the instance of @ref union_decl to compare against.
22324 ///
22325 /// @return true iff the current instance of @ref union_decl equals @p
22326 /// other.
22327 bool
operator ==(const decl_base & other) const22328 union_decl::operator==(const decl_base& other) const
22329 {
22330 const union_decl* op = dynamic_cast<const union_decl*>(&other);
22331 if (!op)
22332 return false;
22333 return try_canonical_compare(this, op);
22334 }
22335
22336 /// Equality operator for union_decl.
22337 ///
22338 /// Re-uses the equality operator that takes a decl_base.
22339 ///
22340 /// @param other the other union_decl to compare against.
22341 ///
22342 /// @return true iff the current instance equals the other one.
22343 bool
operator ==(const type_base & other) const22344 union_decl::operator==(const type_base& other) const
22345 {
22346 const decl_base *o = dynamic_cast<const decl_base*>(&other);
22347 if (!o)
22348 return false;
22349 return *this == *o;
22350 }
22351
22352 /// Comparison operator for @ref union_decl.
22353 ///
22354 /// @param other the instance of @ref union_decl to compare against.
22355 ///
22356 /// @return true iff the current instance of @ref union_decl equals @p
22357 /// other.
22358 bool
operator ==(const union_decl & other) const22359 union_decl::operator==(const union_decl& other) const
22360 {
22361 const decl_base& o = other;
22362 return *this == o;
22363 }
22364
22365 /// This implements the ir_traversable_base::traverse pure virtual
22366 /// function.
22367 ///
22368 /// @param v the visitor used on the current instance and on its
22369 /// members.
22370 ///
22371 /// @return true if the entire IR node tree got traversed, false
22372 /// otherwise.
22373 bool
traverse(ir_node_visitor & v)22374 union_decl::traverse(ir_node_visitor& v)
22375 {
22376 if (v.type_node_has_been_visited(this))
22377 return true;
22378
22379 if (visiting())
22380 return true;
22381
22382 if (v.visit_begin(this))
22383 {
22384 visiting(true);
22385 bool stop = false;
22386
22387 if (!stop)
22388 for (data_members::const_iterator i = get_data_members().begin();
22389 i != get_data_members().end();
22390 ++i)
22391 if (!(*i)->traverse(v))
22392 {
22393 stop = true;
22394 break;
22395 }
22396
22397 if (!stop)
22398 for (member_functions::const_iterator i= get_member_functions().begin();
22399 i != get_member_functions().end();
22400 ++i)
22401 if (!(*i)->traverse(v))
22402 {
22403 stop = true;
22404 break;
22405 }
22406
22407 if (!stop)
22408 for (member_types::const_iterator i = get_member_types().begin();
22409 i != get_member_types().end();
22410 ++i)
22411 if (!(*i)->traverse(v))
22412 {
22413 stop = true;
22414 break;
22415 }
22416
22417 if (!stop)
22418 for (member_function_templates::const_iterator i =
22419 get_member_function_templates().begin();
22420 i != get_member_function_templates().end();
22421 ++i)
22422 if (!(*i)->traverse(v))
22423 {
22424 stop = true;
22425 break;
22426 }
22427
22428 if (!stop)
22429 for (member_class_templates::const_iterator i =
22430 get_member_class_templates().begin();
22431 i != get_member_class_templates().end();
22432 ++i)
22433 if (!(*i)->traverse(v))
22434 {
22435 stop = true;
22436 break;
22437 }
22438 visiting(false);
22439 }
22440
22441 bool result = v.visit_end(this);
22442 v.mark_type_node_as_visited(this);
22443 return result;
22444 }
22445
22446 /// Destructor of the @ref union_decl type.
~union_decl()22447 union_decl::~union_decl()
22448 {}
22449
22450 /// Compares two instances of @ref union_decl.
22451 ///
22452 /// If the two intances are different, set a bitfield to give some
22453 /// insight about the kind of differences there are.
22454 ///
22455 /// @param l the first artifact of the comparison.
22456 ///
22457 /// @param r the second artifact of the comparison.
22458 ///
22459 /// @param k a pointer to a bitfield that gives information about the
22460 /// kind of changes there are between @p l and @p r. This one is set
22461 /// iff @p k is non-null and the function returns false.
22462 ///
22463 /// Please note that setting k to a non-null value does have a
22464 /// negative performance impact because even if @p l and @p r are not
22465 /// equal, the function keeps up the comparison in order to determine
22466 /// the different kinds of ways in which they are different.
22467 ///
22468 /// @return true if @p l equals @p r, false otherwise.
22469 bool
equals(const union_decl & l,const union_decl & r,change_kind * k)22470 equals(const union_decl& l, const union_decl& r, change_kind* k)
22471 {
22472 bool result = equals(static_cast<const class_or_union&>(l),
22473 static_cast<const class_or_union&>(r),
22474 k);
22475 if (result == true)
22476 maybe_propagate_canonical_type(l, r);
22477 return result;
22478 }
22479
22480 /// Copy a method of a @ref union_decl into a new @ref
22481 /// union_decl.
22482 ///
22483 /// @param t the @ref union_decl into which the method is to be copied.
22484 ///
22485 /// @param method the method to copy into @p t.
22486 ///
22487 /// @return the resulting newly copied method.
22488 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl_sptr & f)22489 copy_member_function(const union_decl_sptr& union_type,
22490 const method_decl_sptr& f)
22491 {return copy_member_function(union_type, f.get());}
22492
22493 /// Copy a method of a @ref union_decl into a new @ref
22494 /// union_decl.
22495 ///
22496 /// @param t the @ref union_decl into which the method is to be copied.
22497 ///
22498 /// @param method the method to copy into @p t.
22499 ///
22500 /// @return the resulting newly copied method.
22501 method_decl_sptr
copy_member_function(const union_decl_sptr & union_type,const method_decl * f)22502 copy_member_function(const union_decl_sptr& union_type,
22503 const method_decl* f)
22504 {
22505 const class_or_union_sptr t = union_type;
22506 return copy_member_function(t, f);
22507 }
22508
22509 /// Turn equality of shared_ptr of union_decl into a deep equality;
22510 /// that is, make it compare the pointed to objects too.
22511 ///
22512 /// @param l the left-hand-side operand of the operator
22513 ///
22514 /// @param r the right-hand-side operand of the operator.
22515 ///
22516 /// @return true iff @p l equals @p r.
22517 bool
operator ==(const union_decl_sptr & l,const union_decl_sptr & r)22518 operator==(const union_decl_sptr& l, const union_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 /// Turn inequality of shared_ptr of union_decl into a deep equality;
22529 /// that is, make it compare the pointed to objects too.
22530 ///
22531 /// @param l the left-hand-side operand of the operator
22532 ///
22533 /// @param r the right-hand-side operand of the operator.
22534 ///
22535 /// @return true iff @p l is different from @p r.
22536 bool
operator !=(const union_decl_sptr & l,const union_decl_sptr & r)22537 operator!=(const union_decl_sptr& l, const union_decl_sptr& r)
22538 {return !operator==(l, r);}
22539 // </union_decl>
22540
22541 // <template_decl stuff>
22542
22543 /// Data type of the private data of the @template_decl type.
22544 class template_decl::priv
22545 {
22546 friend class template_decl;
22547
22548 std::list<template_parameter_sptr> parms_;
22549 public:
22550
priv()22551 priv()
22552 {}
22553 }; // end class template_decl::priv
22554
22555 /// Add a new template parameter to the current instance of @ref
22556 /// template_decl.
22557 ///
22558 /// @param p the new template parameter to add.
22559 void
add_template_parameter(const template_parameter_sptr p)22560 template_decl::add_template_parameter(const template_parameter_sptr p)
22561 {priv_->parms_.push_back(p);}
22562
22563 /// Get the list of template parameters of the current instance of
22564 /// @ref template_decl.
22565 ///
22566 /// @return the list of template parameters.
22567 const std::list<template_parameter_sptr>&
get_template_parameters() const22568 template_decl::get_template_parameters() const
22569 {return priv_->parms_;}
22570
22571 /// Constructor.
22572 ///
22573 /// @param env the environment we are operating from.
22574 ///
22575 /// @param name the name of the template decl.
22576 ///
22577 /// @param locus the source location where the template declaration is
22578 /// defined.
22579 ///
22580 /// @param vis the visibility of the template declaration.
template_decl(const environment * env,const string & name,const location & locus,visibility vis)22581 template_decl::template_decl(const environment* env,
22582 const string& name,
22583 const location& locus,
22584 visibility vis)
22585 : type_or_decl_base(env, TEMPLATE_DECL | ABSTRACT_DECL_BASE),
22586 decl_base(env, name, locus, /*mangled_name=*/"", vis),
22587 priv_(new priv)
22588 {
22589 runtime_type_instance(this);
22590 }
22591
22592 /// Destructor.
~template_decl()22593 template_decl::~template_decl()
22594 {}
22595
22596 /// Equality operator.
22597 ///
22598 /// @param o the other instance to compare against.
22599 ///
22600 /// @return true iff @p equals the current instance.
22601 bool
operator ==(const template_decl & o) const22602 template_decl::operator==(const template_decl& o) const
22603 {
22604 try
22605 {
22606 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
22607 for (t0 = get_template_parameters().begin(),
22608 t1 = o.get_template_parameters().begin();
22609 (t0 != get_template_parameters().end()
22610 && t1 != o.get_template_parameters().end());
22611 ++t0, ++t1)
22612 {
22613 if (**t0 != **t1)
22614 return false;
22615 }
22616
22617 if (t0 != get_template_parameters().end()
22618 || t1 != o.get_template_parameters().end())
22619 return false;
22620
22621 return true;
22622 }
22623 catch(...)
22624 {return false;}
22625 }
22626
22627 // </template_decl stuff>
22628
22629 //<template_parameter>
22630
22631 /// The type of the private data of the @ref template_parameter type.
22632 class template_parameter::priv
22633 {
22634 friend class template_parameter;
22635
22636 unsigned index_;
22637 template_decl_wptr template_decl_;
22638 mutable bool hashing_started_;
22639 mutable bool comparison_started_;
22640
22641 priv();
22642
22643 public:
22644
priv(unsigned index,template_decl_sptr enclosing_template_decl)22645 priv(unsigned index, template_decl_sptr enclosing_template_decl)
22646 : index_(index),
22647 template_decl_(enclosing_template_decl),
22648 hashing_started_(),
22649 comparison_started_()
22650 {}
22651 }; // end class template_parameter::priv
22652
template_parameter(unsigned index,template_decl_sptr enclosing_template)22653 template_parameter::template_parameter(unsigned index,
22654 template_decl_sptr enclosing_template)
22655 : priv_(new priv(index, enclosing_template))
22656 {}
22657
22658 unsigned
get_index() const22659 template_parameter::get_index() const
22660 {return priv_->index_;}
22661
22662 const template_decl_sptr
get_enclosing_template_decl() const22663 template_parameter::get_enclosing_template_decl() const
22664 {return priv_->template_decl_.lock();}
22665
22666 bool
get_hashing_has_started() const22667 template_parameter::get_hashing_has_started() const
22668 {return priv_->hashing_started_;}
22669
22670 void
set_hashing_has_started(bool f) const22671 template_parameter::set_hashing_has_started(bool f) const
22672 {priv_->hashing_started_ = f;}
22673
22674 bool
operator ==(const template_parameter & o) const22675 template_parameter::operator==(const template_parameter& o) const
22676 {
22677 if (get_index() != o.get_index())
22678 return false;
22679
22680 if (priv_->comparison_started_)
22681 return true;
22682
22683 bool result = false;
22684
22685 // Avoid inifite loops due to the fact that comparison the enclosing
22686 // template decl might lead to comparing this very same template
22687 // parameter with another one ...
22688 priv_->comparison_started_ = true;
22689
22690 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
22691 ;
22692 else if (get_enclosing_template_decl()
22693 && (*get_enclosing_template_decl()
22694 != *o.get_enclosing_template_decl()))
22695 ;
22696 else
22697 result = true;
22698
22699 priv_->comparison_started_ = false;
22700
22701 return result;
22702 }
22703
22704 /// Inequality operator.
22705 ///
22706 /// @param other the other instance to compare against.
22707 ///
22708 /// @return true iff the other instance is different from the current
22709 /// one.
22710 bool
operator !=(const template_parameter & other) const22711 template_parameter::operator!=(const template_parameter& other) const
22712 {return !operator==(other);}
22713
22714 /// Destructor.
~template_parameter()22715 template_parameter::~template_parameter()
22716 {}
22717
22718 /// The type of the private data of the @ref type_tparameter type.
22719 class type_tparameter::priv
22720 {
22721 friend class type_tparameter;
22722 }; // end class type_tparameter::priv
22723
22724 /// Constructor of the @ref type_tparameter type.
22725 ///
22726 /// @param index the index the type template parameter.
22727 ///
22728 /// @param enclosing_tdecl the enclosing template declaration.
22729 ///
22730 /// @param name the name of the template parameter.
22731 ///
22732 /// @param locus the location of the declaration of this type template
22733 /// parameter.
type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)22734 type_tparameter::type_tparameter(unsigned index,
22735 template_decl_sptr enclosing_tdecl,
22736 const string& name,
22737 const location& locus)
22738 : type_or_decl_base(enclosing_tdecl->get_environment(),
22739 ABSTRACT_DECL_BASE
22740 | ABSTRACT_TYPE_BASE
22741 | BASIC_TYPE),
22742 decl_base(enclosing_tdecl->get_environment(), name, locus),
22743 type_base(enclosing_tdecl->get_environment(), 0, 0),
22744 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
22745 template_parameter(index, enclosing_tdecl),
22746 priv_(new priv)
22747 {
22748 runtime_type_instance(this);
22749 }
22750
22751 bool
operator ==(const type_base & other) const22752 type_tparameter::operator==(const type_base& other) const
22753 {
22754 if (!type_decl::operator==(other))
22755 return false;
22756
22757 try
22758 {
22759 const type_tparameter& o = dynamic_cast<const type_tparameter&>(other);
22760 return template_parameter::operator==(o);
22761 }
22762 catch (...)
22763 {return false;}
22764 }
22765
22766 bool
operator ==(const template_parameter & other) const22767 type_tparameter::operator==(const template_parameter& other) const
22768 {
22769 try
22770 {
22771 const type_base& o = dynamic_cast<const type_base&>(other);
22772 return *this == o;
22773 }
22774 catch(...)
22775 {return false;}
22776 }
22777
22778 bool
operator ==(const type_tparameter & other) const22779 type_tparameter::operator==(const type_tparameter& other) const
22780 {return *this == static_cast<const type_base&>(other);}
22781
~type_tparameter()22782 type_tparameter::~type_tparameter()
22783 {}
22784
22785 /// The type of the private data of the @ref non_type_tparameter type.
22786 class non_type_tparameter::priv
22787 {
22788 friend class non_type_tparameter;
22789
22790 type_base_wptr type_;
22791
22792 priv();
22793
22794 public:
22795
priv(type_base_sptr type)22796 priv(type_base_sptr type)
22797 : type_(type)
22798 {}
22799 }; // end class non_type_tparameter::priv
22800
22801 /// The constructor for the @ref non_type_tparameter type.
22802 ///
22803 /// @param index the index of the template parameter.
22804 ///
22805 /// @param enclosing_tdecl the enclosing template declaration that
22806 /// holds this parameter parameter.
22807 ///
22808 /// @param name the name of the template parameter.
22809 ///
22810 /// @param type the type of the template parameter.
22811 ///
22812 /// @param locus the location of the declaration of this template
22813 /// parameter.
non_type_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,type_base_sptr type,const location & locus)22814 non_type_tparameter::non_type_tparameter(unsigned index,
22815 template_decl_sptr enclosing_tdecl,
22816 const string& name,
22817 type_base_sptr type,
22818 const location& locus)
22819 : type_or_decl_base(type->get_environment(), ABSTRACT_DECL_BASE),
22820 decl_base(type->get_environment(), name, locus, ""),
22821 template_parameter(index, enclosing_tdecl),
22822 priv_(new priv(type))
22823 {
22824 runtime_type_instance(this);
22825 }
22826
22827 /// Getter for the type of the template parameter.
22828 ///
22829 /// @return the type of the template parameter.
22830 const type_base_sptr
get_type() const22831 non_type_tparameter::get_type() const
22832 {return priv_->type_.lock();}
22833
22834 /// Get the hash value of the current instance.
22835 ///
22836 /// @return the hash value.
22837 size_t
get_hash() const22838 non_type_tparameter::get_hash() const
22839 {
22840 non_type_tparameter::hash hash_tparm;
22841 return hash_tparm(this);
22842 }
22843
22844 bool
operator ==(const decl_base & other) const22845 non_type_tparameter::operator==(const decl_base& other) const
22846 {
22847 if (!decl_base::operator==(other))
22848 return false;
22849
22850 try
22851 {
22852 const non_type_tparameter& o =
22853 dynamic_cast<const non_type_tparameter&>(other);
22854 return (template_parameter::operator==(o)
22855 && get_type() == o.get_type());
22856 }
22857 catch(...)
22858 {return false;}
22859 }
22860
22861 bool
operator ==(const template_parameter & other) const22862 non_type_tparameter::operator==(const template_parameter& other) const
22863 {
22864 try
22865 {
22866 const decl_base& o = dynamic_cast<const decl_base&>(other);
22867 return *this == o;
22868 }
22869 catch(...)
22870 {return false;}
22871 }
22872
~non_type_tparameter()22873 non_type_tparameter::~non_type_tparameter()
22874 {}
22875
22876 // <template_tparameter stuff>
22877
22878 /// Type of the private data of the @ref template_tparameter type.
22879 class template_tparameter::priv
22880 {
22881 }; //end class template_tparameter::priv
22882
22883 /// Constructor for the @ref template_tparameter.
22884 ///
22885 /// @param index the index of the template parameter.
22886 ///
22887 /// @param enclosing_tdecl the enclosing template declaration.
22888 ///
22889 /// @param name the name of the template parameter.
22890 ///
22891 /// @param locus the location of the declaration of the template
22892 /// parameter.
template_tparameter(unsigned index,template_decl_sptr enclosing_tdecl,const string & name,const location & locus)22893 template_tparameter::template_tparameter(unsigned index,
22894 template_decl_sptr enclosing_tdecl,
22895 const string& name,
22896 const location& locus)
22897 : type_or_decl_base(enclosing_tdecl->get_environment(),
22898 ABSTRACT_DECL_BASE
22899 | ABSTRACT_TYPE_BASE
22900 | BASIC_TYPE),
22901 decl_base(enclosing_tdecl->get_environment(), name, locus),
22902 type_base(enclosing_tdecl->get_environment(), 0, 0),
22903 type_decl(enclosing_tdecl->get_environment(), name,
22904 0, 0, locus, name, VISIBILITY_DEFAULT),
22905 type_tparameter(index, enclosing_tdecl, name, locus),
22906 template_decl(enclosing_tdecl->get_environment(), name, locus),
22907 priv_(new priv)
22908 {
22909 runtime_type_instance(this);
22910 }
22911
22912 bool
operator ==(const type_base & other) const22913 template_tparameter::operator==(const type_base& other) const
22914 {
22915 try
22916 {
22917 const template_tparameter& o =
22918 dynamic_cast<const template_tparameter&>(other);
22919 return (type_tparameter::operator==(o)
22920 && template_decl::operator==(o));
22921 }
22922 catch(...)
22923 {return false;}
22924 }
22925
22926 bool
operator ==(const template_parameter & o) const22927 template_tparameter::operator==(const template_parameter& o) const
22928 {
22929 try
22930 {
22931 const template_tparameter& other =
22932 dynamic_cast<const template_tparameter&>(o);
22933 return *this == static_cast<const type_base&>(other);
22934 }
22935 catch(...)
22936 {return false;}
22937 }
22938
22939 bool
operator ==(const template_decl & o) const22940 template_tparameter::operator==(const template_decl& o) const
22941 {
22942 try
22943 {
22944 const template_tparameter& other =
22945 dynamic_cast<const template_tparameter&>(o);
22946 return type_base::operator==(other);
22947 }
22948 catch(...)
22949 {return false;}
22950 }
22951
~template_tparameter()22952 template_tparameter::~template_tparameter()
22953 {}
22954
22955 // </template_tparameter stuff>
22956
22957 // <type_composition stuff>
22958
22959 /// The type of the private data of the @ref type_composition type.
22960 class type_composition::priv
22961 {
22962 friend class type_composition;
22963
22964 type_base_wptr type_;
22965
22966 // Forbid this.
22967 priv();
22968
22969 public:
22970
priv(type_base_wptr type)22971 priv(type_base_wptr type)
22972 : type_(type)
22973 {}
22974 }; //end class type_composition::priv
22975
22976 /// Constructor for the @ref type_composition type.
22977 ///
22978 /// @param index the index of the template type composition.
22979 ///
22980 /// @param tdecl the enclosing template parameter that owns the
22981 /// composition.
22982 ///
22983 /// @param t the resulting type.
type_composition(unsigned index,template_decl_sptr tdecl,type_base_sptr t)22984 type_composition::type_composition(unsigned index,
22985 template_decl_sptr tdecl,
22986 type_base_sptr t)
22987 : type_or_decl_base(tdecl->get_environment(),
22988 ABSTRACT_DECL_BASE),
22989 decl_base(tdecl->get_environment(), "", location()),
22990 template_parameter(index, tdecl),
22991 priv_(new priv(t))
22992 {
22993 runtime_type_instance(this);
22994 }
22995
22996 /// Getter for the resulting composed type.
22997 ///
22998 /// @return the composed type.
22999 const type_base_sptr
get_composed_type() const23000 type_composition::get_composed_type() const
23001 {return priv_->type_.lock();}
23002
23003 /// Setter for the resulting composed type.
23004 ///
23005 /// @param t the composed type.
23006 void
set_composed_type(type_base_sptr t)23007 type_composition::set_composed_type(type_base_sptr t)
23008 {priv_->type_ = t;}
23009
23010 /// Get the hash value for the current instance.
23011 ///
23012 /// @return the hash value.
23013 size_t
get_hash() const23014 type_composition::get_hash() const
23015 {
23016 type_composition::hash hash_type_composition;
23017 return hash_type_composition(this);
23018 }
23019
~type_composition()23020 type_composition::~type_composition()
23021 {}
23022
23023 // </type_composition stuff>
23024
23025 //</template_parameter stuff>
23026
23027 // <function_template>
23028
23029 class function_tdecl::priv
23030 {
23031 friend class function_tdecl;
23032
23033 function_decl_sptr pattern_;
23034 binding binding_;
23035
23036 priv();
23037
23038 public:
23039
priv(function_decl_sptr pattern,binding bind)23040 priv(function_decl_sptr pattern, binding bind)
23041 : pattern_(pattern), binding_(bind)
23042 {}
23043
priv(binding bind)23044 priv(binding bind)
23045 : binding_(bind)
23046 {}
23047 }; // end class function_tdecl::priv
23048
23049 /// Constructor for a function template declaration.
23050 ///
23051 /// @param env the environment we are operating from.
23052 ///
23053 /// @param locus the location of the declaration.
23054 ///
23055 /// @param vis the visibility of the declaration. This is the
23056 /// visibility the functions instantiated from this template are going
23057 /// to have.
23058 ///
23059 /// @param bind the binding of the declaration. This is the binding
23060 /// the functions instantiated from this template are going to have.
function_tdecl(const environment * env,const location & locus,visibility vis,binding bind)23061 function_tdecl::function_tdecl(const environment* env,
23062 const location& locus,
23063 visibility vis,
23064 binding bind)
23065 : type_or_decl_base(env,
23066 ABSTRACT_DECL_BASE
23067 | TEMPLATE_DECL
23068 | ABSTRACT_SCOPE_DECL),
23069 decl_base(env, "", locus, "", vis),
23070 template_decl(env, "", locus, vis),
23071 scope_decl(env, "", locus),
23072 priv_(new priv(bind))
23073 {
23074 runtime_type_instance(this);
23075 }
23076
23077 /// Constructor for a function template declaration.
23078 ///
23079 /// @param pattern the pattern of the template.
23080 ///
23081 /// @param locus the location of the declaration.
23082 ///
23083 /// @param vis the visibility of the declaration. This is the
23084 /// visibility the functions instantiated from this template are going
23085 /// to have.
23086 ///
23087 /// @param bind the binding of the declaration. This is the binding
23088 /// the functions instantiated from this template are going to have.
function_tdecl(function_decl_sptr pattern,const location & locus,visibility vis,binding bind)23089 function_tdecl::function_tdecl(function_decl_sptr pattern,
23090 const location& locus,
23091 visibility vis,
23092 binding bind)
23093 : type_or_decl_base(pattern->get_environment(),
23094 ABSTRACT_DECL_BASE
23095 | TEMPLATE_DECL
23096 | ABSTRACT_SCOPE_DECL),
23097 decl_base(pattern->get_environment(), pattern->get_name(), locus,
23098 pattern->get_name(), vis),
23099 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
23100 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
23101 priv_(new priv(pattern, bind))
23102 {
23103 runtime_type_instance(this);
23104 }
23105
23106 /// Set a new pattern to the function template.
23107 ///
23108 /// @param p the new pattern.
23109 void
set_pattern(function_decl_sptr p)23110 function_tdecl::set_pattern(function_decl_sptr p)
23111 {
23112 priv_->pattern_ = p;
23113 add_decl_to_scope(p, this);
23114 set_name(p->get_name());
23115 }
23116
23117 /// Get the pattern of the function template.
23118 ///
23119 /// @return the pattern.
23120 function_decl_sptr
get_pattern() const23121 function_tdecl::get_pattern() const
23122 {return priv_->pattern_;}
23123
23124 /// Get the binding of the function template.
23125 ///
23126 /// @return the binding
23127 decl_base::binding
get_binding() const23128 function_tdecl::get_binding() const
23129 {return priv_->binding_;}
23130
23131 /// Comparison operator for the @ref function_tdecl type.
23132 ///
23133 /// @param other the other instance of @ref function_tdecl to compare against.
23134 ///
23135 /// @return true iff the two instance are equal.
23136 bool
operator ==(const decl_base & other) const23137 function_tdecl::operator==(const decl_base& other) const
23138 {
23139 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
23140 if (o)
23141 return *this == *o;
23142 return false;
23143 }
23144
23145 /// Comparison operator for the @ref function_tdecl type.
23146 ///
23147 /// @param other the other instance of @ref function_tdecl to compare against.
23148 ///
23149 /// @return true iff the two instance are equal.
23150 bool
operator ==(const template_decl & other) const23151 function_tdecl::operator==(const template_decl& other) const
23152 {
23153 const function_tdecl* o = dynamic_cast<const function_tdecl*>(&other);
23154 if (o)
23155 return *this == *o;
23156 return false;
23157 }
23158
23159 /// Comparison operator for the @ref function_tdecl type.
23160 ///
23161 /// @param o the other instance of @ref function_tdecl to compare against.
23162 ///
23163 /// @return true iff the two instance are equal.
23164 bool
operator ==(const function_tdecl & o) const23165 function_tdecl::operator==(const function_tdecl& o) const
23166 {
23167 if (!(get_binding() == o.get_binding()
23168 && template_decl::operator==(o)
23169 && scope_decl::operator==(o)
23170 && !!get_pattern() == !!o.get_pattern()))
23171 return false;
23172
23173 if (get_pattern())
23174 return (*get_pattern() == *o.get_pattern());
23175
23176 return true;
23177 }
23178
23179 /// This implements the ir_traversable_base::traverse pure virtual
23180 /// function.
23181 ///
23182 /// @param v the visitor used on the current instance and on the
23183 /// function pattern of the template.
23184 ///
23185 /// @return true if the entire IR node tree got traversed, false
23186 /// otherwise.
23187 bool
traverse(ir_node_visitor & v)23188 function_tdecl::traverse(ir_node_visitor&v)
23189 {
23190 if (visiting())
23191 return true;
23192
23193 if (!v.visit_begin(this))
23194 {
23195 visiting(true);
23196 if (get_pattern())
23197 get_pattern()->traverse(v);
23198 visiting(false);
23199 }
23200 return v.visit_end(this);
23201 }
23202
~function_tdecl()23203 function_tdecl::~function_tdecl()
23204 {}
23205
23206 // </function_template>
23207
23208 // <class template>
23209
23210 /// Type of the private data of the the @ref class_tdecl type.
23211 class class_tdecl::priv
23212 {
23213 friend class class_tdecl;
23214 class_decl_sptr pattern_;
23215
23216 public:
23217
priv()23218 priv()
23219 {}
23220
priv(class_decl_sptr pattern)23221 priv(class_decl_sptr pattern)
23222 : pattern_(pattern)
23223 {}
23224 }; // end class class_tdecl::priv
23225
23226 /// Constructor for the @ref class_tdecl type.
23227 ///
23228 /// @param env the environment we are operating from.
23229 ///
23230 /// @param locus the location of the declaration of the class_tdecl
23231 /// type.
23232 ///
23233 /// @param vis the visibility of the instance of class instantiated
23234 /// from this template.
class_tdecl(const environment * env,const location & locus,visibility vis)23235 class_tdecl::class_tdecl(const environment* env,
23236 const location& locus,
23237 visibility vis)
23238 : type_or_decl_base(env,
23239 ABSTRACT_DECL_BASE
23240 | TEMPLATE_DECL
23241 | ABSTRACT_SCOPE_DECL),
23242 decl_base(env, "", locus, "", vis),
23243 template_decl(env, "", locus, vis),
23244 scope_decl(env, "", locus),
23245 priv_(new priv)
23246 {
23247 runtime_type_instance(this);
23248 }
23249
23250 /// Constructor for the @ref class_tdecl type.
23251 ///
23252 /// @param pattern The details of the class template. This must NOT be a
23253 /// null pointer. If you really this to be null, please use the
23254 /// constructor above instead.
23255 ///
23256 /// @param locus the source location of the declaration of the type.
23257 ///
23258 /// @param vis the visibility of the instances of class instantiated
23259 /// from this template.
class_tdecl(class_decl_sptr pattern,const location & locus,visibility vis)23260 class_tdecl::class_tdecl(class_decl_sptr pattern,
23261 const location& locus,
23262 visibility vis)
23263 : type_or_decl_base(pattern->get_environment(),
23264 ABSTRACT_DECL_BASE
23265 | TEMPLATE_DECL
23266 | ABSTRACT_SCOPE_DECL),
23267 decl_base(pattern->get_environment(), pattern->get_name(),
23268 locus, pattern->get_name(), vis),
23269 template_decl(pattern->get_environment(), pattern->get_name(), locus, vis),
23270 scope_decl(pattern->get_environment(), pattern->get_name(), locus),
23271 priv_(new priv(pattern))
23272 {
23273 runtime_type_instance(this);
23274 }
23275
23276 /// Setter of the pattern of the template.
23277 ///
23278 /// @param p the new template.
23279 void
set_pattern(class_decl_sptr p)23280 class_tdecl::set_pattern(class_decl_sptr p)
23281 {
23282 priv_->pattern_ = p;
23283 add_decl_to_scope(p, this);
23284 set_name(p->get_name());
23285 }
23286
23287 /// Getter of the pattern of the template.
23288 ///
23289 /// @return p the new template.
23290 class_decl_sptr
get_pattern() const23291 class_tdecl::get_pattern() const
23292 {return priv_->pattern_;}
23293
23294 bool
operator ==(const decl_base & other) const23295 class_tdecl::operator==(const decl_base& other) const
23296 {
23297 try
23298 {
23299 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
23300
23301 if (!(template_decl::operator==(o)
23302 && scope_decl::operator==(o)
23303 && !!get_pattern() == !!o.get_pattern()))
23304 return false;
23305
23306 if (!get_pattern() || !o.get_pattern())
23307 return true;
23308
23309 return get_pattern()->decl_base::operator==(*o.get_pattern());
23310 }
23311 catch(...) {}
23312 return false;
23313 }
23314
23315 bool
operator ==(const template_decl & other) const23316 class_tdecl::operator==(const template_decl& other) const
23317 {
23318 try
23319 {
23320 const class_tdecl& o = dynamic_cast<const class_tdecl&>(other);
23321 return *this == static_cast<const decl_base&>(o);
23322 }
23323 catch(...)
23324 {return false;}
23325 }
23326
23327 bool
operator ==(const class_tdecl & o) const23328 class_tdecl::operator==(const class_tdecl& o) const
23329 {return *this == static_cast<const decl_base&>(o);}
23330
23331 /// This implements the ir_traversable_base::traverse pure virtual
23332 /// function.
23333 ///
23334 /// @param v the visitor used on the current instance and on the class
23335 /// pattern of the template.
23336 ///
23337 /// @return true if the entire IR node tree got traversed, false
23338 /// otherwise.
23339 bool
traverse(ir_node_visitor & v)23340 class_tdecl::traverse(ir_node_visitor&v)
23341 {
23342 if (visiting())
23343 return true;
23344
23345 if (v.visit_begin(this))
23346 {
23347 visiting(true);
23348 if (class_decl_sptr pattern = get_pattern())
23349 pattern->traverse(v);
23350 visiting(false);
23351 }
23352 return v.visit_end(this);
23353 }
23354
~class_tdecl()23355 class_tdecl::~class_tdecl()
23356 {}
23357
23358 /// This visitor checks if a given type as non-canonicalized sub
23359 /// types.
23360 class non_canonicalized_subtype_detector : public ir::ir_node_visitor
23361 {
23362 type_base* type_;
23363 type_base* has_non_canonical_type_;
23364
23365 private:
23366 non_canonicalized_subtype_detector();
23367
23368 public:
non_canonicalized_subtype_detector(type_base * type)23369 non_canonicalized_subtype_detector(type_base* type)
23370 : type_(type),
23371 has_non_canonical_type_()
23372 {}
23373
23374 /// Return true if the visitor detected that there is a
23375 /// non-canonicalized sub-type.
23376 ///
23377 /// @return true if the visitor detected that there is a
23378 /// non-canonicalized sub-type.
23379 type_base*
has_non_canonical_type() const23380 has_non_canonical_type() const
23381 {return has_non_canonical_type_;}
23382
23383 /// The intent of this visitor handler is to avoid looking into
23384 /// sub-types of member functions of the type we are traversing.
23385 bool
visit_begin(function_decl * f)23386 visit_begin(function_decl* f)
23387 {
23388 // Do not look at sub-types of non-virtual member functions.
23389 if (is_member_function(f)
23390 && get_member_function_is_virtual(*f))
23391 return false;
23392 return true;
23393 }
23394
23395 /// When visiting a sub-type, if it's *NOT* been canonicalized, set
23396 /// the 'has_non_canonical_type' flag. And in any case, when
23397 /// visiting a sub-type, do not visit its children nodes. So this
23398 /// function only goes to the level below the level of the top-most
23399 /// type.
23400 ///
23401 /// @return true if we are at the same level as the top-most type,
23402 /// otherwise return false.
23403 bool
visit_begin(type_base * t)23404 visit_begin(type_base* t)
23405 {
23406 if (t != type_)
23407 {
23408 if (!t->get_canonical_type())
23409 // We are looking a sub-type of 'type_' which has no
23410 // canonical type. So tada! we found one! Get out right
23411 // now with the trophy.
23412 has_non_canonical_type_ = t;
23413
23414 return false;
23415 }
23416 return true;
23417 }
23418
23419 /// When we are done visiting a sub-type, if it's been flagged as
23420 /// been non-canonicalized, then stop the traversing.
23421 ///
23422 /// Otherwise, keep going.
23423 ///
23424 /// @return false iff the sub-type that has been visited is
23425 /// non-canonicalized.
23426 bool
visit_end(type_base *)23427 visit_end(type_base* )
23428 {
23429 if (has_non_canonical_type_)
23430 return false;
23431 return true;
23432 }
23433 }; //end class non_canonicalized_subtype_detector
23434
23435 /// Test if a type has sub-types that are non-canonicalized.
23436 ///
23437 /// @param t the type which sub-types to consider.
23438 ///
23439 /// @return true if a type has sub-types that are non-canonicalized.
23440 type_base*
type_has_non_canonicalized_subtype(type_base_sptr t)23441 type_has_non_canonicalized_subtype(type_base_sptr t)
23442 {
23443 if (!t)
23444 return 0;
23445
23446 non_canonicalized_subtype_detector v(t.get());
23447 t->traverse(v);
23448 return v.has_non_canonical_type();
23449 }
23450
23451 /// Tests if the change of a given type effectively comes from just
23452 /// its sub-types. That is, if the type has changed but its type name
23453 /// hasn't changed, then the change of the type mostly likely is a
23454 /// sub-type change.
23455 ///
23456 /// @param t_v1 the first version of the type.
23457 ///
23458 /// @param t_v2 the second version of the type.
23459 ///
23460 /// @return true iff the type changed and the change is about its
23461 /// sub-types.
23462 bool
type_has_sub_type_changes(const type_base_sptr t_v1,const type_base_sptr t_v2)23463 type_has_sub_type_changes(const type_base_sptr t_v1,
23464 const type_base_sptr t_v2)
23465 {
23466 type_base_sptr t1 = strip_typedef(t_v1);
23467 type_base_sptr t2 = strip_typedef(t_v2);
23468
23469 string repr1 = get_pretty_representation(t1),
23470 repr2 = get_pretty_representation(t2);
23471 return (t1 != t2 && repr1 == repr2);
23472 }
23473
23474 /// Make sure that the life time of a given (smart pointer to a) type
23475 /// is the same as the life time of the libabigail library.
23476 ///
23477 /// @param t the type to consider.
23478 void
keep_type_alive(type_base_sptr t)23479 keep_type_alive(type_base_sptr t)
23480 {
23481 environment* env = t->get_environment();
23482 ABG_ASSERT(env);
23483 env->priv_->extra_live_types_.push_back(t);
23484 }
23485
23486 /// Hash an ABI artifact that is either a type or a decl.
23487 ///
23488 /// This function intends to provides the fastest possible hashing for
23489 /// types and decls, while being completely correct.
23490 ///
23491 /// Note that if the artifact is a type and if it has a canonical
23492 /// type, the hash value is going to be the pointer value of the
23493 /// canonical type. Otherwise, this function computes a hash value
23494 /// for the type by recursively walking the type members. This last
23495 /// code path is possibly *very* slow and should only be used when
23496 /// only handful of types are going to be hashed.
23497 ///
23498 /// If the artifact is a decl, then a combination of the hash of its
23499 /// type and the hash of the other properties of the decl is computed.
23500 ///
23501 /// @param tod the type or decl to hash.
23502 ///
23503 /// @return the resulting hash value.
23504 size_t
hash_type_or_decl(const type_or_decl_base * tod)23505 hash_type_or_decl(const type_or_decl_base *tod)
23506 {
23507 size_t result = 0;
23508
23509 if (tod == 0)
23510 ;
23511 else if (const type_base* t = is_type(tod))
23512 result = hash_type(t);
23513 else if (const decl_base* d = is_decl(tod))
23514 {
23515 if (var_decl* v = is_var_decl(d))
23516 {
23517 ABG_ASSERT(v->get_type());
23518 size_t h = hash_type_or_decl(v->get_type());
23519 string repr = v->get_pretty_representation();
23520 std::hash<string> hash_string;
23521 h = hashing::combine_hashes(h, hash_string(repr));
23522 result = h;
23523 }
23524 else if (function_decl* f = is_function_decl(d))
23525 {
23526 ABG_ASSERT(f->get_type());
23527 size_t h = hash_type_or_decl(f->get_type());
23528 string repr = f->get_pretty_representation();
23529 std::hash<string> hash_string;
23530 h = hashing::combine_hashes(h, hash_string(repr));
23531 result = h;
23532 }
23533 else if (function_decl::parameter* p = is_function_parameter(d))
23534 {
23535 type_base_sptr parm_type = p->get_type();
23536 ABG_ASSERT(parm_type);
23537 std::hash<bool> hash_bool;
23538 std::hash<unsigned> hash_unsigned;
23539 size_t h = hash_type_or_decl(parm_type);
23540 h = hashing::combine_hashes(h, hash_unsigned(p->get_index()));
23541 h = hashing::combine_hashes(h, hash_bool(p->get_variadic_marker()));
23542 result = h;
23543 }
23544 else if (class_decl::base_spec *bs = is_class_base_spec(d))
23545 {
23546 member_base::hash hash_member;
23547 std::hash<size_t> hash_size;
23548 std::hash<bool> hash_bool;
23549 type_base_sptr type = bs->get_base_class();
23550 size_t h = hash_type_or_decl(type);
23551 h = hashing::combine_hashes(h, hash_member(*bs));
23552 h = hashing::combine_hashes(h, hash_size(bs->get_offset_in_bits()));
23553 h = hashing::combine_hashes(h, hash_bool(bs->get_is_virtual()));
23554 result = h;
23555 }
23556 else
23557 // This is a *really* *SLOW* path. If it shows up in a
23558 // performance profile, I bet it'd be a good idea to try to
23559 // avoid it altogether.
23560 result = d->get_hash();
23561 }
23562 else
23563 // We should never get here.
23564 abort();
23565 return result;
23566 }
23567
23568 /// Hash an ABI artifact that is either a type.
23569 ///
23570 /// This function intends to provides the fastest possible hashing for
23571 /// types while being completely correct.
23572 ///
23573 /// Note that if the type artifact has a canonical type, the hash
23574 /// value is going to be the pointer value of the canonical type.
23575 /// Otherwise, this function computes a hash value for the type by
23576 /// recursively walking the type members. This last code path is
23577 /// possibly *very* slow and should only be used when only handful of
23578 /// types are going to be hashed.
23579 ///
23580 /// @param t the type or decl to hash.
23581 ///
23582 /// @return the resulting hash value.
23583 size_t
hash_type(const type_base * t)23584 hash_type(const type_base *t)
23585 {return hash_as_canonical_type_or_constant(t);}
23586
23587 /// Hash an ABI artifact that is either a type of a decl.
23588 ///
23589 /// @param tod the ABI artifact to hash.
23590 ///
23591 /// @return the hash value of the ABI artifact.
23592 size_t
hash_type_or_decl(const type_or_decl_base_sptr & tod)23593 hash_type_or_decl(const type_or_decl_base_sptr& tod)
23594 {return hash_type_or_decl(tod.get());}
23595
23596 /// Hash a type by either returning the pointer value of its canonical
23597 /// type or by returning a constant if the type doesn't have a
23598 /// canonical type.
23599 ///
23600 /// This is a subroutine of hash_type.
23601 ///
23602 /// @param t the type to consider.
23603 ///
23604 /// @return the hash value.
23605 static size_t
hash_as_canonical_type_or_constant(const type_base * t)23606 hash_as_canonical_type_or_constant(const type_base *t)
23607 {
23608 type_base *canonical_type = 0;
23609
23610 if (t)
23611 canonical_type = t->get_naked_canonical_type();
23612
23613 if (!canonical_type)
23614 {
23615 // If the type doesn't have a canonical type, maybe it's because
23616 // it's a declaration-only type? If that's the case, let's try
23617 // to get the canonical type of the definition of this
23618 // declaration.
23619 decl_base *decl = is_decl(t);
23620 if (decl
23621 && decl->get_is_declaration_only()
23622 && decl->get_naked_definition_of_declaration())
23623 {
23624 type_base *definition =
23625 is_type(decl->get_naked_definition_of_declaration());
23626 ABG_ASSERT(definition);
23627 canonical_type = definition->get_naked_canonical_type();
23628 }
23629 }
23630
23631 if (canonical_type)
23632 return reinterpret_cast<size_t>(canonical_type);
23633
23634 // If we reached this point, it means we are seeing a
23635 // non-canonicalized type. It must be a decl-only class or a
23636 // function type, otherwise it means that for some weird reason, the
23637 // type hasn't been canonicalized. It should be!
23638 ABG_ASSERT(is_declaration_only_class_or_union_type(t));
23639
23640 return 0xDEADBABE;
23641 }
23642
23643 /// Test if the pretty representation of a given @ref function_decl is
23644 /// lexicographically less then the pretty representation of another
23645 /// @ref function_decl.
23646 ///
23647 /// @param f the first @ref function_decl to consider for comparison.
23648 ///
23649 /// @param s the second @ref function_decl to consider for comparison.
23650 ///
23651 /// @return true iff the pretty representation of @p f is
23652 /// lexicographically less than the pretty representation of @p s.
23653 bool
function_decl_is_less_than(const function_decl & f,const function_decl & s)23654 function_decl_is_less_than(const function_decl &f, const function_decl &s)
23655 {
23656 string fr = f.get_pretty_representation_of_declarator(),
23657 sr = s.get_pretty_representation_of_declarator();
23658
23659 if (fr != sr)
23660 return fr < sr;
23661
23662 fr = f.get_pretty_representation(),
23663 sr = s.get_pretty_representation();
23664
23665 if (fr != sr)
23666 return fr < sr;
23667
23668 if (f.get_symbol())
23669 fr = f.get_symbol()->get_id_string();
23670 else if (!f.get_linkage_name().empty())
23671 fr = f.get_linkage_name();
23672
23673 if (s.get_symbol())
23674 sr = s.get_symbol()->get_id_string();
23675 else if (!s.get_linkage_name().empty())
23676 sr = s.get_linkage_name();
23677
23678 return fr < sr;
23679 }
23680
23681 /// Test if two types have similar structures, even though they are
23682 /// (or can be) different.
23683 ///
23684 /// const and volatile qualifiers are completely ignored.
23685 ///
23686 /// typedef are resolved to their definitions; their names are ignored.
23687 ///
23688 /// Two indirect types (pointers or references) have similar structure
23689 /// if their underlying types are of the same kind and have the same
23690 /// name. In the indirect types case, the size of the underlying type
23691 /// does not matter.
23692 ///
23693 /// Two direct types (i.e, non indirect) have a similar structure if
23694 /// they have the same kind, name and size. Two class types have
23695 /// similar structure if they have the same name, size, and if the
23696 /// types of their data members have similar types.
23697 ///
23698 /// @param first the first type to consider.
23699 ///
23700 /// @param second the second type to consider.
23701 ///
23702 /// @param indirect_type whether to do an indirect comparison
23703 ///
23704 /// @return true iff @p first and @p second have similar structures.
23705 bool
types_have_similar_structure(const type_base_sptr & first,const type_base_sptr & second,bool indirect_type)23706 types_have_similar_structure(const type_base_sptr& first,
23707 const type_base_sptr& second,
23708 bool indirect_type)
23709 {return types_have_similar_structure(first.get(), second.get(), indirect_type);}
23710
23711 /// Test if two types have similar structures, even though they are
23712 /// (or can be) different.
23713 ///
23714 /// const and volatile qualifiers are completely ignored.
23715 ///
23716 /// typedef are resolved to their definitions; their names are ignored.
23717 ///
23718 /// Two indirect types (pointers, references or arrays) have similar
23719 /// structure if their underlying types are of the same kind and have
23720 /// the same name. In the indirect types case, the size of the
23721 /// underlying type does not matter.
23722 ///
23723 /// Two direct types (i.e, non indirect) have a similar structure if
23724 /// they have the same kind, name and size. Two class types have
23725 /// similar structure if they have the same name, size, and if the
23726 /// types of their data members have similar types.
23727 ///
23728 /// @param first the first type to consider.
23729 ///
23730 /// @param second the second type to consider.
23731 ///
23732 /// @param indirect_type if true, then consider @p first and @p
23733 /// second as being underlying types of indirect types. Meaning that
23734 /// their size does not matter.
23735 ///
23736 /// @return true iff @p first and @p second have similar structures.
23737 bool
types_have_similar_structure(const type_base * first,const type_base * second,bool indirect_type)23738 types_have_similar_structure(const type_base* first,
23739 const type_base* second,
23740 bool indirect_type)
23741 {
23742 if (!!first != !!second)
23743 return false;
23744
23745 if (!first)
23746 return false;
23747
23748 // Treat typedefs purely as type aliases and ignore CV-qualifiers.
23749 first = peel_qualified_or_typedef_type(first);
23750 second = peel_qualified_or_typedef_type(second);
23751
23752 // Eliminate all but N of the N^2 comparison cases. This also guarantees the
23753 // various ty2 below cannot be null.
23754 if (typeid(*first) != typeid(*second))
23755 return false;
23756
23757 // Peel off matching pointers.
23758 if (const pointer_type_def* ty1 = is_pointer_type(first))
23759 {
23760 const pointer_type_def* ty2 = is_pointer_type(second);
23761 return types_have_similar_structure(ty1->get_pointed_to_type(),
23762 ty2->get_pointed_to_type(),
23763 /*indirect_type=*/true);
23764 }
23765
23766 // Peel off matching references.
23767 if (const reference_type_def* ty1 = is_reference_type(first))
23768 {
23769 const reference_type_def* ty2 = is_reference_type(second);
23770 if (ty1->is_lvalue() != ty2->is_lvalue())
23771 return false;
23772 return types_have_similar_structure(ty1->get_pointed_to_type(),
23773 ty2->get_pointed_to_type(),
23774 /*indirect_type=*/true);
23775 }
23776
23777 if (const type_decl* ty1 = is_type_decl(first))
23778 {
23779 const type_decl* ty2 = is_type_decl(second);
23780 if (!indirect_type)
23781 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
23782 return false;
23783
23784 return ty1->get_name() == ty2->get_name();
23785 }
23786
23787 if (const enum_type_decl* ty1 = is_enum_type(first))
23788 {
23789 const enum_type_decl* ty2 = is_enum_type(second);
23790 if (!indirect_type)
23791 if (ty1->get_size_in_bits() != ty2->get_size_in_bits())
23792 return false;
23793
23794 return (get_name(ty1->get_underlying_type())
23795 == get_name(ty2->get_underlying_type()));
23796 }
23797
23798 if (const class_decl* ty1 = is_class_type(first))
23799 {
23800 const class_decl* ty2 = is_class_type(second);
23801 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
23802 && ty1->get_name() != ty2->get_name())
23803 return false;
23804
23805 if (!indirect_type)
23806 {
23807 if ((ty1->get_size_in_bits() != ty2->get_size_in_bits())
23808 || (ty1->get_non_static_data_members().size()
23809 != ty2->get_non_static_data_members().size()))
23810 return false;
23811
23812 for (class_or_union::data_members::const_iterator
23813 i = ty1->get_non_static_data_members().begin(),
23814 j = ty2->get_non_static_data_members().begin();
23815 (i != ty1->get_non_static_data_members().end()
23816 && j != ty2->get_non_static_data_members().end());
23817 ++i, ++j)
23818 {
23819 var_decl_sptr dm1 = *i;
23820 var_decl_sptr dm2 = *j;
23821 if (!types_have_similar_structure(dm1->get_type().get(),
23822 dm2->get_type().get(),
23823 indirect_type))
23824 return false;
23825 }
23826 }
23827
23828 return true;
23829 }
23830
23831 if (const union_decl* ty1 = is_union_type(first))
23832 {
23833 const union_decl* ty2 = is_union_type(second);
23834 if (!ty1->get_is_anonymous() && !ty2->get_is_anonymous()
23835 && ty1->get_name() != ty2->get_name())
23836 return false;
23837
23838 if (!indirect_type)
23839 return ty1->get_size_in_bits() == ty2->get_size_in_bits();
23840
23841 return true;
23842 }
23843
23844 if (const array_type_def* ty1 = is_array_type(first))
23845 {
23846 const array_type_def* ty2 = is_array_type(second);
23847 // TODO: Handle int[5][2] vs int[2][5] better.
23848 if (ty1->get_size_in_bits() != ty2->get_size_in_bits()
23849 || ty1->get_dimension_count() != ty2->get_dimension_count()
23850 || !types_have_similar_structure(ty1->get_element_type(),
23851 ty2->get_element_type(),
23852 /*indirect_type=*/true))
23853 return false;
23854
23855 return true;
23856 }
23857
23858 if (const array_type_def::subrange_type *ty1 = is_subrange_type(first))
23859 {
23860 const array_type_def::subrange_type *ty2 = is_subrange_type(second);
23861 if (ty1->get_upper_bound() != ty2->get_upper_bound()
23862 || ty1->get_lower_bound() != ty2->get_lower_bound()
23863 || ty1->get_language() != ty2->get_language()
23864 || !types_have_similar_structure(ty1->get_underlying_type(),
23865 ty2->get_underlying_type(),
23866 indirect_type))
23867 return false;
23868
23869 return true;
23870 }
23871
23872 if (const function_type* ty1 = is_function_type(first))
23873 {
23874 const function_type* ty2 = is_function_type(second);
23875 if (!types_have_similar_structure(ty1->get_return_type(),
23876 ty2->get_return_type(),
23877 indirect_type))
23878 return false;
23879
23880 if (ty1->get_parameters().size() != ty2->get_parameters().size())
23881 return false;
23882
23883 for (function_type::parameters::const_iterator
23884 i = ty1->get_parameters().begin(),
23885 j = ty2->get_parameters().begin();
23886 (i != ty1->get_parameters().end()
23887 && j != ty2->get_parameters().end());
23888 ++i, ++j)
23889 if (!types_have_similar_structure((*i)->get_type(),
23890 (*j)->get_type(),
23891 indirect_type))
23892 return false;
23893
23894 return true;
23895 }
23896
23897 // All kinds of type should have been handled at this point.
23898 ABG_ASSERT_NOT_REACHED;
23899
23900 return false;
23901 }
23902
23903 /// Look for a data member of a given class, struct or union type and
23904 /// return it.
23905 ///
23906 /// The data member is designated by its name.
23907 ///
23908 /// @param type the class, struct or union type to consider.
23909 ///
23910 /// @param dm_name the name of the data member to lookup.
23911 ///
23912 /// @return the data member iff it was found in @type or NULL if no
23913 /// data member with that name was found.
23914 const var_decl*
lookup_data_member(const type_base * type,const char * dm_name)23915 lookup_data_member(const type_base* type,
23916 const char* dm_name)
23917
23918 {
23919 class_or_union *cou = is_class_or_union_type(type);
23920 if (!cou)
23921 return 0;
23922
23923 return cou->find_data_member(dm_name).get();
23924 }
23925
23926 /// Get the function parameter designated by its index.
23927 ///
23928 /// Note that the first function parameter has index 0.
23929 ///
23930 /// @param fun the function to consider.
23931 ///
23932 /// @param parm_index the index of the function parameter to get.
23933 ///
23934 /// @return the function parameter designated by its index, of NULL if
23935 /// no function parameter with that index was found.
23936 const function_decl::parameter*
get_function_parameter(const decl_base * fun,unsigned parm_index)23937 get_function_parameter(const decl_base* fun,
23938 unsigned parm_index)
23939 {
23940 function_decl* fn = is_function_decl(fun);
23941 if (!fn)
23942 return 0;
23943
23944 const function_decl::parameters &parms = fn->get_type()->get_parameters();
23945 if (parms.size() <= parm_index)
23946 return 0;
23947
23948 return parms[parm_index].get();
23949 }
23950
23951 bool
traverse(ir_node_visitor &)23952 ir_traversable_base::traverse(ir_node_visitor&)
23953 {return true;}
23954
23955 // <ir_node_visitor stuff>
23956
23957 /// The private data structure of the ir_node_visitor type.
23958 struct ir_node_visitor::priv
23959 {
23960 pointer_set visited_ir_nodes;
23961 bool allow_visiting_already_visited_type_node;
23962
privabigail::ir::ir_node_visitor::priv23963 priv()
23964 : allow_visiting_already_visited_type_node(true)
23965 {}
23966 }; // end struct ir_node_visitory::priv
23967
23968 /// Default Constructor of the ir_node_visitor type.
ir_node_visitor()23969 ir_node_visitor::ir_node_visitor()
23970 : priv_(new priv)
23971 {}
23972
23973 /// Set if the walker using this visitor is allowed to re-visit a type
23974 /// node that was previously visited or not.
23975 ///
23976 /// @param f if true, then the walker using this visitor is allowed to
23977 /// re-visit a type node that was previously visited.
23978 void
allow_visiting_already_visited_type_node(bool f)23979 ir_node_visitor::allow_visiting_already_visited_type_node(bool f)
23980 {priv_->allow_visiting_already_visited_type_node = f;}
23981
23982 /// Get if the walker using this visitor is allowed to re-visit a type
23983 /// node that was previously visited or not.
23984 ///
23985 /// @return true iff the walker using this visitor is allowed to
23986 /// re-visit a type node that was previously visited.
23987 bool
allow_visiting_already_visited_type_node() const23988 ir_node_visitor::allow_visiting_already_visited_type_node() const
23989 {return priv_->allow_visiting_already_visited_type_node;}
23990
23991 /// Mark a given type node as having been visited.
23992 ///
23993 /// Note that for this function to work, the type node must have been
23994 /// canonicalized. Otherwise the process is aborted.
23995 ///
23996 /// @param p the type to mark as having been visited.
23997 void
mark_type_node_as_visited(type_base * p)23998 ir_node_visitor::mark_type_node_as_visited(type_base *p)
23999 {
24000 if (allow_visiting_already_visited_type_node())
24001 return;
24002
24003 if (p == 0 || type_node_has_been_visited(p))
24004 return;
24005
24006 type_base* canonical_type = p->get_naked_canonical_type();
24007 ABG_ASSERT(canonical_type);
24008
24009 size_t canonical_ptr_value = reinterpret_cast<size_t>(canonical_type);
24010 priv_->visited_ir_nodes.insert(canonical_ptr_value);
24011 }
24012
24013 /// Un-mark all visited type nodes.
24014 ///
24015 /// That is, no type node is going to be considered as having been
24016 /// visited anymore.
24017 ///
24018 /// In other words, after invoking this funciton,
24019 /// ir_node_visitor::type_node_has_been_visited() is going to return
24020 /// false on all type nodes.
24021 void
forget_visited_type_nodes()24022 ir_node_visitor::forget_visited_type_nodes()
24023 {priv_->visited_ir_nodes.clear();}
24024
24025 /// Test if a given type node has been marked as visited.
24026 ///
24027 /// @param p the type node to consider.
24028 ///
24029 /// @return true iff the type node @p p has been marked as visited by
24030 /// the function ir_node_visitor::mark_type_node_as_visited.
24031 bool
type_node_has_been_visited(type_base * p) const24032 ir_node_visitor::type_node_has_been_visited(type_base* p) const
24033 {
24034 if (allow_visiting_already_visited_type_node())
24035 return false;
24036
24037 if (p == 0)
24038 return false;
24039
24040 type_base *canonical_type = p->get_naked_canonical_type();
24041 ABG_ASSERT(canonical_type);
24042
24043 size_t ptr_value = reinterpret_cast<size_t>(canonical_type);
24044 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
24045 if (it == priv_->visited_ir_nodes.end())
24046 return false;
24047
24048 return true;
24049 }
24050
24051 bool
visit_begin(decl_base *)24052 ir_node_visitor::visit_begin(decl_base*)
24053 {return true;}
24054
24055 bool
visit_end(decl_base *)24056 ir_node_visitor::visit_end(decl_base*)
24057 {return true;}
24058
24059 bool
visit_begin(scope_decl *)24060 ir_node_visitor::visit_begin(scope_decl*)
24061 {return true;}
24062
24063 bool
visit_end(scope_decl *)24064 ir_node_visitor::visit_end(scope_decl*)
24065 {return true;}
24066
24067 bool
visit_begin(type_base *)24068 ir_node_visitor::visit_begin(type_base*)
24069 {return true;}
24070
24071 bool
visit_end(type_base *)24072 ir_node_visitor::visit_end(type_base*)
24073 {return true;}
24074
24075 bool
visit_begin(scope_type_decl * t)24076 ir_node_visitor::visit_begin(scope_type_decl* t)
24077 {return visit_begin(static_cast<type_base*>(t));}
24078
24079 bool
visit_end(scope_type_decl * t)24080 ir_node_visitor::visit_end(scope_type_decl* t)
24081 {return visit_end(static_cast<type_base*>(t));}
24082
24083 bool
visit_begin(type_decl * t)24084 ir_node_visitor::visit_begin(type_decl* t)
24085 {return visit_begin(static_cast<type_base*>(t));}
24086
24087 bool
visit_end(type_decl * t)24088 ir_node_visitor::visit_end(type_decl* t)
24089 {return visit_end(static_cast<type_base*>(t));}
24090
24091 bool
visit_begin(namespace_decl * d)24092 ir_node_visitor::visit_begin(namespace_decl* d)
24093 {return visit_begin(static_cast<decl_base*>(d));}
24094
24095 bool
visit_end(namespace_decl * d)24096 ir_node_visitor::visit_end(namespace_decl* d)
24097 {return visit_end(static_cast<decl_base*>(d));}
24098
24099 bool
visit_begin(qualified_type_def * t)24100 ir_node_visitor::visit_begin(qualified_type_def* t)
24101 {return visit_begin(static_cast<type_base*>(t));}
24102
24103 bool
visit_end(qualified_type_def * t)24104 ir_node_visitor::visit_end(qualified_type_def* t)
24105 {return visit_end(static_cast<type_base*>(t));}
24106
24107 bool
visit_begin(pointer_type_def * t)24108 ir_node_visitor::visit_begin(pointer_type_def* t)
24109 {return visit_begin(static_cast<type_base*>(t));}
24110
24111 bool
visit_end(pointer_type_def * t)24112 ir_node_visitor::visit_end(pointer_type_def* t)
24113 {return visit_end(static_cast<type_base*>(t));}
24114
24115 bool
visit_begin(reference_type_def * t)24116 ir_node_visitor::visit_begin(reference_type_def* t)
24117 {return visit_begin(static_cast<type_base*>(t));}
24118
24119 bool
visit_end(reference_type_def * t)24120 ir_node_visitor::visit_end(reference_type_def* t)
24121 {return visit_end(static_cast<type_base*>(t));}
24122
24123 bool
visit_begin(array_type_def * t)24124 ir_node_visitor::visit_begin(array_type_def* t)
24125 {return visit_begin(static_cast<type_base*>(t));}
24126
24127 bool
visit_end(array_type_def * t)24128 ir_node_visitor::visit_end(array_type_def* t)
24129 {return visit_end(static_cast<type_base*>(t));}
24130
24131 bool
visit_begin(array_type_def::subrange_type * t)24132 ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
24133 {return visit_begin(static_cast<type_base*>(t));}
24134
24135 bool
visit_end(array_type_def::subrange_type * t)24136 ir_node_visitor::visit_end(array_type_def::subrange_type* t)
24137 {return visit_end(static_cast<type_base*>(t));}
24138
24139 bool
visit_begin(enum_type_decl * t)24140 ir_node_visitor::visit_begin(enum_type_decl* t)
24141 {return visit_begin(static_cast<type_base*>(t));}
24142
24143 bool
visit_end(enum_type_decl * t)24144 ir_node_visitor::visit_end(enum_type_decl* t)
24145 {return visit_end(static_cast<type_base*>(t));}
24146
24147 bool
visit_begin(typedef_decl * t)24148 ir_node_visitor::visit_begin(typedef_decl* t)
24149 {return visit_begin(static_cast<type_base*>(t));}
24150
24151 bool
visit_end(typedef_decl * t)24152 ir_node_visitor::visit_end(typedef_decl* t)
24153 {return visit_end(static_cast<type_base*>(t));}
24154
24155 bool
visit_begin(function_type * t)24156 ir_node_visitor::visit_begin(function_type* t)
24157 {return visit_begin(static_cast<type_base*>(t));}
24158
24159 bool
visit_end(function_type * t)24160 ir_node_visitor::visit_end(function_type* t)
24161 {return visit_end(static_cast<type_base*>(t));}
24162
24163 bool
visit_begin(var_decl * d)24164 ir_node_visitor::visit_begin(var_decl* d)
24165 {return visit_begin(static_cast<decl_base*>(d));}
24166
24167 bool
visit_end(var_decl * d)24168 ir_node_visitor::visit_end(var_decl* d)
24169 {return visit_end(static_cast<decl_base*>(d));}
24170
24171 bool
visit_begin(function_decl * d)24172 ir_node_visitor::visit_begin(function_decl* d)
24173 {return visit_begin(static_cast<decl_base*>(d));}
24174
24175 bool
visit_end(function_decl * d)24176 ir_node_visitor::visit_end(function_decl* d)
24177 {return visit_end(static_cast<decl_base*>(d));}
24178
24179 bool
visit_begin(function_decl::parameter * d)24180 ir_node_visitor::visit_begin(function_decl::parameter* d)
24181 {return visit_begin(static_cast<decl_base*>(d));}
24182
24183 bool
visit_end(function_decl::parameter * d)24184 ir_node_visitor::visit_end(function_decl::parameter* d)
24185 {return visit_end(static_cast<decl_base*>(d));}
24186
24187 bool
visit_begin(function_tdecl * d)24188 ir_node_visitor::visit_begin(function_tdecl* d)
24189 {return visit_begin(static_cast<decl_base*>(d));}
24190
24191 bool
visit_end(function_tdecl * d)24192 ir_node_visitor::visit_end(function_tdecl* d)
24193 {return visit_end(static_cast<decl_base*>(d));}
24194
24195 bool
visit_begin(class_tdecl * d)24196 ir_node_visitor::visit_begin(class_tdecl* d)
24197 {return visit_begin(static_cast<decl_base*>(d));}
24198
24199 bool
visit_end(class_tdecl * d)24200 ir_node_visitor::visit_end(class_tdecl* d)
24201 {return visit_end(static_cast<decl_base*>(d));}
24202
24203 bool
visit_begin(class_or_union * t)24204 ir_node_visitor::visit_begin(class_or_union* t)
24205 {return visit_begin(static_cast<type_base*>(t));}
24206
24207 bool
visit_end(class_or_union * t)24208 ir_node_visitor::visit_end(class_or_union* t)
24209 {return visit_end(static_cast<type_base*>(t));}
24210
24211 bool
visit_begin(class_decl * t)24212 ir_node_visitor::visit_begin(class_decl* t)
24213 {return visit_begin(static_cast<type_base*>(t));}
24214
24215 bool
visit_end(class_decl * t)24216 ir_node_visitor::visit_end(class_decl* t)
24217 {return visit_end(static_cast<type_base*>(t));}
24218
24219 bool
visit_begin(union_decl * t)24220 ir_node_visitor::visit_begin(union_decl* t)
24221 {return visit_begin(static_cast<type_base*>(t));}
24222
24223 bool
visit_end(union_decl * t)24224 ir_node_visitor::visit_end(union_decl* t)
24225 {return visit_end(static_cast<type_base*>(t));}
24226
24227 bool
visit_begin(class_decl::base_spec * d)24228 ir_node_visitor::visit_begin(class_decl::base_spec* d)
24229 {return visit_begin(static_cast<decl_base*>(d));}
24230
24231 bool
visit_end(class_decl::base_spec * d)24232 ir_node_visitor::visit_end(class_decl::base_spec* d)
24233 {return visit_end(static_cast<decl_base*>(d));}
24234
24235 bool
visit_begin(member_function_template * d)24236 ir_node_visitor::visit_begin(member_function_template* d)
24237 {return visit_begin(static_cast<decl_base*>(d));}
24238
24239 bool
visit_end(member_function_template * d)24240 ir_node_visitor::visit_end(member_function_template* d)
24241 {return visit_end(static_cast<decl_base*>(d));}
24242
24243 bool
visit_begin(member_class_template * d)24244 ir_node_visitor::visit_begin(member_class_template* d)
24245 {return visit_begin(static_cast<decl_base*>(d));}
24246
24247 bool
visit_end(member_class_template * d)24248 ir_node_visitor::visit_end(member_class_template* d)
24249 {return visit_end(static_cast<decl_base*>(d));}
24250
24251 // </ir_node_visitor stuff>
24252
24253 // <debugging facilities>
24254
24255 /// Generate a different string at each invocation.
24256 ///
24257 /// @return the resulting string.
24258 static string
get_next_string()24259 get_next_string()
24260 {
24261 static __thread size_t counter;
24262 ++counter;
24263 std::ostringstream o;
24264 o << counter;
24265 return o.str();
24266 }
24267
24268 /// Convenience typedef for a hash map of pointer to function_decl and
24269 /// string.
24270 typedef unordered_map<const function_decl*, string,
24271 function_decl::hash,
24272 function_decl::ptr_equal> fns_to_str_map_type;
24273
24274 /// Return a string associated to a given function. Two functions
24275 /// that compare equal would yield the same string, as far as this
24276 /// routine is concerned. And two functions that are different would
24277 /// yield different strings.
24278 ///
24279 /// This is used to debug core diffing issues on functions. The
24280 /// sequence of strings can be given to the 'testdiff2' program that
24281 /// is in the tests/ directory of the source tree, to reproduce core
24282 /// diffing issues on string and thus ease the debugging.
24283 ///
24284 /// @param fn the function to generate a string for.
24285 ///
24286 /// @param m the function_decl* <-> string map to be used by this
24287 /// function to generate strings associated to a function.
24288 ///
24289 /// @return the resulting string.
24290 static const string&
fn_to_str(const function_decl * fn,fns_to_str_map_type & m)24291 fn_to_str(const function_decl* fn,
24292 fns_to_str_map_type& m)
24293 {
24294 fns_to_str_map_type::const_iterator i = m.find(fn);
24295 if (i != m.end())
24296 return i->second;
24297 string s = get_next_string();
24298 return m[fn]= s;
24299 }
24300
24301 /// Generate a sequence of string that matches a given sequence of
24302 /// function. In the resulting sequence, each function is "uniquely
24303 /// representated" by a string. For instance, if the same function "foo"
24304 /// appears at indexes 1 and 3, then the same string 'schmurf' (okay,
24305 /// we don't care about the actual string) would appear at index 1 and 3.
24306 ///
24307 /// @param begin the beginning of the sequence of functions to consider.
24308 ///
24309 /// @param end the end of the sequence of functions. This points to
24310 /// one-passed-the-end of the actual sequence.
24311 ///
24312 /// @param m the function_decl* <-> string map to be used by this
24313 /// function to generate strings associated to a function.
24314 ///
24315 /// @param o the output stream where to emit the generated list of
24316 /// strings to.
24317 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)24318 fns_to_str(vector<function_decl*>::const_iterator begin,
24319 vector<function_decl*>::const_iterator end,
24320 fns_to_str_map_type& m,
24321 std::ostream& o)
24322 {
24323 vector<function_decl*>::const_iterator i;
24324 for (i = begin; i != end; ++i)
24325 o << "'" << fn_to_str(*i, m) << "' ";
24326 }
24327
24328 /// For each sequence of functions given in argument, generate a
24329 /// sequence of string that matches a given sequence of function. In
24330 /// the resulting sequence, each function is "uniquely representated"
24331 /// by a string. For instance, if the same function "foo" appears at
24332 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
24333 /// care about the actual string) would appear at index 1 and 3.
24334 ///
24335 /// @param a_begin the beginning of the sequence of functions to consider.
24336 ///
24337 /// @param a_end the end of the sequence of functions. This points to
24338 /// one-passed-the-end of the actual sequence.
24339 ///
24340 /// @param b_begin the beginning of the second sequence of functions
24341 /// to consider.
24342 ///
24343 /// @param b_end the end of the second sequence of functions.
24344 ///
24345 /// @param m the function_decl* <-> string map to be used by this
24346 /// function to generate strings associated to a function.
24347 ///
24348 /// @param o the output stream where to emit the generated list of
24349 /// strings to.
24350 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)24351 fns_to_str(vector<function_decl*>::const_iterator a_begin,
24352 vector<function_decl*>::const_iterator a_end,
24353 vector<function_decl*>::const_iterator b_begin,
24354 vector<function_decl*>::const_iterator b_end,
24355 fns_to_str_map_type& m,
24356 std::ostream& o)
24357 {
24358 fns_to_str(a_begin, a_end, m, o);
24359 o << "->|<- ";
24360 fns_to_str(b_begin, b_end, m, o);
24361 o << "\n";
24362 }
24363
24364 /// For each sequence of functions given in argument, generate a
24365 /// sequence of string that matches a given sequence of function. In
24366 /// the resulting sequence, each function is "uniquely representated"
24367 /// by a string. For instance, if the same function "foo" appears at
24368 /// indexes 1 and 3, then the same string 'schmurf' (okay, we don't
24369 /// care about the actual string) would appear at index 1 and 3.
24370 ///
24371 /// @param a_begin the beginning of the sequence of functions to consider.
24372 ///
24373 /// @param a_end the end of the sequence of functions. This points to
24374 /// one-passed-the-end of the actual sequence.
24375 ///
24376 /// @param b_begin the beginning of the second sequence of functions
24377 /// to consider.
24378 ///
24379 /// @param b_end the end of the second sequence of functions.
24380 ///
24381 /// @param o the output stream where to emit the generated list of
24382 /// strings to.
24383 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)24384 fns_to_str(vector<function_decl*>::const_iterator a_begin,
24385 vector<function_decl*>::const_iterator a_end,
24386 vector<function_decl*>::const_iterator b_begin,
24387 vector<function_decl*>::const_iterator b_end,
24388 std::ostream& o)
24389 {
24390 fns_to_str_map_type m;
24391 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
24392 }
24393
24394 // </debugging facilities>
24395
24396 // </class template>
24397
24398 }// end namespace ir
24399 }//end namespace abigail
24400
24401 namespace
24402 {
24403
24404 /// Update the qualified parent name, qualified name and scoped name
24405 /// of a tree decl node.
24406 ///
24407 /// @return true if the tree walking should continue, false otherwise.
24408 ///
24409 /// @param d the tree node to take in account.
24410 bool
do_update(abigail::ir::decl_base * d)24411 qualified_name_setter::do_update(abigail::ir::decl_base* d)
24412 {
24413 std::string parent_qualified_name;
24414 abigail::ir::scope_decl* parent = d->get_scope();
24415 if (parent)
24416 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
24417 else
24418 d->priv_->qualified_parent_name_ = abigail::interned_string();
24419
24420 abigail::environment* env = d->get_environment();
24421 ABG_ASSERT(env);
24422 if (!d->priv_->qualified_parent_name_.empty())
24423 {
24424 if (d->get_name().empty())
24425 d->priv_->qualified_name_ = abigail::interned_string();
24426 else
24427 d->priv_->qualified_name_ =
24428 env->intern(d->priv_->qualified_parent_name_ + "::" + d->get_name());
24429 }
24430
24431 if (d->priv_->scoped_name_.empty())
24432 {
24433 if (parent
24434 && !parent->get_is_anonymous()
24435 && !parent->get_name().empty())
24436 d->priv_->scoped_name_ =
24437 env->intern(parent->get_name() + "::" + d->get_name());
24438 else
24439 d->priv_->scoped_name_ =
24440 env->intern(d->get_name());
24441 }
24442
24443 if (!is_scope_decl(d))
24444 return false;
24445
24446 return true;
24447 }
24448
24449 /// This is called when we start visiting a decl node, during the
24450 /// udpate of the qualified name of a given sub-tree.
24451 ///
24452 /// @param d the decl node we are visiting.
24453 ///
24454 /// @return true iff the traversal should keep going.
24455 bool
visit_begin(abigail::ir::decl_base * d)24456 qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
24457 {return do_update(d);}
24458
24459 /// This is called when we start visiting a type node, during the
24460 /// udpate of the qualified name of a given sub-tree.
24461 ///
24462 /// @param d the decl node we are visiting.
24463 ///
24464 /// @return true iff the traversal should keep going.
24465 bool
visit_begin(abigail::ir::type_base * t)24466 qualified_name_setter::visit_begin(abigail::ir::type_base* t)
24467 {
24468 if (abigail::ir::decl_base* d = get_type_declaration(t))
24469 return do_update(d);
24470 return false;
24471 }
24472 }// end anonymous namespace.
24473