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