• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
39 ABG_END_EXPORT_DECLARATIONS
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,
95 			  string_elf_symbols_map_sptr&	fn_symdb,
96 			  string_elf_symbols_map_sptr&	var_symdb);
97 
98 static translation_unit_sptr
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:
reader(xml::reader_sptr reader,environment & env)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
do_log() const181   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
tracking_non_reachable_types() const190   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
tracking_non_reachable_types(bool f)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
drop_undefined_syms() const208   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
drop_undefined_syms(bool f)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&
get_path() const223   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
set_path(const string & s)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&
get_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&
get_environment() const246   get_environment() const
247   {return const_cast<reader*>(this)->get_environment();}
248 
249   xml::reader_sptr
get_libxml_reader() const250   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
get_corpus_node() const259   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
set_corpus_node(xmlNodePtr node)268   set_corpus_node(xmlNodePtr node)
269   {m_corp_node = node;}
270 
271   const string_xml_node_map&
get_id_xml_node_map() const272   get_id_xml_node_map() const
273   {return m_id_xml_node_map;}
274 
275   string_xml_node_map&
get_id_xml_node_map()276   get_id_xml_node_map()
277   {return m_id_xml_node_map;}
278 
279   void
clear_id_xml_node_map()280   clear_id_xml_node_map()
281   {get_id_xml_node_map().clear();}
282 
283   const xml_node_decl_base_sptr_map&
get_xml_node_decl_map() const284   get_xml_node_decl_map() const
285   {return m_xml_node_decl_map;}
286 
287   xml_node_decl_base_sptr_map&
get_xml_node_decl_map()288   get_xml_node_decl_map()
289   {return m_xml_node_decl_map;}
290 
291   void
map_xml_node_to_decl(xmlNodePtr node,decl_base_sptr decl)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
get_decl_for_xml_node(xmlNodePtr node) const300   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
clear_xml_node_decl_map()312   clear_xml_node_decl_map()
313   {get_xml_node_decl_map().clear();}
314 
315   void
map_id_and_node(const string & id,xmlNodePtr node)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
get_xml_node_from_id(const string & id) const335   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 
343   scope_decl_sptr
344   get_scope_for_node(xmlNodePtr node,
345 		     access_specifier& access);
346 
347   scope_decl_sptr
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
get_type_decl(const string & id) const371   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>*
get_all_type_decls(const string & id) const393   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>
get_fn_tmpl_decl(const string & id) const414   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>
get_class_tmpl_decl(const string & id) const433   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*
get_cur_scope() const443   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
get_cur_decl() const460   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 
467   translation_unit*
get_translation_unit()468   get_translation_unit()
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
type_is_from_translation_unit(type_base_sptr type)491   type_is_from_translation_unit(type_base_sptr type)
492   {
493     decl_base_sptr d = get_type_declaration(type);
494     if (d)
495       return (ir::get_translation_unit(d) == get_translation_unit());
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
push_decl(decl_base_sptr d)503   push_decl(decl_base_sptr d)
504   {
505     m_decls_stack.push_back(d);
506   }
507 
508   decl_base_sptr
pop_decl()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
pop_scope(scope_decl_sptr scope)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
pop_scope_or_abort(scope_decl_sptr scope)550   pop_scope_or_abort(scope_decl_sptr scope)
551   {ABG_ASSERT(pop_scope(scope));}
552 
553   void
clear_decls_stack()554   clear_decls_stack()
555   {m_decls_stack.clear();}
556 
557   void
clear_type_map()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
clear_types_to_canonicalize()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
types_equal(type_base_sptr t1,type_base_sptr t2)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
key_type_decl(const type_base_sptr & type,const string & id)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
key_fn_tmpl_decl(shared_ptr<function_tdecl> fn_tmpl_decl,const string & id)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
key_class_tmpl_decl(shared_ptr<class_tdecl> class_tmpl_decl,const string & id)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
record_artifact_as_used_by(type_or_decl_base * used,type_or_decl_base * user)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
record_artifact_as_used_by(const type_or_decl_base_sptr & used,const type_or_decl_base_sptr & user)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
record_artifacts_as_used_in_fn_decl(const function_decl * fn)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
record_artifacts_as_used_in_fn_decl(const function_decl_sptr & fn)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
record_artifacts_as_used_in_fn_type(const function_type * fn_type)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
record_artifacts_as_used_in_fn_type(const function_type_sptr & fn_type)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
push_decl_to_scope(const decl_base_sptr & decl,xmlNodePtr node)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
push_decl_to_scope(const decl_base_sptr & decl,scope_decl * scope)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
push_and_key_type_decl(const type_base_sptr & t,const string & id,scope_decl * scope)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
push_and_key_type_decl(const type_base_sptr & t,const xmlNodePtr node,bool add_to_current_scope)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.
838   corpus::exported_decls_builder*
get_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
corpus_is_suppressed_by_soname_or_filename(const string & soname,const string & filename)853   corpus_is_suppressed_by_soname_or_filename(const string& soname,
854 					     const string& filename)
855   {
856     using suppr::suppressions_type;
857     using suppr::file_suppression_sptr;
858     using suppr::is_file_suppression;
859 
860     for (suppressions_type::const_iterator s = suppressions().begin();
861 	 s != suppressions().end();
862 	 ++s)
863       if (file_suppression_sptr suppr = is_file_suppression(*s))
864 	if (suppr::suppression_matches_soname_or_filename(soname, filename,
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
clear_per_translation_unit_data()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
clear_per_corpus_data()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
maybe_check_abixml_canonical_type_stability(type_base_sptr & t)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
maybe_canonicalize_type(type_base_sptr t,bool force_delay=false)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
984 	&& !type_has_non_canonicalized_subtype(t)
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
schedule_type_for_late_canonicalizing(type_base_sptr t)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
perform_late_type_canonicalizing()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
suppression_matches_function_name(const suppr::function_suppression_sptr & s,const string & fn_name) const1059   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
suppression_can_match(const suppr::suppression_base & s) const1075   suppression_can_match(const suppr::suppression_base& s) const
1076   {
1077     corpus_sptr corp = corpus();
1078 
1079     if (!s.priv_->matches_soname(corp->get_soname()))
1080       if (s.has_soname_related_property())
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()))
1087       if (s.has_file_name_related_property())
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
suppression_matches_function_name(const suppr::function_suppression & s,const string & fn_name) const1108   suppression_matches_function_name(const suppr::function_suppression& s,
1109 				    const string& fn_name) const
1110   {
1111     if (!s.get_drops_artifact_from_ir()
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
suppression_matches_type_name_or_location(const suppr::type_suppression & s,const string & type_name,const location & type_location) const1130   suppression_matches_type_name_or_location(const suppr::type_suppression& s,
1131 					    const string& type_name,
1132 					    const location& type_location) const
1133   {
1134     if (!suppression_can_match(s))
1135       return false;
1136 
1137     return suppr::suppression_matches_type_name_or_location(s, type_name,
1138 							    type_location);
1139   }
1140 
1141   virtual ir::corpus_sptr
read_corpus(fe_iface::status & status)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)
1194 	  corp.set_architecture_name
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)
1245 	  corp.set_architecture_name
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
1294 	  (corp.recording_types_reachable_from_public_interface_supported()
1295 	   == is_tracking_non_reachable_types);
1296       }
1297 
1298 
1299     tools_utils::timer t;
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&,
1353 					  string_elf_symbols_map_sptr&,
1354 					  string_elf_symbols_map_sptr&);
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,
1360 					      type_or_decl_base_sptr);
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,
1374 					   elf_symbol::visibility&);
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 
1392 static string_elf_symbols_map_sptr
1393 build_elf_symbol_db(reader&, const xmlNodePtr, bool);
1394 
1395 static function_decl::parameter_sptr
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 
1435 static array_type_def::subrange_sptr
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 
1467 static non_type_tparameter_sptr
1468 build_non_type_tparameter(reader&, const xmlNodePtr,
1469 			  unsigned, template_decl_sptr);
1470 
1471 static template_tparameter_sptr
1472 build_template_tparameter(reader&, const xmlNodePtr,
1473 			  unsigned, template_decl_sptr);
1474 
1475 static template_parameter_sptr
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.
1535 scope_decl_sptr
get_scope_for_node(xmlNodePtr node,access_specifier & access)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 	{
1562 	  translation_unit_sptr tu =
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.
1590 scope_decl_sptr
get_scope_for_node(xmlNodePtr node)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*
get_scope_ptr_for_node(xmlNodePtr node)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
build_or_get_type_decl(const string & id,bool add_decl_to_scope)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
advance_cursor(reader & rdr)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
walk_xml_node_to_map_type_ids(reader & rdr,xmlNodePtr node)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
read_translation_unit(fe_iface & iface,translation_unit & tu,xmlNodePtr node)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)
1739     tu.set_language(string_to_translation_unit_language
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
get_or_read_and_add_translation_unit(reader & rdr,xmlNodePtr node)1782 get_or_read_and_add_translation_unit(reader& rdr, xmlNodePtr node)
1783 {
1784   corpus_sptr corp = rdr.corpus();
1785 
1786   translation_unit_sptr tu;
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
read_translation_unit_from_input(fe_iface & iface)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
read_symbol_db_from_input(reader & rdr,string_elf_symbols_map_sptr & fn_symdb,string_elf_symbols_map_sptr & var_symdb)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
build_needed(xmlNode * node,vector<string> & needed)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"))
1988 	xml::xml_char_sptr_to_string(s, 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
read_elf_needed_from_input(reader & rdr,vector<string> & needed)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
add_reader_suppressions(reader & rdr,const suppr::suppressions_type & supprs)2084 add_reader_suppressions(reader& rdr,
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
consider_types_not_reachable_from_public_interfaces(fe_iface & iface,bool flag)2103 consider_types_not_reachable_from_public_interfaces(fe_iface& iface,
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>*
get_types_from_type_id(fe_iface & iface,const string & type_id)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*>>*
get_artifact_used_by_relation_map(fe_iface & iface)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
handle_version_attribute(xml::reader_sptr & reader,corpus & corp)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
read_corpus_group_from_input(fe_iface & iface)2183 read_corpus_group_from_input(fe_iface& iface)
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
read_corpus_group_from_abixml(std::istream * in,environment & env)2248 read_corpus_group_from_abixml(std::istream* in,
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
read_corpus_group_from_abixml_file(const string & path,environment & env)2270 read_corpus_group_from_abixml_file(const string& path,
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.
2287 translation_unit_sptr
read_translation_unit_from_file(const string & input_file,environment & env)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.
2309 translation_unit_sptr
read_translation_unit_from_buffer(const string & buffer,environment & env)2310 read_translation_unit_from_buffer(const string&	buffer,
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.
2328 translation_unit_sptr
read_translation_unit(fe_iface & iface)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.
2347 static type_or_decl_base_sptr
handle_element_node(reader & rdr,xmlNodePtr node,bool add_to_current_scope)2348 handle_element_node(reader& rdr, xmlNodePtr node,
2349 		    bool add_to_current_scope)
2350 {
2351   type_or_decl_base_sptr decl;
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
read_location(const reader & rdr,xmlNodePtr node,location & loc)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
read_artificial_location(const reader & rdr,xmlNodePtr node,location & loc)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
maybe_set_artificial_location(const reader & rdr,xmlNodePtr node,type_or_decl_base_sptr artefact)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
read_visibility(xmlNodePtr node,decl_base::visibility & vis)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
read_binding(xmlNodePtr node,decl_base::binding & bind)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
read_access(xmlNodePtr node,access_specifier & access)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
read_size_and_alignment(xmlNodePtr node,size_t & size_in_bits,size_t & align_in_bits)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
read_static(xmlNodePtr node,bool & is_static)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
read_offset_in_bits(xmlNodePtr node,size_t & offset_in_bits)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
read_cdtor_const(xmlNodePtr node,bool & is_constructor,bool & is_destructor,bool & is_const)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
read_is_declaration_only(xmlNodePtr node,bool & is_decl_only)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
read_is_artificial(xmlNodePtr node,bool & is_artificial)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
read_tracking_non_reachable_types(xmlNodePtr node,bool & tracking_non_reachable_types)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
read_is_non_reachable_type(xmlNodePtr node,bool & is_non_reachable_type)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
read_naming_typedef_id_string(xmlNodePtr node,string & naming_typedef_id)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
read_is_virtual(xmlNodePtr node,bool & is_virtual)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
read_is_struct(xmlNodePtr node,bool & is_struct)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
read_is_anonymous(xmlNodePtr node,bool & is_anonymous)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
read_elf_symbol_type(xmlNodePtr node,elf_symbol::type & t)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;
2926       xml::xml_char_sptr_to_string(s, 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
read_elf_symbol_binding(xmlNodePtr node,elf_symbol::binding & b)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;
2947       xml::xml_char_sptr_to_string(s, 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
read_elf_symbol_visibility(xmlNodePtr node,elf_symbol::visibility & v)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;
2969       xml::xml_char_sptr_to_string(s, 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
read_type_id_string(xmlNodePtr node,string & type_id)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
maybe_map_type_with_type_id(const type_base_sptr & t,const string & type_id)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
maybe_map_type_with_type_id(const type_base_sptr & t,xmlNodePtr node)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
maybe_set_naming_typedef(reader & rdr,xmlNodePtr node,const decl_base_sptr & decl)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
build_namespace_decl(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
build_elf_symbol(reader & rdr,const xmlNodePtr node,bool drop_if_suppressed)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"))
3165     xml::xml_char_sptr_to_string(s, 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;
3235       xml::xml_char_sptr_to_string(s, 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
build_elf_symbol_from_reference(reader & rdr,const xmlNodePtr node)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.
3300 static string_elf_symbols_map_sptr
build_elf_symbol_db(reader & rdr,const xmlNodePtr node,bool function_syms)3301 build_elf_symbol_db(reader& rdr,
3302 		    const xmlNodePtr node,
3303 		    bool function_syms)
3304 {
3305   string_elf_symbols_map_sptr map, nil;
3306   string_elf_symbol_sptr_map_type id_sym_map;
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>
build_function_parameter(reader & rdr,const xmlNodePtr node)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 
3423   function_decl::parameter_sptr p
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
build_function_decl(reader & rdr,const xmlNodePtr node,class_or_union_sptr as_method_decl,bool add_to_current_scope,bool add_to_exported_decls)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 	{
3510 	  if (function_decl::parameter_sptr p =
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
build_function_decl_if_not_suppressed(reader & rdr,const xmlNodePtr node,class_or_union_sptr as_method_decl,bool add_to_current_scope,bool add_to_exported_decls)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
function_is_suppressed(const reader & rdr,xmlNodePtr node)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
type_is_suppressed(const reader & rdr,xmlNodePtr node)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
build_var_decl_if_not_suppressed(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
variable_is_suppressed(const reader & rdr,xmlNodePtr node)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
variable_is_suppressed(const reader & rdr,const scope_decl * scope,const var_decl & v)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>
build_var_decl(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
build_ir_node_for_void_type(reader & rdr)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
build_ir_node_for_void_pointer_type(reader & rdr)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
build_type_decl(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
build_qualified_type_decl(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
build_pointer_type_def(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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     {
4065       pointer_type_def_sptr result = is_pointer_type(t);
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 
4084   pointer_type_def_sptr t;
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>
build_reference_type_def(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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     {
4144       reference_type_def_sptr ty = is_reference_type(d);
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
build_function_type(reader & rdr,const xmlNodePtr node,bool)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 	{
4253 	  if (function_decl::parameter_sptr p =
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.
4284 static array_type_def::subrange_sptr
build_subrange_type(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)4285 build_subrange_type(reader&		rdr,
4286 		    const xmlNodePtr	node,
4287 		    bool		add_to_current_scope)
4288 {
4289   array_type_def::subrange_sptr nil;
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     {
4296       array_type_def::subrange_sptr result =
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       {
4313 	array_type_def::subrange_sptr ty = is_subrange_type(d);
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 
4379   array_type_def::subrange_sptr p
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
build_array_type_def(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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     {
4429       array_type_def_sptr ty = is_array_type(d);
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);
4479   array_type_def::subranges_type subranges;
4480 
4481   for (xmlNodePtr n = xmlFirstElementChild(node);
4482        n;
4483        n = xmlNextElementSibling(n))
4484     if (xmlStrEqual(n->name, BAD_CAST("subrange")))
4485       {
4486 	if (array_type_def::subrange_sptr s =
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;
4545 	      ABG_ASSERT_NOT_REACHED;
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
build_enum_type_decl_if_not_suppressed(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
build_enum_type_decl(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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;
4634   enum_type_decl::enumerators enums;
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>
build_typedef_decl(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
build_class_decl_if_not_suppressed(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
build_union_decl_if_not_suppressed(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
build_class_decl(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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 
4841   class_decl::member_types mbrs;
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 	{
4960 	  class_decl_sptr d = is_class_type(*i);
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);
5054 		  xml_char_sptr i= XML_NODE_GET_ATTRIBUTE(p, "id");
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
build_union_decl(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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 
5273   union_decl::member_types mbrs;
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);
5431 		  xml_char_sptr i= XML_NODE_GET_ATTRIBUTE(p, "id");
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>
build_function_tdecl(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
build_class_tdecl(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
build_type_tparameter(reader & rdr,const xmlNodePtr node,unsigned index,template_decl_sptr tdecl)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
build_type_composition(reader & rdr,const xmlNodePtr node,unsigned index,template_decl_sptr tdecl)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.
5849 static non_type_tparameter_sptr
build_non_type_tparameter(reader & rdr,const xmlNodePtr node,unsigned index,template_decl_sptr tdecl)5850 build_non_type_tparameter(reader&	rdr,
5851 			  const xmlNodePtr	node,
5852 			  unsigned		index,
5853 			  template_decl_sptr	tdecl)
5854 {
5855   non_type_tparameter_sptr r;
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.
5896 static template_tparameter_sptr
build_template_tparameter(reader & rdr,const xmlNodePtr node,unsigned index,template_decl_sptr tdecl)5897 build_template_tparameter(reader&	rdr,
5898 			  const xmlNodePtr	node,
5899 			  unsigned		index,
5900 			  template_decl_sptr	tdecl)
5901 {
5902   template_tparameter_sptr nil;
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.
5970 static template_parameter_sptr
build_template_parameter(reader & rdr,const xmlNodePtr node,unsigned index,template_decl_sptr tdecl)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
build_type(reader & rdr,const xmlNodePtr node,bool add_to_current_scope)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
handle_type_decl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_namespace_decl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_qualified_type_decl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_pointer_type_def(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_reference_type_def(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_function_type(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_array_type_def(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_enum_type_decl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_typedef_decl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_var_decl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_function_decl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_class_decl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_union_decl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_function_tdecl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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
handle_class_tdecl(reader & rdr,xmlNodePtr node,bool add_to_current_scope)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.
6299 translation_unit_sptr
read_translation_unit_from_istream(istream * in,environment & env)6300 read_translation_unit_from_istream(istream* in, environment& env)
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
operator ()abigail::abixml::array_deleter6309   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
create_reader(const string & path,environment & env)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
create_reader(std::istream * in,environment & env)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
read_corpus_from_abixml(std::istream * in,environment & env)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
read_corpus_from_abixml_file(const string & path,environment & env)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
load_canonical_type_ids(fe_iface & iface,const string & file_path)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
6494