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