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