libabigail
abg-reader.cc
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- mode: C++ -*-
3 //
4 // Copyright (C) 2013-2025 Red Hat, Inc.
5 
6 /// @file
7 ///
8 /// This file contains the definitions of the entry points to
9 /// de-serialize an instance of @ref abigail::translation_unit from an
10 /// ABI Instrumentation file in libabigail native XML format. This
11 /// native XML format is named "ABIXML".
12 
13 #include "config.h"
14 #include <assert.h>
15 #include <libxml/xmlreader.h>
16 #include <libxml/xmlstring.h>
17 #include <cerrno>
18 #include <cstdlib>
19 #include <cstring>
20 #include <deque>
21 #include <memory>
22 #include <sstream>
23 #include <unordered_map>
24 #include <algorithm>
25 
26 #include "abg-suppression-priv.h"
27 
28 #include "abg-internal.h"
29 #include "abg-ir-priv.h"
30 #include "abg-symtab-reader.h"
31 #include "abg-ir-priv.h"
32 
33 // <headers defining libabigail's API go under here>
34 ABG_BEGIN_EXPORT_DECLARATIONS
35 
36 #include "abg-libxml-utils.h"
37 #include "abg-reader.h"
38 #include "abg-corpus.h"
39 #include "abg-fe-iface.h"
40 #include "abg-tools-utils.h"
41 
43 // </headers defining libabigail's API>
44 
45 namespace abigail
46 {
47 
48 using xml::xml_char_sptr;
49 
50 /// The namespace for the native XML file format reader.
51 namespace abixml
52 {
53 using std::string;
54 using std::deque;
55 using std::shared_ptr;
56 using std::unordered_map;
57 using std::dynamic_pointer_cast;
58 using std::vector;
59 using std::istream;
60 
61 /// Convenience typedef for an unordered map of string to a vector of
62 /// strings.
63 typedef unordered_map<string, vector<string>> string_strings_map_type;
64 
65 class reader;
66 
67 static bool read_is_declaration_only(xmlNodePtr, bool&);
68 static bool read_is_artificial(xmlNodePtr, bool&);
69 static bool read_tracking_non_reachable_types(xmlNodePtr, bool&);
70 static bool read_is_non_reachable_type(xmlNodePtr, bool&);
71 static bool read_naming_typedef_id_string(xmlNodePtr, string&);
72 static bool read_type_id_string(xmlNodePtr, string&);
73 static bool read_name(xmlNodePtr, string&);
74 #ifdef WITH_DEBUG_SELF_COMPARISON
75 static bool maybe_map_type_with_type_id(const type_base_sptr&,
76  xmlNodePtr);
77 static bool maybe_map_type_with_type_id(const type_base_sptr&,
78  const string&);
79 
80 #define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node) \
81  maybe_map_type_with_type_id(type, xml_node)
82 #else
83 #define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node)
84 #endif
85 static void maybe_set_naming_typedef(reader& rdr,
86  xmlNodePtr,
87  const decl_base_sptr &);
88 class reader;
89 
90 static int advance_cursor(reader& rdr);
91 
92 static void
93 handle_version_attribute(xml::reader_sptr& reader, corpus& corp);
94 
95 static void
96 walk_xml_node_to_map_type_ids(reader& rdr, xmlNodePtr node);
97 
98 static bool
99 read_elf_needed_from_input(reader& rdr, vector<string>& needed);
100 
101 static bool
102 read_symbol_db_from_input(reader& rdr,
103  string_elf_symbols_map_sptr& fn_symdb,
104  string_elf_symbols_map_sptr& var_symdb,
105  string_strings_map_type& non_resolved_fn_syms_aliases,
106  string_strings_map_type& non_resolved_var_syms_aliases);
107 
109 read_translation_unit_from_input(fe_iface& rdr);
110 
111 static decl_base_sptr
112 build_ir_node_for_void_type(reader& rdr);
113 
114 static decl_base_sptr
115 build_ir_node_for_void_pointer_type(reader& rdr);
116 
117 static decl_base_sptr
118 build_ir_node_for_variadic_parameter_type(reader& rdr);
119 
120 static void
121 resolve_symbol_aliases(string_elf_symbols_map_sptr& fn_syms,
122  string_elf_symbols_map_sptr& var_syms,
123  string_strings_map_type& non_resolved_fn_sym_aliases,
124  string_strings_map_type& non_resolved_var_sym_aliases);
125 static bool
126 read_type_hash_and_cti(xmlNodePtr, uint64_t& hash, uint64_t& cti);
127 
128 /// The ABIXML reader object.
129 ///
130 /// This abstracts the context in which the current ABI
131 /// instrumentation dump is being de-serialized. It carries useful
132 /// information needed during the de-serialization, but that does not
133 /// make sense to be stored in the final resulting in-memory
134 /// representation of ABI Corpus.
135 class reader : public fe_iface
136 {
137 public:
138 
139  typedef unordered_map<string, vector<type_base_sptr> >
140  types_map_type;
141 
142  typedef unordered_map<string,
143  vector<type_base_sptr> >::const_iterator
144  const_types_map_it;
145 
146  typedef unordered_map<string,
147  vector<type_base_sptr> >::iterator
148  types_map_it;
149 
150  typedef unordered_map<string,
151  shared_ptr<function_tdecl> >::const_iterator
152  const_fn_tmpl_map_it;
153 
154  typedef unordered_map<string,
155  shared_ptr<class_tdecl> >::const_iterator
156  const_class_tmpl_map_it;
157 
158  typedef unordered_map<string, xmlNodePtr> string_xml_node_map;
159 
160  typedef unordered_map<xmlNodePtr, decl_base_sptr> xml_node_decl_base_sptr_map;
161 
162  friend vector<type_base_sptr>* get_types_from_type_id(reader&,
163  const string&);
164 
165  friend unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
166  get_artifact_used_by_relation_map(reader& rdr);
167 
168 private:
169  types_map_type m_types_map;
170  unordered_map<string, shared_ptr<function_tdecl> > m_fn_tmpl_map;
171  unordered_map<string, shared_ptr<class_tdecl> > m_class_tmpl_map;
172  vector<type_base_sptr> m_types_to_canonicalize;
173  string_xml_node_map m_id_xml_node_map;
174  xml_node_decl_base_sptr_map m_xml_node_decl_map;
175  xml::reader_sptr m_reader;
176  xmlNodePtr m_corp_node;
177  deque<shared_ptr<decl_base> > m_decls_stack;
178  bool m_tracking_non_reachable_types;
179  bool m_drop_undefined_syms;
180  bool m_drop_hash_value;
181 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
182  unordered_map<type_or_decl_base*,
183  vector<type_or_decl_base*>> m_artifact_used_by_map;
184 #endif
185 
186  reader();
187 
188 public:
189  reader(xml::reader_sptr reader,
190  environment& env)
191  : fe_iface("", env),
192  m_reader(reader),
193  m_corp_node(),
194  m_tracking_non_reachable_types(),
195  m_drop_undefined_syms(),
196  m_drop_hash_value()
197  {
198  }
199 
200  /// The initializer of the reader.
201  ///
202  /// Resets the reader so that it can be re-used to read another
203  /// binary and build a corpus that is part of the same corpus group.
204  ///
205  /// In other words, the same reader is used to analyse all the
206  /// binaries that are part of the same corpus group.
207  ///
208  /// @param corpus_path the new corpus path.
209  void
210  initialize(const string& corpus_path)
211  {
212  fe_iface::initialize(corpus_path);
213  clear_types_to_canonicalize();
214  }
215 
216  /// Test if logging was requested.
217  ///
218  /// @return true iff logging was requested.
219  bool
220  do_log() const
221  {return options().do_log;}
222 
223  /// Getter for the flag that tells us if we are tracking types that
224  /// are not reachable from global functions and variables.
225  ///
226  /// @return true iff we are tracking types that are not reachable
227  /// from global functions and variables.
228  bool
229  tracking_non_reachable_types() const
230  {return m_tracking_non_reachable_types;}
231 
232  /// Setter for the flag that tells us if we are tracking types that
233  /// are not reachable from global functions and variables.
234  ///
235  /// @param f the new value of the flag.
236  /// from global functions and variables.
237  void
238  tracking_non_reachable_types(bool f)
239  {m_tracking_non_reachable_types = f;}
240 
241  /// Getter for the flag that tells us if we are dropping functions
242  /// and variables that have undefined symbols.
243  ///
244  /// @return true iff we are dropping functions and variables that have
245  /// undefined symbols.
246  bool
247  drop_undefined_syms() const
248  {return m_drop_undefined_syms;}
249 
250  /// Setter for the flag that tells us if we are dropping functions
251  /// and variables that have undefined symbols.
252  ///
253  /// @param f the new value of the flag.
254  void
255  drop_undefined_syms(bool f)
256  {m_drop_undefined_syms = f;}
257 
258  /// Getter of the path to the ABI file.
259  ///
260  /// @return the path to the native xml abi file.
261  const string&
262  get_path() const
263  {return corpus_path();}
264 
265  /// Setter of the path to the ABI file.
266  ///
267  /// @param the new path to the native ABI file.
268  void
269  set_path(const string& s)
270  {
271  corpus_path(s);
272  }
273 
274  /// Getter for the environment of this reader.
275  ///
276  /// @return the environment of this reader.
277  environment&
278  get_environment()
279  {return options().env;}
280 
281  /// Getter for the environment of this reader.
282  ///
283  /// @return the environment of this reader.
284  const environment&
285  get_environment() const
286  {return const_cast<reader*>(this)->get_environment();}
287 
289  get_libxml_reader() const
290  {return m_reader;}
291 
292  /// Getter of the current XML node in the corpus element sub-tree
293  /// that needs to be processed.
294  ///
295  /// @return the current XML node in the corpus element sub-tree that
296  /// needs to be processed.
297  xmlNodePtr
298  get_corpus_node() const
299  {return m_corp_node;}
300 
301  /// Setter of the current XML node in the corpus element sub-tree
302  /// that needs to be processed.
303  ///
304  /// @param node set the current XML node in the corpus element
305  /// sub-tree that needs to be processed.
306  void
307  set_corpus_node(xmlNodePtr node)
308  {m_corp_node = node;}
309 
310  const string_xml_node_map&
311  get_id_xml_node_map() const
312  {return m_id_xml_node_map;}
313 
314  string_xml_node_map&
315  get_id_xml_node_map()
316  {return m_id_xml_node_map;}
317 
318  void
319  clear_id_xml_node_map()
320  {get_id_xml_node_map().clear();}
321 
322  const xml_node_decl_base_sptr_map&
323  get_xml_node_decl_map() const
324  {return m_xml_node_decl_map;}
325 
326  xml_node_decl_base_sptr_map&
327  get_xml_node_decl_map()
328  {return m_xml_node_decl_map;}
329 
330  void
331  map_xml_node_to_decl(xmlNodePtr node,
332  decl_base_sptr decl)
333  {
334  if (node)
335  get_xml_node_decl_map()[node]= decl;
336  }
337 
338  decl_base_sptr
339  get_decl_for_xml_node(xmlNodePtr node) const
340  {
341  xml_node_decl_base_sptr_map::const_iterator i =
342  get_xml_node_decl_map().find(node);
343 
344  if (i != get_xml_node_decl_map().end())
345  return i->second;
346 
347  return decl_base_sptr();
348  }
349 
350  void
351  clear_xml_node_decl_map()
352  {get_xml_node_decl_map().clear();}
353 
354  void
355  map_id_and_node (const string& id,
356  xmlNodePtr node)
357  {
358  if (!node)
359  return;
360 
361  string_xml_node_map::iterator i = get_id_xml_node_map().find(id);
362  if (i != get_id_xml_node_map().end())
363  {
364  bool is_declaration = false;
365  read_is_declaration_only(node, is_declaration);
366  if (is_declaration)
367  i->second = node;
368  }
369  else
370  get_id_xml_node_map()[id] = node;
371  }
372 
373  xmlNodePtr
374  get_xml_node_from_id(const string& id) const
375  {
376  string_xml_node_map::const_iterator i = get_id_xml_node_map().find(id);
377  if (i != get_id_xml_node_map().end())
378  return i->second;
379  return 0;
380  }
381 
383  get_scope_for_node(xmlNodePtr node,
384  access_specifier& access);
385 
387  get_scope_for_node(xmlNodePtr node);
388 
389  scope_decl*
390  get_scope_ptr_for_node(xmlNodePtr node);
391 
392  // This is defined later, after build_type() is declared, because it
393  // uses it.
394  type_base_sptr
395  build_or_get_type_decl(const string& id,
396  bool add_decl_to_scope);
397 
398  /// Return the first type already seen, that is identified by a
399  /// given ID.
400  ///
401  /// Note that for a type to be "identified" by id, the function
402  /// key_type_decl must have been previously called with that type
403  /// and with id.
404  ///
405  /// @param id the id to consider.
406  ///
407  /// @return the type identified by the unique id id, or a null
408  /// pointer if no type has ever been associated with id before.
409  type_base_sptr
410  get_type_decl(const string& id) const
411  {
412  const_types_map_it i = m_types_map.find(id);
413  if (i == m_types_map.end())
414  return type_base_sptr();
415  type_base_sptr result = i->second[0];
416  return result;
417  }
418 
419  /// Return the vector of types already seen, that are identified by
420  /// a given ID.
421  ///
422  /// Note that for a type to be "identified" by id, the function
423  /// key_type_decl must have been previously called with that type
424  /// and with id.
425  ///
426  /// @param id the id to consider.
427  ///
428  /// @return thevector of types already seen, that are identified by
429  /// a given ID, or 0 if no type has ever been associated with @p id
430  /// before.
431  const vector<type_base_sptr>*
432  get_all_type_decls(const string& id) const
433  {
434  const_types_map_it i = m_types_map.find(id);
435  if (i == m_types_map.end())
436  return 0;
437  else
438  return &i->second;
439  }
440 
441  /// Return the function template that is identified by a unique ID.
442  ///
443  /// Note that for a function template to be identified by id, the
444  /// function key_fn_tmpl_decl must have been previously called with
445  /// that function template and with id.
446  ///
447  /// @param id the ID to consider.
448  ///
449  /// @return the function template identified by id, or a null
450  /// pointer if no function template has ever been associated with
451  /// id before.
452  shared_ptr<function_tdecl>
453  get_fn_tmpl_decl(const string& id) const
454  {
455  const_fn_tmpl_map_it i = m_fn_tmpl_map.find(id);
456  if (i == m_fn_tmpl_map.end())
457  return shared_ptr<function_tdecl>();
458  return i->second;
459  }
460 
461  /// Return the class template that is identified by a unique ID.
462  ///
463  /// Note that for a class template to be identified by id, the
464  /// function key_class_tmpl_decl must have been previously called
465  /// with that class template and with id.
466  ///
467  /// @param id the ID to consider.
468  ///
469  /// @return the class template identified by id, or a null pointer
470  /// if no class template has ever been associated with id before.
471  shared_ptr<class_tdecl>
472  get_class_tmpl_decl(const string& id) const
473  {
474  const_class_tmpl_map_it i = m_class_tmpl_map.find(id);
475  if (i == m_class_tmpl_map.end())
476  return shared_ptr<class_tdecl>();
477  return i->second;
478  }
479 
480  /// Return the current lexical scope.
481  scope_decl*
482  get_cur_scope() const
483  {
484  shared_ptr<decl_base> cur_decl = get_cur_decl();
485 
486  if (dynamic_cast<scope_decl*>(cur_decl.get()))
487  // The current decl is a scope_decl, so it's our lexical scope.
488  return dynamic_pointer_cast<scope_decl>(cur_decl).get();
489  else if (cur_decl)
490  // The current decl is not a scope_decl, so our lexical scope is
491  // the scope of this decl.
492  return cur_decl->get_scope();
493  else
494  // We have no scope set.
495  return 0;
496  }
497 
498  decl_base_sptr
499  get_cur_decl() const
500  {
501  if (m_decls_stack.empty())
502  return shared_ptr<decl_base>(static_cast<decl_base*>(0));
503  return m_decls_stack.back();
504  }
505 
506  translation_unit*
508  {
509  const global_scope* global = 0;
510  for (deque<shared_ptr<decl_base> >::reverse_iterator i =
511  m_decls_stack.rbegin();
512  i != m_decls_stack.rend();
513  ++i)
514  if (decl_base_sptr d = *i)
515  if ((global = get_global_scope(d)))
516  break;
517 
518  if (global)
519  return global->get_translation_unit();
520 
521  return 0;
522  }
523 
524  /// Test if a given type is from the current translation unit.
525  ///
526  /// @param type the type to consider.
527  ///
528  /// @return true iff the type is from the current translation unit.
529  bool
530  type_is_from_translation_unit(type_base_sptr type)
531  {
532  decl_base_sptr d = get_type_declaration(type);
533  if (d)
535  else if (function_type_sptr fn_type = is_function_type(type))
536  return bool(lookup_function_type(fn_type, *get_translation_unit()));
537  else
538  return false;
539  }
540 
541  void
542  push_decl(decl_base_sptr d)
543  {
544  m_decls_stack.push_back(d);
545  }
546 
547  decl_base_sptr
548  pop_decl()
549  {
550  if (m_decls_stack.empty())
551  return decl_base_sptr();
552 
553  shared_ptr<decl_base> t = get_cur_decl();
554  m_decls_stack.pop_back();
555  return t;
556  }
557 
558  /// Pop all decls until a give scope is popped.
559  ///
560  /// @param scope the scope to pop.
561  ///
562  /// @return true if the scope was popped, false otherwise. Note
563  /// that if the scope wasn't found, it might mean that many other
564  /// decls were popped.
565  bool
566  pop_scope(scope_decl_sptr scope)
567  {
568  decl_base_sptr d;
569  do
570  {
571  d = pop_decl();
572  scope_decl_sptr s = dynamic_pointer_cast<scope_decl>(d);
573  if (s == scope)
574  break;
575  }
576  while (d);
577 
578  if (!d)
579  return false;
580 
581  return dynamic_pointer_cast<scope_decl>(d) == scope;
582  }
583 
584  /// like @ref pop_scope, but if the scope couldn't be popped, the
585  /// function aborts the execution of the process.
586  ///
587  /// @param scope the scope to pop.
588  void
589  pop_scope_or_abort(scope_decl_sptr scope)
590  {ABG_ASSERT(pop_scope(scope));}
591 
592  void
593  clear_decls_stack()
594  {m_decls_stack.clear();}
595 
596  void
597  clear_type_map()
598  {m_types_map.clear();}
599 
600  /// Clean the vector of types to canonicalize after the translation
601  /// unit has been read.
602  void
603  clear_types_to_canonicalize()
604  {m_types_to_canonicalize.clear();}
605 
606 
607  /// Test if two types are equal, without comparing them structurally.
608  ///
609  /// This either tests that type pointers are equal, or it tests
610  /// their names. This is because it might be two early to compare
611  /// types structurally because we are not necessarily done building
612  /// them yet.
613  ///
614  /// @param t1 the first type to compare.
615  ///
616  /// @param t2 the second type to compare.
617  ///
618  /// @return true iff the types are equal.
619  bool
620  types_equal(type_base_sptr t1, type_base_sptr t2)
621  {
622  if (t1.get() == t2.get())
623  return true;
624 
625  // We are going to test qualified names only if both types have
626  // already been added to their scope.
627  bool qualified = (get_type_scope(t1) && get_type_scope(t2));
628 
629  return (get_type_name(t1, qualified)
630  == get_type_name(t2, qualified));
631  }
632 
633  /// Associate an ID with a type.
634  ///
635  /// @param type the type to associate with the ID.
636  ///
637  /// @param id the ID to associate to the type.
638  ///
639  /// @return true upon successful completion.
640  bool
641  key_type_decl(const type_base_sptr& type, const string& id)
642  {
643  if (!type)
644  return false;
645 
646  m_types_map[id].push_back(type);
647 
648  return true;
649  }
650 
651  /// Associate an ID to a function template.
652  ///
653  /// @param fn_tmpl_decl the function template to consider.
654  ///
655  /// @param id the ID to associate to the function template.
656  ///
657  /// @return true upon successful completion, false otherwise. Note
658  /// that the function returns false if an ID was previously
659  /// associated to the function template.
660  bool
661  key_fn_tmpl_decl(shared_ptr<function_tdecl> fn_tmpl_decl,
662  const string& id)
663  {
664  ABG_ASSERT(fn_tmpl_decl);
665 
666  const_fn_tmpl_map_it i = m_fn_tmpl_map.find(id);
667  if (i != m_fn_tmpl_map.end())
668  return false;
669 
670  m_fn_tmpl_map[id] = fn_tmpl_decl;
671  return true;
672  }
673 
674  /// Associate an ID to a class template.
675  ///
676  /// @param class_tmpl_decl the class template to consider.
677  ///
678  /// @param id the ID to associate to the class template.
679  ///
680  /// @return true upon successful completion, false otherwise. Note
681  /// that the function returns false if an ID was previously
682  /// associated to the class template.
683  bool
684  key_class_tmpl_decl(shared_ptr<class_tdecl> class_tmpl_decl,
685  const string& id)
686  {
687  ABG_ASSERT(class_tmpl_decl);
688 
689  const_class_tmpl_map_it i = m_class_tmpl_map.find(id);
690  if (i != m_class_tmpl_map.end())
691  return false;
692 
693  m_class_tmpl_map[id] = class_tmpl_decl;
694  return true;
695  }
696 
697 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
698  /// Record that an artifact is used by another one.
699  ///
700  /// If a type is "used" by another one (as in the type is a sub-type
701  /// of another one), this function records that relation.
702  ///
703  /// @param used the type that is used.
704  ///
705  /// @param user the type that uses @p used.
706  void
707  record_artifact_as_used_by(type_or_decl_base* used,
708  type_or_decl_base* user)
709  {
710  if (m_artifact_used_by_map.find(used) == m_artifact_used_by_map.end())
711  {
712  vector<type_or_decl_base*> v;
713  m_artifact_used_by_map[used] = v;
714  }
715  m_artifact_used_by_map[used].push_back(user);
716  }
717 
718  /// Record that an artifact is used by another one.
719  ///
720  /// If a type is "used" by another one (as in the type is a sub-type
721  /// of another one), this function records that relation.
722  ///
723  /// @param used the type that is used.
724  ///
725  /// @param user the type that uses @p used.
726  void
727  record_artifact_as_used_by(const type_or_decl_base_sptr& used,
728  const type_or_decl_base_sptr& user)
729  {record_artifact_as_used_by(used.get(), user.get());}
730 
731  /// Record the sub-types of a fn-decl as being used by the fn-decl.
732  ///
733  /// @param fn the function decl to consider.
734  void
735  record_artifacts_as_used_in_fn_decl(const function_decl *fn)
736  {
737  if (!fn)
738  return;
739 
740  type_base_sptr t = fn->get_return_type();
741  record_artifact_as_used_by(t.get(), const_cast<function_decl*>(fn));
742 
743  for (auto pit : fn->get_parameters())
744  {
745  type_base_sptr t = pit->get_type();
746  record_artifact_as_used_by(t.get(), const_cast<function_decl*>(fn));
747  }
748  }
749 
750  /// Record the sub-types of a function decl as being used by it.
751  ///
752  /// @param fn the function decl to consider.
753  void
754  record_artifacts_as_used_in_fn_decl(const function_decl_sptr& fn)
755  {record_artifacts_as_used_in_fn_decl(fn.get());}
756 
757  /// Record the sub-types of a function type as being used by it.
758  ///
759  /// @param fn_type the function decl to consider.
760  void
761  record_artifacts_as_used_in_fn_type(const function_type *fn_type)
762  {
763  if (!fn_type)
764  return;
765 
766  type_base_sptr t = fn_type->get_return_type();
767  record_artifact_as_used_by(t.get(), const_cast<function_type*>(fn_type));
768 
769  for (auto pit : fn_type->get_parameters())
770  {
771  type_base_sptr t = pit->get_type();
772  record_artifact_as_used_by(t.get(),
773  const_cast<function_type*>(fn_type));
774  }
775  }
776 
777  /// Record the sub-types of a function type as being used by it.
778  ///
779  /// @param fn_type the function decl to consider.
780  void
781  record_artifacts_as_used_in_fn_type(const function_type_sptr& fn_type)
782  {record_artifacts_as_used_in_fn_type(fn_type.get());}
783 #endif
784 
785  /// This function must be called on each declaration that is created
786  /// during the parsing. It adds the declaration to the scope that
787  /// its XML node belongs to and updates the state of the parsing
788  /// context accordingly.
789  ///
790  /// @param decl the newly created declaration.
791  ///
792  /// @param node the xml node @p decl originated from.
793  void
794  push_decl_to_scope(const decl_base_sptr& decl, xmlNodePtr node)
795  {
796  scope_decl* scope = nullptr;
797  scope = get_scope_ptr_for_node(node);
798  return push_decl_to_scope(decl, scope);
799  }
800 
801  /// This function must be called on each declaration that is created during
802  /// the parsing. It adds the declaration to the current scope, and updates
803  /// the state of the parsing context accordingly.
804  ///
805  /// @param decl the newly created declaration.
806  void
807  push_decl_to_scope(const decl_base_sptr& decl,
808  scope_decl* scope)
809  {
810  ABG_ASSERT(decl);
811  if (scope)
812  {
813  add_decl_to_scope(decl, scope);
814  if (!decl->get_translation_unit())
815  decl->set_translation_unit(get_translation_unit());
816  ABG_ASSERT(decl->get_translation_unit());
817  }
818  push_decl(decl);
819  }
820 
821  /// This function must be called on each type decl that is created
822  /// during the parsing. It adds the type decl to the current scope
823  /// and associates a unique ID to it.
824  ///
825  /// @param t type_decl
826  ///
827  /// @param id the unique ID to be associated to t
828  ///
829  /// @param scope the scope to add the type to.
830  ///
831  /// @return true upon successful completion.
832  ///
833  bool
834  push_and_key_type_decl(const type_base_sptr& t,
835  const string& id,
836  scope_decl* scope)
837  {
838  decl_base_sptr decl = get_type_declaration(t);
839  ABG_ASSERT(decl);
840 
841  push_decl_to_scope(decl, scope);
842  if (!t->get_translation_unit())
843  t->set_translation_unit(get_translation_unit());
844  ABG_ASSERT(t->get_translation_unit());
845  key_type_decl(t, id);
846  return true;
847  }
848 
849  /// This function must be called on each type decl that is created
850  /// during the parsing. It adds the type decl to the current scope
851  /// and associates a unique ID to it.
852  ///
853  /// @param t the type to consider.
854  ///
855  /// @param node the XML it originates from.
856  ///
857  /// @return true upon successful completion.
858  ///
859  bool
860  push_and_key_type_decl(const type_base_sptr& t,
861  const xmlNodePtr node,
862  bool add_to_current_scope)
863  {
864  string id;
865  if (!read_type_id_string(node, id))
866  return false;
867 
868  scope_decl* scope = nullptr;
869  if (add_to_current_scope && !is_unique_type(t))
870  scope = get_scope_ptr_for_node(node);
871  return push_and_key_type_decl(t, id, scope);
872  }
873 
874  /// Getter for the object that determines if a given declaration
875  /// ought to be put in the set of exported decls of the current
876  /// corpus.
877  ///
878  /// @return the exported decls builder.
879  corpus::exported_decls_builder*
880  get_exported_decls_builder()
881  {return corpus()->get_exported_decls_builder().get();}
882 
883  /// Test if there are suppression specifications (associated to the
884  /// current corpus) that match a given SONAME or file name.
885  ///
886  /// @param soname the SONAME to consider.
887  ///
888  /// @param the file name to consider.
889  ///
890  /// @return true iff there are suppression specifications (associated to the
891  /// current corpus) that match the SONAME denoted by @p soname or
892  /// the file name denoted by @p filename.
893  bool
894  corpus_is_suppressed_by_soname_or_filename(const string& soname,
895  const string& filename)
896  {
900 
901  for (suppressions_type::const_iterator s = suppressions().begin();
902  s != suppressions().end();
903  ++s)
904  if (file_suppression_sptr suppr = is_file_suppression(*s))
906  *suppr))
907  return true;
908 
909  return false;
910  }
911 
912  /// Clear all the data that must absolutely be cleared at the end of
913  /// the parsing of a translation unit.
914  void
915  clear_per_translation_unit_data()
916  {
917  }
918 
919 #ifdef WITH_DEBUG_SELF_COMPARISON
920  /// Perform a debugging routine for the "self-comparison" mode.
921  ///
922  /// This is done when this command is on:
923  ///
924  /// "abidw --debug-abidiff".
925  ///
926  /// Consider a type 't' built from an XML element from the abixml
927  /// reader and that has just been canonicalized.
928  ///
929  /// This function checks if the canonical type of 't' is the same as
930  /// the canonical type of the type which was saved into the abixml
931  /// with the same "type-id" as the one of 't'.
932  ///
933  /// Note that at abixml saving time, a debugging file was saved on
934  /// disk to record the mapping of canonical type pointers and their
935  /// type-ids. Right before reading the abixml again, that file was
936  /// read again and the mapping was loaded in the map returned by
937  /// environment::get_type_id_canonical_type_map().
938  void
939  maybe_check_abixml_canonical_type_stability(type_base_sptr& t)
940  {
941  if (!get_environment().self_comparison_debug_is_on()
942  || get_environment().get_type_id_canonical_type_map().empty())
943  return ;
944 
945  if (class_decl_sptr c = is_class_type(t))
946  if (odr_is_relevant(*c) && c->get_is_declaration_only())
947  // Declaration-only classes don't have canonical types in
948  // environments where ODR is relevant (like in C++).
949  return;
950 
951  // Let's get the type-id of this type as recorded in the
952  // originating abixml file.
953  string type_id =
954  get_environment().get_type_id_from_pointer(reinterpret_cast<uintptr_t>(t.get()));
955 
956  if (!type_id.empty())
957  {
958  // Now let's get the canonical type that initially led to the
959  // serialization of a type with this type-id, when the abixml
960  // was being serialized.
961  auto j = get_environment().get_type_id_canonical_type_map().find(type_id);
962  if (j == get_environment().get_type_id_canonical_type_map().end())
963  {
964  if (t->get_naked_canonical_type())
965  std::cerr << "error: no type with type-id: '"
966  << type_id
967  << "' could be read back from the typeid file\n";
968  }
969  else if (j->second
970  != reinterpret_cast<uintptr_t>(t->get_canonical_type().get()))
971  // So the canonical type of 't' (at abixml de-serialization
972  // time) is different from the canonical type that led to
973  // the serialization of 't' at abixml serialization time.
974  // Report this because it needs further debugging.
975  std::cerr << "error: canonical type for type '"
976  << t->get_pretty_representation(/*internal=*/true,
977  /*qualified=*/true)
978  << "' of type-id '" << type_id
979  << "' changed from '" << std::hex
980  << j->second << "' to '" << std::hex
981  << reinterpret_cast<uintptr_t>(t->get_canonical_type().get())
982  << std::dec
983  << "'\n";
984  }
985  }
986 #endif
987 
988  /// Schedule a type for being canonicalized after the current
989  /// translation unit is read.
990  ///
991  /// @param t the type to consider for canonicalization.
992  void
993  schedule_type_for_canonicalization(type_base_sptr t)
994  {
995  if (t)
996  m_types_to_canonicalize.push_back(t);
997  }
998 
999  /// Perform the canonicalizing of types that ought to be done after
1000  /// the current translation unit is read. This function is called
1001  /// when the current corpus is fully built.
1002  void
1003  perform_type_canonicalization()
1004  {
1005  tools_utils::timer cn_timer;
1006  if (do_log())
1007  {
1008  std::cerr << "ABIXML Reader is going to canonicalize "
1009  << m_types_to_canonicalize.size()
1010  << " types";
1011  corpus_sptr c = corpus();
1012  if (c)
1013  std::cerr << " of corpus " << corpus()->get_path() << "\n";
1014  cn_timer.start();
1015  }
1016 
1017 
1018  ir::hash_and_canonicalize_types(m_types_to_canonicalize.begin(),
1019  m_types_to_canonicalize.end(),
1020  [](const vector<type_base_sptr>::const_iterator& i)
1021  {return *i;},
1022  do_log());
1023 
1024  if (do_log())
1025  {
1026  cn_timer.stop();
1027  std::cerr << "ABIXML Reader: canonicalized all types in: " << cn_timer << "\n";
1028  }
1029  }
1030 
1031  /// Test whether if a given function suppression matches a function
1032  /// designated by a regular expression that describes its name.
1033  ///
1034  /// @param s the suppression specification to evaluate to see if it
1035  /// matches a given function name.
1036  ///
1037  /// @param fn_name the name of the function of interest. Note that
1038  /// this name must be *non* qualified.
1039  ///
1040  /// @return true iff the suppression specification @p s matches the
1041  /// function whose name is @p fn_name.
1042  bool
1043  suppression_matches_function_name(const suppr::function_suppression_sptr& s,
1044  const string& fn_name) const
1045  {
1046  if (!s)
1047  return false;
1048  return suppression_matches_function_name(*s, fn_name);
1049  }
1050 
1051  /// Tests if a suppression specification can match ABI artifacts
1052  /// coming from the ABI corpus being analyzed.
1053  ///
1054  /// This tests if the suppression matches the soname of and binary
1055  /// name of the corpus being analyzed.
1056  ///
1057  /// @param s the suppression specification to consider.
1058  bool
1059  suppression_can_match(const suppr::suppression_base& s) const
1060  {
1061  corpus_sptr corp = corpus();
1062 
1063  if (!s.priv_->matches_soname(corp->get_soname()))
1064  if (s.has_soname_related_property())
1065  // The suppression has some SONAME related properties, but
1066  // none of them match the SONAME of the current binary. So
1067  // the suppression cannot match the current binary.
1068  return false;
1069 
1070  if (!s.priv_->matches_binary_name(corp->get_path()))
1071  if (s.has_file_name_related_property())
1072  // The suppression has some file_name related properties, but
1073  // none of them match the file name of the current binary. So
1074  // the suppression cannot match the current binary.
1075  return false;
1076 
1077  return true;
1078  }
1079 
1080  /// Test whether if a given function suppression matches a function
1081  /// designated by a regular expression that describes its name.
1082  ///
1083  /// @param s the suppression specification to evaluate to see if it
1084  /// matches a given function name.
1085  ///
1086  /// @param fn_name the name of the function of interest. Note that
1087  /// this name must be *non* qualified.
1088  ///
1089  /// @return true iff the suppression specification @p s matches the
1090  /// function whose name is @p fn_name.
1091  bool
1092  suppression_matches_function_name(const suppr::function_suppression& s,
1093  const string& fn_name) const
1094  {
1095  if (!s.get_drops_artifact_from_ir()
1096  || !suppression_can_match(s))
1097  return false;
1098 
1099  return suppr::suppression_matches_function_name(s, fn_name);
1100  }
1101 
1102  /// Test if a given type suppression specification matches a type
1103  /// designated by its name and location.
1104  ///
1105  /// @param s the suppression specification to consider.
1106  ///
1107  /// @param type_name the fully qualified type name to consider.
1108  ///
1109  /// @param type_location the type location to consider.
1110  ///
1111  /// @return true iff the type suppression specification matches a
1112  /// type of a given name and location.
1113  bool
1114  suppression_matches_type_name_or_location(const suppr::type_suppression& s,
1115  const string& type_name,
1116  const location& type_location) const
1117  {
1118  if (!suppression_can_match(s))
1119  return false;
1120 
1122  type_location);
1123  }
1124 
1125  virtual ir::corpus_sptr
1126  read_corpus(fe_iface::status& status)
1127  {
1128  tools_utils::timer global_timer;
1129  global_timer.start();
1130 
1131  corpus_sptr nil;
1132 
1133  xml::reader_sptr xml_reader = get_libxml_reader();
1134  if (!xml_reader)
1135  return nil;
1136 
1137  // This is to remember to call xmlTextReaderNext if we ever call
1138  // xmlTextReaderExpand.
1139  bool call_reader_next = false;
1140 
1141  xmlNodePtr node = get_corpus_node();
1142  if (!node)
1143  {
1144  // The document must start with the abi-corpus node.
1145  int status = 1;
1146  while (status == 1
1147  && XML_READER_GET_NODE_TYPE(xml_reader) != XML_READER_TYPE_ELEMENT)
1148  status = advance_cursor (*this);
1149 
1150  if (status != 1 || !xmlStrEqual (XML_READER_GET_NODE_NAME(xml_reader).get(),
1151  BAD_CAST("abi-corpus")))
1152  return nil;
1153 
1154 #ifdef WITH_DEBUG_SELF_COMPARISON
1155  if (get_environment().self_comparison_debug_is_on())
1156  get_environment().set_self_comparison_debug_input(corpus());
1157 #endif
1158 
1159  ir::corpus& corp = *corpus();
1160 
1161  corp.set_origin(corpus::NATIVE_XML_ORIGIN);
1162 
1163  handle_version_attribute(xml_reader, corp);
1164 
1165  maybe_drop_hash_values();
1166 
1167  xml::xml_char_sptr path_str = XML_READER_GET_ATTRIBUTE(xml_reader, "path");
1168  string path;
1169 
1170  if (path_str)
1171  {
1172  path = reinterpret_cast<char*>(path_str.get());
1173  corpus_path(path);
1174  corp.set_path(path);
1175  }
1176 
1177  xml::xml_char_sptr architecture_str =
1178  XML_READER_GET_ATTRIBUTE(xml_reader, "architecture");
1179  if (architecture_str)
1180  corp.set_architecture_name
1181  (reinterpret_cast<char*>(architecture_str.get()));
1182 
1183  xml::xml_char_sptr soname_str =
1184  XML_READER_GET_ATTRIBUTE(xml_reader, "soname");
1185  string soname;
1186 
1187  if (soname_str)
1188  {
1189  soname = reinterpret_cast<char*>(soname_str.get());
1190  dt_soname(soname);
1191  corp.set_soname(soname);
1192  }
1193 
1194  // Apply suppression specifications here to honour:
1195  //
1196  // [suppress_file]
1197  // (soname_regexp
1198  // |soname_not_regexp
1199  // |file_name_regexp
1200  // |file_name_not_regexp) = <soname-or-file-name>
1201  if ((!soname.empty() || !path.empty())
1202  && corpus_is_suppressed_by_soname_or_filename(soname, path))
1203  return nil;
1204 
1205  node = xmlTextReaderExpand(xml_reader.get());
1206  if (!node)
1207  return nil;
1208 
1209  call_reader_next = true;
1210  }
1211  else
1212  {
1213 #ifdef WITH_DEBUG_SELF_COMPARISON
1214  if (get_environment().self_comparison_debug_is_on())
1215  get_environment().set_self_comparison_debug_input(corpus());
1216 #endif
1217 
1218  ir::corpus& corp = *corpus();
1219  corp.set_origin(corpus::NATIVE_XML_ORIGIN);
1220 
1221  xml::xml_char_sptr path_str = XML_NODE_GET_ATTRIBUTE(node, "path");
1222  if (path_str)
1223  corp.set_path(reinterpret_cast<char*>(path_str.get()));
1224 
1225  xml::xml_char_sptr architecture_str =
1226  XML_NODE_GET_ATTRIBUTE(node, "architecture");
1227  if (architecture_str)
1228  corp.set_architecture_name
1229  (reinterpret_cast<char*>(architecture_str.get()));
1230 
1231  xml::xml_char_sptr soname_str =
1232  XML_NODE_GET_ATTRIBUTE(node, "soname");
1233  if (soname_str)
1234  corp.set_soname(reinterpret_cast<char*>(soname_str.get()));
1235  }
1236 
1237  // If the corpus element node has children nodes, make
1238  // get_corpus_node() returns the first child element node of
1239  // the corpus element that *needs* to be processed.
1240  if (node->children)
1241  {
1242  xmlNodePtr n = xmlFirstElementChild(node);
1243  set_corpus_node(n);
1244  }
1245 
1246  ir::corpus& corp = *corpus();
1247 
1248  tools_utils::timer t;
1249 
1250  if (do_log())
1251  {
1252  std::cerr << "ABIXML Reader: mapping XML nodes to type ID "
1253  << "for corpus " << corp.get_path()
1254  << "...\n";
1255  t.start();
1256  }
1257 
1258  walk_xml_node_to_map_type_ids(*this, node);
1259 
1260  if (do_log())
1261  {
1262  t.stop();
1263  std::cerr << "ABIXML Reader: mapped XML nodes to type ID "
1264  << "for corpus " << corp.get_path()
1265  << " in: "
1266  << t
1267  << "\n";
1268  }
1269 
1270  // Read the needed element
1271  vector<string> needed;
1272  read_elf_needed_from_input(*this, needed);
1273  if (!needed.empty())
1274  corp.set_needed(needed);
1275 
1277  var_sym_db(new string_elf_symbols_map_type);
1278 
1279  if (do_log())
1280  {
1281  std::cerr << "ABIXML Reader: reading symbols information "
1282  << "for corpus " << corp.get_path()
1283  << " ...\n";
1284  t.start();
1285  }
1286 
1287  // Read the symbol databases.
1288  string_strings_map_type non_resolved_fn_syms_aliases, non_resolved_var_syms_aliases;
1289  read_symbol_db_from_input(*this, fn_sym_db, var_sym_db,
1290  non_resolved_fn_syms_aliases,
1291  non_resolved_var_syms_aliases);
1292  resolve_symbol_aliases(fn_sym_db, var_sym_db,
1293  non_resolved_fn_syms_aliases,
1294  non_resolved_var_syms_aliases);
1295 
1296  // Note that it's possible that both fn_sym_db and var_sym_db are nil,
1297  // due to potential suppression specifications. That's fine.
1298  corp.set_symtab(symtab_reader::symtab::load(fn_sym_db, var_sym_db));
1299 
1300  if (do_log())
1301  {
1302  t.stop();
1303  std::cerr << "ABIXML Reader: read symbols information "
1304  << "for corpus " << corp.get_path()
1305  << " in: "
1306  << t
1307  << "\n";
1308  }
1309 
1310  get_environment().canonicalization_is_done(false);
1311 
1312  if (do_log())
1313  {
1314  std::cerr << "ABIXML Reader: building IR "
1315  << "for corpus " << corp.get_path()
1316  << "...\n";
1317  t.start();
1318  }
1319 
1320  // Read the translation units.
1321  while (read_translation_unit_from_input(*this))
1322  ;
1323 
1324  if (do_log())
1325  {
1326  t.stop();
1327  std::cerr << "ABIXML Reader: built IR "
1328  << "for corpus " << corp.get_path()
1329  << " in: " << t << "\n";
1330  }
1331 
1332  if (tracking_non_reachable_types())
1333  {
1334  bool is_tracking_non_reachable_types = false;
1335  read_tracking_non_reachable_types(node, is_tracking_non_reachable_types);
1336 
1337  ABG_ASSERT
1338  (corp.recording_types_reachable_from_public_interface_supported()
1339  == is_tracking_non_reachable_types);
1340  }
1341 
1342 
1343  if (do_log())
1344  {
1345  std::cerr << "ABIXML Reader: canonicalizing types "
1346  << "for corpus " << corp.get_path()
1347  << " ...\n";
1348  t.start();
1349  }
1350 
1351  perform_type_canonicalization();
1352 
1353  if (do_log())
1354  {
1355  t.stop();
1356  std::cerr << "ABIXML Reader: canonicalized types for corpus "
1357  << corpus()->get_path()
1358  << " in :" << t << "\n";
1359  }
1360 
1361  get_environment().canonicalization_is_done(true);
1362 
1363  if (call_reader_next)
1364  {
1365  // This is the necessary counter-part of the xmlTextReaderExpand()
1366  // call at the beginning of the function.
1367  xmlTextReaderNext(xml_reader.get());
1368  // The call above invalidates the xml node returned by
1369  // xmlTextReaderExpand, which is can still be accessed via
1370  // set_corpus_node.
1371  set_corpus_node(0);
1372  }
1373  else
1374  {
1375  node = get_corpus_node();
1376  node = xmlNextElementSibling(node);
1377  if (!node)
1378  {
1379  node = get_corpus_node();
1380  if (node)
1381  node = xmlNextElementSibling(node->parent);
1382  }
1383  set_corpus_node(node);
1384  }
1385 
1386  if (do_log())
1387  {
1388  std::cerr << "ABIXML Reader: sorting functions and variables for corpus "
1389  << corp.get_path()
1390  << "\n";
1391  t.start();
1392  }
1393 
1394  corpus()->sort_functions();
1395  corpus()->sort_variables();
1396 
1397  if (do_log())
1398  {
1399  t.stop();
1400  std::cerr << "ABIXML Reader: sorted functions and variables for corpus "
1401  << corpus()->get_path()
1402  << " in " << t
1403  << "\n";
1404  }
1405 
1406  if (do_log())
1407  {
1408  global_timer.stop();
1409  std::cerr << "ABIXML Reader: Analyzed corpus " << corpus()->get_path()
1410  << " in " << global_timer << "\n";
1411  std::cerr << "======================================================\n";
1412  }
1413 
1414  status = STATUS_OK;
1415  return corpus();
1416  }
1417 
1418  /// Test if the reader should drop the hash values coming from the
1419  /// ABIXML on the floor.
1420  ///
1421  /// If the minor version number of the ABIXML document is older than
1422  /// the current minor abixml version of the document being read,
1423  /// then the hash values are dropped and new ones are going to be
1424  /// computed by ir::hash_and_canonicalize_types.
1425  void
1426  maybe_drop_hash_values()
1427  {
1428  string current_major, current_minor;
1429  abigail::abigail_get_abixml_version(current_major, current_minor);
1430 
1431  if (current_major.empty() || current_minor.empty())
1432  return;
1433 
1434  ir::corpus& corp = *corpus();
1435  bool drop_hash_values_from_abixml = false;
1436  if (current_major > corp.get_format_major_version_number()
1437  || current_minor > corp.get_format_minor_version_number())
1438  drop_hash_values_from_abixml = true;
1439 
1440  if (drop_hash_values_from_abixml)
1441  m_drop_hash_value = true;
1442  }
1443 
1444  /// Read the hash value from an XML node and set it onto an IR node.
1445  ///
1446  /// @param node the XML node to read the hash value from.
1447  ///
1448  /// @param ir_node output parameter. The IR node to set the hash
1449  /// value read from @p node onto.
1450  void
1451  read_hash_and_stash(const xmlNodePtr node,
1452  const type_or_decl_base_sptr& ir_node)
1453  {
1454  uint64_t hash = 0, cti = 0;
1455  if (!m_drop_hash_value
1456  && read_type_hash_and_cti(node, hash, cti))
1457  {
1458  ir_node->priv_->force_set_hash_value(hash);
1459  type_base_sptr type;
1460  if (function_decl_sptr fn = is_function_decl(ir_node))
1461  type = fn->get_type();
1462  else
1463  type = is_type(ir_node);
1464 
1465  if (type)
1466  {
1467  type->type_or_decl_base::priv_->force_set_hash_value(hash);
1468  type->priv_->canonical_type_index = cti;
1469  }
1470  }
1471  }
1472 };// end class reader
1473 
1474 typedef shared_ptr<reader> reader_sptr;
1475 
1476 static int advance_cursor(reader&);
1477 static bool read_translation_unit(fe_iface&, translation_unit&, xmlNodePtr);
1478 static translation_unit_sptr get_or_read_and_add_translation_unit(reader&, xmlNodePtr);
1479 static translation_unit_sptr read_translation_unit_from_input(fe_iface&);
1480 static bool read_symbol_db_from_input(reader&,
1483  string_strings_map_type&,
1484  string_strings_map_type&);
1485 static bool read_location(const reader&, xmlNodePtr, location&);
1486 static bool read_artificial_location(const reader&,
1487  xmlNodePtr, location&);
1488 static bool maybe_set_artificial_location(const reader&,
1489  xmlNodePtr,
1491 static bool read_visibility(xmlNodePtr, decl_base::visibility&);
1492 static bool read_binding(xmlNodePtr, decl_base::binding&);
1493 static bool read_access(xmlNodePtr, access_specifier&);
1494 static bool read_size_and_alignment(xmlNodePtr, size_t&, size_t&);
1495 static bool read_static(xmlNodePtr, bool&);
1496 static bool read_offset_in_bits(xmlNodePtr, size_t&);
1497 static bool read_cdtor_const(xmlNodePtr, bool&, bool&, bool&);
1498 static bool read_is_virtual(xmlNodePtr, bool&);
1499 static bool read_is_struct(xmlNodePtr, bool&);
1500 static bool read_is_anonymous(xmlNodePtr, bool&);
1501 static bool read_elf_symbol_type(xmlNodePtr, elf_symbol::type&);
1502 static bool read_elf_symbol_binding(xmlNodePtr, elf_symbol::binding&);
1503 static bool read_elf_symbol_visibility(xmlNodePtr,
1505 static namespace_decl_sptr
1506 build_namespace_decl(reader&, const xmlNodePtr, bool);
1507 
1508 // <build a c++ class from an instance of xmlNodePtr>
1509 //
1510 // Note that whenever a new function to build a type is added here,
1511 // you should make sure to call it from the build_type function, which
1512 // should be the last function of the list of declarated function
1513 // below.
1514 
1515 static elf_symbol_sptr
1516 build_elf_symbol(reader&, const xmlNodePtr, bool);
1517 
1518 static elf_symbol_sptr
1519 build_elf_symbol_from_reference(reader&, const xmlNodePtr);
1520 
1521 static bool
1522 build_elf_symbol_db(reader&, const xmlNodePtr, bool,
1524  string_strings_map_type&);
1525 
1527 build_function_parameter (reader&, const xmlNodePtr);
1528 
1529 static function_decl_sptr
1530 build_function_decl(reader&, const xmlNodePtr,
1531  class_or_union_sptr, bool, bool);
1532 
1533 static function_decl_sptr
1534 build_function_decl_if_not_suppressed(reader&, const xmlNodePtr,
1535  class_or_union_sptr, bool, bool);
1536 
1537 static bool
1538 function_is_suppressed(const reader& rdr,
1539  xmlNodePtr node);
1540 
1541 static var_decl_sptr
1542 build_var_decl_if_not_suppressed(reader&, const xmlNodePtr, bool);
1543 
1544 static var_decl_sptr
1545 build_var_decl(reader&, const xmlNodePtr, bool);
1546 
1547 static bool
1548 variable_is_suppressed(const reader& rdr,
1549  xmlNodePtr node);
1550 
1551 static shared_ptr<type_decl>
1552 build_type_decl(reader&, const xmlNodePtr, bool);
1553 
1554 static qualified_type_def_sptr
1555 build_qualified_type_decl(reader&, const xmlNodePtr, bool);
1556 
1557 static shared_ptr<pointer_type_def>
1558 build_pointer_type_def(reader&, const xmlNodePtr, bool);
1559 
1560 static shared_ptr<reference_type_def>
1561 build_reference_type_def(reader&, const xmlNodePtr, bool);
1562 
1563 static ptr_to_mbr_type_sptr
1564 build_ptr_to_mbr_type(reader&, const xmlNodePtr, bool);
1565 
1566 static shared_ptr<function_type>
1567 build_function_type(reader&, const xmlNodePtr, bool);
1568 
1570 build_subrange_type(reader&, const xmlNodePtr, bool);
1571 
1572 static array_type_def_sptr
1573 build_array_type_def(reader&, const xmlNodePtr, bool);
1574 
1575 static enum_type_decl_sptr
1576 build_enum_type_decl(reader&, const xmlNodePtr, bool);
1577 
1578 static shared_ptr<typedef_decl>
1579 build_typedef_decl(reader&, const xmlNodePtr, bool);
1580 
1581 static class_decl_sptr
1582 build_class_decl(reader&, const xmlNodePtr, bool);
1583 
1584 static union_decl_sptr
1585 build_union_decl(reader&, const xmlNodePtr, bool);
1586 
1587 static shared_ptr<function_tdecl>
1588 build_function_tdecl(reader&, const xmlNodePtr, bool);
1589 
1590 static shared_ptr<class_tdecl>
1591 build_class_tdecl(reader&, const xmlNodePtr, bool);
1592 
1593 static type_tparameter_sptr
1594 build_type_tparameter(reader&, const xmlNodePtr,
1595  unsigned, template_decl_sptr);
1596 
1597 static type_composition_sptr
1598 build_type_composition(reader&, const xmlNodePtr,
1599  unsigned, template_decl_sptr);
1600 
1602 build_non_type_tparameter(reader&, const xmlNodePtr,
1603  unsigned, template_decl_sptr);
1604 
1606 build_template_tparameter(reader&, const xmlNodePtr,
1607  unsigned, template_decl_sptr);
1608 
1610 build_template_parameter(reader&, const xmlNodePtr,
1611  unsigned, template_decl_sptr);
1612 
1613 // Please make this build_type function be the last one of the list.
1614 // Note that it should call each type-building function above. So
1615 // please make sure to update it accordingly, whenever a new
1616 // type-building function is added here.
1617 static shared_ptr<type_base>
1618 build_type(reader&, const xmlNodePtr, bool);
1619 // </build a c++ class from an instance of xmlNodePtr>
1620 
1621 static type_or_decl_base_sptr handle_element_node(reader&, xmlNodePtr, bool);
1622 static decl_base_sptr handle_type_decl(reader&, xmlNodePtr, bool);
1623 static decl_base_sptr handle_namespace_decl(reader&, xmlNodePtr, bool);
1624 static decl_base_sptr handle_qualified_type_decl(reader&,
1625  xmlNodePtr, bool);
1626 static decl_base_sptr handle_pointer_type_def(reader&,
1627  xmlNodePtr, bool);
1628 static decl_base_sptr handle_reference_type_def(reader&,
1629  xmlNodePtr, bool);
1630 static type_base_sptr handle_function_type(reader&,
1631  xmlNodePtr, bool);
1632 static decl_base_sptr handle_array_type_def(reader&,
1633  xmlNodePtr, bool);
1634 static decl_base_sptr handle_enum_type_decl(reader&, xmlNodePtr, bool);
1635 static decl_base_sptr handle_typedef_decl(reader&, xmlNodePtr, bool);
1636 static decl_base_sptr handle_var_decl(reader&, xmlNodePtr, bool);
1637 static decl_base_sptr handle_function_decl(reader&, xmlNodePtr, bool);
1638 static decl_base_sptr handle_class_decl(reader&, xmlNodePtr, bool);
1639 static decl_base_sptr handle_union_decl(reader&, xmlNodePtr, bool);
1640 static decl_base_sptr handle_function_tdecl(reader&, xmlNodePtr, bool);
1641 static decl_base_sptr handle_class_tdecl(reader&, xmlNodePtr, bool);
1642 
1643 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
1644 #define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user) \
1645  rdr.record_artifact_as_used_by(used,user)
1646 #define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn) \
1647  rdr.record_artifacts_as_used_in_fn_decl(fn)
1648 #define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)\
1649  rdr.record_artifacts_as_used_in_fn_type(fn_type)
1650 #else
1651 #define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user)
1652 #define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn)
1653 #define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)
1654 #endif
1655 
1656 /// Get the IR node representing the scope for a given XML node.
1657 ///
1658 /// This function might trigger the building of a full sub-tree of IR.
1659 ///
1660 /// @param node the XML for which to return the scope decl. If its
1661 /// parent XML node has no corresponding IR node, that IR node is constructed.
1662 ///
1663 /// @param access the access specifier of the node in its scope, if
1664 /// applicable. If the node doesn't have any access specifier
1665 /// provided in its scope, then the parameter is set to no_access.
1666 ///
1667 /// @return the IR node representing the scope of the IR node for the
1668 /// XML node given in argument.
1670 reader::get_scope_for_node(xmlNodePtr node, access_specifier& access)
1671 {
1672  scope_decl_sptr nil, scope;
1673  if (!node)
1674  return nil;
1675 
1676  xmlNodePtr parent = node->parent;
1677  access = no_access;
1678  if (parent
1679  && (xmlStrEqual(parent->name, BAD_CAST("data-member"))
1680  || xmlStrEqual(parent->name, BAD_CAST("member-type"))
1681  || xmlStrEqual(parent->name, BAD_CAST("member-function"))
1682  || xmlStrEqual(parent->name, BAD_CAST("member-template"))
1683  || xmlStrEqual(parent->name, BAD_CAST("template-parameter-type-composition"))
1684  || xmlStrEqual(parent->name, BAD_CAST("array-type-def"))))
1685  {
1686  read_access(parent, access);
1687  parent = parent->parent;
1688  }
1689 
1690  xml_node_decl_base_sptr_map::const_iterator i =
1691  get_xml_node_decl_map().find(parent);
1692  if (i == get_xml_node_decl_map().end())
1693  {
1694  if (xmlStrEqual(parent->name, BAD_CAST("abi-instr")))
1695  {
1697  get_or_read_and_add_translation_unit(*this, parent);
1698  return tu->get_global_scope();
1699  }
1700 
1701  access_specifier a = no_access;
1702  scope_decl_sptr parent_scope = get_scope_for_node(parent, a);
1703  push_decl(parent_scope);
1704  scope = dynamic_pointer_cast<scope_decl>
1705  (handle_element_node(*this, parent, /*add_decl_to_scope=*/true));
1706  ABG_ASSERT(scope);
1707  pop_scope_or_abort(parent_scope);
1708  }
1709  else
1710  scope = dynamic_pointer_cast<scope_decl>(i->second);
1711 
1712  return scope;
1713 }
1714 
1715 /// Get the IR node representing the scope for a given XML node.
1716 ///
1717 /// This function might trigger the building of a full sub-tree of IR.
1718 ///
1719 /// @param node the XML for which to return the scope decl. If its
1720 /// parent XML node has no corresponding IR node, that IR node is constructed.
1721 ///
1722 /// @return the IR node representing the scope of the IR node for the
1723 /// XML node given in argument.
1725 reader::get_scope_for_node(xmlNodePtr node)
1726 {
1727  access_specifier access;
1728  return get_scope_for_node(node, access);
1729 }
1730 
1731 /// Get the IR node representing the scope for a given XML node.
1732 ///
1733 /// This function might trigger the building of a full sub-tree of IR.
1734 ///
1735 /// @param node the XML for which to return the scope decl. If its
1736 /// parent XML node has no corresponding IR node, that IR node is constructed.
1737 ///
1738 /// @return the IR node representing the scope of the IR node for the
1739 /// XML node given in argument.
1740 scope_decl*
1741 reader::get_scope_ptr_for_node(xmlNodePtr node)
1742 {
1743  scope_decl_sptr scope = get_scope_for_node(node);
1744  if (scope)
1745  return scope.get();
1746  return nullptr;
1747 }
1748 
1749 /// Get the type declaration IR node that matches a given XML type node ID.
1750 ///
1751 /// If no IR node has been built for this ID, this function builds the
1752 /// type declaration IR node and returns it. Subsequent invocation of
1753 /// this function with this ID will just return that ID previously returned.
1754 ///
1755 /// @param id the XML node ID to consider.
1756 ///
1757 /// @return the type declaration for the ID given in parameter.
1758 type_base_sptr
1759 reader::build_or_get_type_decl(const string& id, bool add_decl_to_scope)
1760 {
1761  type_base_sptr t = get_type_decl(id);
1762 
1763  if (!t)
1764  {
1765  xmlNodePtr n = get_xml_node_from_id(id);
1766  ABG_ASSERT(n);
1767 
1768  scope_decl_sptr scope;
1769  access_specifier access = no_access;
1770  if (add_decl_to_scope)
1771  {
1772  scope = get_scope_for_node(n, access);
1773  /// In some cases, if for instance the scope of 'n' is a
1774  /// namespace, get_scope_for_node() can trigger the building
1775  /// of what is underneath of the namespace, if that has not
1776  /// already been done. So after that, the IR node for 'n'
1777  /// might have been built; let's try to see if we are in
1778  /// that case. Otherwise, we'll just build the IR node for
1779  /// 'n' ourselves.
1780  if ((t = get_type_decl(id)))
1781  return t;
1782  ABG_ASSERT(scope);
1783  push_decl(scope);
1784  }
1785 
1786  t = build_type(*this, n, add_decl_to_scope);
1787  ABG_ASSERT(t);
1788  if (is_member_type(t) && access != no_access)
1789  {
1790  ABG_ASSERT(add_decl_to_scope);
1791  decl_base_sptr d = get_type_declaration(t);
1792  ABG_ASSERT(d);
1793  set_member_access_specifier(d, access);
1794  }
1795  map_xml_node_to_decl(n, get_type_declaration(t));
1796 
1797  if (add_decl_to_scope)
1798  pop_scope_or_abort(scope);
1799 
1800  schedule_type_for_canonicalization(t);
1801  }
1802  return t;
1803 }
1804 
1805 /// Moves the xmlTextReader cursor to the next xml node in the input
1806 /// document. Return 1 of the parsing was successful, 0 if no input
1807 /// xml token is left, or -1 in case of error.
1808 ///
1809 /// @param rdr the ABIXML reader
1810 ///
1811 static int
1812 advance_cursor(reader& rdr)
1813 {
1814  xml::reader_sptr reader = rdr.get_libxml_reader();
1815  return xmlTextReaderRead(reader.get());
1816 }
1817 
1818 /// Walk an entire XML sub-tree to build a map where the key is the
1819 /// the value of the 'id' attribute (for type definitions) and the value
1820 /// is the xml node containing the 'id' attribute.
1821 ///
1822 /// @param rdr the context of the reader.
1823 ///
1824 /// @param node the XML sub-tree node to walk. It must be an element
1825 /// node.
1826 static void
1827 walk_xml_node_to_map_type_ids(reader& rdr,
1828  xmlNodePtr node)
1829 {
1830  xmlNodePtr n = node;
1831 
1832  if (!n || n->type != XML_ELEMENT_NODE)
1833  return;
1834 
1835  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(n, "id"))
1836  {
1837  string id = CHAR_STR(s);
1838  rdr.map_id_and_node(id, n);
1839  }
1840 
1841  for (n = xmlFirstElementChild(n); n; n = xmlNextElementSibling(n))
1842  walk_xml_node_to_map_type_ids(rdr, n);
1843 }
1844 
1845 static bool
1846 read_translation_unit(fe_iface& iface, translation_unit& tu, xmlNodePtr node)
1847 {
1848  abixml::reader& rdr = dynamic_cast<abixml::reader&>(iface);
1849 
1850  if (!rdr.corpus()->is_empty())
1851  tu.set_corpus(rdr.corpus().get());
1852 
1853  xml::xml_char_sptr addrsize_str =
1854  XML_NODE_GET_ATTRIBUTE(node, "address-size");
1855  if (addrsize_str)
1856  {
1857  char address_size = atoi(reinterpret_cast<char*>(addrsize_str.get()));
1858  tu.set_address_size(address_size);
1859  }
1860 
1861  xml::xml_char_sptr path_str = XML_NODE_GET_ATTRIBUTE(node, "path");
1862  if (path_str)
1863  tu.set_path(reinterpret_cast<char*>(path_str.get()));
1864 
1865  xml::xml_char_sptr comp_dir_path_str =
1866  XML_NODE_GET_ATTRIBUTE(node, "comp-dir-path");
1867  if (comp_dir_path_str)
1868  tu.set_compilation_dir_path(reinterpret_cast<char*>
1869  (comp_dir_path_str.get()));
1870 
1871  xml::xml_char_sptr language_str = XML_NODE_GET_ATTRIBUTE(node, "language");
1872  if (language_str)
1873  tu.set_language(string_to_translation_unit_language
1874  (reinterpret_cast<char*>(language_str.get())));
1875 
1876 
1877  // We are at global scope, as we've just seen the top-most
1878  // "abi-instr" element.
1879  rdr.push_decl(tu.get_global_scope());
1880  rdr.map_xml_node_to_decl(node, tu.get_global_scope());
1881 
1882  if (rdr.get_id_xml_node_map().empty()
1883  || !rdr.corpus())
1884  walk_xml_node_to_map_type_ids(rdr, node);
1885 
1886  for (xmlNodePtr n = xmlFirstElementChild(node);
1887  n;
1888  n = xmlNextElementSibling(n))
1889  handle_element_node(rdr, n, /*add_decl_to_scope=*/true);
1890 
1891  rdr.pop_scope_or_abort(tu.get_global_scope());
1892 
1893  xml::reader_sptr reader = rdr.get_libxml_reader();
1894  if (!reader)
1895  return false;
1896 
1897  rdr.clear_per_translation_unit_data();
1898 
1899  return true;
1900 }
1901 
1902 /// Read a given xml node representing a tranlsation unit.
1903 ///
1904 /// If the current corpus already contains a translation unit of the
1905 /// path of the xml node we need to look at, then return that
1906 /// translation unit. Otherwise, read the translation unit, build a
1907 /// @ref translation_unit out of it, add it to the current corpus and
1908 /// return it.
1909 ///
1910 /// @param rdr the ABIXML reader.
1911 ///
1912 /// @param node the XML node to consider.
1913 ///
1914 /// @return the resulting translation unit.
1915 static translation_unit_sptr
1916 get_or_read_and_add_translation_unit(reader& rdr, xmlNodePtr node)
1917 {
1918  corpus_sptr corp = rdr.corpus();
1919 
1921  string tu_path;
1922  xml::xml_char_sptr path_str = XML_NODE_GET_ATTRIBUTE(node, "path");
1923 
1924  if (corp && !corp->is_empty())
1925  {
1926  if (path_str.get())
1927  tu_path = reinterpret_cast<char*>(path_str.get());
1928  tu = corp->find_translation_unit(tu_path);
1929  if (tu)
1930  return tu;
1931  }
1932 
1933  tu.reset(new translation_unit(rdr.get_environment(), tu_path));
1934  if (corp && !corp->is_empty())
1935  corp->add(tu);
1936 
1937  if (read_translation_unit(rdr, *tu, node))
1938  return tu;
1939 
1940  return translation_unit_sptr();
1941 }
1942 
1943 /// Parse the input XML document containing a translation_unit,
1944 /// represented by an 'abi-instr' element node, associated to the current
1945 /// context.
1946 ///
1947 /// @param rdr the current input context
1948 ///
1949 /// @return the translation unit resulting from the parsing upon
1950 /// successful completion, or nil.
1951 static translation_unit_sptr
1952 read_translation_unit_from_input(fe_iface& iface)
1953 {
1954  translation_unit_sptr tu, nil;
1955 
1956  abixml::reader& rdr = dynamic_cast<abixml::reader&>(iface);
1957 
1958  xmlNodePtr node = rdr.get_corpus_node();
1959  if (!node)
1960  {
1961  xml::reader_sptr reader = rdr.get_libxml_reader();
1962  if (!reader)
1963  return nil;
1964 
1965  // The document must start with the abi-instr node.
1966  int status = 1;
1967  while (status == 1
1968  && XML_READER_GET_NODE_TYPE(reader) != XML_READER_TYPE_ELEMENT)
1969  status = advance_cursor (rdr);
1970 
1971  if (status != 1 || !xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
1972  BAD_CAST("abi-instr")))
1973  return nil;
1974 
1975  node = xmlTextReaderExpand(reader.get());
1976  if (!node)
1977  return nil;
1978  }
1979  else
1980  {
1981  node = 0;
1982  for (xmlNodePtr n = rdr.get_corpus_node();
1983  n;
1984  n = xmlNextElementSibling(n))
1985  {
1986  if (!xmlStrEqual(n->name, BAD_CAST("abi-instr")))
1987  return nil;
1988  node = n;
1989  break;
1990  }
1991  }
1992 
1993  if (node == 0)
1994  return nil;
1995 
1996  tu = get_or_read_and_add_translation_unit(rdr, node);
1997 
1998  if (rdr.get_corpus_node())
1999  {
2000  // We are not in the mode where the current corpus node came
2001  // from a local invocation of xmlTextReaderExpand. So let's set
2002  // rdr.get_corpus_node to the next child element node of the
2003  // corpus that needs to be processed.
2004  node = xmlNextElementSibling(node);
2005  rdr.set_corpus_node(node);
2006  }
2007 
2008  return tu;
2009 }
2010 
2011 /// Parse the input XML document that may contain function symbol and
2012 /// variable symbol databases.
2013 ///
2014 /// A function symbols database is an XML element named
2015 /// "elf-function-symbols" or "undefined-elf-function-symbols" and a
2016 /// variable symbols database is an XML element named
2017 /// "elf-variable-symbols." or "undefined-elf-variable-symbols". They
2018 /// contains "elf-symbol" XML elements.
2019 ///
2020 /// @param rdr the reader to use for the parsing.
2021 ///
2022 /// @param fn_symdb any resulting function symbol database object, if
2023 /// elf-function-symbols was present.
2024 ///
2025 /// @param var_symdb any resulting variable symbol database object, if
2026 /// elf-variable-symbols was present.
2027 ///
2028 /// @param non_resolved_fn_syms_aliases this is a map that associates
2029 /// a function symbol name N to a vector of alias symbol names that
2030 /// are aliases to N. Normally, N is a function symbol that has
2031 /// aliases that are other symbols that are usually function symbols
2032 /// that should be found (or resolved) in @p fn_symdb. If all symbol
2033 /// aliases resolve to symbols in @p fn_symdb then this map is empty.
2034 /// Otherwise, if these alias symbols are not found in @p fn_symbd,
2035 /// then they are stored in this map. The caller of this function
2036 /// might then subsequently try to resolve these elf alias symbols to
2037 /// variable symbols found in @p var_symdb. Note that a function
2038 /// symbol aliasing variable symbols is a feature found in ELF
2039 /// binaries emitted from the OCaml language on platforms like s390x
2040 /// or ppcle.
2041 ///
2042 /// @param non_resolved_var_syms_aliases this is a map that associates
2043 /// a variable symbol name N to a vector of alias symbol names that
2044 /// are aliases to N. Normally, N is a variable symbol that has
2045 /// aliases that are other symbols that are usually variable symbols
2046 /// that should be found (or resolved) in @p var_symdb. If all symbol
2047 /// aliases resolve to symbols in @p var_symdb then this map is empty.
2048 /// Otherwise, if these alias symbols are not found in @p var_symbd,
2049 /// then they are stored in this map. The caller of this function
2050 /// might then subsequently try to resolve these elf alias symbols to
2051 /// function symbols found in @p fn_symdb. Note that a variable
2052 /// symbol aliasing function symbols is a feature found in ELF
2053 /// binaries emitted from the OCaml language on platforms like s390x
2054 /// or ppcle.
2055 ///
2056 /// @return true upon successful parsing, false otherwise.
2057 static bool
2058 read_symbol_db_from_input(reader& rdr,
2059  string_elf_symbols_map_sptr& fn_symdb,
2060  string_elf_symbols_map_sptr& var_symdb,
2061  string_strings_map_type& non_resolved_fn_syms_aliases,
2062  string_strings_map_type& non_resolved_var_syms_aliases)
2063 {
2064  xml::reader_sptr reader = rdr.get_libxml_reader();
2065  if (!reader)
2066  return false;
2067 
2068  if (!rdr.get_corpus_node())
2069  for (;;)
2070  {
2071  int status = 1;
2072  while (status == 1
2073  && XML_READER_GET_NODE_TYPE(reader) != XML_READER_TYPE_ELEMENT)
2074  status = advance_cursor (rdr);
2075 
2076  if (status != 1)
2077  return false;
2078 
2079  bool has_fn_syms = false, has_undefined_fn_syms = false,
2080  has_var_syms = false, has_undefined_var_syms = false;
2081  if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
2082  BAD_CAST("elf-function-symbols")))
2083  has_fn_syms = true;
2084  else if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
2085  BAD_CAST("elf-variable-symbols")))
2086  has_var_syms = true;
2087  else if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
2088  BAD_CAST("undefined-elf-function-symbols")))
2089  has_undefined_fn_syms = true;
2090  else if (xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
2091  BAD_CAST("undefined-elf-variable-symbols")))
2092  has_undefined_var_syms = true;
2093  else
2094  break;
2095 
2096  xmlNodePtr node = xmlTextReaderExpand(reader.get());
2097  if (!node)
2098  return false;
2099 
2100  if (has_fn_syms)
2101  build_elf_symbol_db(rdr, node, /*function_sym=*/true, fn_symdb,
2102  non_resolved_fn_syms_aliases);
2103  else if (has_undefined_fn_syms)
2104  build_elf_symbol_db(rdr, node, /*function_sym=*/true, fn_symdb,
2105  non_resolved_fn_syms_aliases);
2106  else if (has_var_syms)
2107  build_elf_symbol_db(rdr, node, /*function_sym=*/false, var_symdb,
2108  non_resolved_var_syms_aliases);
2109  else if (has_undefined_var_syms)
2110  build_elf_symbol_db(rdr, node, /*function_sym=*/false, var_symdb,
2111  non_resolved_var_syms_aliases);
2112 
2113  xmlTextReaderNext(reader.get());
2114  }
2115  else
2116  for (xmlNodePtr n = rdr.get_corpus_node(); n; n = xmlNextElementSibling(n))
2117  {
2118  bool has_fn_syms = false, has_undefined_fn_syms = false,
2119  has_var_syms = false, has_undefined_var_syms = false;
2120  if (xmlStrEqual(n->name, BAD_CAST("elf-function-symbols")))
2121  has_fn_syms = true;
2122  else if (xmlStrEqual(n->name, BAD_CAST("undefined-elf-function-symbols")))
2123  has_undefined_fn_syms = true;
2124  else if (xmlStrEqual(n->name, BAD_CAST("elf-variable-symbols")))
2125  has_var_syms = true;
2126  else if (xmlStrEqual(n->name,
2127  BAD_CAST("undefined-elf-variable-symbols")))
2128  has_undefined_var_syms = true;
2129  else
2130  {
2131  rdr.set_corpus_node(n);
2132  break;
2133  }
2134 
2135  if (has_fn_syms)
2136  build_elf_symbol_db(rdr, n, /*function_sym=*/true, fn_symdb,
2137  non_resolved_fn_syms_aliases);
2138  else if (has_undefined_fn_syms)
2139  build_elf_symbol_db(rdr, n, /*function_sym=*/true, fn_symdb,
2140  non_resolved_fn_syms_aliases);
2141  else if (has_var_syms)
2142  build_elf_symbol_db(rdr, n, /*function_sym=*/false, var_symdb,
2143  non_resolved_var_syms_aliases);
2144  else if (has_undefined_var_syms)
2145  build_elf_symbol_db(rdr, n, /*function_sym=*/false, var_symdb,
2146  non_resolved_var_syms_aliases);
2147  else
2148  break;
2149  }
2150 
2151  return true;
2152 }
2153 
2154 /// From an "elf-needed" XML_ELEMENT node, build a vector of strings
2155 /// representing the vector of the dependencies needed by a given
2156 /// corpus.
2157 ///
2158 /// @param node the XML_ELEMENT node of name "elf-needed".
2159 ///
2160 /// @param needed the output vector of string to populate with the
2161 /// vector of dependency names found on the xml node @p node.
2162 ///
2163 /// @return true upon successful completion, false otherwise.
2164 static bool
2165 build_needed(xmlNode* node, vector<string>& needed)
2166 {
2167  if (!node || !xmlStrEqual(node->name,BAD_CAST("elf-needed")))
2168  return false;
2169 
2170  for (xmlNodePtr n = xmlFirstElementChild(node);
2171  n;
2172  n = xmlNextElementSibling(n))
2173  {
2174  if (!xmlStrEqual(n->name, BAD_CAST("dependency")))
2175  continue;
2176 
2177  string name;
2178  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(n, "name"))
2180 
2181  if (!name.empty())
2182  needed.push_back(name);
2183  }
2184 
2185  return true;
2186 }
2187 
2188 /// Move to the next xml element node and expext it to be named
2189 /// "elf-needed". Then read the sub-tree to made of that node and
2190 /// extracts a vector of needed dependencies name from it.
2191 ///
2192 /// @param rdr the ABIXML reader used to the xml reading.
2193 ///
2194 /// @param needed the resulting vector of dependency names.
2195 ///
2196 /// @return true upon successful completion, false otherwise.
2197 static bool
2198 read_elf_needed_from_input(reader& rdr,
2199  vector<string>& needed)
2200 {
2201  xml::reader_sptr reader = rdr.get_libxml_reader();
2202  if (!reader)
2203  return false;
2204 
2205  xmlNodePtr node = 0;
2206 
2207  if (rdr.get_corpus_node() == 0)
2208  {
2209  int status = 1;
2210  while (status == 1
2211  && XML_READER_GET_NODE_TYPE(reader) != XML_READER_TYPE_ELEMENT)
2212  status = advance_cursor (rdr);
2213 
2214  if (status != 1)
2215  return false;
2216 
2217  if (!xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
2218  BAD_CAST("elf-needed")))
2219  return false;
2220 
2221  node = xmlTextReaderExpand(reader.get());
2222  if (!node)
2223  return false;
2224  }
2225  else
2226  {
2227  for (xmlNodePtr n = rdr.get_corpus_node();
2228  n;
2229  n = xmlNextElementSibling(n))
2230  {
2231  if (!xmlStrEqual(n->name, BAD_CAST("elf-needed")))
2232  return false;
2233  node = n;
2234  break;
2235  }
2236  }
2237 
2238  bool result = false;
2239  if (node)
2240  {
2241  result = build_needed(node, needed);
2242  node = xmlNextElementSibling(node);
2243  rdr.set_corpus_node(node);
2244  }
2245 
2246  return result;
2247 }
2248 
2249 /// Add suppressions specifications to the set of suppressions to be
2250 /// used during the construction of the ABI internal representation
2251 /// (the ABI corpus) from ELF and DWARF.
2252 ///
2253 /// During the construction of the ABI corpus, ABI artifacts that
2254 /// match the a given suppression specification are dropped on the
2255 /// floor; that is, they are discarded and won't be part of the final
2256 /// ABI corpus. This is a way to reduce the amount of data held by
2257 /// the final ABI corpus.
2258 ///
2259 /// Note that the suppression specifications provided to this function
2260 /// are only considered during the construction of the ABI corpus.
2261 /// For instance, they are not taken into account during e.g
2262 /// comparisons of two ABI corpora that might happen later. If you
2263 /// want to apply suppression specifications to the comparison (or
2264 /// reporting) of ABI corpora please refer to the documentation of the
2265 /// @ref diff_context type to learn how to set suppressions that are
2266 /// to be used in that context.
2267 ///
2268 /// @param rdr the context that is going to be used by functions that
2269 /// read types and declarations information to construct and ABI
2270 /// corpus.
2271 ///
2272 /// @param supprs the suppression specifications to be applied during
2273 /// the construction of the ABI corpus.
2274 void
2276  const suppr::suppressions_type& supprs)
2277 {
2278  for (suppr::suppressions_type::const_iterator i = supprs.begin();
2279  i != supprs.end();
2280  ++i)
2281  if ((*i)->get_drops_artifact_from_ir())
2282  rdr.suppressions().push_back(*i);
2283 }
2284 
2285 /// Configure the @ref reader so that types not reachable from
2286 /// public interface are taken into account when the abixml file is
2287 /// read.
2288 ///
2289 /// @param rdr the @reader to consider.
2290 ///
2291 /// @param flag if yes, then types not reachable from public interface
2292 /// are taken into account when the abixml file is read.
2293 void
2295  bool flag)
2296 {
2297  abixml::reader& rdr = dynamic_cast<abixml::reader&>(iface);
2298  rdr.tracking_non_reachable_types(flag);
2299 }
2300 
2301 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
2302 /// Get the vector of types that have a given type-id.
2303 ///
2304 /// This function is available only if the project has been configured
2305 /// with --enable-show-type-use-in-abilint.
2306 ///
2307 /// @param rdr the abixml text reader context to use.
2308 ///
2309 /// @param type_id the type-id to consider.
2310 vector<type_base_sptr>*
2311 get_types_from_type_id(fe_iface& iface, const string& type_id)
2312 {
2313  xml_reader::reader& rdr = dynamic_cast<xml_reader::reader&>(iface);
2314  auto it = rdr.m_types_map.find(type_id);
2315  if (it == rdr.m_types_map.end())
2316  return nullptr;
2317  return &it->second;
2318 }
2319 
2320 /// Get the map that associates an artififact to its users.
2321 ///
2322 /// This function is available only if the project has been configured
2323 /// with --enable-show-type-use-in-abilint.
2324 ///
2325 /// @param rdr the abixml text reader context to use.
2326 unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
2327 get_artifact_used_by_relation_map(fe_iface& iface)
2328 {
2329  xml_reader::reader& rdr = dynamic_cast<xml_reader::reader&>(iface);
2330  return &rdr.m_artifact_used_by_map;
2331 }
2332 #endif
2333 
2334 /// Read the "version" attribute from the current XML element which is
2335 /// supposed to be a corpus or a corpus group and set the format
2336 /// version to the corpus object accordingly.
2337 ///
2338 /// Note that this is a subroutine of read_corpus_from_input and
2339 /// read_corpus_group_from_input.
2340 ///
2341 /// @param reader the XML reader to consider. That reader must be
2342 /// set to an XML element representing a corpus or a corpus group.
2343 ///
2344 /// @param corp output parameter. The corpus object which format
2345 /// version string is going to be set according to the value of the
2346 /// "version" attribute found on the current XML element.
2347 static void
2348 handle_version_attribute(xml::reader_sptr& reader, corpus& corp)
2349 {
2350  string version_string;
2351  if (xml_char_sptr s = XML_READER_GET_ATTRIBUTE(reader, "version"))
2352  xml::xml_char_sptr_to_string(s, version_string);
2353 
2354  vector<string> v;
2355  if (version_string.empty())
2356  {
2357  v.push_back("1");
2358  v.push_back("0");
2359  }
2360  else
2361  tools_utils::split_string(version_string, ".", v);
2362  corp.set_format_major_version_number(v[0]);
2363  corp.set_format_minor_version_number(v[1]);
2364 }
2365 
2366 /// Parse the input XML document containing an ABI corpus group,
2367 /// represented by an 'abi-corpus-group' element node, associated to
2368 /// the current context.
2369 ///
2370 /// @param rdr the current input context.
2371 ///
2372 /// @return the corpus group resulting from the parsing
2373 corpus_group_sptr
2375 {
2376  corpus_group_sptr nil;
2377 
2378  abixml::reader& rdr = dynamic_cast<abixml::reader&>(iface);
2379  xml::reader_sptr reader = rdr.get_libxml_reader();
2380  if (!reader)
2381  return nil;
2382 
2383  // The document must start with the abi-corpus-group node.
2384  int status = 1;
2385  while (status == 1
2386  && XML_READER_GET_NODE_TYPE(reader) != XML_READER_TYPE_ELEMENT)
2387  status = advance_cursor (rdr);
2388 
2389  if (status != 1 || !xmlStrEqual (XML_READER_GET_NODE_NAME(reader).get(),
2390  BAD_CAST("abi-corpus-group")))
2391  return nil;
2392 
2394 
2395  if (!rdr.corpus_group())
2396  {
2397  corpus_group_sptr g(new corpus_group(rdr.get_environment(),
2398  rdr.get_path()));
2399  g->set_origin(corpus::NATIVE_XML_ORIGIN);
2400  rdr.corpus_group(g);
2401  }
2402 
2403  corpus_group_sptr group = rdr.corpus_group();
2404 
2405  handle_version_attribute(reader, *group);
2406 
2407  xml::xml_char_sptr path_str = XML_READER_GET_ATTRIBUTE(reader, "path");
2408  if (path_str)
2409  group->set_path(reinterpret_cast<char*>(path_str.get()));
2410 
2411  if (rdr.do_log())
2412  {
2413  std::cerr << "ABIXML Reader: reading corpus group : '"
2414  << group->get_path()
2415  << "' ...\n";
2416  t.start();
2417  }
2418 
2419  xmlNodePtr node = xmlTextReaderExpand(reader.get());
2420  if (!node)
2421  return nil;
2422 
2423  node = xmlFirstElementChild(node);
2424  rdr.set_corpus_node(node);
2425 
2426  corpus_sptr corp;
2427  fe_iface::status sts;
2428  while ((corp = rdr.read_corpus(sts)))
2429  {
2430  rdr.corpus_group()->add_corpus(corp);
2431  node = xmlNextElementSibling(node);
2432  if (!node || !xmlStrEqual(node->name, BAD_CAST("abi-corpus")))
2433  break;
2434  rdr.initialize("");
2435  rdr.set_corpus_node(node);
2436  }
2437 
2438  xmlTextReaderNext(reader.get());
2439 
2440  if (rdr.do_log())
2441  {
2442  t.stop();
2443  std::cerr << "ABIXML Reader: Read corpus group : "
2444  << group->get_path()
2445  << " in: " << t << "\n";
2446  }
2447 
2448  return rdr.corpus_group();
2449 }
2450 
2451 /// De-serialize an ABI corpus group from an input XML document which
2452 /// root node is 'abi-corpus-group'.
2453 ///
2454 /// @param in the input stream to read the XML document from.
2455 ///
2456 /// @param env the environment to use. Note that the life time of
2457 /// this environment must be greater than the lifetime of the
2458 /// resulting corpus as the corpus uses resources that are allocated
2459 /// in the environment.
2460 ///
2461 /// @return the resulting corpus group de-serialized from the parsing.
2462 /// This is non-null iff the parsing resulted in a valid corpus group.
2463 corpus_group_sptr
2465  environment& env)
2466 {
2467  fe_iface_sptr rdr = create_reader(in, env);
2468  return read_corpus_group_from_input(*rdr);
2469 }
2470 
2471 /// De-serialize an ABI corpus group from an XML document file which
2472 /// root node is 'abi-corpus-group'.
2473 ///
2474 /// @param path the path to the input file to read the XML document
2475 /// from.
2476 ///
2477 /// @param env the environment to use. Note that the life time of
2478 /// this environment must be greater than the lifetime of the
2479 /// resulting corpus as the corpus uses resources that are allocated
2480 /// in the environment.
2481 ///
2482 /// @return the resulting corpus group de-serialized from the parsing.
2483 /// This is non-null if the parsing successfully resulted in a corpus
2484 /// group.
2485 corpus_group_sptr
2487  environment& env)
2488 {
2489  fe_iface_sptr rdr = create_reader(path, env);
2490  corpus_group_sptr group = read_corpus_group_from_input(*rdr);
2491  return group;
2492 }
2493 
2494 /// Parse an ABI instrumentation file (in XML format) at a given path.
2495 ///
2496 /// @param input_file a path to the file containing the xml document
2497 /// to parse.
2498 ///
2499 /// @param env the environment to use.
2500 ///
2501 /// @return the translation unit resulting from the parsing upon
2502 /// successful completion, or nil.
2504 read_translation_unit_from_file(const string& input_file,
2505  environment& env)
2506 {
2507  reader rdr(xml::new_reader_from_file(input_file), env);
2508  translation_unit_sptr tu = read_translation_unit_from_input(rdr);
2509  env.canonicalization_is_done(false);
2510  rdr.perform_type_canonicalization();
2511  env.canonicalization_is_done(true);
2512  return tu;
2513 }
2514 
2515 /// Parse an ABI instrumentation file (in XML format) from an
2516 /// in-memory buffer.
2517 ///
2518 /// @param buffer the in-memory buffer containing the xml document to
2519 /// parse.
2520 ///
2521 /// @param env the environment to use.
2522 ///
2523 /// @return the translation unit resulting from the parsing upon
2524 /// successful completion, or nil.
2527  environment& env)
2528 {
2529  reader rdr(xml::new_reader_from_buffer(buffer), env);
2530  translation_unit_sptr tu = read_translation_unit_from_input(rdr);
2531  env.canonicalization_is_done(false);
2532  rdr.perform_type_canonicalization();
2533  env.canonicalization_is_done(true);
2534  return tu;
2535 }
2536 
2537 /// Parse a translation unit from an abixml input from a given
2538 /// context.
2539 ///
2540 /// @param rdr the @ref reader to consider.
2541 ///
2542 /// @return the constructed @ref translation_unit from the content of
2543 /// the input abixml.
2545 read_translation_unit(fe_iface& iface)
2546 {
2547  abixml::reader& rdr = dynamic_cast<abixml::reader&>(iface);
2548  translation_unit_sptr tu = read_translation_unit_from_input(rdr);
2549  rdr.options().env.canonicalization_is_done(false);
2550  rdr.perform_type_canonicalization();
2551  rdr.options().env.canonicalization_is_done(true);
2552  return tu;
2553 }
2554 
2555 /// This function is called by @ref read_translation_unit_from_input.
2556 /// It handles the current xml element node of the reading context.
2557 /// The result of the "handling" is to build the representation of the
2558 /// xml node and tied it to the current translation unit.
2559 ///
2560 /// @param rdr the current parsing context.
2561 ///
2562 /// @return true upon successful completion, false otherwise.
2564 handle_element_node(reader& rdr, xmlNodePtr node,
2565  bool add_to_current_scope)
2566 {
2568  if (!node)
2569  return decl;
2570 
2571  ((decl = handle_namespace_decl(rdr, node, add_to_current_scope))
2572  ||(decl = handle_type_decl(rdr, node, add_to_current_scope))
2573  ||(decl = handle_qualified_type_decl(rdr, node,
2574  add_to_current_scope))
2575  ||(decl = handle_pointer_type_def(rdr, node,
2576  add_to_current_scope))
2577  || (decl = handle_reference_type_def(rdr, node, add_to_current_scope))
2578  || (decl = handle_function_type(rdr, node, add_to_current_scope))
2579  || (decl = handle_array_type_def(rdr, node, add_to_current_scope))
2580  || (decl = handle_enum_type_decl(rdr, node,
2581  add_to_current_scope))
2582  || (decl = handle_typedef_decl(rdr, node,
2583  add_to_current_scope))
2584  || (decl = handle_var_decl(rdr, node,
2585  add_to_current_scope))
2586  || (decl = handle_function_decl(rdr, node,
2587  add_to_current_scope))
2588  || (decl = handle_class_decl(rdr, node,
2589  add_to_current_scope))
2590  || (decl = handle_union_decl(rdr, node,
2591  add_to_current_scope))
2592  || (decl = handle_function_tdecl(rdr, node,
2593  add_to_current_scope))
2594  || (decl = handle_class_tdecl(rdr, node,
2595  add_to_current_scope)));
2596 
2597  // If the user wants us to track non-reachable types, then read the
2598  // 'is-non-reachable-type' attribute on type elements and record
2599  // reachable types accordingly.
2600  if (rdr.tracking_non_reachable_types())
2601  {
2602  if (type_base_sptr t = is_type(decl))
2603  {
2604  corpus_sptr abi = rdr.corpus();
2605  ABG_ASSERT(abi);
2606  bool is_non_reachable_type = false;
2607  read_is_non_reachable_type(node, is_non_reachable_type);
2608  if (!is_non_reachable_type)
2609  abi->record_type_as_reachable_from_public_interfaces(*t);
2610  }
2611  }
2612 
2613  return decl;
2614 }
2615 
2616 /// Parses location attributes on an xmlNodePtr.
2617 ///
2618 ///@param rdr the current parsing context
2619 ///
2620 ///@param loc the resulting location.
2621 ///
2622 /// @return true upon sucessful parsing, false otherwise.
2623 static bool
2624 read_location(const reader& rdr,
2625  xmlNodePtr node,
2626  location& loc)
2627 {
2628  string file_path;
2629  size_t line = 0, column = 0;
2630 
2631  if (xml_char_sptr f = xml::build_sptr(xmlGetProp(node, BAD_CAST("filepath"))))
2632  file_path = CHAR_STR(f);
2633 
2634  if (file_path.empty())
2635  return read_artificial_location(rdr, node, loc);
2636 
2637  if (xml_char_sptr l = xml::build_sptr(xmlGetProp(node, BAD_CAST("line"))))
2638  line = atoi(CHAR_STR(l));
2639  else
2640  return read_artificial_location(rdr, node, loc);
2641 
2642  if (xml_char_sptr c = xml::build_sptr(xmlGetProp(node, BAD_CAST("column"))))
2643  column = atoi(CHAR_STR(c));
2644 
2645  reader& c = const_cast<reader&>(rdr);
2646  loc = c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2647  line,
2648  column);
2649  return true;
2650 }
2651 
2652 /// Parses the artificial location attributes on an xmlNodePtr.
2653 ///
2654 /// The artificial location is the line number of the xmlNode as well
2655 /// as the URI of the node.
2656 ///
2657 ///@param rdr the current parsing context
2658 ///
2659 ///@param loc the resulting location.
2660 ///
2661 /// @return true upon sucessful parsing, false otherwise.
2662 static bool
2663 read_artificial_location(const reader& rdr,
2664  xmlNodePtr node,
2665  location& loc)
2666 {
2667  if (!node)
2668  return false;
2669 
2670  string file_path;
2671  size_t line = 0, column = 0;
2672 
2673  line = node->line;
2674 
2675  if (node->doc)
2676  file_path = reinterpret_cast<const char*>(node->doc->URL);
2677 
2678  reader& c = const_cast<reader&>(rdr);
2679  loc =
2680  c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2681  line, column);
2682  loc.set_is_artificial(true);
2683  return true;
2684 }
2685 
2686 /// Set the artificial location of a xmlNode to an artifact.
2687 ///
2688 /// The artificial location is the line number of the xmlNode as well
2689 /// as the URI of the node.
2690 ///
2691 /// The function sets the artificial location only if the artifact
2692 /// doesn"t already have one.
2693 ///
2694 ///@param rdr the current parsing context
2695 ///
2696 ///@param node the XML node to consider.
2697 ///
2698 ///@param artifact the ABI artifact.
2699 ///
2700 /// @return true iff the location was set on the artifact.
2701 static bool
2702 maybe_set_artificial_location(const reader& rdr,
2703  xmlNodePtr node,
2704  type_or_decl_base_sptr artefact)
2705 {
2706  if (artefact && !artefact->has_artificial_location())
2707  {
2708  location l;
2709  if (read_artificial_location(rdr, node, l))
2710  {
2711  artefact->set_artificial_location(l);
2712  return true;
2713  }
2714  }
2715  return false;
2716 }
2717 
2718 /// Parse the visibility attribute.
2719 ///
2720 /// @param node the xml node to read from.
2721 ///
2722 /// @param vis the resulting visibility.
2723 ///
2724 /// @return true upon successful completion, false otherwise.
2725 static bool
2726 read_visibility(xmlNodePtr node, decl_base::visibility& vis)
2727 {
2728  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "visibility"))
2729  {
2730  string v = CHAR_STR(s);
2731 
2732  if (v == "default")
2733  vis = decl_base::VISIBILITY_DEFAULT;
2734  else if (v == "hidden")
2735  vis = decl_base::VISIBILITY_HIDDEN;
2736  else if (v == "internal")
2737  vis = decl_base::VISIBILITY_INTERNAL;
2738  else if (v == "protected")
2739  vis = decl_base::VISIBILITY_PROTECTED;
2740  else
2741  vis = decl_base::VISIBILITY_DEFAULT;
2742  return true;
2743  }
2744  return false;
2745 }
2746 
2747 /// Parse the "binding" attribute on the current element.
2748 ///
2749 /// @param node the xml node to build parse the bind from.
2750 ///
2751 /// @param bind the resulting binding attribute.
2752 ///
2753 /// @return true upon successful completion, false otherwise.
2754 static bool
2755 read_binding(xmlNodePtr node, decl_base::binding& bind)
2756 {
2757  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "binding"))
2758  {
2759  string b = CHAR_STR(s);
2760 
2761  if (b == "global")
2762  bind = decl_base::BINDING_GLOBAL;
2763  else if (b == "local")
2764  bind = decl_base::BINDING_LOCAL;
2765  else if (b == "weak")
2766  bind = decl_base::BINDING_WEAK;
2767  else
2768  bind = decl_base::BINDING_GLOBAL;
2769  return true;
2770  }
2771 
2772  return false;
2773 }
2774 
2775 /// Read the 'access' attribute on the current xml node.
2776 ///
2777 /// @param node the xml node to consider.
2778 ///
2779 /// @param access the access attribute. Set iff the function returns true.
2780 ///
2781 /// @return true upon sucessful completion, false otherwise.
2782 static bool
2783 read_access(xmlNodePtr node, access_specifier& access)
2784 {
2785  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "access"))
2786  {
2787  string a = CHAR_STR(s);
2788 
2789  if (a == "private")
2790  access = private_access;
2791  else if (a == "protected")
2792  access = protected_access;
2793  else if (a == "public")
2794  access = public_access;
2795  else
2796  /// If there is an access specifier of an unsupported value,
2797  /// we should not assume anything and abort.
2798  abort();
2799 
2800  return true;
2801  }
2802  return false;
2803 }
2804 
2805 /// Parse 'size-in-bits' and 'alignment-in-bits' attributes of a given
2806 /// xmlNodePtr reprensting an xml element.
2807 ///
2808 /// @param node the xml element node to consider.
2809 ///
2810 /// @param size_in_bits the resulting value for the 'size-in-bits'
2811 /// attribute. This set only if this function returns true and the if
2812 /// the attribute was present on the xml element node.
2813 ///
2814 /// @param align_in_bits the resulting value for the
2815 /// 'alignment-in-bits' attribute. This set only if this function
2816 /// returns true and the if the attribute was present on the xml
2817 /// element node.
2818 ///
2819 /// @return true if either one of the two attributes above were set,
2820 /// false otherwise.
2821 static bool
2822 read_size_and_alignment(xmlNodePtr node,
2823  size_t& size_in_bits,
2824  size_t& align_in_bits)
2825 {
2826 
2827  bool got_something = false;
2828  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size-in-bits"))
2829  {
2830  size_in_bits = atoll(CHAR_STR(s));
2831  got_something = true;
2832  }
2833 
2834  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "alignment-in-bits"))
2835  {
2836  align_in_bits = atoll(CHAR_STR(s));
2837  got_something = true;
2838  }
2839  return got_something;
2840 }
2841 
2842 /// Parse the 'static' attribute of a given xml element node.
2843 ///
2844 /// @param node the xml element node to consider.
2845 ///
2846 /// @param is_static the resulting the parsing. Is set if the
2847 /// function returns true.
2848 ///
2849 /// @return true if the xml element node has the 'static' attribute
2850 /// set, false otherwise.
2851 static bool
2852 read_static(xmlNodePtr node, bool& is_static)
2853 {
2854  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "static"))
2855  {
2856  string b = CHAR_STR(s);
2857  is_static = b == "yes";
2858  return true;
2859  }
2860  return false;
2861 }
2862 
2863 /// Parse the 'layout-offset-in-bits' attribute of a given xml element node.
2864 ///
2865 /// @param offset_in_bits set to true if the element node contains the
2866 /// attribute.
2867 ///
2868 /// @return true iff the xml element node contains the attribute.
2869 static bool
2870 read_offset_in_bits(xmlNodePtr node,
2871  size_t& offset_in_bits)
2872 {
2873  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "layout-offset-in-bits"))
2874  {
2875  offset_in_bits = strtoull(CHAR_STR(s), 0, 0);
2876  return true;
2877  }
2878  return false;
2879 }
2880 
2881 /// Parse the 'constructor', 'destructor' and 'const' attribute of a
2882 /// given xml node.
2883 ///
2884 /// @param is_constructor the resulting value of the parsing of the
2885 /// 'constructor' attribute. Is set if the xml node contains the
2886 /// attribute and if the function returns true.
2887 ///
2888 /// @param is_destructor the resulting value of the parsing of the
2889 /// 'destructor' attribute. Is set if the xml node contains the
2890 /// attribute and if the function returns true.
2891 ///
2892 /// @param is_const the resulting value of the parsing of the 'const'
2893 /// attribute. Is set if the xml node contains the attribute and if
2894 /// the function returns true.
2895 ///
2896 /// @return true if at least of the attributes above is set, false
2897 /// otherwise.
2898 ///
2899 /// Note that callers of this function should initialize
2900 /// is_constructor, is_destructor and is_const prior to passing them
2901 /// to this function.
2902 static bool
2903 read_cdtor_const(xmlNodePtr node,
2904  bool& is_constructor,
2905  bool& is_destructor,
2906  bool& is_const)
2907 {
2908  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "constructor"))
2909  {
2910  string b = CHAR_STR(s);
2911  if (b == "yes")
2912  is_constructor = true;
2913  else
2914  is_constructor = false;
2915 
2916  return true;
2917  }
2918 
2919  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "destructor"))
2920  {
2921  string b = CHAR_STR(s);
2922  if (b == "yes")
2923  is_destructor = true;
2924  else
2925  is_destructor = false;
2926 
2927  return true;
2928  }
2929 
2930  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "const"))
2931  {
2932  string b = CHAR_STR(s);
2933  if (b == "yes")
2934  is_const = true;
2935  else
2936  is_const = false;
2937 
2938  return true;
2939  }
2940 
2941  return false;
2942 }
2943 
2944 /// Read the "is-declaration-only" attribute of the current xml node.
2945 ///
2946 /// @param node the xml node to consider.
2947 ///
2948 /// @param is_decl_only is set to true iff the "is-declaration-only" attribute
2949 /// is present and set to "yes".
2950 ///
2951 /// @return true iff the is_decl_only attribute was set.
2952 static bool
2953 read_is_declaration_only(xmlNodePtr node, bool& is_decl_only)
2954 {
2955  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-declaration-only"))
2956  {
2957  string str = CHAR_STR(s);
2958  if (str == "yes")
2959  is_decl_only = true;
2960  else
2961  is_decl_only = false;
2962  return true;
2963  }
2964  return false;
2965 }
2966 
2967 /// Read the "is-artificial" attribute of the current XML node.
2968 ///
2969 /// @param node the XML node to consider.
2970 ///
2971 /// @param is_artificial this output parameter is set to true iff the
2972 /// "is-artificial" parameter is present and set to 'yes'.
2973 ///
2974 /// @return true iff the "is-artificial" parameter was present on the
2975 /// XML node.
2976 static bool
2977 read_is_artificial(xmlNodePtr node, bool& is_artificial)
2978 {
2979  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-artificial"))
2980  {
2981  string is_artificial_str = CHAR_STR(s) ? CHAR_STR(s) : "";
2982  is_artificial = is_artificial_str == "yes";
2983  return true;
2984  }
2985  return false;
2986 }
2987 
2988 /// Read the 'tracking-non-reachable-types' attribute on the current
2989 /// XML element.
2990 ///
2991 /// @param node the current XML element.
2992 ///
2993 /// @param tracking_non_reachable_types output parameter. This is set
2994 /// to true iff the 'tracking-non-reachable-types' attribute is
2995 /// present on the current XML node and set to 'yes'. In that case,
2996 /// the function returns true.
2997 ///
2998 /// @return true iff the 'tracking-non-reachable-types' attribute is
2999 /// present on the current XML node and set to 'yes'.
3000 static bool
3001 read_tracking_non_reachable_types(xmlNodePtr node,
3002  bool& tracking_non_reachable_types)
3003 {
3004  if (xml_char_sptr s =
3005  XML_NODE_GET_ATTRIBUTE(node, "tracking-non-reachable-types"))
3006  {
3007  string tracking_non_reachable_types_str = CHAR_STR(s) ? CHAR_STR(s) : "";
3008  tracking_non_reachable_types =
3009  (tracking_non_reachable_types_str == "yes")
3010  ? true
3011  : false;
3012  return true;
3013  }
3014  return false;
3015 }
3016 
3017 /// Read the 'is-non-reachable' attribute on the current XML element.
3018 ///
3019 /// @param node the current XML element.
3020 ///
3021 /// @param is_non_reachable_type output parameter. This is set to true
3022 /// iff the 'is-non-reachable' attribute is present on the current XML
3023 /// element with a value se to 'yes'.
3024 ///
3025 /// @return true iff the 'is-non-reachable' attribute is present on
3026 /// the current XML element with a value se to 'yes'.
3027 static bool
3028 read_is_non_reachable_type(xmlNodePtr node, bool& is_non_reachable_type)
3029 {
3030  if (xml_char_sptr s =
3031  XML_NODE_GET_ATTRIBUTE(node, "is-non-reachable"))
3032  {
3033  string is_non_reachable_type_str = CHAR_STR(s) ? CHAR_STR(s) : "";
3034  is_non_reachable_type =
3035  (is_non_reachable_type_str == "yes")
3036  ? true
3037  : false;
3038  return true;
3039  }
3040  return false;
3041 }
3042 
3043 /// Read the "naming-typedef-id" property from an XML node.
3044 ///
3045 /// @param node the XML node to consider.
3046 ///
3047 /// @param naming_typedef_id output parameter. It's set to the
3048 /// content of the "naming-typedef-id" property, if it's present.
3049 ///
3050 /// @return true iff the "naming-typedef-id" property exists and was
3051 /// read from @p node.
3052 static bool
3053 read_naming_typedef_id_string(xmlNodePtr node, string& naming_typedef_id)
3054 {
3055  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "naming-typedef-id"))
3056  {
3057  naming_typedef_id = xml::unescape_xml_string(CHAR_STR(s));
3058  return true;
3059  }
3060  return false;
3061 }
3062 
3063 /// Read the "is-virtual" attribute of the current xml node.
3064 ///
3065 /// @param node the xml node to read the attribute from
3066 ///
3067 /// @param is_virtual is set to true iff the "is-virtual" attribute is
3068 /// present and set to "yes".
3069 ///
3070 /// @return true iff the is-virtual attribute is present.
3071 static bool
3072 read_is_virtual(xmlNodePtr node, bool& is_virtual)
3073 {
3074  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-virtual"))
3075  {
3076  string str = CHAR_STR(s);
3077  if (str == "yes")
3078  is_virtual = true;
3079  else
3080  is_virtual = false;
3081  return true;
3082  }
3083  return false;
3084 }
3085 
3086 /// Read the 'is-struct' attribute.
3087 ///
3088 /// @param node the xml node to read the attribute from.
3089 ///
3090 /// @param is_struct is set to true iff the "is-struct" attribute is
3091 /// present and set to "yes".
3092 ///
3093 /// @return true iff the "is-struct" attribute is present.
3094 static bool
3095 read_is_struct(xmlNodePtr node, bool& is_struct)
3096 {
3097  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-struct"))
3098  {
3099  string str = CHAR_STR(s);
3100  if (str == "yes")
3101  is_struct = true;
3102  else
3103  is_struct = false;
3104  return true;
3105  }
3106  return false;
3107 }
3108 
3109 /// Read the 'is-anonymous' attribute.
3110 ///
3111 /// @param node the xml node to read the attribute from.
3112 ///
3113 /// @param is_anonymous is set to true iff the "is-anonymous" is present
3114 /// and set to "yes".
3115 ///
3116 /// @return true iff the "is-anonymous" attribute is present.
3117 static bool
3118 read_is_anonymous(xmlNodePtr node, bool& is_anonymous)
3119 {
3120  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-anonymous"))
3121  {
3122  string str = CHAR_STR(s);
3123  is_anonymous = (str == "yes");
3124  return true;
3125  }
3126  return false;
3127 }
3128 
3129 /// Read the 'type' attribute of the 'elf-symbol' element.
3130 ///
3131 /// @param node the XML node to read the attribute from.
3132 ///
3133 /// @param t the resulting elf_symbol::type.
3134 ///
3135 /// @return true iff the function completed successfully.
3136 static bool
3137 read_elf_symbol_type(xmlNodePtr node, elf_symbol::type& t)
3138 {
3139  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type"))
3140  {
3141  string str;
3143  if (!string_to_elf_symbol_type(str, t))
3144  return false;
3145  return true;
3146  }
3147  return false;
3148 }
3149 
3150 /// Read the 'binding' attribute of the of the 'elf-symbol' element.
3151 ///
3152 /// @param node the XML node to read the attribute from.
3153 ///
3154 /// @param b the XML the resulting elf_symbol::binding.
3155 ///
3156 /// @return true iff the function completed successfully.
3157 static bool
3158 read_elf_symbol_binding(xmlNodePtr node, elf_symbol::binding& b)
3159 {
3160  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "binding"))
3161  {
3162  string str;
3164  if (!string_to_elf_symbol_binding(str, b))
3165  return false;
3166  return true;
3167  }
3168  return false;
3169 }
3170 
3171 /// Read the 'visibility' attribute of the of the 'elf-symbol'
3172 /// element.
3173 ///
3174 /// @param node the XML node to read the attribute from.
3175 ///
3176 /// @param b the XML the resulting elf_symbol::visibility.
3177 ///
3178 /// @return true iff the function completed successfully.
3179 static bool
3180 read_elf_symbol_visibility(xmlNodePtr node, elf_symbol::visibility& v)
3181 {
3182  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "visibility"))
3183  {
3184  string str;
3186  if (!string_to_elf_symbol_visibility(str, v))
3187  return false;
3188  return true;
3189  }
3190  return false;
3191 }
3192 /// Read the value of the 'id' attribute from a given XML node.
3193 ///
3194 /// @param node the XML node to consider.
3195 ///
3196 /// @param type_id the string to set the 'id' to.
3197 ///
3198 /// @return true iff @p type_id was successfully set.
3199 static bool
3200 read_type_id_string(xmlNodePtr node, string& type_id)
3201 {
3202  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
3203  {
3204  type_id = CHAR_STR(s);
3205  return true;
3206  }
3207  return false;
3208 }
3209 
3210 /// Read of the value of the "name" attribute from a given XML node.
3211 ///
3212 /// @param node the XML node to consider.
3213 ///
3214 /// @param name the value of the "name" attribute read, iff the
3215 /// function returns true.
3216 ///
3217 /// @return true iff a the "name" attribute was found an its value
3218 /// could be read and set to the @p name parameter.
3219 static bool
3220 read_name(xmlNodePtr node, string& name)
3221 {
3222  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
3223  {
3224  name = CHAR_STR(s);
3225  return true;
3226  }
3227  return false;
3228 }
3229 
3230 /// Read the hash value and a the CTI from a (type) node.
3231 ///
3232 /// The value of the 'hash' property has the form:
3233 /// '<hash-value-in-hexa>#cti-in-decimal'.
3234 ///
3235 /// @param node the XML node to read the hash value from.
3236 ///
3237 /// @param hash output parameter. This is set to the hash value read
3238 /// from the XML node @p node iff the function returns true.
3239 ///
3240 /// @param cti output parameter. This is set to the value of the CTI
3241 /// read from the CTI part of the value of the 'hash' property.
3242 ///
3243 /// @return true iff the function read a hash value and set it into
3244 /// the @p hash output parameter.
3245 static bool
3246 read_type_hash_and_cti(xmlNodePtr node, uint64_t& hash, uint64_t& cti)
3247 {
3248  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "hash"))
3249  {
3250  string str = CHAR_STR(s);
3251  vector<string> parts;
3252  tools_utils::split_string(str, "#", parts);
3253  if (!parts.empty() && !parts.front().empty())
3254  {
3255  ABG_ASSERT(hashing::deserialize_hash(parts[0], hash));
3256  if (parts.size() > 1)
3257  cti = atoll(parts[1].c_str());
3258  return true;
3259  }
3260  }
3261  return false;
3262 }
3263 
3264 #ifdef WITH_DEBUG_SELF_COMPARISON
3265 /// Associate a type-id string with the type that was constructed from
3266 /// it.
3267 ///
3268 /// Note that if we are not in "self comparison debugging" mode or if
3269 /// the type we are looking at is not canonicalized, then this
3270 /// function does nothing.
3271 ///
3272 /// @param t the type built from the a type XML node that has a
3273 /// particular type-id.
3274 ///
3275 /// @param type_id the type-id of type @p t.
3276 ///
3277 /// @return true if the association was performed.
3278 static bool
3279 maybe_map_type_with_type_id(const type_base_sptr& t,
3280  const string& type_id)
3281 {
3282  if (!t)
3283  return false;
3284 
3285  const environment& env = t->get_environment();
3286  if (!env.self_comparison_debug_is_on()
3287  || is_non_canonicalized_type(t.get()))
3288  return false;
3289 
3290  const_cast<environment&>(env).
3291  get_pointer_type_id_map()[reinterpret_cast<uintptr_t>(t.get())] = type_id;
3292 
3293  return true;
3294 }
3295 
3296 /// Associate a type-id string with the type that was constructed from
3297 /// it.
3298 ///
3299 /// Note that if we are not in "self comparison debugging" mode or if
3300 /// the type we are looking at is not canonicalized, then this
3301 /// function does nothing.
3302 ///
3303 /// @param t the type built from the a type XML node that has a
3304 /// particular type-id.
3305 ///
3306 /// @param type_id the type-id of type @p t.
3307 ///
3308 /// @return true if the association was performed.
3309 static bool
3310 maybe_map_type_with_type_id(const type_base_sptr& t,
3311  xmlNodePtr node)
3312 {
3313  if (!t)
3314  return false;
3315 
3316  const environment&env = t->get_environment();
3317  if (!env.self_comparison_debug_is_on()
3318  || is_non_canonicalized_type(t.get()))
3319  return false;
3320 
3321  string type_id;
3322  if (!read_type_id_string(node, type_id) || type_id.empty())
3323  return false;
3324 
3325  return maybe_map_type_with_type_id(t, type_id);
3326 }
3327 
3328 #endif
3329 
3330 /// Set the naming typedef to a given decl depending on the content of
3331 /// the "naming-typedef-id" property of its descriptive XML element.
3332 ///
3333 /// @param rdr the current ABIXML reader.
3334 ///
3335 /// @param node the XML node to read from.
3336 ///
3337 /// @param decl the decl to set the naming typedef to.
3338 static void
3339 maybe_set_naming_typedef(reader& rdr,
3340  xmlNodePtr node,
3341  const decl_base_sptr& decl)
3342 {
3343  string naming_typedef_id;
3344  read_naming_typedef_id_string(node, naming_typedef_id);
3345  if (!naming_typedef_id.empty())
3346  {
3347  typedef_decl_sptr naming_typedef =
3348  is_typedef(rdr.build_or_get_type_decl(naming_typedef_id, true));
3349  ABG_ASSERT(naming_typedef);
3350  decl->set_naming_typedef(naming_typedef);
3351  }
3352 }
3353 
3354 /// Build a @ref namespace_decl from an XML element node which name is
3355 /// "namespace-decl". Note that this function recursively reads the
3356 /// content of the namespace and builds the proper IR nodes
3357 /// accordingly.
3358 ///
3359 /// @param rdr the ABIXML reader to use.
3360 ///
3361 /// @param node the XML node to consider. It must constain the
3362 /// content of the namespace, that is, children XML nodes representing
3363 /// what is inside the namespace, unless the namespace is empty.
3364 ///
3365 /// @param add_to_current_scope if set to yes, the resulting
3366 /// namespace_decl is added to the IR being currently built.
3367 ///
3368 /// @return a pointer to the the resulting @ref namespace_decl.
3369 static namespace_decl_sptr
3370 build_namespace_decl(reader& rdr,
3371  const xmlNodePtr node,
3372  bool add_to_current_scope)
3373 {
3374  namespace_decl_sptr nil;
3375  if (!node || !xmlStrEqual(node->name, BAD_CAST("namespace-decl")))
3376  return nil;
3377 
3378  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3379  {
3380  namespace_decl_sptr result = dynamic_pointer_cast<namespace_decl>(d);
3381  ABG_ASSERT(result);
3382  return result;
3383  }
3384 
3385  string name;
3386  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
3387  name = xml::unescape_xml_string(CHAR_STR(s));
3388 
3389  location loc;
3390  read_location(rdr, node, loc);
3391 
3392  const environment& env = rdr.get_environment();
3393  namespace_decl_sptr decl(new namespace_decl(env, name, loc));
3394  maybe_set_artificial_location(rdr, node, decl);
3395  rdr.push_decl_to_scope(decl,
3396  add_to_current_scope
3397  ? rdr.get_scope_ptr_for_node(node)
3398  : nullptr);
3399  rdr.map_xml_node_to_decl(node, decl);
3400 
3401  for (xmlNodePtr n = xmlFirstElementChild(node);
3402  n;
3403  n = xmlNextElementSibling(n))
3404  handle_element_node(rdr, n, /*add_to_current_scope=*/true);
3405 
3406  rdr.pop_scope_or_abort(decl);
3407 
3408  return decl;
3409 }
3410 
3411 /// Build an instance of @ref elf_symbol from an XML element node
3412 /// which name is 'elf-symbol'.
3413 ///
3414 /// @param rdr the context used for reading the XML input.
3415 ///
3416 /// @param node the XML node to read.
3417 ///
3418 /// @param drop_if_suppressed if the elf symbol was suppressed by a
3419 /// suppression specification then do not build it.
3420 ///
3421 /// @return the @ref elf_symbol built, or nil if it couldn't be built.
3422 static elf_symbol_sptr
3423 build_elf_symbol(reader& rdr, const xmlNodePtr node,
3424  bool drop_if_suppressed)
3425 {
3426  elf_symbol_sptr nil;
3427 
3428  if (!node
3429  || node->type != XML_ELEMENT_NODE
3430  || !xmlStrEqual(node->name, BAD_CAST("elf-symbol")))
3431  return nil;
3432 
3433  string name;
3434  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
3436 
3437  size_t size = 0;
3438  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size"))
3439  size = strtol(CHAR_STR(s), NULL, 0);
3440 
3441  bool is_defined = true;
3442  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-defined"))
3443  {
3444  string value;
3445  xml::xml_char_sptr_to_string(s, value);
3446  if (value == "true" || value == "yes")
3447  is_defined = true;
3448  else
3449  is_defined = false;
3450  }
3451 
3452  bool is_common = false;
3453  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-common"))
3454  {
3455  string value;
3456  xml::xml_char_sptr_to_string(s, value);
3457  if (value == "true" || value == "yes")
3458  is_common = true;
3459  else
3460  is_common = false;
3461  }
3462 
3463  string version_string;
3464  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "version"))
3465  xml::xml_char_sptr_to_string(s, version_string);
3466 
3467  bool is_default_version = false;
3468  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "is-default-version"))
3469  {
3470  string value;
3471  xml::xml_char_sptr_to_string(s, value);
3472  if (value == "true" || value == "yes")
3473  is_default_version = true;
3474  }
3475 
3476  elf_symbol::type type = elf_symbol::NOTYPE_TYPE;
3477  read_elf_symbol_type(node, type);
3478 
3479  elf_symbol::binding binding = elf_symbol::GLOBAL_BINDING;
3480  read_elf_symbol_binding(node, binding);
3481 
3482  elf_symbol::visibility visibility = elf_symbol::DEFAULT_VISIBILITY;
3483  read_elf_symbol_visibility(node, visibility);
3484 
3485  elf_symbol::version version(version_string, is_default_version);
3486 
3487  const bool is_suppressed = suppr::is_elf_symbol_suppressed(rdr, name, type);
3488  if (drop_if_suppressed && is_suppressed)
3489  return elf_symbol_sptr();
3490 
3491  const environment& env = rdr.get_environment();
3492  elf_symbol_sptr e = elf_symbol::create(env, /*index=*/0,
3493  size, name, type, binding,
3494  is_defined, is_common,
3495  version, visibility);
3496 
3497  e->set_is_suppressed(is_suppressed);
3498 
3499  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "crc"))
3500  e->set_crc(strtoull(CHAR_STR(s), NULL, 0));
3501 
3502  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "namespace"))
3503  {
3504  std::string ns;
3506  e->set_namespace(ns);
3507  }
3508 
3509  return e;
3510 }
3511 
3512 /// Build and instance of elf_symbol from an XML attribute named
3513 /// 'elf-symbol-id' which value is the ID of a symbol that should
3514 /// present in the symbol db of the corpus associated to the current
3515 /// context.
3516 ///
3517 /// @param rdr the current context to consider.
3518 ///
3519 /// @param node the xml element node to consider.
3520 ///
3521 /// @param function_symbol is true if we should look for a function
3522 /// symbol, is false if we should look for a variable symbol.
3523 ///
3524 /// @return a shared pointer the resutling elf_symbol.
3525 static elf_symbol_sptr
3526 build_elf_symbol_from_reference(reader& rdr, const xmlNodePtr node)
3527 {
3528  elf_symbol_sptr nil;
3529 
3530  if (!node)
3531  return nil;
3532 
3533  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "elf-symbol-id"))
3534  {
3535  string sym_id;
3536  xml::xml_char_sptr_to_string(s, sym_id);
3537  if (sym_id.empty())
3538  return nil;
3539 
3540  string name, ver;
3541  elf_symbol::get_name_and_version_from_id(sym_id, name, ver);
3542  if (name.empty())
3543  return nil;
3544 
3545  if (rdr.corpus()->get_symtab())
3546  {
3547  const elf_symbols& symbols =
3548  rdr.corpus()->get_symtab()->lookup_symbol(name);
3549 
3550  for (const auto& symbol : symbols)
3551  if (symbol->get_id_string() == sym_id)
3552  return symbol;
3553  }
3554  }
3555 
3556  return nil;
3557 }
3558 
3559 /// Build an instance of string_elf_symbols_map_type from an XML
3560 /// element representing either a function symbols data base, or a
3561 /// variable symbols database.
3562 ///
3563 /// @param rdr the context to take in account.
3564 ///
3565 /// @param node the XML node to consider.
3566 ///
3567 /// @param function_syms true if we should look for a function symbols
3568 /// data base, false if we should look for a variable symbols data
3569 /// base.
3570 ///
3571 /// @param map a pointer to the map to fill with the symbol database.
3572 ///
3573 /// @param non_resolved_aliases this is a map that associates a
3574 /// function symbol name N to a vector of alias symbol names that are
3575 /// aliases to N. Normally, N is a function symbol that has aliases
3576 /// that are other symbols that are usually function (resp variable)
3577 /// symbols that should be found (or resolved) in @p map. If all
3578 /// symbol aliases resolve to symbols in @p map then this map is
3579 /// empty. Otherwise, if these alias symbols are not found in @p map,
3580 /// then they are stored in this map.
3581 ///
3582 /// @return true if some elf symbols were found.
3583 static bool
3584 build_elf_symbol_db(reader& rdr,
3585  const xmlNodePtr node,
3586  bool function_syms,
3588  string_strings_map_type& non_resolved_aliases)
3589 {
3591 
3592  if (!node)
3593  return false;
3594 
3595  if (function_syms
3596  && !xmlStrEqual(node->name, BAD_CAST("elf-function-symbols"))
3597  && !xmlStrEqual(node->name, BAD_CAST("undefined-elf-function-symbols")))
3598  return false;
3599 
3600  if (!function_syms
3601  && !xmlStrEqual(node->name, BAD_CAST("elf-variable-symbols"))
3602  && !xmlStrEqual(node->name, BAD_CAST("undefined-elf-variable-symbols")))
3603  return false;
3604 
3605  rdr.set_corpus_node(node);
3606 
3607  typedef std::unordered_map<xmlNodePtr, elf_symbol_sptr>
3608  xml_node_ptr_elf_symbol_sptr_map_type;
3609  xml_node_ptr_elf_symbol_sptr_map_type xml_node_ptr_elf_symbol_map;
3610 
3611  elf_symbol_sptr sym;
3612  for (xmlNodePtr n = xmlFirstElementChild(node);
3613  n;
3614  n = xmlNextElementSibling(n))
3615  if ((sym = build_elf_symbol(rdr, n, /*drop_if_suppress=*/false)))
3616  {
3617  id_sym_map[sym->get_id_string()] = sym;
3618  xml_node_ptr_elf_symbol_map[n] = sym;
3619  }
3620 
3621  if (id_sym_map.empty())
3622  return false;
3623 
3624  string_elf_symbols_map_type::iterator it;
3625  for (string_elf_symbol_sptr_map_type::const_iterator i = id_sym_map.begin();
3626  i != id_sym_map.end();
3627  ++i)
3628  (*map)[i->second->get_name()].push_back(i->second);
3629 
3630  // Now build the alias relations
3631  for (xml_node_ptr_elf_symbol_sptr_map_type::const_iterator x =
3632  xml_node_ptr_elf_symbol_map.begin();
3633  x != xml_node_ptr_elf_symbol_map.end();
3634  ++x)
3635  {
3636  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(x->first, "alias"))
3637  {
3638  string alias_id = CHAR_STR(s);
3639 
3640  // Symbol aliases can be multiple separated by comma(,), split them
3641  std::vector<std::string> elems;
3642  std::stringstream aliases(alias_id);
3643  std::string item;
3644  while (std::getline(aliases, item, ','))
3645  elems.push_back(item);
3646  for (std::vector<string>::iterator alias = elems.begin();
3647  alias != elems.end(); ++alias)
3648  {
3649  string_elf_symbol_sptr_map_type::const_iterator i =
3650  id_sym_map.find(*alias);
3651  if (i == id_sym_map.end())
3652  // This symbol aliases a symbol that is not (yet)
3653  // found in the set of symbols built so far. So let's
3654  // record this information in the "symbol ->
3655  // non-resolved-symbol-aliases" map so that the
3656  // aliases can be resolved later.
3657  non_resolved_aliases[x->second->get_name()].push_back(*alias);
3658  else
3659  {
3660  ABG_ASSERT(i->second->is_main_symbol());
3661  x->second->get_main_symbol()->add_alias(i->second);
3662  }
3663  }
3664  }
3665  }
3666 
3667  return true;
3668 }
3669 
3670 /// Resolve symbol aliases to their target symbols.
3671 ///
3672 /// The aliases to be resolved are found in the @p
3673 /// non_resolved_fn_syms_aliases and @p non_resolved_var_syms_aliases
3674 /// parameters.
3675 ///
3676 /// @param fn_syms the target function symbols to consider.
3677 ///
3678 /// @param var_syms the target variable symbols to consider.
3679 ///
3680 /// @param non_resolved_fn_syms_aliases is a map that associates the
3681 /// name of a function symbol F to its alias symbols. The alias
3682 /// symbols are either function symbols (as is what is generally the
3683 /// case) to be found in @p fn_syms or can be variable symbols (as is
3684 /// sometimes the case for the OCaml language on s390x and ppcle, for
3685 /// instance) to be found in @p var_syms.
3686 ///
3687 /// @param non_resolved_var_syms_aliases is a map that associates the
3688 /// name of a variable symbol V to its alias symbols. The alias
3689 /// symbols are either variable symbols (as is what is generally the
3690 /// case) to be found in @p var_syms or can be variable symbols (as is
3691 /// sometimes the case for the OCaml language on s390x and ppcle, for
3692 /// instance) to be found in @p fn_syms.
3693 static void
3694 resolve_symbol_aliases(string_elf_symbols_map_sptr& fn_syms,
3695  string_elf_symbols_map_sptr& var_syms,
3696  string_strings_map_type& non_resolved_fn_sym_aliases,
3697  string_strings_map_type& non_resolved_var_sym_aliases)
3698 {
3699  for (auto& entry : non_resolved_fn_sym_aliases)
3700  {
3701  auto i = fn_syms->find(entry.first);
3702  ABG_ASSERT(i != fn_syms->end());
3703  // Symbol to build the aliases for.
3704  elf_symbol_sptr sym = i->second.front();
3705  ABG_ASSERT(sym);
3706  sym = sym->get_main_symbol();
3707  elf_symbol_sptr alias_sym;
3708  for (string& alias : entry.second)
3709  {
3710  auto fn_a = fn_syms->find(alias);
3711  if (fn_a == fn_syms->end())
3712  {
3713  // no function symbol alias found. Let's see if a
3714  // variable symbol aliases this function symbol.
3715  auto var_a = var_syms->find(alias);
3716  ABG_ASSERT(var_a != var_syms->end());
3717  alias_sym = var_a->second.front();
3718  ABG_ASSERT(alias_sym);
3719  }
3720  else
3721  {
3722  alias_sym = fn_a->second.front();
3723  ABG_ASSERT(alias_sym);
3724  }
3725  sym->add_alias(alias_sym);
3726  }
3727  }
3728 
3729  for (auto& entry : non_resolved_var_sym_aliases)
3730  {
3731  auto i = var_syms->find(entry.first);
3732  ABG_ASSERT(i != var_syms->end());
3733  // Symbol to build the aliases for.
3734  elf_symbol_sptr sym = i->second.front();
3735  ABG_ASSERT(sym);
3736  sym = sym->get_main_symbol();
3737  elf_symbol_sptr alias_sym;
3738  for (string& alias : entry.second)
3739  {
3740  auto var_a = var_syms->find(alias);
3741  if (var_a == var_syms->end())
3742  {
3743  // no variable symbol alias found. Let's see if a
3744  // function symbol aliases this variable symbol.
3745  auto fn_a = fn_syms->find(alias);
3746  ABG_ASSERT(fn_a != fn_syms->end());
3747  alias_sym = fn_a->second.front();
3748  ABG_ASSERT(alias_sym);
3749  }
3750  else
3751  {
3752  alias_sym = var_a->second.front();
3753  ABG_ASSERT(alias_sym);
3754  }
3755  sym->add_alias(alias_sym);
3756  }
3757  }
3758 }
3759 
3760 /// Build a function parameter from a 'parameter' xml element node.
3761 ///
3762 /// @param rdr the contexte of the xml parsing.
3763 ///
3764 /// @param node the xml 'parameter' element node to de-serialize from.
3765 static shared_ptr<function_decl::parameter>
3766 build_function_parameter(reader& rdr, const xmlNodePtr node)
3767 {
3768  shared_ptr<function_decl::parameter> nil;
3769 
3770  if (!node || !xmlStrEqual(node->name, BAD_CAST("parameter")))
3771  return nil;
3772 
3773  bool is_variadic = false;
3774  string is_variadic_str;
3775  if (xml_char_sptr s =
3776  xml::build_sptr(xmlGetProp(node, BAD_CAST("is-variadic"))))
3777  {
3778  is_variadic_str = CHAR_STR(s) ? CHAR_STR(s) : "";
3779  is_variadic = is_variadic_str == "yes";
3780  }
3781 
3782  bool is_artificial = false;
3783  read_is_artificial(node, is_artificial);
3784 
3785  string type_id;
3786  if (xml_char_sptr a = xml::build_sptr(xmlGetProp(node, BAD_CAST("type-id"))))
3787  type_id = CHAR_STR(a);
3788 
3789  type_base_sptr type;
3790  if (is_variadic)
3791  type = is_type(build_ir_node_for_variadic_parameter_type(rdr));
3792  else
3793  {
3794  ABG_ASSERT(!type_id.empty());
3795  type = rdr.build_or_get_type_decl(type_id, true);
3796  }
3797  ABG_ASSERT(type);
3798 
3799  string name;
3800  if (xml_char_sptr a = xml::build_sptr(xmlGetProp(node, BAD_CAST("name"))))
3801  name = CHAR_STR(a);
3802 
3803  location loc;
3804  read_location(rdr, node, loc);
3805 
3807  (new function_decl::parameter(type, name, loc,
3808  is_variadic, is_artificial));
3809 
3810  return p;
3811 }
3812 
3813 /// Build a function_decl from a 'function-decl' xml node.
3814 ///
3815 /// @param rdr the context of the parsing.
3816 ///
3817 /// @param node the xml node to build the function_decl from.
3818 ///
3819 /// @param as_method_decl if this is set to a class_decl pointer, it
3820 /// means that the 'function-decl' xml node should be parsed as a
3821 /// method_decl. The class_decl pointer is the class decl to which
3822 /// the resulting method_decl is a member function of. The resulting
3823 /// shared_ptr<function_decl> that is returned is then really a
3824 /// shared_ptr<method_decl>.
3825 ///
3826 /// @param add_to_current_scope if set to yes, the result of
3827 /// this function is added to its current scope.
3828 ///
3829 /// @param add_to_exported_decls if set to yes, the resulting of this
3830 /// function is added to the set of decls exported by the current
3831 /// corpus being built.
3832 ///
3833 /// @return a pointer to a newly created function_decl upon successful
3834 /// completion, a null pointer otherwise.
3835 static function_decl_sptr
3836 build_function_decl(reader& rdr,
3837  const xmlNodePtr node,
3838  class_or_union_sptr as_method_decl,
3839  bool add_to_current_scope,
3840  bool add_to_exported_decls)
3841 {
3842  function_decl_sptr nil;
3843 
3844  if (!xmlStrEqual(node->name, BAD_CAST("function-decl")))
3845  return nil;
3846 
3847  string name;
3848  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
3849  name = xml::unescape_xml_string(CHAR_STR(s));
3850 
3851  string mangled_name;
3852  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "mangled-name"))
3853  mangled_name = xml::unescape_xml_string(CHAR_STR(s));
3854 
3855  if (as_method_decl
3856  && !mangled_name.empty()
3857  && as_method_decl->find_member_function_sptr(mangled_name))
3858  {
3859  function_decl_sptr result =
3860  as_method_decl->find_member_function_sptr(mangled_name);
3861  if (result)
3862  return result;
3863  }
3864 
3865  string inline_prop;
3866  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "declared-inline"))
3867  inline_prop = CHAR_STR(s);
3868  bool declared_inline = inline_prop == "yes";
3869 
3870  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
3871  read_visibility(node, vis);
3872 
3873  decl_base::binding bind = decl_base::BINDING_NONE;
3874  read_binding(node, bind);
3875 
3876  size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
3877  read_size_and_alignment(node, size, align);
3878 
3879  location loc;
3880  read_location(rdr, node, loc);
3881 
3882  const environment& env = rdr.get_environment();
3883 
3884  std::vector<function_decl::parameter_sptr> parms;
3885  type_base_sptr return_type = env.get_void_type();
3886 
3887  for (xmlNodePtr n = xmlFirstElementChild(node);
3888  n ;
3889  n = xmlNextElementSibling(n))
3890  {
3891  if (xmlStrEqual(n->name, BAD_CAST("parameter")))
3892  {
3894  build_function_parameter(rdr, n))
3895  parms.push_back(p);
3896  }
3897  else if (xmlStrEqual(n->name, BAD_CAST("return")))
3898  {
3899  string type_id;
3900  if (xml_char_sptr s =
3901  xml::build_sptr(xmlGetProp(n, BAD_CAST("type-id"))))
3902  type_id = CHAR_STR(s);
3903  if (!type_id.empty())
3904  return_type = rdr.build_or_get_type_decl(type_id, true);
3905  }
3906  }
3907 
3908  function_type_sptr fn_type(as_method_decl
3909  ? new method_type(return_type, as_method_decl,
3910  parms, /*is_const=*/false,
3911  size, align)
3912  : new function_type(return_type,
3913  parms, size, align));
3914 
3915  ABG_ASSERT(fn_type);
3916 
3917  rdr.read_hash_and_stash(node, fn_type);
3918 
3919  fn_type->set_is_artificial(true);
3920 
3921  function_decl_sptr fn_decl(as_method_decl
3922  ? new method_decl (name, fn_type,
3923  declared_inline, loc,
3924  mangled_name, vis, bind)
3925  : new function_decl(name, fn_type,
3926  declared_inline, loc,
3927  mangled_name, vis,
3928  bind));
3929 
3930  maybe_set_artificial_location(rdr, node, fn_decl);
3931  rdr.push_decl_to_scope(fn_decl,
3932  add_to_current_scope
3933  ? rdr.get_scope_ptr_for_node(node)
3934  : nullptr);
3935  RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn_decl);
3936 
3937  elf_symbol_sptr sym = build_elf_symbol_from_reference(rdr, node);
3938  if (sym)
3939  fn_decl->set_symbol(sym);
3940 
3941  if (fn_decl->get_symbol() && fn_decl->get_symbol()->is_public())
3942  fn_decl->set_is_in_public_symbol_table(true);
3943 
3944  rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
3945 
3946  rdr.schedule_type_for_canonicalization(fn_type);
3947 
3948  if (add_to_exported_decls)
3949  rdr.add_fn_to_exported_or_undefined_decls(fn_decl.get());
3950 
3951  return fn_decl;
3952 }
3953 
3954 /// Build a function_decl from a 'function-decl' xml node if it's not
3955 /// been suppressed by a suppression specification that is in the
3956 /// context.
3957 ///
3958 /// @param rdr the context of the parsing.
3959 ///
3960 /// @param node the xml node to build the function_decl from.
3961 ///
3962 /// @param as_method_decl if this is set to a class_or_union pointer,
3963 /// it means that the 'function-decl' xml node should be parsed as a
3964 /// method_decl. The class_or_union pointer is the class or union the
3965 /// resulting method_decl is a member function of. The resulting @ref
3966 /// function_decl_sptr that is returned is then really a @ref
3967 /// method_decl_sptr.
3968 ///
3969 /// @param add_to_current_scope if set to yes, the resulting of
3970 /// this function is added to its current scope.
3971 ///
3972 /// @param add_to_exported_decls if set to yes, the resulting of this
3973 /// function is added to the set of decls exported by the current
3974 /// corpus being built.
3975 ///
3976 /// @return a pointer to a newly created function_decl upon successful
3977 /// completion. If the function was suppressed by a suppression
3978 /// specification then returns nil.
3979 static function_decl_sptr
3980 build_function_decl_if_not_suppressed(reader& rdr,
3981  const xmlNodePtr node,
3982  class_or_union_sptr as_method_decl,
3983  bool add_to_current_scope,
3984  bool add_to_exported_decls)
3985 {
3986  function_decl_sptr fn;
3987 
3988  if (function_is_suppressed(rdr, node))
3989  // The function was suppressed by at least one suppression
3990  // specification associated to the current ABIXML reader. So
3991  // don't build any IR for it.
3992  ;
3993  else
3994  fn = build_function_decl(rdr, node, as_method_decl,
3995  add_to_current_scope,
3996  add_to_exported_decls);
3997  return fn;
3998 }
3999 
4000 /// Test if a given function denoted by its name and linkage name is
4001 /// suppressed by any of the suppression specifications associated to
4002 /// a given context of native xml reading.
4003 ///
4004 /// @param rdr the native xml reading context of interest.
4005 ///
4006 /// @param note the XML node that represents the fucntion.
4007 /// match.
4008 ///
4009 /// @return true iff at least one function specification matches the
4010 /// function denoted by the node @p node.
4011 static bool
4012 function_is_suppressed(const reader& rdr, xmlNodePtr node)
4013 {
4014  string fname;
4015  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
4016  fname = xml::unescape_xml_string(CHAR_STR(s));
4017 
4018  string flinkage_name;
4019  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "mangled-name"))
4020  flinkage_name = xml::unescape_xml_string(CHAR_STR(s));
4021 
4022  scope_decl* scope = rdr.get_cur_scope();
4023 
4024  string qualified_name = build_qualified_name(scope, fname);
4025 
4026  return suppr::is_function_suppressed(rdr, qualified_name, flinkage_name);
4027 }
4028 
4029 /// Test if a type denoted by its name, context and location is
4030 /// suppressed by the suppression specifications that are associated
4031 /// to a given ABIXML reader.
4032 ///
4033 /// @param rdr the ABIXML reader to consider.
4034 ///
4035 /// @param note the XML node that represents the type.
4036 ///
4037 /// @return true iff the type designated by @p node is suppressed by
4038 /// at least of suppression specifications associated to the current
4039 /// ABIXML reader.
4040 static bool
4041 type_is_suppressed(const reader& rdr, xmlNodePtr node)
4042 {
4043  string type_name;
4044  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
4045  type_name = xml::unescape_xml_string(CHAR_STR(s));
4046 
4047  location type_location;
4048  read_location(rdr, node, type_location);
4049 
4050  scope_decl* scope = rdr.get_cur_scope();
4051 
4052  string qualified_name = build_qualified_name(scope, type_name);
4053 
4054  bool type_is_private = false;
4055  return suppr::is_type_suppressed(rdr, qualified_name, type_location,
4056  type_is_private,
4057  /*require_drop_property=*/true);
4058 }
4059 
4060 /// Build a @ref var_decl out of a an XML node that describes it iff
4061 /// the variable denoted by the XML node is not suppressed by a
4062 /// suppression specification associated to the current ABIXML reader.
4063 ///
4064 /// @param rdr the ABIXML reader to use.
4065 ///
4066 /// @param node the XML node for the variable to consider.
4067 ///
4068 /// @parm add_to_current_scope whether to add the built @ref var_decl
4069 /// to the current scope or not.
4070 ///
4071 /// @return true iff the @ref var_decl was built.
4072 static var_decl_sptr
4073 build_var_decl_if_not_suppressed(reader& rdr,
4074  const xmlNodePtr node,
4075  bool add_to_current_scope)
4076 {
4077  var_decl_sptr var;
4078  if (!variable_is_suppressed(rdr, node))
4079  var = build_var_decl(rdr, node, add_to_current_scope);
4080  return var;
4081 }
4082 
4083 /// Test if a variable denoted by its XML node is suppressed by a
4084 /// suppression specification that is present in a given ABIXML reader.
4085 ///
4086 /// @param rdr the ABIXML reader to consider.
4087 ///
4088 /// @param node the XML node of the variable to consider.
4089 ///
4090 /// @return true iff the variable denoted by @p node is suppressed.
4091 static bool
4092 variable_is_suppressed(const reader& rdr, xmlNodePtr node)
4093 {
4094  string name;
4095  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
4096  name = xml::unescape_xml_string(CHAR_STR(s));
4097 
4098  string linkage_name;
4099  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "mangled-name"))
4100  linkage_name = xml::unescape_xml_string(CHAR_STR(s));
4101 
4102  scope_decl* scope = rdr.get_cur_scope();
4103 
4104  string qualified_name = build_qualified_name(scope, name);
4105 
4106  return suppr::is_variable_suppressed(rdr, qualified_name, linkage_name);
4107 }
4108 
4109 /// Test if a variable in a particular scope is suppressed by a
4110 /// suppression specification that is present in a given ABIXML reader.
4111 ///
4112 /// @parm rdr the ABIXML reader to consider.
4113 ///
4114 /// @param scope the scope of the variable to consider.
4115 ///
4116 /// @param v the variable to consider.
4117 ///
4118 /// @return true iff the variable @p v is suppressed.
4119 static bool
4120 variable_is_suppressed(const reader& rdr,
4121  const scope_decl* scope,
4122  const var_decl& v)
4123 {
4124  string qualified_name = build_qualified_name(scope, v.get_name());
4125  return suppr::is_variable_suppressed(rdr, qualified_name,
4126  v.get_linkage_name());
4127 }
4128 
4129 /// Build pointer to var_decl from a 'var-decl' xml Node
4130 ///
4131 /// @param rdr the context of the parsing.
4132 ///
4133 /// @param node the xml node to build the var_decl from.
4134 ///
4135 /// @return a pointer to a newly built var_decl upon successful
4136 /// completion, a null pointer otherwise.
4137 static shared_ptr<var_decl>
4138 build_var_decl(reader& rdr,
4139  const xmlNodePtr node,
4140  bool add_to_current_scope)
4141 {
4142  shared_ptr<var_decl> nil;
4143 
4144  if (!xmlStrEqual(node->name, BAD_CAST("var-decl")))
4145  return nil;
4146 
4147  string name;
4148  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
4149  name = xml::unescape_xml_string(CHAR_STR(s));
4150 
4151  string type_id;
4152  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
4153  type_id = CHAR_STR(s);
4154  type_base_sptr underlying_type = rdr.build_or_get_type_decl(type_id,
4155  true);
4156  ABG_ASSERT(underlying_type);
4157 
4158  string mangled_name;
4159  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "mangled-name"))
4160  mangled_name = xml::unescape_xml_string(CHAR_STR(s));
4161 
4162  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
4163  read_visibility(node, vis);
4164 
4165  decl_base::binding bind = decl_base::BINDING_NONE;
4166  read_binding(node, bind);
4167 
4168  location locus;
4169  read_location(rdr, node, locus);
4170 
4171  var_decl_sptr decl(new var_decl(name, underlying_type,
4172  locus, mangled_name,
4173  vis, bind));
4174  maybe_set_artificial_location(rdr, node, decl);
4175 
4176  elf_symbol_sptr sym = build_elf_symbol_from_reference(rdr, node);
4177  if (sym)
4178  decl->set_symbol(sym);
4179 
4180  rdr.push_decl_to_scope(decl,
4181  add_to_current_scope
4182  ? rdr.get_scope_ptr_for_node(node)
4183  : nullptr);
4184  if (add_to_current_scope)
4185  {
4186  // This variable is really being kept in the IR, so let's record
4187  // that it's using its type.
4188  RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
4189  }
4190 
4191  if (decl->get_symbol() && decl->get_symbol()->is_public())
4192  decl->set_is_in_public_symbol_table(true);
4193 
4194  return decl;
4195 }
4196 
4197 /// Build the IR node for a void type.
4198 ///
4199 /// @param rdr the ABIXML reader to use.
4200 ///
4201 /// @return the void type node.
4202 static decl_base_sptr
4203 build_ir_node_for_void_type(reader& rdr)
4204 {
4205  const environment& env = rdr.get_environment();
4206 
4207  type_base_sptr t = env.get_void_type();
4208  if (!get_type_scope(t))
4209  {
4211  rdr.get_translation_unit()->get_global_scope());
4212  rdr.schedule_type_for_canonicalization(t);
4213  }
4214  decl_base_sptr type_declaration = get_type_declaration(t);
4215  return type_declaration;
4216 }
4217 
4218 /// Build the IR node for a "pointer to void type".
4219 ///
4220 /// That IR node is shared across the ABI corpus.
4221 ///
4222 /// Note that this function just gets that IR node from the
4223 /// environment and, if it's not added to any scope yet, adds it to
4224 /// the global scope associated to the current translation unit.
4225 ///
4226 /// @param rdr the DWARF reader to consider.
4227 ///
4228 /// @return the IR node.
4229 static decl_base_sptr
4230 build_ir_node_for_void_pointer_type(reader& rdr)
4231 {
4232  const environment& env = rdr.get_environment();
4233 
4234  type_base_sptr t = env.get_void_pointer_type();
4235  if (!get_type_scope(t))
4236  {
4238  rdr.get_translation_unit()->get_global_scope());
4239  rdr.schedule_type_for_canonicalization(t);
4240  }
4241  decl_base_sptr type_declaration = get_type_declaration(t);
4242  return type_declaration;
4243 }
4244 
4245 /// Build the IR node for a variadic parameter type.
4246 ///
4247 /// @param rdr the ABIXML reader to use.
4248 ///
4249 /// @return the variadic parameter type.
4250 static decl_base_sptr
4251 build_ir_node_for_variadic_parameter_type(reader& rdr)
4252 {
4253  const environment& env = rdr.get_environment();
4254 
4255  type_base_sptr t = env.get_variadic_parameter_type();
4256  if (!get_type_scope(t))
4257  {
4259  rdr.get_translation_unit()->get_global_scope());
4260  rdr.schedule_type_for_canonicalization(t);
4261  }
4262  decl_base_sptr type_declaration = get_type_declaration(t);
4263  return type_declaration;
4264 }
4265 
4266 /// Build a type_decl from a "type-decl" XML Node.
4267 ///
4268 /// @param rdr the context of the parsing.
4269 ///
4270 /// @param node the XML node to build the type_decl from.
4271 ///
4272 /// @param add_to_current_scope if set to yes, the resulting of
4273 /// this function is added to its current scope.
4274 ///
4275 /// @return a pointer to type_decl upon successful completion, a null
4276 /// pointer otherwise.
4277 static type_decl_sptr
4278 build_type_decl(reader& rdr,
4279  const xmlNodePtr node,
4280  bool add_to_current_scope)
4281 {
4282  shared_ptr<type_decl> nil;
4283 
4284  if (!xmlStrEqual(node->name, BAD_CAST("type-decl")))
4285  return nil;
4286 
4287  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4288  {
4289  type_decl_sptr result = dynamic_pointer_cast<type_decl>(d);
4290  ABG_ASSERT(result);
4291  return result;
4292  }
4293 
4294  string name;
4295  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
4296  name = xml::unescape_xml_string(CHAR_STR(s));
4297 
4298  string id;
4299  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
4300  id = CHAR_STR(s);
4301  ABG_ASSERT(!id.empty());
4302 
4303  size_t size_in_bits= 0;
4304  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size-in-bits"))
4305  size_in_bits = atoi(CHAR_STR(s));
4306 
4307  size_t alignment_in_bits = 0;
4308  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "alignment-in-bits"))
4309  alignment_in_bits = atoi(CHAR_STR(s));
4310 
4311  bool is_decl_only = false;
4312  read_is_declaration_only(node, is_decl_only);
4313 
4314  location loc;
4315  read_location(rdr, node, loc);
4316 
4317  bool is_anonymous = false;
4318  read_is_anonymous(node, is_anonymous);
4319 
4320  if (type_base_sptr d = rdr.get_type_decl(id))
4321  {
4322  // I've seen instances of DSOs where a type_decl would appear
4323  // several times. Hugh.
4324  type_decl_sptr ty = dynamic_pointer_cast<type_decl>(d);
4325  ABG_ASSERT(ty);
4326  ABG_ASSERT(!name.empty());
4327  ABG_ASSERT(!ty->get_name().empty());
4328  ABG_ASSERT(ty->get_size_in_bits() == size_in_bits);
4329  ABG_ASSERT(ty->get_alignment_in_bits() == alignment_in_bits);
4330  return ty;
4331  }
4332 
4333  const environment& env = rdr.get_environment();
4334  type_decl_sptr decl;
4335  if (name == env.get_variadic_parameter_type_name())
4336  decl = is_type_decl(build_ir_node_for_variadic_parameter_type(rdr));
4337  else if (name == "void")
4338  decl = is_type_decl(build_ir_node_for_void_type(rdr));
4339  else
4340  decl.reset(new type_decl(env, name, size_in_bits,
4341  alignment_in_bits, loc));
4342  maybe_set_artificial_location(rdr, node, decl);
4343  decl->set_is_anonymous(is_anonymous);
4344  decl->set_is_declaration_only(is_decl_only);
4345  // Read the stash from the XML node and stash it into the IR node.
4346  rdr.read_hash_and_stash(node, decl);
4347 
4348  if (rdr.push_and_key_type_decl(decl, node, add_to_current_scope))
4349  {
4350  rdr.map_xml_node_to_decl(node, decl);
4351  return decl;
4352  }
4353 
4354  return nil;
4355 }
4356 
4357 /// Build a qualified_type_def from a 'qualified-type-def' xml node.
4358 ///
4359 /// @param rdr the context of the parsing.
4360 ///
4361 /// @param node the xml node to build the qualified_type_def from.
4362 ///
4363 /// @param add_to_current_scope if set to yes, the resulting of this
4364 /// function is added to its current scope.
4365 ///
4366 /// @return a pointer to a newly built qualified_type_def upon
4367 /// successful completion, a null pointer otherwise.
4368 static qualified_type_def_sptr
4369 build_qualified_type_decl(reader& rdr,
4370  const xmlNodePtr node,
4371  bool add_to_current_scope)
4372 {
4373  qualified_type_def_sptr nil;
4374  if (!xmlStrEqual(node->name, BAD_CAST("qualified-type-def")))
4375  return nil;
4376 
4377  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4378  {
4379  qualified_type_def_sptr result =
4380  dynamic_pointer_cast<qualified_type_def>(d);
4381  ABG_ASSERT(result);
4382  return result;
4383  }
4384 
4385  string id;
4386  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE (node, "id"))
4387  id = CHAR_STR(s);
4388 
4389  ABG_ASSERT(!id.empty());
4390 
4391  location loc;
4392  read_location(rdr, node, loc);
4393 
4394  qualified_type_def::CV cv = qualified_type_def::CV_NONE;
4395  string const_str;
4396  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "const"))
4397  const_str = CHAR_STR(s);
4398  bool const_cv = const_str == "yes";
4399 
4400  string volatile_str;
4401  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "volatile"))
4402  volatile_str = CHAR_STR(s);
4403  bool volatile_cv = volatile_str == "yes";
4404 
4405  string restrict_str;
4406  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "restrict"))
4407  restrict_str = CHAR_STR(s);
4408  bool restrict_cv = restrict_str == "yes";
4409 
4410  if (const_cv)
4411  cv = cv | qualified_type_def::CV_CONST;
4412  if (volatile_cv)
4413  cv = cv | qualified_type_def::CV_VOLATILE;
4414  if (restrict_cv)
4415  cv = cv | qualified_type_def::CV_RESTRICT;
4416 
4417  string type_id;
4418  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
4419  type_id = CHAR_STR(s);
4420  ABG_ASSERT(!type_id.empty());
4421 
4422  shared_ptr<type_base> underlying_type =
4423  rdr.build_or_get_type_decl(type_id, true);
4424  ABG_ASSERT(underlying_type);
4425 
4426  if (type_base_sptr t = rdr.get_type_decl(id))
4427  {
4428  qualified_type_def_sptr result = is_qualified_type(t);
4429  ABG_ASSERT(result);
4430  return result;
4431  }
4432 
4433  qualified_type_def_sptr decl;
4434  if (type_base_sptr t = rdr.get_type_decl(id))
4435  {
4436  decl = is_qualified_type(t);
4437  ABG_ASSERT(decl);
4438  }
4439  else
4440  {
4441  decl.reset(new qualified_type_def(underlying_type, cv, loc));
4442  maybe_set_artificial_location(rdr, node, decl);
4443  rdr.push_and_key_type_decl(decl, node, add_to_current_scope);
4444  RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
4445  }
4446  // Read the stash from the XML node and stash it into the IR node.
4447  rdr.read_hash_and_stash(node, decl);
4448 
4449  rdr.map_xml_node_to_decl(node, decl);
4450 
4451  return decl;
4452 }
4453 
4454 /// Build a pointer_type_def from a 'pointer-type-def' xml node.
4455 ///
4456 /// @param rdr the context of the parsing.
4457 ///
4458 /// @param node the xml node to build the pointer_type_def from.
4459 ///
4460 /// @param add_to_current_scope if set to yes, the resulting of
4461 /// this function is added to its current scope.
4462 ///
4463 /// @return a pointer to a newly built pointer_type_def upon
4464 /// successful completion, a null pointer otherwise.
4465 static pointer_type_def_sptr
4466 build_pointer_type_def(reader& rdr,
4467  const xmlNodePtr node,
4468  bool add_to_current_scope)
4469 {
4470 
4471  shared_ptr<pointer_type_def> nil;
4472 
4473  if (!xmlStrEqual(node->name, BAD_CAST("pointer-type-def")))
4474  return nil;
4475 
4476  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4477  {
4478  pointer_type_def_sptr result =
4479  dynamic_pointer_cast<pointer_type_def>(d);
4480  ABG_ASSERT(result);
4481  return result;
4482  }
4483 
4484  string id;
4485  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
4486  id = CHAR_STR(s);
4487  ABG_ASSERT(!id.empty());
4488 
4489  if (type_base_sptr t = rdr.get_type_decl(id))
4490  {
4492  ABG_ASSERT(result);
4493  return result;
4494  }
4495 
4496  string type_id;
4497  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
4498  type_id = CHAR_STR(s);
4499 
4500  size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4501  size_t alignment_in_bits = 0;
4502  read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4503  location loc;
4504  read_location(rdr, node, loc);
4505 
4506  type_base_sptr pointed_to_type =
4507  rdr.build_or_get_type_decl(type_id, true);
4508  ABG_ASSERT(pointed_to_type);
4509 
4510  if (type_base_sptr t = rdr.get_type_decl(id))
4511  {
4513  ABG_ASSERT(result);
4514  return result;
4515  }
4516 
4518  if (rdr.get_environment().is_void_type(pointed_to_type))
4519  t = is_pointer_type(build_ir_node_for_void_pointer_type(rdr));
4520  else
4521  // Create the pointer type /before/ the pointed-to type. After the
4522  // creation, the type is 'keyed' using rdr.push_and_key_type_decl.
4523  // This means that the type can be retrieved from its type ID. This
4524  // is so that if the pointed-to type indirectly uses this pointer
4525  // type (via recursion) then that is made possible.
4526  t.reset(new pointer_type_def(pointed_to_type,
4527  size_in_bits,
4528  alignment_in_bits,
4529  loc));
4530 
4531  maybe_set_artificial_location(rdr, node, t);
4532 
4533  rdr.push_and_key_type_decl(t, node, add_to_current_scope);
4534  rdr.map_xml_node_to_decl(node, t);
4535 
4536  // Read the stash from the XML node and stash it into the IR node.
4537  rdr.read_hash_and_stash(node, t);
4538 
4539  RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4540  return t;
4541 }
4542 
4543 /// Build a reference_type_def from a pointer to 'reference-type-def'
4544 /// xml node.
4545 ///
4546 /// @param rdr the context of the parsing.
4547 ///
4548 /// @param node the xml node to build the reference_type_def from.
4549 ///
4550 /// @param add_to_current_scope if set to yes, the resulting of
4551 /// this function is added to its current scope.
4552 ///
4553 /// @return a pointer to a newly built reference_type_def upon
4554 /// successful completio, a null pointer otherwise.
4555 static shared_ptr<reference_type_def>
4556 build_reference_type_def(reader& rdr,
4557  const xmlNodePtr node,
4558  bool add_to_current_scope)
4559 {
4560  shared_ptr<reference_type_def> nil;
4561 
4562  if (!xmlStrEqual(node->name, BAD_CAST("reference-type-def")))
4563  return nil;
4564 
4565  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4566  {
4567  reference_type_def_sptr result =
4568  dynamic_pointer_cast<reference_type_def>(d);
4569  ABG_ASSERT(result);
4570  return result;
4571  }
4572 
4573  string id;
4574  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
4575  id = CHAR_STR(s);
4576  ABG_ASSERT(!id.empty());
4577 
4578  if (type_base_sptr d = rdr.get_type_decl(id))
4579  {
4581  ABG_ASSERT(ty);
4582  return ty;
4583  }
4584 
4585  location loc;
4586  read_location(rdr, node, loc);
4587  string kind;
4588  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "kind"))
4589  kind = CHAR_STR(s); // this should be either "lvalue" or "rvalue".
4590  bool is_lvalue = kind == "lvalue";
4591 
4592  size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4593  size_t alignment_in_bits = 0;
4594  read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4595 
4596  string type_id;
4597  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
4598  type_id = CHAR_STR(s);
4599  ABG_ASSERT(!type_id.empty());
4600 
4601 
4602  type_base_sptr pointed_to_type =
4603  rdr.build_or_get_type_decl(type_id, /*add_to_current_scope=*/ true);
4604  ABG_ASSERT(pointed_to_type);
4605 
4606  // The call to rdr.build_or_get_type_decl above might have triggered
4607  // the building of the current type. If so, then return it.
4608  if (type_base_sptr t = rdr.get_type_decl(id))
4609  {
4611  ABG_ASSERT(result);
4612  return result;
4613  }
4614 
4615  // Create the reference type /before/ the pointed-to type. After
4616  // the creation, the type is 'keyed' using
4617  // rdr.push_and_key_type_decl. This means that the type can be
4618  // retrieved from its type ID. This is so that if the pointed-to
4619  // type indirectly uses this reference type (via recursion) then
4620  // that is made possible.
4621  reference_type_def_sptr t(new reference_type_def(pointed_to_type,
4622  is_lvalue, size_in_bits,
4623  alignment_in_bits, loc));
4624  maybe_set_artificial_location(rdr, node, t);
4625  ABG_ASSERT(rdr.push_and_key_type_decl(t, node, add_to_current_scope));
4626  rdr.map_xml_node_to_decl(node, t);
4627 
4628  // Read the stash from the XML node and stash it into the IR node.
4629  rdr.read_hash_and_stash(node, t);
4630 
4631  RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4632 
4633  return t;
4634 }
4635 
4636 /// Build a @ref ptr_to_mbr_type from a pointer to
4637 /// 'pointer-to-member-type' xml node.
4638 ///
4639 /// @param rdr the reader used for parsing.
4640 ///
4641 /// @param node the xml node to build the reference_type_def from.
4642 ///
4643 /// @param add_to_current_scope if set to yes, the resulting of
4644 /// this function is added to its current scope.
4645 ///
4646 /// @return a pointer to a newly built @ref ptr_to_mbr_type upon
4647 /// successful completio, a null pointer otherwise.
4648 static ptr_to_mbr_type_sptr
4649 build_ptr_to_mbr_type(reader& rdr,
4650  const xmlNodePtr node,
4651  bool add_to_current_scope)
4652 {
4653  ptr_to_mbr_type_sptr result, nil;
4654 
4655  if (!xmlStrEqual(node->name, BAD_CAST("pointer-to-member-type")))
4656  return nil;
4657 
4658  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4659  {
4660  result = is_ptr_to_mbr_type(d);
4661  ABG_ASSERT(result);
4662  return result;
4663  }
4664 
4665  string id;
4666  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
4667  id = CHAR_STR(s);
4668 
4669  if (id.empty())
4670  return nil;
4671 
4672  if (type_base_sptr d = rdr.get_type_decl(id))
4673  {
4674  result = is_ptr_to_mbr_type(d);
4675  ABG_ASSERT(result);
4676  return result;
4677  }
4678 
4679  size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4680  size_t alignment_in_bits = 0;
4681  read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4682 
4683  location loc;
4684  read_location(rdr, node, loc);
4685 
4686  string member_type_id;
4687  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "member-type-id"))
4688  member_type_id = CHAR_STR(s);
4689  if (member_type_id.empty())
4690  return nil;
4691  type_base_sptr member_type =
4692  is_type(rdr.build_or_get_type_decl(member_type_id, true));
4693  if (!member_type)
4694  return nil;
4695 
4696  if (type_base_sptr t = rdr.get_type_decl(id))
4697  {
4699  ABG_ASSERT(result);
4700  return result;
4701  }
4702 
4703  string containing_type_id;
4704  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "containing-type-id"))
4705  containing_type_id = CHAR_STR(s);
4706  if (containing_type_id.empty())
4707  return nil;
4708  type_base_sptr containing_type =
4709  rdr.build_or_get_type_decl(containing_type_id, true);
4711  return nil;
4712 
4713  if (type_base_sptr t = rdr.get_type_decl(id))
4714  {
4716  ABG_ASSERT(result);
4717  return result;
4718  }
4719 
4720  result.reset(new ptr_to_mbr_type(rdr.get_environment(),
4721  member_type, containing_type,
4722  size_in_bits, alignment_in_bits,
4723  loc));
4724 
4725  // Read the stash from the XML node and stash it into the IR node.
4726  rdr.read_hash_and_stash(node, result);
4727 
4728  if (rdr.push_and_key_type_decl(result, node, add_to_current_scope))
4729  rdr.map_xml_node_to_decl(node, result);
4730 
4731  return result;
4732 }
4733 
4734 /// Build a function_type from a pointer to 'function-type'
4735 /// xml node.
4736 ///
4737 /// @param rdr the context of the parsing.
4738 ///
4739 /// @param node the xml node to build the function_type from.
4740 ///
4741 /// @param add_to_current_scope if set to yes, the result of
4742 /// this function is added to its current scope.
4743 ///
4744 /// @return a pointer to a newly built function_type upon
4745 /// successful completion, a null pointer otherwise.
4746 static function_type_sptr
4747 build_function_type(reader& rdr,
4748  const xmlNodePtr node,
4749  bool /*add_to_current_scope*/)
4750 {
4751  function_type_sptr nil;
4752 
4753  if (!xmlStrEqual(node->name, BAD_CAST("function-type")))
4754  return nil;
4755 
4756  string id;
4757  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
4758  id = CHAR_STR(s);
4759  ABG_ASSERT(!id.empty());
4760 
4761  string method_class_id;
4762  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "method-class-id"))
4763  method_class_id = CHAR_STR(s);
4764 
4765  bool is_method_t = !method_class_id.empty();
4766 
4767  size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
4768  read_size_and_alignment(node, size, align);
4769 
4770  const environment& env = rdr.get_environment();
4771  std::vector<shared_ptr<function_decl::parameter> > parms;
4772  type_base_sptr return_type = env.get_void_type();
4773 
4774  class_or_union_sptr method_class_type;
4775  if (is_method_t)
4776  {
4777  method_class_type =
4778  is_class_or_union_type(rdr.build_or_get_type_decl(method_class_id,
4779  /*add_decl_to_scope=*/true));
4780  ABG_ASSERT(method_class_type);
4781  }
4782 
4783  function_type_sptr fn_type(is_method_t
4784  ? new method_type(method_class_type,
4785  /*is_const=*/false,
4786  size, align)
4787  : new function_type(return_type,
4788  parms, size, align));
4789 
4790  // Read the stash from the XML node and stash it into the IR node.
4791  rdr.read_hash_and_stash(node, fn_type);
4792 
4793  rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
4794  rdr.key_type_decl(fn_type, id);
4795  RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type);
4796 
4797  for (xmlNodePtr n = xmlFirstElementChild(node);
4798  n;
4799  n = xmlNextElementSibling(n))
4800  {
4801  if (xmlStrEqual(n->name, BAD_CAST("parameter")))
4802  {
4804  build_function_parameter(rdr, n))
4805  parms.push_back(p);
4806  }
4807  else if (xmlStrEqual(n->name, BAD_CAST("return")))
4808  {
4809  string type_id;
4810  if (xml_char_sptr s =
4811  xml::build_sptr(xmlGetProp(n, BAD_CAST("type-id"))))
4812  type_id = CHAR_STR(s);
4813  type_base_sptr ret_type;
4814  if (!type_id.empty())
4815  ret_type = rdr.build_or_get_type_decl (type_id, true);
4816  if (!ret_type)
4817  ret_type = return_type;
4818  fn_type->set_return_type(ret_type);
4819  }
4820  }
4821  if (!fn_type->get_return_type())
4822  fn_type->set_return_type(return_type);
4823 
4824  fn_type->set_parameters(parms);
4825 
4826  return fn_type;
4827 }
4828 
4829 /// Build a array_type_def::subrange_type from a 'subrange' xml node.
4830 ///
4831 /// @param rdr the context of the parsing.
4832 ///
4833 /// @param node the xml node to build the
4834 /// array_type_def::subrange_type from.
4835 ///
4836 ///
4837 /// @return a pointer to a newly built array_type_def::subrange_type
4838 /// upon successful completion, a null pointer otherwise.
4840 build_subrange_type(reader& rdr,
4841  const xmlNodePtr node,
4842  bool add_to_current_scope)
4843 {
4845 
4846  if (!node || !xmlStrEqual(node->name, BAD_CAST("subrange")))
4847  return nil;
4848 
4849  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4850  {
4852  dynamic_pointer_cast<array_type_def::subrange_type>(d);
4853  ABG_ASSERT(result);
4854  return result;
4855  }
4856 
4857  string id;
4858  // Note that in early implementations, the subrange didn't carry its
4859  // own ID as the subrange was just a detail of an array. So we
4860  // still need to support the abixml emitted by those early
4861  // implementations.
4862  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
4863  id = CHAR_STR(s);
4864 
4865  if (!id.empty())
4866  if (type_base_sptr d = rdr.get_type_decl(id))
4867  {
4869  ABG_ASSERT(ty);
4870  return ty;
4871  }
4872 
4873  string name;
4874  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
4875  name = CHAR_STR(s);
4876 
4877  uint64_t length = 0;
4878  string length_str;
4879  bool is_non_finite = false;
4880  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "length"))
4881  {
4882  if (string(CHAR_STR(s)) == "infinite" || string(CHAR_STR(s)) == "unknown")
4883  is_non_finite = true;
4884  else
4885  length = strtoull(CHAR_STR(s), NULL, 0);
4886  }
4887 
4888  uint64_t size_in_bits = 0;
4889  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size-in-bits"))
4890  {
4891  char *endptr = nullptr;
4892  size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4893  if (*endptr != '\0')
4894  {
4895  if (!strcmp(CHAR_STR(s), "infinite")
4896  ||!strcmp(CHAR_STR(s), "unknown"))
4897  size_in_bits = (size_t) -1;
4898  else
4899  return nil;
4900  }
4901  }
4902 
4903  int64_t lower_bound = 0, upper_bound = 0;
4904  bool bounds_present = false;
4905  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "lower-bound"))
4906  {
4907  lower_bound = strtoll(CHAR_STR(s), NULL, 0);
4908  s = XML_NODE_GET_ATTRIBUTE(node, "upper-bound");
4909  if (!string(CHAR_STR(s)).empty())
4910  upper_bound = strtoll(CHAR_STR(s), NULL, 0);
4911  bounds_present = true;
4912  ABG_ASSERT(is_non_finite
4913  || (length == (uint64_t) upper_bound - lower_bound + 1));
4914  }
4915 
4916  string underlying_type_id;
4917  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
4918  underlying_type_id = CHAR_STR(s);
4919 
4920  type_base_sptr underlying_type;
4921  if (!underlying_type_id.empty())
4922  {
4923  underlying_type = rdr.build_or_get_type_decl(underlying_type_id, true);
4924  ABG_ASSERT(underlying_type);
4925  }
4926 
4927  if (type_base_sptr t = rdr.get_type_decl(id))
4928  {
4930  ABG_ASSERT(result);
4931  return result;
4932  }
4933 
4934  location loc;
4935  read_location(rdr, node, loc);
4936 
4937  // Note that DWARF would actually have a upper_bound of -1 for an
4938  // array of length 0. In the past (before ABIXML version 2.3), the
4939  // IR would reflect that, so let's stay compatible with that.
4940  array_type_def::subrange_type::bound_value max_bound;
4941  array_type_def::subrange_type::bound_value min_bound;
4942  if (!is_non_finite)
4943  if (length > 0)
4944  // By default, if no 'lower-bound/upper-bound' attributes are
4945  // set, we assume that the lower bound is 0 and the upper bound
4946  // is length - 1.
4947  max_bound.set_signed(length - 1);
4948 
4949  if (bounds_present)
4950  {
4951  // So lower_bound/upper_bound are set. Let's set them rather
4952  // than assume that mind_bound is zero.
4953  min_bound.set_signed(lower_bound);
4954  max_bound.set_signed(upper_bound);
4955  }
4956 
4958  (new array_type_def::subrange_type(rdr.get_environment(),
4959  name, min_bound, max_bound,
4960  underlying_type, loc));
4961  maybe_set_artificial_location(rdr, node, p);
4962  p->is_non_finite(is_non_finite);
4963  if (size_in_bits)
4964  p->set_size_in_bits(size_in_bits);
4965 
4966  // Read the stash from the XML node and stash it into the IR node.
4967  rdr.read_hash_and_stash(node, p);
4968 
4969  if (rdr.push_and_key_type_decl(p, node, add_to_current_scope))
4970  rdr.map_xml_node_to_decl(node, p);
4971 
4972  return p;
4973 }
4974 
4975 /// Build a array_type_def from a 'array-type-def' xml node.
4976 ///
4977 /// @param rdr the context of the parsing.
4978 ///
4979 /// @param node the xml node to build the array_type_def from.
4980 ///
4981 /// @param add_to_current_scope if set to yes, the resulting of
4982 /// this function is added to its current scope.
4983 ///
4984 /// @return a pointer to a newly built array_type_def upon
4985 /// successful completion, a null pointer otherwise.
4986 static array_type_def_sptr
4987 build_array_type_def(reader& rdr,
4988  const xmlNodePtr node,
4989  bool add_to_current_scope)
4990 {
4991 
4992  array_type_def_sptr nil;
4993 
4994  if (!xmlStrEqual(node->name, BAD_CAST("array-type-def")))
4995  return nil;
4996 
4997  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4998  {
4999  array_type_def_sptr result =
5000  dynamic_pointer_cast<array_type_def>(d);
5001  ABG_ASSERT(result);
5002  return result;
5003  }
5004 
5005  string id;
5006  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
5007  id = CHAR_STR(s);
5008  ABG_ASSERT(!id.empty());
5009 
5010  if (type_base_sptr d = rdr.get_type_decl(id))
5011  {
5013  ABG_ASSERT(ty);
5014  return ty;
5015  }
5016 
5017  int dimensions = 0;
5018  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "dimensions"))
5019  dimensions = atoi(CHAR_STR(s));
5020 
5021  string type_id;
5022  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
5023  type_id = CHAR_STR(s);
5024 
5025  size_t size_in_bits = 0, alignment_in_bits = 0;
5026  bool has_size_in_bits = false;
5027  char *endptr;
5028 
5029  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "size-in-bits"))
5030  {
5031  size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
5032  if (*endptr != '\0')
5033  {
5034  if (!strcmp(CHAR_STR(s), "infinite")
5035  ||!strcmp(CHAR_STR(s), "unknown"))
5036  size_in_bits = (size_t) -1;
5037  else
5038  return nil;
5039  }
5040  has_size_in_bits = true;
5041  }
5042 
5043  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "alignment-in-bits"))
5044  {
5045  alignment_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
5046  if (*endptr != '\0')
5047  return nil;
5048  }
5049 
5050  location loc;
5051  read_location(rdr, node, loc);
5053 
5054  for (xmlNodePtr n = xmlFirstElementChild(node);
5055  n;
5056  n = xmlNextElementSibling(n))
5057  if (xmlStrEqual(n->name, BAD_CAST("subrange")))
5058  {
5060  build_subrange_type(rdr, n, /*add_to_current_scope=*/true))
5061  {
5062  MAYBE_MAP_TYPE_WITH_TYPE_ID(s, n);
5063  if (add_to_current_scope)
5064  {
5065  add_decl_to_scope(s, rdr.get_cur_scope());
5066  rdr.schedule_type_for_canonicalization(s);
5067  }
5068  subranges.push_back(s);
5069  }
5070  }
5071 
5072  // The type of array elements.
5073  type_base_sptr type =
5074  rdr.build_or_get_type_decl(type_id, true);
5075  ABG_ASSERT(type);
5076 
5077  // maybe building the type of array elements triggered building this
5078  // one in the mean time ...
5079  if (type_base_sptr t = rdr.get_type_decl(id))
5080  {
5081  array_type_def_sptr result = is_array_type(t);
5082  ABG_ASSERT(result);
5083  return result;
5084  }
5085 
5086  array_type_def_sptr ar_type(new array_type_def(type, subranges, loc));
5087  // Read the stash from the XML node and stash it into the IR node.
5088  rdr.read_hash_and_stash(node, ar_type);
5089 
5090  maybe_set_artificial_location(rdr, node, ar_type);
5091  if (rdr.push_and_key_type_decl(ar_type, node, add_to_current_scope))
5092  rdr.map_xml_node_to_decl(node, ar_type);
5093  RECORD_ARTIFACT_AS_USED_BY(rdr, type, ar_type);
5094 
5095  if (dimensions != ar_type->get_dimension_count()
5096  || (alignment_in_bits
5097  != ar_type->get_element_type()->get_alignment_in_bits()))
5098  return nil;
5099 
5100  if (has_size_in_bits && size_in_bits != (size_t) -1
5101  && size_in_bits != ar_type->get_size_in_bits())
5102  {
5103  // We have a potential discrepancy between calculated and recorded sizes.
5104  size_t element_size = ar_type->get_element_type()->get_size_in_bits();
5105  if (element_size && element_size != (size_t)-1)
5106  {
5107  // Older versions miscalculated multidimensional array sizes.
5108  size_t bad_count = 0;
5109  for (vector<array_type_def::subrange_sptr>::const_iterator i =
5110  subranges.begin();
5111  i != subranges.end();
5112  ++i)
5113  bad_count += (*i)->get_length();
5114  if (size_in_bits == bad_count * element_size)
5115  {
5116  static bool reported = false;
5117  if (!reported)
5118  {
5119  std::cerr << "notice: Found incorrectly calculated array "
5120  << "sizes in XML - this is benign.\nOlder versions "
5121  << "of libabigail miscalculated multidimensional "
5122  << "array sizes." << std::endl;
5123  reported = true;
5124  }
5125  }
5126  else
5127  {
5128  std::cerr << "error: Found incorrectly calculated array size in "
5129  << "XML (id=\"" << id << "\")." << std::endl;
5131  }
5132  }
5133  }
5134 
5135  return ar_type;
5136 }
5137 
5138 /// Build an @ref enum_type_decl from the XML node that represents it,
5139 /// if it was not suppressed by a supression specification present in
5140 /// the current reader.
5141 ///
5142 /// @param rdr the reader to take into account.
5143 ///
5144 /// @param node the XML node representing the @ref enum_type_decl to
5145 /// build.
5146 ///
5147 /// @param add_to_current_scope whether to add the built @ref
5148 /// enum_type_decl to the current scope.
5149 ///
5150 /// @return the newly built @ref enum_type_decl iff it was effectively
5151 /// built.
5152 static enum_type_decl_sptr
5153 build_enum_type_decl_if_not_suppressed(reader& rdr,
5154  const xmlNodePtr node,
5155  bool add_to_current_scope)
5156 {
5157  enum_type_decl_sptr enum_type;
5158  if (!type_is_suppressed(rdr, node))
5159  enum_type = build_enum_type_decl(rdr, node, add_to_current_scope);
5160  return enum_type;
5161 }
5162 
5163 /// Build an enum_type_decl from an 'enum-type-decl' xml node.
5164 ///
5165 /// @param rdr the context of the parsing.
5166 ///
5167 /// @param node the xml node to build the enum_type_decl from.
5168 ///
5169 /// param add_to_current_scope if set to yes, the resulting of this
5170 /// function is added to its current scope.
5171 ///
5172 /// @return a pointer to a newly built enum_type_decl upon successful
5173 /// completion, a null pointer otherwise.
5174 static enum_type_decl_sptr
5175 build_enum_type_decl(reader& rdr,
5176  const xmlNodePtr node,
5177  bool add_to_current_scope)
5178 {
5179  enum_type_decl_sptr nil;
5180 
5181  if (!xmlStrEqual(node->name, BAD_CAST("enum-decl")))
5182  return nil;
5183 
5184  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5185  {
5186  enum_type_decl_sptr result =
5187  dynamic_pointer_cast<enum_type_decl>(d);
5188  ABG_ASSERT(result);
5189  return result;
5190  }
5191 
5192  string name;
5193  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
5194  name = xml::unescape_xml_string(CHAR_STR(s));
5195 
5196  string linkage_name;
5197  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "linkage-name"))
5198  linkage_name = xml::unescape_xml_string(CHAR_STR(s));
5199 
5200  location loc;
5201  read_location(rdr, node, loc);
5202 
5203  bool is_decl_only = false;
5204  read_is_declaration_only(node, is_decl_only);
5205 
5206  bool is_anonymous = false;
5207  read_is_anonymous(node, is_anonymous);
5208 
5209  bool is_artificial = false;
5210  read_is_artificial(node, is_artificial);
5211 
5212  string id;
5213  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
5214  id = CHAR_STR(s);
5215 
5216  ABG_ASSERT(!id.empty());
5217 
5218  if (type_base_sptr t = rdr.get_type_decl(id))
5219  {
5220  enum_type_decl_sptr result = is_enum_type(t);
5221  ABG_ASSERT(result);
5222  return result;
5223  }
5224 
5225  string base_type_id;
5227  for (xmlNodePtr n = xmlFirstElementChild(node);
5228  n;
5229  n = xmlNextElementSibling(n))
5230  {
5231  if (xmlStrEqual(n->name, BAD_CAST("underlying-type")))
5232  {
5233  xml_char_sptr a = xml::build_sptr(xmlGetProp(n, BAD_CAST("type-id")));
5234  if (a)
5235  base_type_id = CHAR_STR(a);
5236  continue;
5237  }
5238  else if (xmlStrEqual(n->name, BAD_CAST("enumerator")))
5239  {
5240  string name;
5241  int64_t value = 0;
5242 
5243  xml_char_sptr a = xml::build_sptr(xmlGetProp(n, BAD_CAST("name")));
5244  if (a)
5245  name = xml::unescape_xml_string(CHAR_STR(a));
5246 
5247  a = xml::build_sptr(xmlGetProp(n, BAD_CAST("value")));
5248  if (a)
5249  {
5250  value = strtoll(CHAR_STR(a), NULL, 0);
5251  // when strtoll encounters overflow or underflow, errno
5252  // is set to ERANGE and the returned value is either
5253  // LLONG_MIN or LLONG_MAX.
5254  if ((errno == ERANGE)
5255  && (value == LLONG_MIN || value == LLONG_MAX))
5256  return nil;
5257  }
5258 
5259  enums.push_back(enum_type_decl::enumerator(name, value));
5260  }
5261  }
5262 
5263  type_base_sptr underlying_type =
5264  rdr.build_or_get_type_decl(base_type_id, true);
5265  ABG_ASSERT(underlying_type);
5266 
5267  if (type_base_sptr t = rdr.get_type_decl(id))
5268  {
5269  enum_type_decl_sptr result = is_enum_type(t);
5270  ABG_ASSERT(result);
5271  return result;
5272  }
5273 
5274  enum_type_decl_sptr t(new enum_type_decl(name, loc,
5275  underlying_type,
5276  enums, linkage_name));
5277  maybe_set_artificial_location(rdr, node, t);
5278  t->set_is_anonymous(is_anonymous);
5279  t->set_is_artificial(is_artificial);
5280  t->set_is_declaration_only(is_decl_only);
5281  // Read the stash from the XML node and stash it into the IR node.
5282  rdr.read_hash_and_stash(node, t);
5283 
5284  if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
5285  {
5286  maybe_set_naming_typedef(rdr, node, t);
5287  rdr.map_xml_node_to_decl(node, t);
5288  RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
5289  return t;
5290  }
5291 
5292  return nil;
5293 }
5294 
5295 /// Build a typedef_decl from a 'typedef-decl' xml node.
5296 ///
5297 /// @param rdr the context of the parsing.
5298 ///
5299 /// @param node the xml node to build the typedef_decl from.
5300 ///
5301 /// @return a pointer to a newly built typedef_decl upon successful
5302 /// completion, a null pointer otherwise.
5303 static shared_ptr<typedef_decl>
5304 build_typedef_decl(reader& rdr,
5305  const xmlNodePtr node,
5306  bool add_to_current_scope)
5307 {
5308  shared_ptr<typedef_decl> nil;
5309 
5310  if (!xmlStrEqual(node->name, BAD_CAST("typedef-decl")))
5311  return nil;
5312 
5313  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5314  {
5315  typedef_decl_sptr result = is_typedef(d);
5316  ABG_ASSERT(result);
5317  return result;
5318  }
5319 
5320  string id;
5321  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
5322  id = CHAR_STR(s);
5323  ABG_ASSERT(!id.empty());
5324 
5325  if (type_base_sptr t = rdr.get_type_decl(id))
5326  {
5327  typedef_decl_sptr result = is_typedef(t);
5328  ABG_ASSERT(result);
5329  return result;
5330  }
5331 
5332  string name;
5333  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
5334  name = xml::unescape_xml_string(CHAR_STR(s));
5335 
5336  location loc;
5337  read_location(rdr, node, loc);
5338 
5339  string type_id;
5340  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
5341  type_id = CHAR_STR(s);
5342  ABG_ASSERT(!type_id.empty());
5343 
5344  type_base_sptr underlying_type(rdr.build_or_get_type_decl(type_id, true));
5345  ABG_ASSERT(underlying_type);
5346 
5347  // Maybe the building of the underlying type triggered the building
5348  // of the current type. If so, then return it.
5349  if (type_base_sptr t = rdr.get_type_decl(id))
5350  {
5351  typedef_decl_sptr result = is_typedef(t);
5352  ABG_ASSERT(result);
5353  return result;
5354  }
5355 
5356  typedef_decl_sptr t(new typedef_decl(name, underlying_type, loc));
5357  maybe_set_artificial_location(rdr, node, t);
5358 
5359  // Read the hash from the XML node and stash it into the IR node.
5360  rdr.read_hash_and_stash(node, t);
5361 
5362  rdr.push_and_key_type_decl(t, node, add_to_current_scope);
5363  rdr.map_xml_node_to_decl(node, t);
5364  RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
5365 
5366  return t;
5367 }
5368 
5369 /// Build a class from its XML node if it is not suppressed by a
5370 /// suppression specification that is present in the ABIXML reader.
5371 ///
5372 /// @param rdr the ABIXML reader to consider.
5373 ///
5374 /// @param node the XML node to consider.
5375 ///
5376 /// @param add_to_current_scope whether to add the built class to the
5377 /// current context or not.
5378 ///
5379 /// @return true iff the class was built.
5380 static class_decl_sptr
5381 build_class_decl_if_not_suppressed(reader& rdr,
5382  const xmlNodePtr node,
5383  bool add_to_current_scope)
5384 {
5385  class_decl_sptr class_type;
5386  if (!type_is_suppressed(rdr, node))
5387  class_type = build_class_decl(rdr, node, add_to_current_scope);
5388  return class_type;
5389 }
5390 
5391 /// Build a @ref union_decl from its XML node if it is not suppressed
5392 /// by a suppression specification that is present in the read
5393 /// context.
5394 ///
5395 /// @param rdr the ABIXML reader to consider.
5396 ///
5397 /// @param node the XML node to consider.
5398 ///
5399 /// @param add_to_current_scope whether to add the built @ref
5400 /// union_decl to the current context or not.
5401 ///
5402 /// @return true iff the @ref union_decl was built.
5403 static union_decl_sptr
5404 build_union_decl_if_not_suppressed(reader& rdr,
5405  const xmlNodePtr node,
5406  bool add_to_current_scope)
5407 {
5408  union_decl_sptr union_type;
5409  if (!type_is_suppressed(rdr, node))
5410  union_type = build_union_decl(rdr, node, add_to_current_scope);
5411  return union_type;
5412 }
5413 
5414 /// Build a class_decl from a 'class-decl' xml node.
5415 ///
5416 /// @param rdr the context of the parsing.
5417 ///
5418 /// @param node the xml node to build the class_decl from.
5419 ///
5420 /// @param add_to_current_scope if yes, the resulting class node
5421 /// hasn't triggered voluntarily the adding of the resulting
5422 /// class_decl_sptr to the current scope.
5423 ///
5424 /// @return a pointer to class_decl upon successful completion, a null
5425 /// pointer otherwise.
5426 static class_decl_sptr
5427 build_class_decl(reader& rdr,
5428  const xmlNodePtr node,
5429  bool add_to_current_scope)
5430 {
5431  class_decl_sptr nil;
5432 
5433  if (!xmlStrEqual(node->name, BAD_CAST("class-decl")))
5434  return nil;
5435 
5436  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5437  {
5438  class_decl_sptr result = dynamic_pointer_cast<class_decl>(d);
5439  ABG_ASSERT(result);
5440  return result;
5441  }
5442 
5443  string name;
5444  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
5445  name = xml::unescape_xml_string(CHAR_STR(s));
5446 
5447  size_t size_in_bits = 0, alignment_in_bits = 0;
5448  read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5449 
5450  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
5451  read_visibility(node, vis);
5452 
5453  bool is_artificial = false;
5454  read_is_artificial(node, is_artificial);
5455 
5456  string id;
5457  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
5458  id = CHAR_STR(s);
5459 
5460  location loc;
5461  read_location(rdr, node, loc);
5462 
5464  class_decl::data_members data_mbrs;
5465  class_decl::member_functions mbr_functions;
5466  class_decl::base_specs bases;
5467 
5468  class_decl_sptr decl;
5469 
5470  bool is_decl_only = false;
5471  read_is_declaration_only(node, is_decl_only);
5472 
5473  bool is_struct = false;
5474  read_is_struct(node, is_struct);
5475 
5476  bool is_anonymous = false;
5477  read_is_anonymous(node, is_anonymous);
5478 
5479  ABG_ASSERT(!id.empty());
5480 
5481  class_decl_sptr previous_definition, previous_declaration;
5482  if (!is_anonymous)
5483  if (type_base_sptr t = rdr.get_type_decl(id))
5484  {
5485  previous_definition = is_class_type(t);
5486  ABG_ASSERT(previous_definition);
5487  }
5488 
5489  const vector<type_base_sptr> *types_ptr = 0;
5490  if (!is_anonymous && !previous_definition)
5491  types_ptr = rdr.get_all_type_decls(id);
5492  if (types_ptr)
5493  {
5494  // Lets look at the previous declarations and the first previous
5495  // definition of this type that we've already seen while parsing
5496  // this corpus.
5497  for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5498  i != types_ptr->end();
5499  ++i)
5500  {
5501  class_decl_sptr klass = is_class_type(*i);
5502  ABG_ASSERT(klass);
5503  if (klass->get_is_declaration_only()
5504  && !klass->get_definition_of_declaration())
5505  previous_declaration = klass;
5506  else if (!klass->get_is_declaration_only()
5507  && !previous_definition)
5508  previous_definition = klass;
5509  if (previous_definition && previous_declaration)
5510  break;
5511  }
5512 
5513  if (previous_declaration)
5514  ABG_ASSERT(previous_declaration->get_name() == name);
5515 
5516  if (previous_definition)
5517  ABG_ASSERT(previous_definition->get_name() == name);
5518 
5519  if (is_decl_only && previous_declaration)
5520  return previous_declaration;
5521  }
5522 
5523  const environment& env = rdr.get_environment();
5524 
5525  if (!is_decl_only && previous_definition)
5526  // We are in the case where we've read this class definition
5527  // before, but we might need to update it to add some new stuff to
5528  // it; we might thus find the new stuff to add in the current
5529  // (new) incarnation of that definition that we are currently
5530  // reading.
5531  decl = previous_definition;
5532  else
5533  {
5534  if (is_decl_only)
5535  {
5536  decl.reset(new class_decl(env, name, is_struct));
5537  if (size_in_bits)
5538  decl->set_size_in_bits(size_in_bits);
5539  if (is_anonymous)
5540  decl->set_is_anonymous(is_anonymous);
5541  decl->set_location(loc);
5542  }
5543  else
5544  decl.reset(new class_decl(env, name, size_in_bits, alignment_in_bits,
5545  is_struct, loc, vis, bases, mbrs,
5546  data_mbrs, mbr_functions, is_anonymous));
5547  }
5548 
5549  maybe_set_artificial_location(rdr, node, decl);
5550  decl->set_is_artificial(is_artificial);
5551 
5552  // Read the stash from the XML node and stash it into the IR node.
5553  rdr.read_hash_and_stash(node, decl);
5554 
5555  string def_id;
5556  bool is_def_of_decl = false;
5557  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "def-of-decl-id"))
5558  def_id = CHAR_STR(s);
5559 
5560  if (!def_id.empty())
5561  {
5562  decl_base_sptr d = is_decl(rdr.get_type_decl(def_id));
5563  if (d && d->get_is_declaration_only())
5564  {
5565  is_def_of_decl = true;
5566  decl->set_earlier_declaration(d);
5567  d->set_definition_of_declaration(decl);
5568  }
5569  }
5570 
5571  if (!is_decl_only
5572  && decl
5573  && !decl->get_is_declaration_only()
5574  && previous_declaration)
5575  {
5576  // decl is the definition of the previous declaration
5577  // previous_declaration.
5578  //
5579  // Let's link them.
5580  decl->set_earlier_declaration(is_decl(previous_declaration));
5581  for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5582  i != types_ptr->end();
5583  ++i)
5584  {
5586  ABG_ASSERT(d);
5587  if (d->get_is_declaration_only()
5588  && !d->get_definition_of_declaration())
5589  {
5590  previous_declaration->set_definition_of_declaration(decl);
5591  is_def_of_decl = true;
5592  }
5593  }
5594  }
5595 
5596  if (is_decl_only && previous_definition)
5597  {
5598  // decl is a declaration of the previous definition
5599  // previous_definition. Let's link them.
5600  ABG_ASSERT(decl->get_is_declaration_only()
5601  && !decl->get_definition_of_declaration());
5602  decl->set_definition_of_declaration(previous_definition);
5603  }
5604 
5605  ABG_ASSERT(!is_decl_only || !is_def_of_decl);
5606 
5607  rdr.push_decl_to_scope(decl,
5608  add_to_current_scope
5609  ? rdr.get_scope_ptr_for_node(node)
5610  : nullptr);
5611 
5612  rdr.map_xml_node_to_decl(node, decl);
5613  rdr.key_type_decl(decl, id);
5614 
5615  // If this class has a naming typedef, get it and refer to it.
5616  maybe_set_naming_typedef(rdr, node, decl);
5617 
5618  for (xmlNodePtr n = xmlFirstElementChild(node);
5619  n;
5620  n = xmlNextElementSibling(n))
5621  {
5622  if (xmlStrEqual(n->name, BAD_CAST("base-class")))
5623  {
5624  access_specifier access =
5625  is_struct
5626  ? public_access
5627  : private_access;
5628  read_access(n, access);
5629 
5630  string type_id;
5631  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(n, "type-id"))
5632  type_id = CHAR_STR(s);
5633  shared_ptr<class_decl> b =
5634  dynamic_pointer_cast<class_decl>
5635  (rdr.build_or_get_type_decl(type_id, true));
5636  ABG_ASSERT(b);
5637 
5638  if (decl->find_base_class(b->get_qualified_name()))
5639  // We are in updating mode for this class. The version of
5640  // the class we have already has this base class, so we
5641  // are not going to add it again.
5642  continue;
5643 
5644  size_t offset_in_bits = 0;
5645  bool offset_present = read_offset_in_bits (n, offset_in_bits);
5646 
5647  bool is_virtual = false;
5648  read_is_virtual (n, is_virtual);
5649 
5650  shared_ptr<class_decl::base_spec> base (new class_decl::base_spec
5651  (b, access,
5652  offset_present
5653  ? (long) offset_in_bits
5654  : -1,
5655  is_virtual));
5656  decl->add_base_specifier(base);
5657  }
5658  else if (xmlStrEqual(n->name, BAD_CAST("member-type")))
5659  {
5660  access_specifier access =
5661  is_struct
5662  ? public_access
5663  : private_access;
5664  read_access(n, access);
5665 
5666  rdr.map_xml_node_to_decl(n, decl);
5667 
5668  for (xmlNodePtr p = xmlFirstElementChild(n);
5669  p;
5670  p = xmlNextElementSibling(p))
5671  {
5672 
5673  string member_type_name;
5674  read_name(p, member_type_name);
5675  type_base_sptr t;
5676  if (!member_type_name.empty())
5677  t = decl->find_member_type(member_type_name);
5678  if (t)
5679  continue;
5680 
5681  if ((t = build_type(rdr, p, /*add_to_current_scope=*/true)))
5682  {
5683  decl_base_sptr td = get_type_declaration(t);
5684  ABG_ASSERT(td);
5685  if (!td->get_scope())
5686  decl->add_member_type(t);
5687  set_member_access_specifier(td, access);
5688  rdr.schedule_type_for_canonicalization(t);
5690  string id = CHAR_STR(i);
5691  ABG_ASSERT(!id.empty());
5692  rdr.key_type_decl(t, id);
5693  rdr.map_xml_node_to_decl(p, td);
5694  }
5695  }
5696  }
5697  else if (xmlStrEqual(n->name, BAD_CAST("data-member")))
5698  {
5699  rdr.map_xml_node_to_decl(n, decl);
5700 
5701  access_specifier access =
5702  is_struct
5703  ? public_access
5704  : private_access;
5705  read_access(n, access);
5706 
5707  bool is_laid_out = false;
5708  size_t offset_in_bits = 0;
5709  if (read_offset_in_bits(n, offset_in_bits))
5710  is_laid_out = true;
5711 
5712  bool is_static = false;
5713  read_static(n, is_static);
5714 
5715  for (xmlNodePtr p = xmlFirstElementChild(n);
5716  p;
5717  p = xmlNextElementSibling(p))
5718  {
5719  if (var_decl_sptr v =
5720  build_var_decl(rdr, p, /*add_to_cur_scope=*/false))
5721  {
5722  if (decl->find_data_member(v))
5723  {
5724  // We are in updating mode and the current
5725  // version of this class already has this data
5726  // member, so we are not going to add it again.
5727  // So we need to discard the data member we have
5728  // built (and that was pushed to the current
5729  // stack of decls built) and move on.
5730  decl_base_sptr d = rdr.pop_decl();
5731  ABG_ASSERT(is_var_decl(d));
5732  continue;
5733  }
5734 
5735  if (!variable_is_suppressed(rdr, decl.get(), *v))
5736  {
5737  decl->add_data_member(v, access,
5738  is_laid_out,
5739  is_static,
5740  offset_in_bits);
5741  if (is_static)
5742  rdr.add_var_to_exported_or_undefined_decls(v);
5743  // Now let's record the fact that the data
5744  // member uses its type and that the class being
5745  // built uses the data member.
5746  if (is_anonymous_data_member(v))
5747  // This data member is anonymous so recording
5748  // that it uses its type is useless because we
5749  // can't name it. Rather, let's record that
5750  // the class being built uses the type of the
5751  // (anonymous) data member.
5752  RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5753  else
5754  {
5755  RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5756  RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5757  }
5758  }
5759  }
5760  }
5761  }
5762  else if (xmlStrEqual(n->name, BAD_CAST("member-function")))
5763  {
5764  access_specifier access =
5765  is_struct
5766  ? public_access
5767  : private_access;
5768  read_access(n, access);
5769 
5770  bool is_virtual = false;
5771  ssize_t vtable_offset = -1;
5772  if (xml_char_sptr s =
5773  XML_NODE_GET_ATTRIBUTE(n, "vtable-offset"))
5774  {
5775  is_virtual = true;
5776  vtable_offset = atoi(CHAR_STR(s));
5777  }
5778 
5779  bool is_static = false;
5780  read_static(n, is_static);
5781 
5782  bool is_ctor = false, is_dtor = false, is_const = false;
5783  read_cdtor_const(n, is_ctor, is_dtor, is_const);
5784 
5785  for (xmlNodePtr p = xmlFirstElementChild(n);
5786  p;
5787  p = xmlNextElementSibling(p))
5788  {
5789  if (function_decl_sptr f =
5790  build_function_decl_if_not_suppressed(rdr, p, decl,
5791  /*add_to_cur_sc=*/true,
5792  /*add_to_exported_decls=*/false))
5793  {
5794  method_decl_sptr m = is_method_decl(f);
5795  ABG_ASSERT(m);
5796  set_member_access_specifier(m, access);
5797  set_member_is_static(m, is_static);
5798  if (is_virtual)
5799  set_member_function_virtuality(m, is_virtual, vtable_offset);
5800  set_member_function_is_ctor(m, is_ctor);
5801  set_member_function_is_dtor(m, is_dtor);
5802  set_member_function_is_const(m, is_const);
5803  rdr.map_xml_node_to_decl(p, m);
5804  rdr.add_fn_to_exported_or_undefined_decls(f.get());
5805  break;
5806  }
5807  }
5808  }
5809  else if (xmlStrEqual(n->name, BAD_CAST("member-template")))
5810  {
5811  rdr.map_xml_node_to_decl(n, decl);
5812 
5813  access_specifier access =
5814  is_struct
5815  ? public_access
5816  : private_access;
5817  read_access(n, access);
5818 
5819  bool is_static = false;
5820  read_static(n, is_static);
5821 
5822  bool is_ctor = false, is_dtor = false, is_const = false;
5823  read_cdtor_const(n, is_ctor, is_dtor, is_const);
5824 
5825  for (xmlNodePtr p = xmlFirstElementChild(n);
5826  p;
5827  p = xmlNextElementSibling(p))
5828  {
5829  if (shared_ptr<function_tdecl> f =
5830  build_function_tdecl(rdr, p,
5831  /*add_to_current_scope=*/true))
5832  {
5833  shared_ptr<member_function_template> m
5834  (new member_function_template(f, access, is_static,
5835  is_ctor, is_const));
5836  ABG_ASSERT(f->get_scope());
5837  decl->add_member_function_template(m);
5838  }
5839  else if (shared_ptr<class_tdecl> c =
5840  build_class_tdecl(rdr, p,
5841  /*add_to_current_scope=*/true))
5842  {
5843  member_class_template_sptr m(new member_class_template(c,
5844  access,
5845  is_static));
5846  ABG_ASSERT(c->get_scope());
5847  decl->add_member_class_template(m);
5848  }
5849  }
5850  }
5851  }
5852 
5853  rdr.pop_scope_or_abort(decl);
5854 
5855  return decl;
5856 }
5857 
5858 /// Build a union_decl from a 'union-decl' xml node.
5859 ///
5860 /// @param rdr the context of the parsing.
5861 ///
5862 /// @param node the xml node to build the union_decl from.
5863 ///
5864 /// @param add_to_current_scope if yes, the resulting union node
5865 /// hasn't triggered voluntarily the adding of the resulting
5866 /// union_decl_sptr to the current scope.
5867 ///
5868 /// @return a pointer to union_decl upon successful completion, a null
5869 /// pointer otherwise.
5870 static union_decl_sptr
5871 build_union_decl(reader& rdr,
5872  const xmlNodePtr node,
5873  bool add_to_current_scope)
5874 {
5875  union_decl_sptr nil;
5876 
5877  if (!xmlStrEqual(node->name, BAD_CAST("union-decl")))
5878  return nil;
5879 
5880  if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5881  {
5882  union_decl_sptr result = dynamic_pointer_cast<union_decl>(d);
5883  ABG_ASSERT(result);
5884  return result;
5885  }
5886 
5887  string name;
5888  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
5889  name = xml::unescape_xml_string(CHAR_STR(s));
5890 
5891  size_t size_in_bits = 0, alignment_in_bits = 0;
5892  read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5893 
5894  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
5895  read_visibility(node, vis);
5896 
5897  bool is_artificial = false;
5898  read_is_artificial(node, is_artificial);
5899 
5900  string id;
5901  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
5902  id = CHAR_STR(s);
5903 
5904  location loc;
5905  read_location(rdr, node, loc);
5906 
5908  union_decl::data_members data_mbrs;
5909  union_decl::member_functions mbr_functions;
5910 
5911  union_decl_sptr decl;
5912 
5913  bool is_decl_only = false;
5914  read_is_declaration_only(node, is_decl_only);
5915 
5916  bool is_anonymous = false;
5917  read_is_anonymous(node, is_anonymous);
5918 
5919  ABG_ASSERT(!id.empty());
5920  union_decl_sptr previous_definition, previous_declaration;
5921  const vector<type_base_sptr> *types_ptr = 0;
5922  if (!is_anonymous)
5923  types_ptr = rdr.get_all_type_decls(id);
5924  if (types_ptr)
5925  {
5926  // Lets look at the previous declarations and the first previous
5927  // definition of this type that we've already seen while parsing
5928  // this corpus.
5929  for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5930  i != types_ptr->end();
5931  ++i)
5932  {
5933  union_decl_sptr onion = is_union_type(*i);
5934  ABG_ASSERT(onion);
5935  if (onion->get_is_declaration_only()
5936  && !onion->get_definition_of_declaration())
5937  previous_declaration = onion;
5938  else if (!onion->get_is_declaration_only()
5939  && !previous_definition)
5940  previous_definition = onion;
5941  if (previous_definition && previous_declaration)
5942  break;
5943  }
5944 
5945  if (previous_declaration)
5946  ABG_ASSERT(previous_declaration->get_name() == name);
5947 
5948  if (previous_definition)
5949  ABG_ASSERT(previous_definition->get_name() == name);
5950 
5951  if (is_decl_only && previous_declaration)
5952  return previous_declaration;
5953  }
5954 
5955  const environment& env = rdr.get_environment();
5956 
5957  if (!is_decl_only && previous_definition)
5958  // We are in the case where we've read this class definition
5959  // before, but we might need to update it to add some new stuff to
5960  // it; we might thus find the new stuff to add in the current
5961  // (new) incarnation of that definition that we are currently
5962  // reading.
5963  decl = previous_definition;
5964  else
5965  {
5966  if (is_decl_only)
5967  decl.reset(new union_decl(env, name));
5968  else
5969  decl.reset(new union_decl(env, name,
5970  size_in_bits,
5971  loc, vis, mbrs,
5972  data_mbrs,
5973  mbr_functions,
5974  is_anonymous));
5975  }
5976 
5977  // Read the stash from the XML node and stash it into the IR node.
5978  rdr.read_hash_and_stash(node, decl);
5979 
5980  maybe_set_artificial_location(rdr, node, decl);
5981  decl->set_is_artificial(is_artificial);
5982 
5983  string def_id;
5984  bool is_def_of_decl = false;
5985  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "def-of-decl-id"))
5986  def_id = CHAR_STR(s);
5987 
5988  if (!def_id.empty())
5989  {
5990  class_decl_sptr d =
5991  dynamic_pointer_cast<class_decl>(rdr.get_type_decl(def_id));
5992  if (d && d->get_is_declaration_only())
5993  {
5994  is_def_of_decl = true;
5995  decl->set_earlier_declaration(d);
5996  d->set_definition_of_declaration(decl);
5997  }
5998  }
5999 
6000  if (!is_decl_only
6001  && decl
6002  && !decl->get_is_declaration_only()
6003  && previous_declaration)
6004  {
6005  // decl is the definition of the previous declaration
6006  // previous_declaration.
6007  //
6008  // Let's link them.
6009  decl->set_earlier_declaration(previous_declaration);
6010  for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
6011  i != types_ptr->end();
6012  ++i)
6013  {
6014  union_decl_sptr d = is_union_type(*i);
6015  ABG_ASSERT(d);
6016  if (d->get_is_declaration_only()
6017  && !d->get_definition_of_declaration())
6018  {
6019  previous_declaration->set_definition_of_declaration(decl);
6020  is_def_of_decl = true;
6021  }
6022  }
6023  }
6024 
6025  if (is_decl_only && previous_definition)
6026  {
6027  // decl is a declaration of the previous definition
6028  // previous_definition. Let's link them.
6029  ABG_ASSERT(decl->get_is_declaration_only()
6030  && !decl->get_definition_of_declaration());
6031  decl->set_definition_of_declaration(previous_definition);
6032  }
6033 
6034  ABG_ASSERT(!is_decl_only || !is_def_of_decl);
6035 
6036  rdr.push_decl_to_scope(decl,
6037  add_to_current_scope
6038  ? rdr.get_scope_ptr_for_node(node)
6039  : nullptr);
6040 
6041  rdr.map_xml_node_to_decl(node, decl);
6042  rdr.key_type_decl(decl, id);
6043 
6044  maybe_set_naming_typedef(rdr, node, decl);
6045 
6046  for (xmlNodePtr n = xmlFirstElementChild(node);
6047  !is_decl_only && n;
6048  n = xmlNextElementSibling(n))
6049  {
6050  if (xmlStrEqual(n->name, BAD_CAST("member-type")))
6051  {
6052  access_specifier access = private_access;
6053  read_access(n, access);
6054 
6055  rdr.map_xml_node_to_decl(n, decl);
6056 
6057  for (xmlNodePtr p = xmlFirstElementChild(n);
6058  p;
6059  p = xmlNextElementSibling(p))
6060  {
6061  string member_type_name;
6062  read_name(p, member_type_name);
6063  type_base_sptr t;
6064  if (!member_type_name.empty())
6065  t = decl->find_member_type(member_type_name);
6066  if (t)
6067  continue;
6068  if ((t = build_type(rdr, p, /*add_to_current_scope=*/true)))
6069  {
6070  decl_base_sptr td = get_type_declaration(t);
6071  ABG_ASSERT(td);
6072  if (!td->get_scope())
6073  decl->add_member_type(t);
6074  set_member_access_specifier(td, access);
6075  rdr.schedule_type_for_canonicalization(t);
6076 
6078  string id = CHAR_STR(i);
6079  ABG_ASSERT(!id.empty());
6080  rdr.key_type_decl(t, id);
6081  rdr.map_xml_node_to_decl(p, td);
6082  }
6083  }
6084  }
6085  else if (xmlStrEqual(n->name, BAD_CAST("data-member")))
6086  {
6087  rdr.map_xml_node_to_decl(n, decl);
6088 
6089  access_specifier access = private_access;
6090  read_access(n, access);
6091 
6092  bool is_laid_out = true;
6093  size_t offset_in_bits = 0;
6094  bool is_static = false;
6095  read_static(n, is_static);
6096 
6097  for (xmlNodePtr p = xmlFirstElementChild(n);
6098  p;
6099  p = xmlNextElementSibling(p))
6100  {
6101  if (var_decl_sptr v =
6102  build_var_decl(rdr, p, /*add_to_cur_scope=*/false))
6103  {
6104  if (decl->find_data_member(v))
6105  {
6106  // We are in updating mode and the current
6107  // version of this class already has this data
6108  // member, so we are not going to add it again.
6109  // So we need to discard the data member we have
6110  // built (and that was pushed to the current
6111  // stack of decls built) and move on.
6112  decl_base_sptr d = rdr.pop_decl();
6113  ABG_ASSERT(is_var_decl(d));
6114  continue;
6115  }
6116  if (!is_static
6117  || !variable_is_suppressed(rdr, decl.get(), *v))
6118  {
6119  decl->add_data_member(v, access,
6120  is_laid_out,
6121  is_static,
6122  offset_in_bits);
6123  // Now let's record the fact that the data
6124  // member uses its type and that the union being
6125  // built uses the data member.
6126  if (is_anonymous_data_member(v))
6127  // This data member is anonymous so recording
6128  // that it uses its type is useless because we
6129  // can't name it. Rather, let's record that
6130  // the class being built uses the type of the
6131  // (anonymous) data member.
6132  RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
6133  else
6134  {
6135  RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
6136  RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
6137  }
6138  }
6139  }
6140  }
6141  }
6142  else if (xmlStrEqual(n->name, BAD_CAST("member-function")))
6143  {
6144  rdr.map_xml_node_to_decl(n, decl);
6145 
6146  access_specifier access = private_access;
6147  read_access(n, access);
6148 
6149  bool is_static = false;
6150  read_static(n, is_static);
6151 
6152  bool is_ctor = false, is_dtor = false, is_const = false;
6153  read_cdtor_const(n, is_ctor, is_dtor, is_const);
6154 
6155  for (xmlNodePtr p = xmlFirstElementChild(n);
6156  p;
6157  p = xmlNextElementSibling(p))
6158  {
6159  if (function_decl_sptr f =
6160  build_function_decl_if_not_suppressed(rdr, p, decl,
6161  /*add_to_cur_sc=*/true,
6162  /*add_to_exported_decls=*/false))
6163  {
6164  method_decl_sptr m = is_method_decl(f);
6165  ABG_ASSERT(m);
6166  set_member_access_specifier(m, access);
6167  set_member_is_static(m, is_static);
6168  set_member_function_is_ctor(m, is_ctor);
6169  set_member_function_is_dtor(m, is_dtor);
6170  set_member_function_is_const(m, is_const);
6171  rdr.add_fn_to_exported_or_undefined_decls(f.get());
6172  break;
6173  }
6174  }
6175  }
6176  else if (xmlStrEqual(n->name, BAD_CAST("member-template")))
6177  {
6178  rdr.map_xml_node_to_decl(n, decl);
6179 
6180  access_specifier access = private_access;
6181  read_access(n, access);
6182 
6183  bool is_static = false;
6184  read_static(n, is_static);
6185 
6186  bool is_ctor = false, is_dtor = false, is_const = false;
6187  read_cdtor_const(n, is_ctor, is_dtor, is_const);
6188 
6189  for (xmlNodePtr p = xmlFirstElementChild(n);
6190  p;
6191  p = xmlNextElementSibling(p))
6192  {
6193  if (function_tdecl_sptr f =
6194  build_function_tdecl(rdr, p,
6195  /*add_to_current_scope=*/true))
6196  {
6197  member_function_template_sptr m
6198  (new member_function_template(f, access, is_static,
6199  is_ctor, is_const));
6200  ABG_ASSERT(f->get_scope());
6201  decl->add_member_function_template(m);
6202  }
6203  else if (class_tdecl_sptr c =
6204  build_class_tdecl(rdr, p,
6205  /*add_to_current_scope=*/true))
6206  {
6207  member_class_template_sptr m(new member_class_template(c,
6208  access,
6209  is_static));
6210  ABG_ASSERT(c->get_scope());
6211  decl->add_member_class_template(m);
6212  }
6213  }
6214  }
6215  }
6216 
6217  rdr.pop_scope_or_abort(decl);
6218 
6219  return decl;
6220 }
6221 
6222 /// Build an intance of function_tdecl, from an
6223 /// 'function-template-decl' xml element node.
6224 ///
6225 /// @param rdr the context of the parsing.
6226 ///
6227 /// @param node the xml node to parse from.
6228 ///
6229 /// @param add_to_current_scope if set to yes, the resulting of
6230 /// this function is added to its current scope.
6231 ///
6232 /// @return the newly built function_tdecl upon successful
6233 /// completion, a null pointer otherwise.
6234 static shared_ptr<function_tdecl>
6235 build_function_tdecl(reader& rdr,
6236  const xmlNodePtr node,
6237  bool add_to_current_scope)
6238 {
6239  shared_ptr<function_tdecl> nil, result;
6240 
6241  if (!xmlStrEqual(node->name, BAD_CAST("function-template-decl")))
6242  return nil;
6243 
6244  string id;
6245  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
6246  id = CHAR_STR(s);
6247  if (id.empty() || rdr.get_fn_tmpl_decl(id))
6248  return nil;
6249 
6250  location loc;
6251  read_location(rdr, node, loc);
6252 
6253  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
6254  read_visibility(node, vis);
6255 
6256  decl_base::binding bind = decl_base::BINDING_NONE;
6257  read_binding(node, bind);
6258 
6259  const environment& env = rdr.get_environment();
6260 
6261  function_tdecl_sptr fn_tmpl_decl(new function_tdecl(env, loc, vis, bind));
6262  maybe_set_artificial_location(rdr, node, fn_tmpl_decl);
6263 
6264  rdr.push_decl_to_scope(fn_tmpl_decl,
6265  add_to_current_scope
6266  ? rdr.get_scope_ptr_for_node(node)
6267  : nullptr);
6268  rdr.key_fn_tmpl_decl(fn_tmpl_decl, id);
6269  rdr.map_xml_node_to_decl(node, fn_tmpl_decl);
6270 
6271  unsigned parm_index = 0;
6272  for (xmlNodePtr n = xmlFirstElementChild(node);
6273  n;
6274  n = xmlNextElementSibling(n))
6275  {
6276  if (template_parameter_sptr parm =
6277  build_template_parameter(rdr, n, parm_index, fn_tmpl_decl))
6278  {
6279  fn_tmpl_decl->add_template_parameter(parm);
6280  ++parm_index;
6281  }
6282  else if (function_decl_sptr f =
6283  build_function_decl_if_not_suppressed(rdr, n, class_decl_sptr(),
6284  /*add_to_current_scope=*/true,
6285  /*add_to_exported_decls=*/true))
6286  fn_tmpl_decl->set_pattern(f);
6287  }
6288 
6289  rdr.key_fn_tmpl_decl(fn_tmpl_decl, id);
6290 
6291  return fn_tmpl_decl;
6292 }
6293 
6294 /// Build an intance of class_tdecl, from a
6295 /// 'class-template-decl' xml element node.
6296 ///
6297 /// @param rdr the context of the parsing.
6298 ///
6299 /// @param node the xml node to parse from.
6300 ///
6301 /// @param add_to_current_scope if set to yes, the resulting of this
6302 /// function is added to its current scope.
6303 ///
6304 /// @return the newly built function_tdecl upon successful
6305 /// completion, a null pointer otherwise.
6306 static class_tdecl_sptr
6307 build_class_tdecl(reader& rdr,
6308  const xmlNodePtr node,
6309  bool add_to_current_scope)
6310 {
6311  class_tdecl_sptr nil, result;
6312 
6313  if (!xmlStrEqual(node->name, BAD_CAST("class-template-decl")))
6314  return nil;
6315 
6316  string id;
6317  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
6318  id = CHAR_STR(s);
6319  if (id.empty() || rdr.get_class_tmpl_decl(id))
6320  return nil;
6321 
6322  location loc;
6323  read_location(rdr, node, loc);
6324 
6325  decl_base::visibility vis = decl_base::VISIBILITY_NONE;
6326  read_visibility(node, vis);
6327 
6328  const environment& env = rdr.get_environment();
6329 
6330  class_tdecl_sptr class_tmpl (new class_tdecl(env, loc, vis));
6331  maybe_set_artificial_location(rdr, node, class_tmpl);
6332 
6333  if (add_to_current_scope)
6334  rdr.push_decl_to_scope(class_tmpl, node);
6335  rdr.key_class_tmpl_decl(class_tmpl, id);
6336  rdr.map_xml_node_to_decl(node, class_tmpl);
6337 
6338  unsigned parm_index = 0;
6339  for (xmlNodePtr n = xmlFirstElementChild(node);
6340  n;
6341  n = xmlNextElementSibling(n))
6342  {
6343  if (template_parameter_sptr parm=
6344  build_template_parameter(rdr, n, parm_index, class_tmpl))
6345  {
6346  class_tmpl->add_template_parameter(parm);
6347  ++parm_index;
6348  }
6349  else if (class_decl_sptr c =
6350  build_class_decl_if_not_suppressed(rdr, n,
6351  add_to_current_scope))
6352  {
6353  if (c->get_scope())
6354  rdr.schedule_type_for_canonicalization(c);
6355  class_tmpl->set_pattern(c);
6356  }
6357  }
6358 
6359  rdr.key_class_tmpl_decl(class_tmpl, id);
6360 
6361  return class_tmpl;
6362 }
6363 
6364 /// Build a type_tparameter from a 'template-type-parameter'
6365 /// xml element node.
6366 ///
6367 /// @param rdr the context of the parsing.
6368 ///
6369 /// @param node the xml node to parse from.
6370 ///
6371 /// @param index the index (occurrence index, starting from 0) of the
6372 /// template parameter.
6373 ///
6374 /// @param tdecl the enclosing template declaration that holds the
6375 /// template type parameter.
6376 ///
6377 /// @return a pointer to a newly created instance of
6378 /// type_tparameter, a null pointer otherwise.
6379 static type_tparameter_sptr
6380 build_type_tparameter(reader& rdr,
6381  const xmlNodePtr node,
6382  unsigned index,
6383  template_decl_sptr tdecl)
6384 {
6385  type_tparameter_sptr nil, result;
6386 
6387  if (!xmlStrEqual(node->name, BAD_CAST("template-type-parameter")))
6388  return nil;
6389 
6390  string id;
6391  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
6392  id = CHAR_STR(s);
6393  if (!id.empty())
6394  ABG_ASSERT(!rdr.get_type_decl(id));
6395 
6396  string type_id;
6397  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
6398  type_id = CHAR_STR(s);
6399  if (!type_id.empty()
6400  && !(result = dynamic_pointer_cast<type_tparameter>
6401  (rdr.build_or_get_type_decl(type_id, true))))
6402  abort();
6403 
6404  string name;
6405  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
6406  name = xml::unescape_xml_string(CHAR_STR(s));
6407 
6408  location loc;
6409  read_location(rdr, node,loc);
6410 
6411  result.reset(new type_tparameter(index, tdecl, name, loc));
6412  maybe_set_artificial_location(rdr, node, result);
6413 
6414  if (id.empty())
6415  rdr.push_decl_to_scope(is_decl(result), node);
6416  else
6417  rdr.push_and_key_type_decl(result, node, /*add_to_current_scope=*/true);
6418 
6419  rdr.schedule_type_for_canonicalization(result);
6420 
6421  return result;
6422 }
6423 
6424 /// Build a tmpl_parm_type_composition from a
6425 /// "template-parameter-type-composition" xml element node.
6426 ///
6427 /// @param rdr the context of the parsing.
6428 ///
6429 /// @param node the xml node to parse from.
6430 ///
6431 /// @param index the index of the previous normal template parameter.
6432 ///
6433 /// @param tdecl the enclosing template declaration that holds this
6434 /// template parameter type composition.
6435 ///
6436 /// @return a pointer to a new instance of tmpl_parm_type_composition
6437 /// upon successful completion, a null pointer otherwise.
6438 static type_composition_sptr
6439 build_type_composition(reader& rdr,
6440  const xmlNodePtr node,
6441  unsigned index,
6442  template_decl_sptr tdecl)
6443 {
6444  type_composition_sptr nil, result;
6445 
6446  if (!xmlStrEqual(node->name, BAD_CAST("template-parameter-type-composition")))
6447  return nil;
6448 
6449  type_base_sptr composed_type;
6450  result.reset(new type_composition(index, tdecl, composed_type));
6451  rdr.push_decl_to_scope(is_decl(result), node);
6452 
6453  for (xmlNodePtr n = xmlFirstElementChild(node);
6454  n;
6455  n = xmlNextElementSibling(n))
6456  {
6457  if ((composed_type =
6458  build_pointer_type_def(rdr, n,
6459  /*add_to_current_scope=*/true))
6460  ||(composed_type =
6461  build_reference_type_def(rdr, n,
6462  /*add_to_current_scope=*/true))
6463  ||(composed_type =
6464  build_array_type_def(rdr, n,
6465  /*add_to_current_scope=*/true))
6466  || (composed_type =
6467  build_qualified_type_decl(rdr, n,
6468  /*add_to_current_scope=*/true)))
6469  {
6470  rdr.schedule_type_for_canonicalization(composed_type);
6471  result->set_composed_type(composed_type);
6472  break;
6473  }
6474  }
6475 
6476  return result;
6477 }
6478 
6479 /// Build an instance of non_type_tparameter from a
6480 /// 'template-non-type-parameter' xml element node.
6481 ///
6482 /// @param rdr the context of the parsing.
6483 ///
6484 /// @param node the xml node to parse from.
6485 ///
6486 /// @param index the index of the parameter.
6487 ///
6488 /// @param tdecl the enclosing template declaration that holds this
6489 /// non type template parameter.
6490 ///
6491 /// @return a pointer to a newly created instance of
6492 /// non_type_tparameter upon successful completion, a null
6493 /// pointer code otherwise.
6495 build_non_type_tparameter(reader& rdr,
6496  const xmlNodePtr node,
6497  unsigned index,
6498  template_decl_sptr tdecl)
6499 {
6501 
6502  if (!xmlStrEqual(node->name, BAD_CAST("template-non-type-parameter")))
6503  return r;
6504 
6505  string type_id;
6506  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
6507  type_id = CHAR_STR(s);
6508  type_base_sptr type;
6509  if (type_id.empty()
6510  || !(type = rdr.build_or_get_type_decl(type_id, true)))
6511  abort();
6512 
6513  string name;
6514  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
6515  name = xml::unescape_xml_string(CHAR_STR(s));
6516 
6517  location loc;
6518  read_location(rdr, node,loc);
6519 
6520  r.reset(new non_type_tparameter(index, tdecl, name, type, loc));
6521  maybe_set_artificial_location(rdr, node, r);
6522  rdr.push_decl_to_scope(is_decl(r), node);
6523 
6524  return r;
6525 }
6526 
6527 /// Build an intance of template_tparameter from a
6528 /// 'template-template-parameter' xml element node.
6529 ///
6530 /// @param rdr the context of the parsing.
6531 ///
6532 /// @param node the xml node to parse from.
6533 ///
6534 /// @param index the index of the template parameter.
6535 ///
6536 /// @param tdecl the enclosing template declaration that holds this
6537 /// template template parameter.
6538 ///
6539 /// @return a pointer to a new instance of template_tparameter
6540 /// upon successful completion, a null pointer otherwise.
6542 build_template_tparameter(reader& rdr,
6543  const xmlNodePtr node,
6544  unsigned index,
6545  template_decl_sptr tdecl)
6546 {
6548 
6549  if (!xmlStrEqual(node->name, BAD_CAST("template-template-parameter")))
6550  return nil;
6551 
6552  string id;
6553  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "id"))
6554  id = CHAR_STR(s);
6555  // Bail out if a type with the same ID already exists.
6556  ABG_ASSERT(!id.empty());
6557 
6558  string type_id;
6559  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "type-id"))
6560  type_id = CHAR_STR(s);
6561  // Bail out if no type with this ID exists.
6562  if (!type_id.empty()
6563  && !(dynamic_pointer_cast<template_tparameter>
6564  (rdr.build_or_get_type_decl(type_id, true))))
6565  abort();
6566 
6567  string name;
6568  if (xml_char_sptr s = XML_NODE_GET_ATTRIBUTE(node, "name"))
6569  name = xml::unescape_xml_string(CHAR_STR(s));
6570 
6571  location loc;
6572  read_location(rdr, node, loc);
6573 
6574  template_tparameter_sptr result(new template_tparameter(index, tdecl,
6575  name, loc));
6576  maybe_set_artificial_location(rdr, node, result);
6577  rdr.push_decl_to_scope(result, node);
6578 
6579  // Go parse template parameters that are children nodes
6580  int parm_index = 0;
6581  for (xmlNodePtr n = xmlFirstElementChild(node);
6582  n;
6583  n = xmlNextElementSibling(n))
6584  if (shared_ptr<template_parameter> p =
6585  build_template_parameter(rdr, n, parm_index, result))
6586  {
6587  result->add_template_parameter(p);
6588  ++parm_index;
6589  }
6590 
6591  if (result)
6592  {
6593  rdr.key_type_decl(result, id);
6594  rdr.schedule_type_for_canonicalization(result);
6595  }
6596 
6597  return result;
6598 }
6599 
6600 /// Build a template parameter type from several possible xml elment
6601 /// nodes representing a serialized form a template parameter.
6602 ///
6603 /// @param rdr the context of the parsing.
6604 ///
6605 /// @param node the xml element node to parse from.
6606 ///
6607 /// @param index the index of the template parameter we are parsing.
6608 ///
6609 /// @param tdecl the enclosing template declaration that holds this
6610 /// template parameter.
6611 ///
6612 /// @return a pointer to a newly created instance of
6613 /// template_parameter upon successful completion, a null pointer
6614 /// otherwise.
6616 build_template_parameter(reader& rdr,
6617  const xmlNodePtr node,
6618  unsigned index,
6619  template_decl_sptr tdecl)
6620 {
6621  shared_ptr<template_parameter> r;
6622  ((r = build_type_tparameter(rdr, node, index, tdecl))
6623  || (r = build_non_type_tparameter(rdr, node, index, tdecl))
6624  || (r = build_template_tparameter(rdr, node, index, tdecl))
6625  || (r = build_type_composition(rdr, node, index, tdecl)));
6626 
6627  return r;
6628 }
6629 
6630 /// Build a type from an xml node.
6631 ///
6632 /// @param rdr the context of the parsing.
6633 ///
6634 /// @param node the xml node to build the type_base from.
6635 ///
6636 /// @return a pointer to the newly built type_base upon successful
6637 /// completion, a null pointer otherwise.
6638 static type_base_sptr
6639 build_type(reader& rdr,
6640  const xmlNodePtr node,
6641  bool add_to_current_scope)
6642 {
6643  type_base_sptr t;
6644 
6645  ((t = build_type_decl(rdr, node, add_to_current_scope))
6646  || (t = build_qualified_type_decl(rdr, node, add_to_current_scope))
6647  || (t = build_pointer_type_def(rdr, node, add_to_current_scope))
6648  || (t = build_reference_type_def(rdr, node , add_to_current_scope))
6649  || (t = build_ptr_to_mbr_type(rdr, node , add_to_current_scope))
6650  || (t = build_function_type(rdr, node, add_to_current_scope))
6651  || (t = build_array_type_def(rdr, node, add_to_current_scope))
6652  || (t = build_subrange_type(rdr, node, add_to_current_scope))
6653  || (t = build_enum_type_decl_if_not_suppressed(rdr, node,
6654  add_to_current_scope))
6655  || (t = build_typedef_decl(rdr, node, add_to_current_scope))
6656  || (t = build_class_decl_if_not_suppressed(rdr, node,
6657  add_to_current_scope))
6658  || (t = build_union_decl_if_not_suppressed(rdr, node,
6659  add_to_current_scope)));
6660 
6661  if (rdr.tracking_non_reachable_types() && t)
6662  {
6663  corpus_sptr abi = rdr.corpus();
6664  ABG_ASSERT(abi);
6665  bool is_non_reachable_type = false;
6666  read_is_non_reachable_type(node, is_non_reachable_type);
6667  if (!is_non_reachable_type)
6668  abi->record_type_as_reachable_from_public_interfaces(*t);
6669  }
6670 
6671  MAYBE_MAP_TYPE_WITH_TYPE_ID(t, node);
6672 
6673  if (t)
6674  rdr.schedule_type_for_canonicalization(t);
6675  return t;
6676 }
6677 
6678 /// Parses 'type-decl' xml element.
6679 ///
6680 /// @param rdr the parsing context.
6681 ///
6682 /// @return true upon successful parsing, false otherwise.
6683 static decl_base_sptr
6684 handle_type_decl(reader& rdr,
6685  xmlNodePtr node,
6686  bool add_to_current_scope)
6687 {
6688  type_decl_sptr decl = build_type_decl(rdr, node, add_to_current_scope);
6689  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6690  if (decl && decl->get_scope())
6691  rdr.schedule_type_for_canonicalization(decl);
6692  return decl;
6693 }
6694 
6695 /// Parses 'namespace-decl' xml element.
6696 ///
6697 /// @param rdr the parsing context.
6698 ///
6699 /// @return true upon successful parsing, false otherwise.
6700 static decl_base_sptr
6701 handle_namespace_decl(reader& rdr,
6702  xmlNodePtr node,
6703  bool add_to_current_scope)
6704 {
6705  namespace_decl_sptr d = build_namespace_decl(rdr, node,
6706  add_to_current_scope);
6707  return d;
6708 }
6709 
6710 /// Parse a qualified-type-def xml element.
6711 ///
6712 /// @param rdr the parsing context.
6713 ///
6714 /// @return true upon successful parsing, false otherwise.
6715 static decl_base_sptr
6716 handle_qualified_type_decl(reader& rdr,
6717  xmlNodePtr node,
6718  bool add_to_current_scope)
6719 {
6720  qualified_type_def_sptr decl =
6721  build_qualified_type_decl(rdr, node,
6722  add_to_current_scope);
6723  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6724  if (decl && decl->get_scope())
6725  rdr.schedule_type_for_canonicalization(decl);
6726  return decl;
6727 }
6728 
6729 /// Parse a pointer-type-decl element.
6730 ///
6731 /// @param rdr the context of the parsing.
6732 ///
6733 /// @return true upon successful completion, false otherwise.
6734 static decl_base_sptr
6735 handle_pointer_type_def(reader& rdr,
6736  xmlNodePtr node,
6737  bool add_to_current_scope)
6738 {
6739  pointer_type_def_sptr decl = build_pointer_type_def(rdr, node,
6740  add_to_current_scope);
6741  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6742  if (decl && decl->get_scope())
6743  rdr.schedule_type_for_canonicalization(decl);
6744  return decl;
6745 }
6746 
6747 /// Parse a reference-type-def element.
6748 ///
6749 /// @param rdr the context of the parsing.
6750 ///
6751 /// reference_type_def is added to.
6752 static decl_base_sptr
6753 handle_reference_type_def(reader& rdr,
6754  xmlNodePtr node,
6755  bool add_to_current_scope)
6756 {
6757  reference_type_def_sptr decl = build_reference_type_def(rdr, node,
6758  add_to_current_scope);
6759  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6760  if (decl && decl->get_scope())
6761  rdr.schedule_type_for_canonicalization(decl);
6762  return decl;
6763 }
6764 
6765 /// Parse a function-type element.
6766 ///
6767 /// @param rdr the context of the parsing.
6768 ///
6769 /// function_type is added to.
6770 static type_base_sptr
6771 handle_function_type(reader& rdr,
6772  xmlNodePtr node,
6773  bool add_to_current_scope)
6774 {
6775  function_type_sptr type = build_function_type(rdr, node,
6776  add_to_current_scope);
6777  MAYBE_MAP_TYPE_WITH_TYPE_ID(type, node);
6778  rdr.schedule_type_for_canonicalization(type);
6779  return type;
6780 }
6781 
6782 /// Parse a array-type-def element.
6783 ///
6784 /// @param rdr the context of the parsing.
6785 ///
6786 /// array_type_def is added to.
6787 static decl_base_sptr
6788 handle_array_type_def(reader& rdr,
6789  xmlNodePtr node,
6790  bool add_to_current_scope)
6791 {
6792  array_type_def_sptr decl = build_array_type_def(rdr, node,
6793  add_to_current_scope);
6794  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6795  rdr.schedule_type_for_canonicalization(decl);
6796  return decl;
6797 }
6798 
6799 /// Parse an enum-decl element.
6800 ///
6801 /// @param rdr the context of the parsing.
6802 static decl_base_sptr
6803 handle_enum_type_decl(reader& rdr,
6804  xmlNodePtr node,
6805  bool add_to_current_scope)
6806 {
6807  enum_type_decl_sptr decl =
6808  build_enum_type_decl_if_not_suppressed(rdr, node,
6809  add_to_current_scope);
6810  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6811  if (decl && decl->get_scope())
6812  rdr.schedule_type_for_canonicalization(decl);
6813  return decl;
6814 }
6815 
6816 /// Parse a typedef-decl element.
6817 ///
6818 /// @param rdr the context of the parsing.
6819 static decl_base_sptr
6820 handle_typedef_decl(reader& rdr,
6821  xmlNodePtr node,
6822  bool add_to_current_scope)
6823 {
6824  typedef_decl_sptr decl = build_typedef_decl(rdr, node,
6825  add_to_current_scope);
6826  MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6827  if (decl && decl->get_scope())
6828  rdr.schedule_type_for_canonicalization(decl);
6829  return decl;
6830 }
6831 
6832 /// Parse a var-decl element.
6833 ///
6834 /// @param rdr the context of the parsing.
6835 ///
6836 /// @param node the node to read & parse from.
6837 ///
6838 /// @param add_to_current_scope if set to yes, the resulting of this
6839 /// function is added to its current scope.
6840 static decl_base_sptr
6841 handle_var_decl(reader& rdr,
6842  xmlNodePtr node,
6843  bool add_to_current_scope)
6844 {
6845  decl_base_sptr decl = build_var_decl_if_not_suppressed(rdr, node,
6846  add_to_current_scope);
6847  rdr.add_var_to_exported_or_undefined_decls(is_var_decl(decl));
6848  return decl;
6849 }
6850 
6851 /// Parse a function-decl element.
6852 ///
6853 /// @param rdr the context of the parsing
6854 ///
6855 /// @return true upon successful completion of the parsing, false
6856 /// otherwise.
6857 static decl_base_sptr
6858 handle_function_decl(reader& rdr,
6859  xmlNodePtr node,
6860  bool add_to_current_scope)
6861 {
6862  return build_function_decl_if_not_suppressed(rdr, node, class_decl_sptr(),
6863  add_to_current_scope,
6864  /*add_to_exported_decls=*/true);
6865 }
6866 
6867 /// Parse a 'class-decl' xml element.
6868 ///
6869 /// @param rdr the context of the parsing.
6870 ///
6871 /// @return the resulting @ref class_decl built from the XML element
6872 /// upon successful completion of the parsing, nil otherwise.
6873 static decl_base_sptr
6874 handle_class_decl(reader& rdr,
6875  xmlNodePtr node,
6876  bool add_to_current_scope)
6877 {
6878  class_decl_sptr decl =
6879  build_class_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6880  MAYBE_MAP_TYPE_WITH_TYPE_ID(is_type(decl), node);
6881  if (decl && decl->get_scope())
6882  rdr.schedule_type_for_canonicalization(decl);
6883  return decl;
6884 }
6885 
6886 /// Parse a 'union-decl' xml element.
6887 ///
6888 /// @param rdr the context of the parsing.
6889 ///
6890 /// @return the resulting @ref union_decl built from the XML element
6891 /// upon successful completion of the parsing, nil otherwise.
6892 static decl_base_sptr
6893 handle_union_decl(reader& rdr,
6894  xmlNodePtr node,
6895  bool add_to_current_scope)
6896 {
6897  union_decl_sptr decl =
6898  build_union_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6899  MAYBE_MAP_TYPE_WITH_TYPE_ID(is_type(decl), node);
6900  if (decl && decl->get_scope())
6901  rdr.schedule_type_for_canonicalization(decl);
6902  return decl;
6903 }
6904 
6905 /// Parse a 'function-template-decl' xml element.
6906 ///
6907 /// @param rdr the parsing context.
6908 ///
6909 /// @return true upon successful completion of the parsing, false
6910 /// otherwise.
6911 static decl_base_sptr
6912 handle_function_tdecl(reader& rdr,
6913  xmlNodePtr node,
6914  bool add_to_current_scope)
6915 {
6916  function_tdecl_sptr d = build_function_tdecl(rdr, node,
6917  add_to_current_scope);
6918  return d;
6919 }
6920 
6921 /// Parse a 'class-template-decl' xml element.
6922 ///
6923 /// @param rdr the context of the parsing.
6924 ///
6925 /// @return true upon successful completion, false otherwise.
6926 static decl_base_sptr
6927 handle_class_tdecl(reader& rdr,
6928  xmlNodePtr node,
6929  bool add_to_current_scope)
6930 {
6931  class_tdecl_sptr decl = build_class_tdecl(rdr, node,
6932  add_to_current_scope);
6933  return decl;
6934 }
6935 
6936 /// De-serialize a translation unit from an ABI Instrumentation xml
6937 /// file coming from an input stream.
6938 ///
6939 /// @param in a pointer to the input stream.
6940 ///
6941 /// @param env the environment to use.
6942 ///
6943 /// @return the translation unit resulting from the parsing upon
6944 /// successful completion, or nil.
6947 {
6948  reader read_rdr(xml::new_reader_from_istream(in), env);
6949  return read_translation_unit_from_input(read_rdr);
6950 }
6951 template<typename T>
6952 struct array_deleter
6953 {
6954  void
6955  operator()(T* a)
6956  {
6957  delete [] a;
6958  }
6959 };//end array_deleter
6960 
6961 
6962 /// Create an xml_reader::reader to read a native XML ABI file.
6963 ///
6964 /// @param path the path to the native XML file to read.
6965 ///
6966 /// @param env the environment to use.
6967 ///
6968 /// @return the created context.
6969 fe_iface_sptr
6970 create_reader(const string& path, environment& env)
6971 {
6972  reader_sptr result(new reader(xml::new_reader_from_file(path),
6973  env));
6974  corpus_sptr corp = result->corpus();
6975  corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6976 #ifdef WITH_DEBUG_SELF_COMPARISON
6977  if (env.self_comparison_debug_is_on())
6978  env.set_self_comparison_debug_input(result->corpus());
6979 #endif
6980  result->set_path(path);
6981  return result;
6982 }
6983 
6984 /// Create an xml_reader::reader to read a native XML ABI from
6985 /// an input stream..
6986 ///
6987 /// @param in the input stream that contains the native XML file to read.
6988 ///
6989 /// @param env the environment to use.
6990 ///
6991 /// @return the created context.
6992 fe_iface_sptr
6993 create_reader(std::istream* in, environment& env)
6994 {
6995  reader_sptr result(new reader(xml::new_reader_from_istream(in),
6996  env));
6997  corpus_sptr corp = result->corpus();
6998  corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6999 #ifdef WITH_DEBUG_SELF_COMPARISON
7000  if (env.self_comparison_debug_is_on())
7001  env.set_self_comparison_debug_input(result->corpus());
7002 #endif
7003  return result;
7004 }
7005 
7006 /// De-serialize an ABI corpus from an input XML document which root
7007 /// node is 'abi-corpus'.
7008 ///
7009 /// @param in the input stream to read the XML document from.
7010 ///
7011 /// @param env the environment to use. Note that the life time of
7012 /// this environment must be greater than the lifetime of the
7013 /// resulting corpus as the corpus uses resources that are allocated
7014 /// in the environment.
7015 ///
7016 /// @return the resulting corpus de-serialized from the parsing. This
7017 /// is non-null iff the parsing resulted in a valid corpus.
7018 corpus_sptr
7019 read_corpus_from_abixml(std::istream* in,
7020  environment& env)
7021 {
7022  fe_iface_sptr rdr = create_reader(in, env);
7023  fe_iface::status sts;
7024  return rdr->read_corpus(sts);
7025 }
7026 
7027 /// De-serialize an ABI corpus from an XML document file which root
7028 /// node is 'abi-corpus'.
7029 ///
7030 /// @param path the path to the input file to read the XML document
7031 /// from.
7032 ///
7033 /// @param env the environment to use. Note that the life time of
7034 /// this environment must be greater than the lifetime of the
7035 /// resulting corpus as the corpus uses resources that are allocated
7036 /// in the environment.
7037 ///
7038 /// @return the resulting corpus de-serialized from the parsing. This
7039 /// is non-null if the parsing successfully resulted in a corpus.
7040 corpus_sptr
7041 read_corpus_from_abixml_file(const string& path,
7042  environment& env)
7043 {
7044  fe_iface_sptr rdr = create_reader(path, env);
7045  fe_iface::status sts;
7046  corpus_sptr corp = rdr->read_corpus(sts);
7047  return corp;
7048 }
7049 
7050 }//end namespace xml_reader
7051 
7052 #ifdef WITH_DEBUG_SELF_COMPARISON
7053 /// Load the map that is stored at
7054 /// environment::get_type_id_canonical_type_map().
7055 ///
7056 /// That map associates type-ids to the pointer value of the canonical
7057 /// types they correspond to. The map is loaded from a file that was
7058 /// stored on disk by some debugging primitive that is activated when
7059 /// the command "abidw --debug-abidiff <binary>' is used."
7060 ///
7061 /// The function that stored the map in that file is
7062 /// write_canonical_type_ids.
7063 ///
7064 /// @param rdr the ABIXML reader to use.
7065 ///
7066 /// @param file_path the path to the file containing the type-ids <->
7067 /// canonical type mapping.
7068 ///
7069 /// @return true iff the loading was successful.
7070 bool
7071 load_canonical_type_ids(fe_iface& iface, const string &file_path)
7072 {
7073  abixml::reader& rdr = dynamic_cast<abixml::reader&>(iface);
7074 
7075  xmlDocPtr doc = xmlReadFile(file_path.c_str(), NULL, XML_PARSE_NOERROR);
7076  if (!doc)
7077  return false;
7078 
7079  xmlNodePtr node = xmlDocGetRootElement(doc);
7080  if (!node)
7081  return false;
7082 
7083  // We expect a file which content looks like:
7084  //
7085  // <abixml-types-check>
7086  // <type>
7087  // <id>type-id-573</id>
7088  // <c>0x262ee28</c>
7089  // </type>
7090  // <type>
7091  // <id>type-id-569</id>
7092  // <c>0x2628298</c>
7093  // </type>
7094  // <type>
7095  // <id>type-id-575</id>
7096  // <c>0x25f9ba8</c>
7097  // </type>
7098  // <abixml-types-check>
7099  //
7100  // So let's parse it!
7101 
7102  if (xmlStrcmp(node->name, (xmlChar*) "abixml-types-check"))
7103  return false;
7104 
7105  for (node = xmlFirstElementChild(node);
7106  node;
7107  node = xmlNextElementSibling(node))
7108  {
7109  if (xmlStrcmp(node->name, (xmlChar*) "type"))
7110  continue;
7111 
7112  string id, canonical_address;
7113  xmlNodePtr data = xmlFirstElementChild(node);
7114  if (data && !xmlStrcmp(data->name, (xmlChar*) "id")
7115  && data->children && xmlNodeIsText(data->children))
7116  id = (char*) XML_GET_CONTENT(data->children);
7117 
7118  data = xmlNextElementSibling(data);
7119  if (data && !xmlStrcmp(data->name, (xmlChar*) "c")
7120  && data->children && xmlNodeIsText(data->children))
7121  {
7122  canonical_address = (char*) XML_GET_CONTENT(data->children);
7123  std::stringstream s;
7124  s << canonical_address;
7125  uintptr_t v = 0;
7126  s >> std::hex >> v;
7127  if (!id.empty()
7128  // 0xdeadbabe is the special value the hash of types
7129  // that are not canonicalized. Look into function
7130  // hash_as_canonical_type_or_constant for the details.
7131  && v != 0xdeadbabe)
7132  rdr.get_environment().get_type_id_canonical_type_map()[id] = v;
7133  }
7134  }
7135  return true;
7136 }
7137 #endif
7138 
7139 }//end namespace abigail
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition: abg-ir.cc:8450
A type used to time various part of the libabigail system.
bool is_elf_symbol_suppressed(const fe_iface &fe, const elf_symbol_sptr &symbol)
Test if an ELF symbol is suppressed by at least one of the suppression specifications associated with...
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10807
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
Definition: abg-ir.cc:3097
suppr::suppressions_type & suppressions()
Getter of the vector of suppression specifications associated with the current front-end.
#define XML_READER_GET_NODE_NAME(reader)
Get the name of the current element node the reader is pointing to. Note that this macro returns an i...
bool suppression_can_match(const fe_iface &fe, const suppression_base &s)
Test if a given suppression specification can match an ABI artifact coming from the corpus being anal...
shared_ptr< T > build_sptr(T *p)
This is to be specialized for the diverse C types that needs wrapping in shared_ptr.
visibility
The visibility of the symbol.
Definition: abg-ir.h:986
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
Definition: abg-ir.cc:10909
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition: abg-ir.cc:3531
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
Definition: abg-ir.cc:8732
fe_iface_sptr create_reader(const string &path, environment &env)
Create an xml_reader::reader to read a native XML ABI file.
Definition: abg-reader.cc:6970
reader_sptr new_reader_from_istream(std::istream *in)
Instanciate an xmlTextReader that parses a content coming from an input stream.
This file contains the declarations for the fe_iface a.k.a "Front End Interface". ...
The base class of all libabigail front-ends: The Front End Interface.
Definition: abg-fe-iface.h:28
corpus_group_sptr read_corpus_group_from_abixml(std::istream *in, environment &env)
De-serialize an ABI corpus group from an input XML document which root node is 'abi-corpus-group'.
Definition: abg-reader.cc:2464
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
Definition: abg-ir.cc:2063
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Definition: abg-ir.cc:11165
shared_ptr< xmlChar > xml_char_sptr
A convenience typedef for a shared pointer of xmlChar.
bool xml_char_sptr_to_string(xml_char_sptr &ssptr, std::string &s)
Convert a shared pointer to xmlChar into an std::string.
bool start()
Start the timer.
const options_type & options() const
Getter of the the options of the current Front End Interface.
Definition: abg-fe-iface.cc:91
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition: abg-fwd.h:208
#define ABG_ASSERT_NOT_REACHED
A macro that expands to aborting the program when executed.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition: abg-corpus.h:24
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
Definition: abg-ir.cc:10503
The base class of both types and declarations.
Definition: abg-ir.h:1405
#define XML_NODE_GET_ATTRIBUTE(node, name)
Get the value of attribute 'name' ont the instance of xmlNodePtr denoted by 'node'.
reader_sptr new_reader_from_buffer(const std::string &buffer)
Instanciate an xmlTextReader that parses the content of an in-memory buffer, wrap it into a smart poi...
bool string_to_elf_symbol_visibility(const string &s, elf_symbol::visibility &v)
Convert a string representing a an elf symbol visibility into an elf_symbol::visibility.
Definition: abg-ir.cc:3122
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
Definition: abg-ir.cc:11858
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
Definition: abg-ir.cc:25793
translation_unit_sptr read_translation_unit_from_istream(istream *in, environment &env)
De-serialize a translation unit from an ABI Instrumentation xml file coming from an input stream...
Definition: abg-reader.cc:6946
status
The status of the fe_iface::read_corpus call.
Definition: abg-fe-iface.h:37
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition: abg-fwd.h:253
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
Definition: abg-ir.cc:6538
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
Definition: abg-ir.cc:8543
const ptr_to_mbr_type * is_ptr_to_mbr_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type.
Definition: abg-ir.cc:11711
shared_ptr< file_suppression > file_suppression_sptr
A convenience typedef for a shared_ptr to file_suppression.
#define XML_READER_GET_NODE_TYPE(reader)
Get the type of the current node of the shared_ptr passed in argument.
file_suppression_sptr is_file_suppression(const suppression_sptr s)
Test if a given suppression specification is a file suppression specification.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
Definition: abg-ir.cc:11396
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition: abg-fwd.h:133
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition: abg-fwd.h:164
bool suppression_matches_type_name_or_location(const type_suppression &s, const string &type_name, const location &type_location)
Test if a type suppression matches a type name and location.
std::unordered_map< string, elf_symbol_sptr > string_elf_symbol_sptr_map_type
Convenience typedef for a map which key is a string and which value if the elf symbol of the same nam...
Definition: abg-ir.h:934
This contains the declarations for the symtab reader.
shared_ptr< type_composition > type_composition_sptr
Convenience typedef for shared pointer to type_composition.
Definition: abg-fwd.h:343
vector< type_base_sptr > member_types
Convenience typedef.
Definition: abg-ir.h:4002
bool string_to_elf_symbol_type(const string &s, elf_symbol::type &t)
Convert a string representing a symbol type into an elf_symbol::type.
Definition: abg-ir.cc:3064
bool is_variable_suppressed(const fe_iface &fe, const string &var_name, const string &var_linkage_name, bool require_drop_property)
Test if a variable is matched by at least one suppression specification associated with a given front...
void hash_and_canonicalize_types(IteratorType begin, IteratorType end, deref_lambda deref, bool do_log=false, bool show_stats=false)
Hash and canonicalize a sequence of types.
Definition: abg-ir-priv.h:1524
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
Definition: abg-ir.h:942
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
Definition: abg-ir.cc:12059
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
Definition: abg-ir.cc:28634
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition: abg-ir.h:2798
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
Definition: abg-ir.cc:10207
shared_ptr< xmlTextReader > reader_sptr
A convenience typedef for a shared pointer of xmlTextReader.
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
Definition: abg-ir.cc:28670
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Definition: abg-ir.cc:11011
void set_member_function_virtuality(function_decl &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
Definition: abg-ir.cc:6715
Toplevel namespace for libabigail.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
Definition: abg-fwd.h:237
void abigail_get_abixml_version(std::string &major, std::string &minor)
Return the version numbers for the ABIXML format.
Definition: abg-config.cc:98
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
Definition: abg-ir.cc:6482
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
Definition: abg-fwd.h:261
bool is_type_suppressed(const fe_iface &fe, const string &type_name, const location &type_location, bool &type_is_opaque, bool require_drop_property)
Test if a type is matched by at least one suppression specification associated with a given front-end...
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
Definition: abg-ir.cc:6425
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition: abg-fwd.h:266
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10747
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
Definition: abg-ir.cc:11100
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol...
Definition: abg-ir.h:947
shared_ptr< template_tparameter > template_tparameter_sptr
Convenience typedef for a shared_ptr to template_tparameter.
Definition: abg-fwd.h:324
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3183
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
Definition: abg-fwd.h:291
translation_unit_sptr read_translation_unit_from_file(const string &input_file, environment &env)
Parse an ABI instrumentation file (in XML format) at a given path.
Definition: abg-reader.cc:2504
This contains the private implementation of the suppression engine of libabigail. ...
corpus_sptr read_corpus_from_abixml(std::istream *in, environment &env)
De-serialize an ABI corpus from an input XML document which root node is 'abi-corpus'.
Definition: abg-reader.cc:7019
corpus_group_sptr read_corpus_group_from_abixml_file(const string &path, environment &env)
De-serialize an ABI corpus group from an XML document file which root node is 'abi-corpus-group'.
Definition: abg-reader.cc:2486
bool split_string(const string &input_string, const string &delims, vector< string > &result)
Split a given string into substrings, given some delimiters.
static bool get_name_and_version_from_id(const string &id, string &name, string &ver)
Given the ID of a symbol, get the name and the version of said symbol.
Definition: abg-ir.cc:2752
type
The type of a symbol.
Definition: abg-ir.h:964
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:10229
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
Definition: abg-fwd.h:118
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition: abg-fwd.h:159
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
Definition: abg-ir.cc:26893
translation_unit_sptr read_translation_unit_from_buffer(const string &buffer, environment &env)
Parse an ABI instrumentation file (in XML format) from an in-memory buffer.
Definition: abg-reader.cc:2526
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition: abg-ir.h:147
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
vector< method_decl_sptr > member_functions
Convenience typedef.
Definition: abg-ir.h:4008
This contains the private implementation of the suppression engine of libabigail. ...
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
Definition: abg-fwd.h:232
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
Definition: abg-ir.cc:5544
corpus_sptr corpus()
Getter for the ABI corpus being built by the current front-end.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
Definition: abg-ir.h:924
unordered_map< string, vector< string > > string_strings_map_type
Convenience typedef for an unordered map of string to a vector of strings.
Definition: abg-reader.cc:63
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
Definition: abg-fwd.h:1743
#define XML_READER_GET_ATTRIBUTE(reader, name)
Get the value of attribute 'name' on the current node of 'reader' which is an instance of shared_ptr<...
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
Definition: abg-fwd.h:1687
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:11445
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
Definition: abg-ir.cc:12123
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
Definition: abg-ir.cc:10695
bool suppression_matches_soname_or_filename(const string &soname, const string &filename, const suppression_base &suppr)
Test if a given SONAME or file name is matched by a given suppression specification.
bool deserialize_hash(const string &input, uint64_t &hash)
Read a string of characters representing a string of hexadecimal digits which itself represents a has...
Definition: abg-hash.cc:99
binding
The binding of a symbol.
Definition: abg-ir.h:977
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
Definition: abg-fwd.h:286
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
Definition: abg-ir.cc:4961
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
Definition: abg-ir.cc:8800
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
Definition: abg-fwd.h:281
void unescape_xml_string(const std::string &str, std::string &escaped)
Read a string, detect the 5 predefined XML entities it may contain and un-escape them, by writting their corresponding characters back in. The pre-defined entities are:
translation_unit::language string_to_translation_unit_language(const string &l)
Parse a string representing a language into a translation_unit::language enumerator into a string...
Definition: abg-ir.cc:1670
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition: abg-fwd.h:172
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition: abg-fwd.h:190
void initialize()
The initialization function of libxml2 abstraction layer. This function must be called prior to using...
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
Definition: abg-ir.cc:8835
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
Definition: abg-ir.cc:11838
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
Definition: abg-ir.cc:11614
function_type_sptr lookup_function_type(const interned_string &type_name, const translation_unit &tu)
Lookup a function type from a translation unit.
Definition: abg-ir.cc:12840
const std::string & corpus_path() const
Getter of the path to the file which an ABI corpus is to be created for.
shared_ptr< non_type_tparameter > non_type_tparameter_sptr
Convenience typedef for shared pointer to non_type_template_parameter.
Definition: abg-fwd.h:316
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
Definition: abg-ir.cc:12215
static symtab_ptr load(Elf *elf_handle, const ir::environment &env, symbol_predicate is_suppressed=NULL)
Construct a symtab object and instantiate it from an ELF handle. Also pass in the ir::environment we ...
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition: abg-ir.h:2569
reader_sptr new_reader_from_file(const std::string &path)
Instantiate an xmlTextReader that parses the content of an on-disk file, wrap it into a smart pointer...
const string & dt_soname() const
Getter for the SONAME of the analyzed binary.
Abstraction of a group of corpora.
Definition: abg-corpus.h:385
vector< var_decl_sptr > data_members
Convenience typedef.
Definition: abg-ir.h:4007
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
Definition: abg-ir.cc:5872
access_specifier
Access specifier for class members.
Definition: abg-ir.h:916
corpus_group_sptr read_corpus_group_from_input(fe_iface &iface)
Parse the input XML document containing an ABI corpus group, represented by an 'abi-corpus-group' ele...
Definition: abg-reader.cc:2374
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
Definition: abg-fwd.h:303
shared_ptr< function_suppression > function_suppression_sptr
Convenience typedef for a shared pointer to function_suppression.
void consider_types_not_reachable_from_public_interfaces(fe_iface &iface, bool flag)
Configure the reader so that types not reachable from public interface are taken into account when th...
Definition: abg-reader.cc:2294
void add_reader_suppressions(reader &rdr, const suppr::suppressions_type &supprs)
Add suppressions specifications to the set of suppressions to be used during the construction of the ...
Definition: abg-reader.cc:2275
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
Definition: abg-fwd.h:311
vector< base_spec_sptr > base_specs
Convenience typedef.
Definition: abg-ir.h:4193
corpus_sptr read_corpus_from_abixml_file(const string &path, environment &env)
De-serialize an ABI corpus from an XML document file which root node is 'abi-corpus'.
Definition: abg-reader.cc:7041
shared_ptr< string_elf_symbols_map_type > string_elf_symbols_map_sptr
Convenience typedef for a shared pointer to string_elf_symbols_map_type.
Definition: abg-ir.h:951
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
Definition: abg-ir.cc:11651
virtual void initialize(const std::string &corpus_path)
Re-initialize the current Front End.
Definition: abg-fe-iface.cc:81
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition: abg-ir.h:2562
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition: abg-fwd.h:241
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition: abg-fwd.h:223
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
Definition: abg-ir.cc:11479
shared_ptr< type_tparameter > type_tparameter_sptr
Convenience typedef for a shared pointer to type_tparameter.
Definition: abg-fwd.h:330
This status is for when the call went OK.
Definition: abg-fe-iface.h:43
binding
ELF binding.
Definition: abg-ir.h:1635
hash_t hash(uint64_t v, uint64_t seed)
Hash an integer value and combine it with a hash previously computed.
Definition: abg-hash.cc:196
bool stop()
Stop the timer.
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition: abg-ir.h:2254
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
Definition: abg-ir.cc:5464
visibility
ELF visibility.
Definition: abg-ir.h:1625
bool is_function_suppressed(const fe_iface &fe, const string &fn_name, const string &fn_linkage_name, bool require_drop_property)
Test if a function is matched by at least one suppression specification associated with a given front...