libabigail
abg-ctf-reader.cc
Go to the documentation of this file.
1 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2 // -*- Mode: C++ -*-
3 //
4 // Copyright (C) 2021-2025 Oracle, Inc.
5 //
6 // Author: Jose E. Marchesi
7 
8 /// @file
9 ///
10 /// This file contains the definitions of the entry points to
11 /// de-serialize an instance of @ref abigail::corpus from a file in
12 /// ELF format, containing CTF information.
13 
14 #include "config.h"
15 
16 #include <fcntl.h> /* For open(3) */
17 #include <sstream>
18 #include <iostream>
19 #include <memory>
20 #include <map>
21 #include <algorithm>
22 
23 #include "ctf-api.h"
24 
25 #include "abg-internal.h"
26 #include "abg-ir-priv.h"
27 #include "abg-symtab-reader.h"
28 
29 
30 #include "abg-internal.h"
31 // <headers defining libabigail's API go under here>
32 ABG_BEGIN_EXPORT_DECLARATIONS
33 
34 #include "abg-ctf-reader.h"
35 #include "abg-elf-based-reader.h"
36 #include "abg-corpus.h"
37 #include "abg-tools-utils.h"
38 #include "abg-elf-helpers.h"
39 
41 // </headers defining libabigail's API>
42 
43 namespace abigail
44 {
45 
46 using std::cerr;
47 
48 /// Namespace of the reader for the CTF debug information
49 namespace ctf
50 {
51 using std::dynamic_pointer_cast;
54 
55 class reader;
56 
57 static typedef_decl_sptr
58 process_ctf_typedef(reader *rdr,
59  ctf_dict_t *ctf_dictionary,
60  ctf_id_t ctf_type);
61 
62 static type_decl_sptr
63 process_ctf_base_type(reader *rdr,
64  ctf_dict_t *ctf_dictionary,
65  ctf_id_t ctf_type);
66 
67 static decl_base_sptr
68 build_ir_node_for_variadic_parameter_type(reader &rdr,
69  const translation_unit_sptr& tunit);
70 
71 static decl_base_sptr
72 build_ir_node_for_void_type(reader& rdr,
73  const translation_unit_sptr& tunit);
74 
76 build_ir_node_for_void_pointer_type(reader& rdr,
77  const translation_unit_sptr& tunit);
78 
79 static function_type_sptr
80 process_ctf_function_type(reader *rdr,
81  ctf_dict_t *ctf_dictionary,
82  ctf_id_t ctf_type);
83 
84 static void
85 process_ctf_sou_members(reader *rdr,
86  ctf_dict_t *ctf_dictionary,
87  ctf_id_t ctf_type,
88  class_or_union_sptr sou);
89 
90 static type_base_sptr
91 process_ctf_forward_type(reader *rdr,
92  ctf_dict_t *ctf_dictionary,
93  ctf_id_t ctf_type);
94 
95 static class_decl_sptr
96 process_ctf_struct_type(reader *rdr,
97  ctf_dict_t *ctf_dictionary,
98  ctf_id_t ctf_type);
99 
100 static union_decl_sptr
101 process_ctf_union_type(reader *rdr,
102  ctf_dict_t *ctf_dictionary,
103  ctf_id_t ctf_type);
104 
105 static array_type_def_sptr
106 process_ctf_array_type(reader *rdr,
107  ctf_dict_t *ctf_dictionary,
108  ctf_id_t ctf_type);
109 
110 static type_base_sptr
111 process_ctf_qualified_type(reader *rdr,
112  ctf_dict_t *ctf_dictionary,
113  ctf_id_t ctf_type);
114 
116 process_ctf_pointer_type(reader *rdr,
117  ctf_dict_t *ctf_dictionary,
118  ctf_id_t ctf_type);
119 
120 static enum_type_decl_sptr
121 process_ctf_enum_type(reader *rdr,
122  ctf_dict_t *ctf_dictionary,
123  ctf_id_t ctf_type);
124 
125 static void
126 fill_ctf_section(const Elf_Scn *elf_section, ctf_sect_t *ctf_section);
127 
128 static ctf_id_t
129 lookup_symbol_in_ctf_archive(ctf_archive_t *ctfa, ctf_dict_t **ctf_dict,
130  const char *sym_name);
131 
132 static std::string
133 dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type);
134 
135 /// The abstraction of a CTF reader.
136 ///
137 /// It groks the type information contains the CTF-specific part of
138 /// the ELF file and builds an ABI corpus out of it.
139 class reader : public elf_based_reader
140 {
141  /// The CTF archive read from FILENAME. If an archive couldn't
142  /// be read from the file then this is NULL.
143  ctf_archive_t *ctfa;
144 
145  /// A map associating CTF type ids with libabigail IR types. This
146  /// is used to reuse already generated types.
148  vector<type_base_sptr> types_to_canonicalize;
149 
150  /// Vector of additional types created during the analysis. These
151  /// types don't have assocaited CTF type IDs.
152  vector<type_base_sptr> additional_types_to_canonicalize;
153 
154  /// The vector of types present in types_map. This is used to sort
155  /// the types before canonicalizing them.
156  vector<type_base_sptr> types;
157 
158  /// A set associating unknown CTF type ids
159  std::set<ctf_id_t> unknown_types_set;
160 
161  /// Raw contents of several sections from the ELF file. These are
162  /// used by libctf.
163  ctf_sect_t ctf_sect;
164  ctf_sect_t symtab_sect;
165  ctf_sect_t strtab_sect;
166  translation_unit_sptr cur_tu_;
167 
168 public:
169 
170  /// Getter of the exported decls builder object.
171  ///
172  /// @return the exported decls builder.
174  exported_decls_builder()
175  {return corpus()->get_exported_decls_builder().get();}
176 
177  /// Associate a given CTF type ID with a given libabigail IR type.
178  ///
179  /// The IR type is a newly created type that needs to be
180  /// canonicalized at the end of the processing of the current
181  /// corpus.
182  ///
183  /// @param dic the dictionnary the type belongs to.
184  ///
185  /// @param ctf_type the type ID.
186  ///
187  /// @param type the type to associate to the ID.
188  void
189  add_type(ctf_dict_t *dic, ctf_id_t ctf_type, type_base_sptr type)
190  {
191  string key = dic_type_key(dic, ctf_type);
192  if (types_map.insert(std::make_pair(key, type)).second)
193  types_to_canonicalize.push_back(type);
194  }
195 
196  /// Add a type to the vector of types to be (sorted and)
197  /// canonicalized.
198  ///
199  /// @param t the type to schedule for canonicalization.
200  void
201  add_type(const type_base_sptr& t)
202  {additional_types_to_canonicalize.push_back(t);}
203 
204  /// Insert a given CTF unknown type ID.
205  ///
206  /// @param ctf_type the unknown type ID to be added.
207  void
208  add_unknown_type(ctf_id_t ctf_type)
209  {
210  unknown_types_set.insert(ctf_type);
211  }
212 
213  /// Lookup a given CTF type ID in the types map.
214  ///
215  /// @param dic the dictionnary the type belongs to.
216  ///
217  /// @param ctf_type the type ID of the type to lookup.
218  type_base_sptr
219  lookup_type(ctf_dict_t *dic, ctf_id_t ctf_type)
220  {
221  type_base_sptr result;
222  std::string key = dic_type_key(dic, ctf_type);
223 
224  auto search = types_map.find(key);
225  if (search != types_map.end())
226  result = search->second;
227 
228  return result;
229  }
230 
231  /// Lookup a given CTF unknown type ID in the unknown set.
232  /// @param ctf_type the unknown type ID to lookup.
233  bool
234  lookup_unknown_type(ctf_id_t ctf_type)
235  { return unknown_types_set.find(ctf_type) != unknown_types_set.end(); }
236 
237  /// Canonicalize all the types stored in the types map.
238  void
239  canonicalize_all_types(void)
240  {
241  for (auto& t: additional_types_to_canonicalize)
242  types_to_canonicalize.push_back(t);
243  additional_types_to_canonicalize.clear();
244 
245  ir::hash_and_canonicalize_types(types_to_canonicalize.begin(),
246  types_to_canonicalize.end(),
247  [](vector<type_base_sptr>::iterator& i)
248  {return *i;});
249  }
250 
251  /// Constructor.
252  ///
253  /// @param elf_path the path to the ELF file.
254  ///
255  /// @param debug_info_root_paths vector with the paths
256  /// to directories where .debug file is located.
257  ///
258  /// @param env the environment used by the current context.
259  /// This environment contains resources needed by the reader and by
260  /// the types and declarations that are to be created later. Note
261  /// that ABI artifacts that are to be compared all need to be
262  /// created within the same environment.
263  reader(const string& elf_path,
264  const vector<string>& debug_info_root_paths,
265  environment& env)
266  : elf_based_reader(elf_path, debug_info_root_paths, env),
267  ctfa(), ctf_sect(), symtab_sect(), strtab_sect()
268  {
269  reset();
270  }
271 
272  /// Initializer of the reader.
273  ///
274  /// This is useful to clear out the data used by the reader and get
275  /// it ready to be used again.
276  ///
277  /// Note that the reader keeps (doesn't clear) the same environment
278  /// it has been originally created with.
279  ///
280  /// Please also note that the life time of this environment object
281  /// must be greater than the life time of the resulting @ref reader
282  /// the context uses resources that are allocated in the
283  /// environment.
284  void
285  reset()
286  {
287  types_to_canonicalize.clear();
288  cur_tu_.reset();
289  }
290 
291  /// Initializer of the reader.
292  ///
293  /// This first makes sure the data used by the reader is cleared.
294  /// And then it initlizes it with the information passed in
295  /// argument.
296  ///
297  /// This is useful to clear out the data used by the reader and get
298  /// it ready to be used again.
299  ///
300  /// Note that the reader keeps the same environment it has been
301  /// originally created with.
302  ///
303  /// @param elf_path the new path to the new ELF file to use.
304  ///
305  /// @param debug_info_root_paths a vector of paths to use to look
306  /// for debug info that is split out into a separate file.
307  ///
308  /// @param load_all_types currently not used.
309  ///
310  /// @param linux_kernel_mode currently not used.
311  ///
312  void
313  initialize(const string& elf_path,
314  const vector<string>& debug_info_root_paths,
315  bool load_all_types = false,
316  bool linux_kernel_mode = false)
317  {
318  reset();
319  options().load_all_types = load_all_types;
320  options().load_in_linux_kernel_mode = linux_kernel_mode;
321  elf_based_reader::initialize(elf_path, debug_info_root_paths);
322  }
323 
324  /// Setter of the current translation unit.
325  ///
326  /// @param tu the current translation unit being constructed.
327  void
328  cur_transl_unit(translation_unit_sptr tu)
329  {
330  if (tu)
331  cur_tu_ = tu;
332  }
333 
334  /// Getter of the current translation unit.
335  ///
336  /// @return the current translation unit being constructed.
337  const translation_unit_sptr&
338  cur_transl_unit() const
339  {return cur_tu_;}
340 
341  /// Getter of the environment of the current CTF reader.
342  ///
343  /// @return the environment of the current CTF reader.
344  const environment&
345  env() const
346  {return options().env;}
347 
348  /// Getter of the environment of the current CTF reader.
349  ///
350  /// @return the environment of the current CTF reader.
351  environment&
352  env()
353  {return options().env;}
354 
355  /// Getter of the "do_log" flag.
356  ///
357  /// This flag tells if we should log about various internal
358  /// details.
359  ///
360  /// return the "do_log" flag.
361  bool
362  do_log() const
363  {return options().do_log;}
364 
365  /// Look for vmlinux.ctfa file in default directory or in
366  /// directories provided by debug-info-dir command line option,
367  /// it stores location path in @ref ctfa_file.
368  ///
369  /// @param ctfa_file file name found.
370  /// @return true if file is found.
371  bool
372  find_ctfa_file(std::string& ctfa_file)
373  {
374  std::string ctfa_dirname;
375  dir_name(corpus_path(), ctfa_dirname, false);
376 
377  // In corpus group we assume vmlinux as first file to
378  // be processed, so default location for vmlinux.cfa
379  // is vmlinux dirname.
380  ctfa_file = ctfa_dirname + "/vmlinux.ctfa";
381  if (file_exists(ctfa_file))
382  return true;
383 
384  // If it's proccessing a module, then location directory
385  // for vmlinux.ctfa should be provided with --debug-info-dir
386  // option.
387  for (const auto& path : debug_info_root_paths())
388  if (tools_utils::find_file_under_dir(path, "vmlinux.ctfa", ctfa_file))
389  return true;
390 
391  return false;
392  }
393 
394  /// Slurp certain information from the underlying ELF file, and
395  /// install it the current libabigail corpus associated to the
396  /// current CTF reader.
397  ///
398  /// @param status the resulting status flags.
399  void
400  slurp_elf_info(fe_iface::status& status)
401  {
402  // Read the ELF-specific parts of the corpus.
403  elf::reader::read_corpus(status);
404 
405  corpus_sptr corp = corpus();
406 
407  if ((status & STATUS_NO_SYMBOLS_FOUND)
408  || !(status & STATUS_OK))
409  // Either we couldn't find ELF symbols or something went badly
410  // wrong. There is nothing we can do with this ELF file. Bail
411  // out.
412  return;
413 
414  GElf_Ehdr *ehdr, eh_mem;
415  if (!(ehdr = gelf_getehdr(elf_handle(), &eh_mem)))
416  return;
417 
418  // ET_{EXEC,DYN} needs .dyn{sym,str} in ctf_arc_bufopen
419  const char *symtab_name = ".dynsym";
420  const char *strtab_name = ".dynstr";
421 
422  if (ehdr->e_type == ET_REL)
423  {
424  symtab_name = ".symtab";
425  strtab_name = ".strtab";
426  }
427 
428  const Elf_Scn* ctf_scn = find_ctf_section();
429  if (ctf_scn)
430  fill_ctf_section(ctf_scn, &ctf_sect);
431 
432  const Elf_Scn* symtab_scn =
433  elf_helpers::find_section_by_name(elf_handle(), symtab_name);
434  if (symtab_scn)
435  fill_ctf_section(symtab_scn, &symtab_sect);
436 
437  const Elf_Scn* strtab_scn =
438  elf_helpers::find_section_by_name(elf_handle(), strtab_name);
439  if (strtab_scn)
440  fill_ctf_section(strtab_scn, &strtab_sect);
441 
442  if (ctf_scn && symtab_scn && strtab_scn)
443  status |= fe_iface::STATUS_OK;
444  else if (corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
445  {
446  // Not finding any debug info so far is expected if we are
447  // building a kABI.
448  status &= static_cast<abigail::fe_iface::status>
449  (~STATUS_DEBUG_INFO_NOT_FOUND);
450  return;
451  }
452  }
453 
454  /// Process a CTF archive and create libabigail IR for the types,
455  /// variables and function declarations found in the archive, iterating
456  /// over public symbols. The IR is added to the given corpus.
457  void
458  process_ctf_archive()
459  {
460  corpus_sptr corp = corpus();
461  /* We only have a translation unit. */
462  translation_unit_sptr ir_translation_unit =
463  std::make_shared<translation_unit>(env(), "", 64);
464  ir_translation_unit->set_language(translation_unit::LANG_C);
465  corp->add(ir_translation_unit);
466  cur_transl_unit(ir_translation_unit);
467 
468  ctf_dict_t *ctf_dict = nullptr, *initial_ctf_dict = nullptr;
469  const auto symt = symtab();
470  symtab_reader::symtab_filter filter = symt->make_filter();
471  filter.set_public_symbols();
472 
473  ctf_next_t *it = nullptr;
474  // Iterate through the dictionnaries of the archive and get the
475  // first one, which should be the parent dictionnary.
476  initial_ctf_dict = ctf_archive_next(ctfa, /*iterator=*/&it,
477  /*dict_name=*/nullptr,
478  /*skip_parent=*/false,
479  /*ctf_error=*/nullptr);
480  if (!initial_ctf_dict)
481  {
482  std::cerr << "Could not find any dictionnary in the CTF archive\n";
483  ctf_next_destroy(it);
484  return;
485  }
486 
487  ctf_dict = initial_ctf_dict;
488  for (const auto& symbol : symtab_reader::filtered_symtab(*symt, filter))
489  {
490  std::string sym_name = symbol->get_name();
491  ctf_id_t ctf_sym_type;
492 
493  ctf_sym_type = lookup_symbol_in_ctf_archive(ctfa, &ctf_dict,
494  sym_name.c_str());
495  if (ctf_sym_type == CTF_ERR)
496  continue;
497 
498  if (ctf_type_kind(ctf_dict, ctf_sym_type) != CTF_K_FUNCTION)
499  {
500  const char *var_name = sym_name.c_str();
501  type_base_sptr var_type = build_type(ctf_dict, ctf_sym_type);
502  if (!var_type)
503  /* Ignore variable if its type can't be sorted out. */
504  continue;
505 
506  var_decl_sptr var_declaration;
507  var_declaration.reset(new var_decl(var_name,
508  var_type,
509  location(),
510  var_name));
511 
512  var_declaration->set_symbol(symbol);
513  add_decl_to_scope(var_declaration,
514  ir_translation_unit->get_global_scope());
515  var_declaration->set_is_in_public_symbol_table(true);
516  add_var_to_exported_or_undefined_decls(var_declaration);
517  }
518  else
519  {
520  const char *func_name = sym_name.c_str();
521  ctf_id_t ctf_sym = ctf_sym_type;
522  type_base_sptr func_type = build_type(ctf_dict, ctf_sym);
523  if (!func_type)
524  /* Ignore function if its type can't be sorted out. */
525  continue;
526 
527  function_decl_sptr func_declaration;
528  func_declaration.reset(new function_decl(func_name,
529  func_type,
530  0 /* is_inline */,
531  location()));
532  func_declaration->set_symbol(symbol);
533  add_decl_to_scope(func_declaration,
534  ir_translation_unit->get_global_scope());
535  func_declaration->set_is_in_public_symbol_table(true);
536  add_fn_to_exported_or_undefined_decls(func_declaration.get());
537  }
538  if (ctf_dict != initial_ctf_dict)
539  {
540  ctf_dict_close(initial_ctf_dict);
541  initial_ctf_dict = ctf_dict;
542  }
543  }
544  ctf_dict_close(ctf_dict);
545  ctf_next_destroy(it);
546  }
547 
548  /// Add a new type declaration to the given libabigail IR corpus CORP.
549  ///
550  /// @param ctf_dictionary the CTF dictionary being read.
551  /// @param ctf_type the CTF type ID of the source type.
552  ///
553  /// Note that if @ref ctf_type can't reliably be translated to the IR
554  /// then it is simply ignored.
555  ///
556  /// @return a shared pointer to the IR node for the type.
557  type_base_sptr
558  process_ctf_type(ctf_dict_t *ctf_dictionary,
559  ctf_id_t ctf_type)
560  {
561  corpus_sptr corp = corpus();
562  translation_unit_sptr tunit = cur_transl_unit();
563  int type_kind = ctf_type_kind(ctf_dictionary, ctf_type);
564  type_base_sptr result;
565 
566  if (lookup_unknown_type(ctf_type))
567  return nullptr;
568 
569  if ((result = lookup_type(ctf_dictionary, ctf_type)))
570  return result;
571 
572  switch (type_kind)
573  {
574  case CTF_K_INTEGER:
575  case CTF_K_FLOAT:
576  {
578  = process_ctf_base_type(this, ctf_dictionary, ctf_type);
579  result = is_type(type_decl);
580  break;
581  }
582  case CTF_K_TYPEDEF:
583  {
585  = process_ctf_typedef(this, ctf_dictionary, ctf_type);
586  result = is_type(typedef_decl);
587  break;
588  }
589  case CTF_K_POINTER:
590  {
591  pointer_type_def_sptr pointer_type
592  = process_ctf_pointer_type(this, ctf_dictionary, ctf_type);
593  result = pointer_type;
594  break;
595  }
596  case CTF_K_CONST:
597  case CTF_K_VOLATILE:
598  case CTF_K_RESTRICT:
599  {
600  type_base_sptr qualified_type
601  = process_ctf_qualified_type(this, ctf_dictionary, ctf_type);
602  result = qualified_type;
603  break;
604  }
605  case CTF_K_ARRAY:
606  {
607  array_type_def_sptr array_type
608  = process_ctf_array_type(this, ctf_dictionary, ctf_type);
609  result = array_type;
610  break;
611  }
612  case CTF_K_ENUM:
613  {
614  enum_type_decl_sptr enum_type
615  = process_ctf_enum_type(this, ctf_dictionary, ctf_type);
616  result = enum_type;
617  break;
618  }
619  case CTF_K_FUNCTION:
620  {
622  = process_ctf_function_type(this, ctf_dictionary, ctf_type);
623  result = function_type;
624  break;
625  }
626  case CTF_K_STRUCT:
627  {
628  class_decl_sptr struct_decl
629  = process_ctf_struct_type(this, ctf_dictionary, ctf_type);
630  result = is_type(struct_decl);
631  break;
632  }
633  case CTF_K_FORWARD:
634  result = process_ctf_forward_type(this, ctf_dictionary, ctf_type);
635  break;
636  case CTF_K_UNION:
637  {
638  union_decl_sptr union_decl
639  = process_ctf_union_type(this, ctf_dictionary, ctf_type);
640  result = is_type(union_decl);
641  break;
642  }
643  case CTF_K_UNKNOWN:
644  /* Unknown types are simply ignored. */
645  default:
646  break;
647  }
648 
649  if (!result)
650  {
651  fprintf(stderr, "NOT PROCESSED TYPE %lu\n", ctf_type);
652  add_unknown_type(ctf_type);
653  }
654 
655  return result;
656  }
657 
658  /// Given a CTF type id, build the corresponding libabigail IR type.
659  /// If the IR type has been generated it returns the corresponding
660  /// type.
661  ///
662  /// @param ctf_dictionary the CTF dictionary being read.
663  /// @param ctf_type the CTF type ID of the looked type.
664  ///
665  /// Note that if @ref ctf_type can't reliably be translated to the IR
666  /// then a NULL shared pointer is returned.
667  ///
668  /// @return a shared pointer to the IR node for the type.
669  type_base_sptr
670  build_type(ctf_dict_t *ctf_dictionary, ctf_id_t ctf_type)
671  {
672  type_base_sptr result = lookup_type(ctf_dictionary, ctf_type);
673 
674  if (!result)
675  result = process_ctf_type(ctf_dictionary, ctf_type);
676  return result;
677  }
678 
679  /// Read the CTF information in the binary and construct an ABI
680  /// corpus from it.
681  ///
682  /// @param status output parameter. Contains the status of the ABI
683  /// corpus construction.
684  ///
685  /// @return the corpus created as a result of processing the debug
686  /// information.
687  corpus_sptr
688  read_corpus(fe_iface::status &status)
689  {
690  corpus_sptr corp = corpus();
691  status = fe_iface::STATUS_UNKNOWN;
692 
693  corpus::origin origin = corpus()->get_origin();
694  origin |= corpus::CTF_ORIGIN;
695  corp->set_origin(origin);
696  if (corpus_group())
697  {
698  origin |= corpus_group()->get_origin();
699  corpus_group()->set_origin(origin);
700  }
701 
702  slurp_elf_info(status);
704  return corpus_sptr();
705 
706  if (!(origin & corpus::LINUX_KERNEL_BINARY_ORIGIN)
708  return corp;
709 
710 #ifdef WITH_DEBUG_SELF_COMPARISON
711  if (env().self_comparison_debug_is_on())
712  {
713  corpus_group_sptr g = corpus_group();
714  if (g)
715  env().set_self_comparison_debug_input(g);
716  else
717  env().set_self_comparison_debug_input(corpus());
718  }
719 #endif
720 
722  if (do_log())
723  t.start();
724 
725  int errp;
726  if (corp->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
727  {
728  if (ctfa == nullptr)
729  {
730  std::string ctfa_filename;
731  if (find_ctfa_file(ctfa_filename))
732  ctfa = ctf_arc_open(ctfa_filename.c_str(), &errp);
733  }
734  }
735 
736  /* Build the ctfa from the contents of the relevant ELF sections,
737  and process the CTF archive in the read context, if any.
738  Information about the types, variables, functions, etc contained
739  in the archive are added to the given corpus. */
740  if (ctfa == nullptr
741  && ctf_sect.cts_data
742  && symtab_sect.cts_data
743  && strtab_sect.cts_data)
744  ctfa = ctf_arc_bufopen(&ctf_sect, &symtab_sect,
745  &strtab_sect, &errp);
746 
747  if (do_log())
748  {
749  t.stop();
750  cerr << "CTF Reader: Reading CTF info in:" << t << "\n";
751  t.start();
752  }
753 
754  env().canonicalization_is_done(false);
755  if (ctfa == NULL)
757  else
758  {
759  process_ctf_archive();
760  /* Canonicalize all the types generated above. This must be
761  done "a posteriori" because the processing of types may
762  require other related types to not be already
763  canonicalized. */
764  canonicalize_all_types();
765  corpus()->sort_functions();
766  corpus()->sort_variables();
767  }
768 
769  env().canonicalization_is_done(true);
770 
771  if (do_log())
772  {
773  t.stop();
774  cerr << "CTF Reader: Building ABG-IR in:" << t << "\n";
775  }
776 
777  return corp;
778  }
779 
780  /// Destructor of the CTF reader.
781  ~reader()
782  {
783  ctf_close(ctfa);
784  ctfa = nullptr;
785  }
786 }; // end class reader.
787 
788 typedef shared_ptr<reader> reader_sptr;
789 
790 /// Build and return a typedef libabigail IR.
791 ///
792 /// @param rdr the read context.
793 /// @param ctf_dictionary the CTF dictionary being read.
794 /// @param ctf_type the CTF type ID of the source type.
795 ///
796 /// @return a shared pointer to the IR node for the typedef.
797 
798 static typedef_decl_sptr
799 process_ctf_typedef(reader *rdr,
800  ctf_dict_t *ctf_dictionary,
801  ctf_id_t ctf_type)
802 {
803  corpus_sptr corp = rdr->corpus();
804  translation_unit_sptr tunit = rdr->cur_transl_unit();
805  typedef_decl_sptr result;
806 
807  ctf_id_t ctf_utype = ctf_type_reference(ctf_dictionary, ctf_type);
808  if (ctf_utype == CTF_ERR)
809  return result;
810 
811  const char *typedef_name = ctf_type_name_raw(ctf_dictionary, ctf_type);
812  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
813  if ((result = lookup_typedef_type(typedef_name, *corp)))
814  return result;
815 
816  type_base_sptr utype = rdr->build_type(ctf_dictionary, ctf_utype);
817 
818  if (!utype)
819  return result;
820 
821  result = dynamic_pointer_cast<typedef_decl>
822  (rdr->lookup_type(ctf_dictionary, ctf_type));
823  if (result)
824  return result;
825 
826  result.reset(new typedef_decl(typedef_name, utype, location(),
827  typedef_name /* mangled_name */));
828 
829  /* If this typedef "names" an anonymous type, reflect this fact in
830  the underlying type. In C enum, struct and union types can be
831  anonymous. */
832  if (is_anonymous_type(utype)
833  && (is_enum_type(utype) || is_class_or_union_type(utype)))
834  {
835  decl_base_sptr decl = is_decl(utype);
836  ABG_ASSERT(decl);
837  decl->set_naming_typedef(result);
838  }
839 
840  if (result)
841  {
842  add_decl_to_scope(result, tunit->get_global_scope());
843  rdr->add_type(ctf_dictionary, ctf_type, result);
844  }
845 
846  return result;
847 }
848 
849 /// Build and return an integer or float type declaration libabigail
850 /// IR.
851 ///
852 /// @param rdr the read context.
853 /// @param ctf_dictionary the CTF dictionary being read.
854 /// @param ctf_type the CTF type ID of the source type.
855 ///
856 /// @return a shared pointer to the IR node for the type.
857 
858 static type_decl_sptr
859 process_ctf_base_type(reader *rdr,
860  ctf_dict_t *ctf_dictionary,
861  ctf_id_t ctf_type)
862 {
863  corpus_sptr corp = rdr->corpus();
864  translation_unit_sptr tunit = rdr->cur_transl_unit();
865  type_decl_sptr result;
866 
867  ctf_id_t ctf_ref = ctf_type_reference(ctf_dictionary, ctf_type);
868  const char *type_name = ctf_type_name_raw(ctf_dictionary,
869  (ctf_ref != CTF_ERR) ? ctf_ref : ctf_type);
870 
871  /* Get the type encoding and extract some useful properties of
872  the type from it. In case of any error, just ignore the
873  type. */
874  ctf_encoding_t type_encoding;
875  if (ctf_type_encoding(ctf_dictionary,
876  (ctf_ref != CTF_ERR) ? ctf_ref : ctf_type,
877  &type_encoding))
878  return result;
879 
880  /* Create the IR type corresponding to the CTF type. */
881  if (type_encoding.cte_bits == 0
882  && type_encoding.cte_format == CTF_INT_SIGNED)
883  {
884  /* This is the `void' type. */
885  decl_base_sptr type_declaration = build_ir_node_for_void_type(*rdr,
886  tunit);
887  type_base_sptr void_type = is_type(type_declaration);
888  result = is_type_decl(type_declaration);
889  }
890  else
891  {
892  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
893  {
894  string normalized_type_name = type_name;
896  if (parse_real_type(type_name, real_type))
897  normalized_type_name = real_type.to_string();
898  if ((result = lookup_basic_type(normalized_type_name, *corp)))
899  return result;
900  }
901 
902  result = lookup_basic_type(type_name, *corp);
903  if (!result)
904  result.reset(new type_decl(rdr->env(),
905  type_name,
906  type_encoding.cte_bits,
907  /*alignment=*/0,
908  location(),
909  type_name /* mangled_name */));
910 
911  }
912 
913  if (result)
914  {
915  add_decl_to_scope(result, tunit->get_global_scope());
916  rdr->add_type(ctf_dictionary, ctf_type, result);
917  }
918 
919  return result;
920 }
921 
922 /// Build the IR node for a variadic parameter type.
923 ///
924 /// @param rdr the read context to use.
925 ///
926 /// @param tunit the translation unit it should belong to.
927 ///
928 /// @return the variadic parameter type.
929 static decl_base_sptr
930 build_ir_node_for_variadic_parameter_type(reader &rdr,
931  const translation_unit_sptr& tunit)
932 {
933 
934  const ir::environment& env = rdr.env();
935  type_base_sptr t = env.get_variadic_parameter_type();
936  decl_base_sptr type_declaration = get_type_declaration(t);
937  add_decl_to_scope(type_declaration, tunit->get_global_scope());
938  rdr.add_type(t);
939  return type_declaration;
940 }
941 
942 /// Build the IR node for a void type.
943 ///
944 /// Note that this returns the unique pointer
945 /// environment::get_void_type(), which is added to the current
946 /// translation unit if it's the first it's being used.
947 ///
948 /// @param rdr the read context to use.
949 ///
950 /// @param tunit the translation unit it should belong to.
951 ///
952 /// @return the void type type.
953 static decl_base_sptr
954 build_ir_node_for_void_type(reader& rdr, const translation_unit_sptr& tunit)
955 {
956  const environment& env = rdr.env();
957  type_base_sptr t = env.get_void_type();
958  add_decl_to_scope(is_decl(t), tunit->get_global_scope());
959  rdr.add_type(t);
960  return is_decl(t);
961 }
962 
963 /// Build the IR node for a void pointer type.
964 ///
965 /// Note that this returns the unique pointer
966 /// environment::get_void_pointer_type(), which is added to the
967 /// current translation unit if it's the first it's being used.
968 ///
969 /// @param rdr the read context to use.
970 ///
971 /// @param tunit the translation unit it should belong to.
972 ///
973 /// @return the void pointer type.
975 build_ir_node_for_void_pointer_type(reader& rdr,
976  const translation_unit_sptr& tunit)
977 {
978  const environment& env = rdr.env();
979  type_base_sptr t = env.get_void_pointer_type();
980  add_decl_to_scope(is_decl(t), tunit->get_global_scope());
981  rdr.add_type(t);
982  return is_decl(t);
983 }
984 
985 /// Build and return a function type libabigail IR.
986 ///
987 /// @param rdr the read context.
988 /// @param ctf_dictionary the CTF dictionary being read.
989 /// @param ctf_type the CTF type ID of the source type.
990 ///
991 /// @return a shared pointer to the IR node for the function type.
992 
993 static function_type_sptr
994 process_ctf_function_type(reader *rdr,
995  ctf_dict_t *ctf_dictionary,
996  ctf_id_t ctf_type)
997 {
998  corpus_sptr corp = rdr->corpus();
999  translation_unit_sptr tunit = rdr->cur_transl_unit();
1000  function_type_sptr result;
1001 
1002  /* Fetch the function type info from the CTF type. */
1003  ctf_funcinfo_t funcinfo;
1004  ctf_func_type_info(ctf_dictionary, ctf_type, &funcinfo);
1005  int vararg_p = funcinfo.ctc_flags & CTF_FUNC_VARARG;
1006 
1007  /* Take care first of the result type. */
1008  ctf_id_t ctf_ret_type = funcinfo.ctc_return;
1009  type_base_sptr ret_type = rdr->build_type(ctf_dictionary, ctf_ret_type);
1010  if (!ret_type)
1011  return result;
1012 
1013  /* Now process the argument types. */
1014  int argc = funcinfo.ctc_argc;
1015  std::vector<ctf_id_t> argv(argc);
1016  if (static_cast<ctf_id_t>(ctf_func_type_args(ctf_dictionary, ctf_type,
1017  argc, argv.data())) == CTF_ERR)
1018  return result;
1019 
1020  function_decl::parameters function_parms;
1021  for (int i = 0; i < argc; i++)
1022  {
1023  ctf_id_t ctf_arg_type = argv[i];
1024  type_base_sptr arg_type = rdr->build_type(ctf_dictionary, ctf_arg_type);
1025  if (!arg_type)
1026  return result;
1027 
1029  (new function_decl::parameter(arg_type, "",
1030  location(),
1031  false,
1032  false /* is_artificial */));
1033  function_parms.push_back(parm);
1034  }
1035 
1036  if (vararg_p)
1037  {
1038  type_base_sptr arg_type =
1039  is_type(build_ir_node_for_variadic_parameter_type(*rdr, tunit));
1040 
1042  (new function_decl::parameter(arg_type, "",
1043  location(),
1044  true,
1045  false /* is_artificial */));
1046  function_parms.push_back(parm);
1047  }
1048 
1049  result = dynamic_pointer_cast<function_type>
1050  (rdr->lookup_type(ctf_dictionary, ctf_type));
1051  if (result)
1052  return result;
1053 
1054  /* Ok now the function type itself. */
1055  result.reset(new function_type(ret_type,
1056  function_parms,
1057  tunit->get_address_size(),
1058  /*alignment=*/0));
1059 
1060  if (result)
1061  {
1062  tunit->bind_function_type_life_time(result);
1063  result->set_is_artificial(true);
1064  decl_base_sptr function_type_decl = get_type_declaration(result);
1065  add_decl_to_scope(function_type_decl, tunit->get_global_scope());
1066  rdr->add_type(ctf_dictionary, ctf_type, result);
1067  }
1068 
1069  return result;
1070 }
1071 
1072 /// Add member information to a IR struct or union type.
1073 ///
1074 /// @param rdr the read context.
1075 /// @param ctf_dictionary the CTF dictionary being read.
1076 /// @param ctf_type the CTF type ID of the source type.
1077 /// @param sou the IR struct or union type to which add the members.
1078 
1079 static void
1080 process_ctf_sou_members(reader *rdr,
1081  ctf_dict_t *ctf_dictionary,
1082  ctf_id_t ctf_type,
1083  class_or_union_sptr sou)
1084 {
1085  corpus_sptr corp = rdr->corpus();
1086  translation_unit_sptr tunit = rdr->cur_transl_unit();
1087  ssize_t member_size;
1088  ctf_next_t *member_next = NULL;
1089  const char *member_name = NULL;
1090  ctf_id_t member_ctf_type;
1091 
1092  while ((member_size = ctf_member_next(ctf_dictionary, ctf_type,
1093  &member_next, &member_name,
1094  &member_ctf_type,
1095  0 /* flags */)) >= 0)
1096  {
1097  ctf_membinfo_t membinfo;
1098 
1099  if (static_cast<ctf_id_t>(ctf_member_info(ctf_dictionary,
1100  ctf_type,
1101  member_name,
1102  &membinfo)) == CTF_ERR)
1103  return;
1104 
1105  /* Build the IR for the member's type. */
1106  type_base_sptr member_type = rdr->build_type(ctf_dictionary,
1107  member_ctf_type);
1108  if (!member_type)
1109  /* Ignore this member. */
1110  continue;
1111 
1112  /* Create a declaration IR node for the member and add it to the
1113  struct type. */
1114  var_decl_sptr data_member_decl(new var_decl(member_name,
1115  member_type,
1116  location(),
1117  member_name));
1118  sou->add_data_member(data_member_decl,
1119  public_access,
1120  true /* is_laid_out */,
1121  false /* is_static */,
1122  is_union_type(sou) ? 0 : membinfo.ctm_offset);
1123  }
1124  if (ctf_errno(ctf_dictionary) != ECTF_NEXT_END)
1125  fprintf(stderr, "ERROR from ctf_member_next\n");
1126 }
1127 
1128 /// Create a declaration-only union or struct type and add it to the
1129 /// IR.
1130 ///
1131 /// @param rdr the read context.
1132 /// @param ctf_dictionary the CTF dictionary being read.
1133 /// @param ctf_type the CTF type ID of the source type.
1134 /// @return the resulting IR node created.
1135 
1136 static type_base_sptr
1137 process_ctf_forward_type(reader *rdr,
1138  ctf_dict_t *ctf_dictionary,
1139  ctf_id_t ctf_type)
1140 {
1141  translation_unit_sptr tunit = rdr->cur_transl_unit();
1142  decl_base_sptr result;
1143  std::string type_name = ctf_type_name_raw(ctf_dictionary,
1144  ctf_type);
1145  bool type_is_anonymous = (type_name == "");
1146  uint32_t kind = ctf_type_kind_forwarded (ctf_dictionary, ctf_type);
1147 
1148  if (kind == CTF_K_UNION)
1149  {
1150  union_decl_sptr
1151  union_fwd(new union_decl(rdr->env(),
1152  type_name,
1153  /*alignment=*/0,
1154  location(),
1155  decl_base::VISIBILITY_DEFAULT,
1156  type_is_anonymous));
1157  union_fwd->set_is_declaration_only(true);
1158  result = union_fwd;
1159  }
1160  else
1161  {
1162  if (!type_is_anonymous)
1163  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1164  if ((result = lookup_class_type(type_name, *corp)))
1165  return is_type(result);
1166 
1168  struct_fwd(new class_decl(rdr->env(), type_name,
1169  /*alignment=*/0, /*size=*/0,
1170  true /* is_struct */,
1171  location(),
1172  decl_base::VISIBILITY_DEFAULT,
1173  type_is_anonymous));
1174  struct_fwd->set_is_declaration_only(true);
1175  result = struct_fwd;
1176  }
1177 
1178  if (!result)
1179  return is_type(result);
1180 
1181  add_decl_to_scope(result, tunit->get_global_scope());
1182  rdr->add_type(ctf_dictionary, ctf_type, is_type(result));
1183 
1184  return is_type(result);
1185 }
1186 
1187 /// Build and return a struct type libabigail IR.
1188 ///
1189 /// @param rdr the read context.
1190 /// @param ctf_dictionary the CTF dictionary being read.
1191 /// @param ctf_type the CTF type ID of the source type.
1192 ///
1193 /// @return a shared pointer to the IR node for the struct type.
1194 
1195 static class_decl_sptr
1196 process_ctf_struct_type(reader *rdr,
1197  ctf_dict_t *ctf_dictionary,
1198  ctf_id_t ctf_type)
1199 {
1200  corpus_sptr corp = rdr->corpus();
1201  translation_unit_sptr tunit = rdr->cur_transl_unit();
1202  class_decl_sptr result;
1203  std::string struct_type_name = ctf_type_name_raw(ctf_dictionary,
1204  ctf_type);
1205  bool struct_type_is_anonymous = (struct_type_name == "");
1206 
1207  if (!struct_type_is_anonymous)
1208  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1209  if ((result = lookup_class_type(struct_type_name, *corp)))
1210  return result;
1211 
1212  /* The libabigail IR encodes C struct types in `class' IR nodes. */
1213  result.reset(new class_decl(rdr->env(),
1214  struct_type_name,
1215  ctf_type_size(ctf_dictionary, ctf_type) * 8,
1216  /*alignment=*/0,
1217  true /* is_struct */,
1218  location(),
1219  decl_base::VISIBILITY_DEFAULT,
1220  struct_type_is_anonymous));
1221  if (!result)
1222  return result;
1223 
1224  /* The C type system indirectly supports loops by the mean of
1225  pointers to structs or unions. Since some contained type can
1226  refer to this struct, we have to make it available in the cache
1227  at this point even if the members haven't been added to the IR
1228  node yet. */
1229  add_decl_to_scope(result, tunit->get_global_scope());
1230  rdr->add_type(ctf_dictionary, ctf_type, result);
1231 
1232  /* Now add the struct members as specified in the CTF type description.
1233  This is C, so named types can only be defined in the global
1234  scope. */
1235  process_ctf_sou_members(rdr, ctf_dictionary, ctf_type, result);
1236 
1237  return result;
1238 }
1239 
1240 /// Build and return an union type libabigail IR.
1241 ///
1242 /// @param rdr the read context.
1243 /// @param ctf_dictionary the CTF dictionary being read.
1244 /// @param ctf_type the CTF type ID of the source type.
1245 ///
1246 /// @return a shared pointer to the IR node for the union type.
1247 
1248 static union_decl_sptr
1249 process_ctf_union_type(reader *rdr,
1250  ctf_dict_t *ctf_dictionary,
1251  ctf_id_t ctf_type)
1252 {
1253  corpus_sptr corp = rdr->corpus();
1254  translation_unit_sptr tunit = rdr->cur_transl_unit();
1255  union_decl_sptr result;
1256  std::string union_type_name = ctf_type_name_raw(ctf_dictionary,
1257  ctf_type);
1258  bool union_type_is_anonymous = (union_type_name == "");
1259 
1260  if (!union_type_is_anonymous)
1261  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1262  if ((result = lookup_union_type(union_type_name, *corp)))
1263  return result;
1264 
1265  /* Create the corresponding libabigail union IR node. */
1266  result.reset(new union_decl(rdr->env(),
1267  union_type_name,
1268  ctf_type_size(ctf_dictionary, ctf_type) * 8,
1269  location(),
1270  decl_base::VISIBILITY_DEFAULT,
1271  union_type_is_anonymous));
1272  if (!result)
1273  return result;
1274 
1275  /* The C type system indirectly supports loops by the mean of
1276  pointers to structs or unions. Since some contained type can
1277  refer to this union, we have to make it available in the cache
1278  at this point even if the members haven't been added to the IR
1279  node yet. */
1280  add_decl_to_scope(result, tunit->get_global_scope());
1281  rdr->add_type(ctf_dictionary, ctf_type, result);
1282 
1283  /* Now add the union members as specified in the CTF type description.
1284  This is C, so named types can only be defined in the global
1285  scope. */
1286  process_ctf_sou_members(rdr, ctf_dictionary, ctf_type, result);
1287 
1288  return result;
1289 }
1290 
1291 /// Build and return an array subrange.
1292 ///
1293 /// @param rdr the read context.
1294 ///
1295 /// @param ctf_dictionary the CTF dictionary where @ref index
1296 /// will be found.
1297 ///
1298 /// @param index the CTF type ID for the array index.
1299 ///
1300 /// @param nelems the elements number of the array.
1301 ///
1302 /// @return a shared pointer to subrange built.
1304 build_array_ctf_range(reader *rdr, ctf_dict_t *dic,
1305  ctf_id_t index, uint64_t nelems)
1306 {
1307  bool is_non_finite = false;
1308  corpus_sptr corp = rdr->corpus();
1309  translation_unit_sptr tunit = rdr->cur_transl_unit();
1313 
1314  type_base_sptr index_type = rdr->build_type(dic, index);
1315  if (!index_type)
1316  return nullptr;
1317 
1318  lower_bound.set_unsigned(0); /* CTF supports C only. */
1319  upper_bound.set_unsigned(nelems > 0 ? nelems - 1 : 0U);
1320 
1321  /* for VLAs number of array elements is 0 */
1322  if (upper_bound.get_unsigned_value() == 0 && nelems == 0)
1323  is_non_finite = true;
1324 
1325  subrange.reset(new array_type_def::subrange_type(rdr->env(),
1326  "",
1327  lower_bound,
1328  upper_bound,
1329  index_type,
1330  location(),
1331  translation_unit::LANG_C));
1332  if (!index_type)
1333  subrange->set_size_in_bits(rdr->cur_transl_unit()->get_address_size());
1334 
1335  if (!subrange)
1336  return nullptr;
1337 
1338  subrange->is_non_finite(is_non_finite);
1339  add_decl_to_scope(subrange, tunit->get_global_scope());
1340  rdr->add_type(subrange);
1341  return subrange;
1342 }
1343 
1344 /// Build and return an array type libabigail IR.
1345 ///
1346 /// @param rdr the read context.
1347 ///
1348 /// @param ctf_dictionary the CTF dictionary being read.
1349 ///
1350 /// @param ctf_type the CTF type ID of the source type.
1351 ///
1352 /// @return a shared pointer to the IR node for the array type.
1353 static array_type_def_sptr
1354 process_ctf_array_type(reader *rdr,
1355  ctf_dict_t *ctf_dictionary,
1356  ctf_id_t ctf_type)
1357 {
1358  corpus_sptr corp = rdr->corpus();
1359  translation_unit_sptr tunit = rdr->cur_transl_unit();
1360  array_type_def_sptr result;
1361  ctf_arinfo_t ctf_ainfo;
1362 
1363  /* First, get the information about the CTF array. */
1364  if (static_cast<ctf_id_t>(ctf_array_info(ctf_dictionary,
1365  ctf_type,
1366  &ctf_ainfo)) == CTF_ERR)
1367  return result;
1368 
1369  ctf_id_t ctf_element_type = ctf_ainfo.ctr_contents;
1370  ctf_id_t ctf_index_type = ctf_ainfo.ctr_index;
1371  uint64_t nelems = ctf_ainfo.ctr_nelems;
1374 
1375  int type_array_kind = ctf_type_kind(ctf_dictionary, ctf_element_type);
1376  while (type_array_kind == CTF_K_ARRAY)
1377  {
1378  if (static_cast<ctf_id_t>(ctf_array_info(ctf_dictionary,
1379  ctf_element_type,
1380  &ctf_ainfo)) == CTF_ERR)
1381  return result;
1382 
1383  subrange = build_array_ctf_range(rdr, ctf_dictionary,
1384  ctf_ainfo.ctr_index,
1385  ctf_ainfo.ctr_nelems);
1386  subranges.push_back(subrange);
1387  ctf_element_type = ctf_ainfo.ctr_contents;
1388  type_array_kind = ctf_type_kind(ctf_dictionary, ctf_element_type);
1389  }
1390 
1391  std::reverse(subranges.begin(), subranges.end());
1392 
1393  /* Make sure the element type is generated. */
1394  type_base_sptr element_type = rdr->build_type(ctf_dictionary,
1395  ctf_element_type);
1396  if (!element_type)
1397  return result;
1398 
1399  /* Ditto for the index type. */
1400  type_base_sptr index_type = rdr->build_type(ctf_dictionary,
1401  ctf_index_type);
1402  if (!index_type)
1403  return result;
1404 
1405  result = dynamic_pointer_cast<array_type_def>
1406  (rdr->lookup_type(ctf_dictionary, ctf_type));
1407  if (result)
1408  return result;
1409 
1410  subrange = build_array_ctf_range(rdr, ctf_dictionary,
1411  ctf_index_type, nelems);
1412  subranges.push_back(subrange);
1413 
1414  /* Finally build the IR for the array type and return it. */
1415  result.reset(new array_type_def(element_type, subranges, location()));
1416  if (result)
1417  {
1418  decl_base_sptr array_type_decl = get_type_declaration(result);
1419  add_decl_to_scope(array_type_decl, tunit->get_global_scope());
1420  rdr->add_type(ctf_dictionary, ctf_type, result);
1421  }
1422 
1423  return result;
1424 }
1425 
1426 /// Strip qualification from a qualified type, when it makes sense.
1427 ///
1428 /// The C language specification says in [6.7.3]/8:
1429 ///
1430 /// [If the specification of an array type includes any type
1431 /// qualifiers, the element type is so- qualified, not the
1432 /// array type.]
1433 ///
1434 /// In more mundane words, a const array of int is the same as an
1435 /// array of const int.
1436 ///
1437 /// This function thus removes the qualifiers of the array and applies
1438 /// them to the array element. The function then pretends that the
1439 /// array itself it not qualified.
1440 ///
1441 /// It might contain code to strip other cases like this in the
1442 /// future.
1443 ///
1444 /// @param t the type to strip const qualification from.
1445 ///
1446 /// @return the stripped type or just return @p t.
1447 static decl_base_sptr
1448 maybe_strip_qualification(const qualified_type_def_sptr t)
1449 {
1450  if (!t)
1451  return t;
1452 
1453  decl_base_sptr result = t;
1454  type_base_sptr u = t->get_underlying_type();
1455 
1456  if (is_array_type(u))
1457  {
1458  // Let's apply the qualifiers of the array to the array element
1459  // and pretend that the array itself is not qualified, as per
1460  // section [6.7.3]/8 of the C specification.
1461 
1463  ABG_ASSERT(array);
1464  // We should not be editing types that are already canonicalized.
1465  ABG_ASSERT(!array->get_canonical_type());
1466  type_base_sptr element_type = array->get_element_type();
1467 
1468  if (qualified_type_def_sptr qualified = is_qualified_type(element_type))
1469  {
1470  qualified_type_def::CV quals = qualified->get_cv_quals();
1471  quals |= t->get_cv_quals();
1472  // So we apply the qualifiers of the array to the array
1473  // element.
1474  qualified->set_cv_quals(quals);
1475  // Let's pretend that the array is no more qualified.
1476  result = is_decl(u);
1477  }
1478  }
1479 
1480  return result;
1481 }
1482 
1483 /// Build and return a qualified type libabigail IR.
1484 ///
1485 /// @param rdr the read context.
1486 /// @param ctf_dictionary the CTF dictionary being read.
1487 /// @param ctf_type the CTF type ID of the source type.
1488 
1489 static type_base_sptr
1490 process_ctf_qualified_type(reader *rdr,
1491  ctf_dict_t *ctf_dictionary,
1492  ctf_id_t ctf_type)
1493 {
1494  corpus_sptr corp = rdr->corpus();
1495  translation_unit_sptr tunit = rdr->cur_transl_unit();
1496  type_base_sptr result;
1497  int type_kind = ctf_type_kind(ctf_dictionary, ctf_type);
1498  ctf_id_t ctf_utype = ctf_type_reference(ctf_dictionary, ctf_type);
1499  type_base_sptr utype = rdr->build_type(ctf_dictionary, ctf_utype);
1500  if (!utype)
1501  return result;
1502 
1503  result = dynamic_pointer_cast<type_base>
1504  (rdr->lookup_type(ctf_dictionary, ctf_type));
1505  if (result)
1506  return result;
1507 
1508  qualified_type_def::CV qualifiers = qualified_type_def::CV_NONE;
1509  if (type_kind == CTF_K_CONST)
1510  qualifiers |= qualified_type_def::CV_CONST;
1511  else if (type_kind == CTF_K_VOLATILE)
1512  qualifiers |= qualified_type_def::CV_VOLATILE;
1513  else if (type_kind == CTF_K_RESTRICT)
1514  qualifiers |= qualified_type_def::CV_RESTRICT;
1515  else
1517 
1518  // qualifiers are not be use in functions
1519  if (is_function_type(utype))
1520  return result;
1521 
1522  result.reset(new qualified_type_def(utype, qualifiers, location()));
1523  if (result)
1524  {
1525  // Strip some potentially redundant type qualifiers from
1526  // the qualified type we just built.
1527  decl_base_sptr d = maybe_strip_qualification(is_qualified_type(result));
1528  if (!d)
1529  d = get_type_declaration(result);
1530  ABG_ASSERT(d);
1531 
1532  add_decl_to_scope(d, tunit->get_global_scope());
1533  result = is_type(d);
1534  rdr->add_type(ctf_dictionary, ctf_type, result);
1535  }
1536 
1537  return result;
1538 }
1539 
1540 /// Build and return a pointer type libabigail IR.
1541 ///
1542 /// @param rdr the read context.
1543 /// @param ctf_dictionary the CTF dictionary being read.
1544 /// @param ctf_type the CTF type ID of the source type.
1545 ///
1546 /// @return a shared pointer to the IR node for the pointer type.
1547 
1548 static pointer_type_def_sptr
1549 process_ctf_pointer_type(reader *rdr,
1550  ctf_dict_t *ctf_dictionary,
1551  ctf_id_t ctf_type)
1552 {
1553  corpus_sptr corp = rdr->corpus();
1554  translation_unit_sptr tunit = rdr->cur_transl_unit();
1555  pointer_type_def_sptr result;
1556  ctf_id_t ctf_target_type = ctf_type_reference(ctf_dictionary, ctf_type);
1557  if (ctf_target_type == CTF_ERR)
1558  return result;
1559 
1560  type_base_sptr target_type = rdr->build_type(ctf_dictionary,
1561  ctf_target_type);
1562  if (!target_type)
1563  return result;
1564 
1565  result = dynamic_pointer_cast<pointer_type_def>
1566  (rdr->lookup_type(ctf_dictionary, ctf_type));
1567  if (result)
1568  return result;
1569 
1570  if (rdr->env().is_void_type(target_type))
1571  result = is_pointer_type(build_ir_node_for_void_pointer_type(*rdr, tunit));
1572  else
1573  result.reset(new pointer_type_def(target_type,
1574  ctf_type_size(ctf_dictionary,
1575  ctf_type) * 8,
1576  ctf_type_align(ctf_dictionary,
1577  ctf_type) * 8,
1578  location()));
1579  if (result)
1580  {
1581  add_decl_to_scope(result, tunit->get_global_scope());
1582  rdr->add_type(ctf_dictionary, ctf_type, result);
1583  }
1584 
1585  return result;
1586 }
1587 
1588 /// Build and return an enum type libabigail IR.
1589 ///
1590 /// @param rdr the read context.
1591 /// @param ctf_dictionary the CTF dictionary being read.
1592 /// @param ctf_type the CTF type ID of the source type.
1593 ///
1594 /// @return a shared pointer to the IR node for the enum type.
1595 
1596 static enum_type_decl_sptr
1597 process_ctf_enum_type(reader *rdr,
1598  ctf_dict_t *ctf_dictionary,
1599  ctf_id_t ctf_type)
1600 {
1601  translation_unit_sptr tunit = rdr->cur_transl_unit();
1602  enum_type_decl_sptr result;
1603  ctf_id_t ctf_ref = ctf_type_reference(ctf_dictionary, ctf_type);
1604  std::string enum_name = ctf_type_name_raw(ctf_dictionary,
1605  (ctf_ref != CTF_ERR)
1606  ? ctf_ref : ctf_type);
1607 
1608  if (!enum_name.empty())
1609  if (corpus_sptr corp = rdr->should_reuse_type_from_corpus_group())
1610  if ((result = lookup_enum_type(enum_name, *corp)))
1611  return result;
1612 
1613  /* Build a signed integral type for the type of the enumerators, aka
1614  the underlying type. The size of the enumerators in bytes is
1615  specified in the CTF enumeration type. */
1616  size_t utype_size_in_bits = ctf_type_size(ctf_dictionary,
1617  (ctf_ref != CTF_ERR)
1618  ? ctf_ref : ctf_type) * 8;
1619  string underlying_type_name =
1621  utype_size_in_bits);
1622 
1623  type_decl_sptr utype;
1624  utype.reset(new type_decl(rdr->env(),
1625  underlying_type_name,
1626  utype_size_in_bits,
1627  utype_size_in_bits,
1628  location()));
1629  utype->set_is_anonymous(true);
1630  utype->set_is_artificial(true);
1631  if (!utype)
1632  return result;
1633 
1634  add_decl_to_scope(utype, tunit->get_global_scope());
1635  rdr->add_type(utype);
1636 
1637  /* Iterate over the enum entries. */
1639  ctf_next_t *enum_next = NULL;
1640  const char *ename;
1641  int evalue;
1642 
1643  while ((ename = ctf_enum_next(ctf_dictionary, ctf_type, &enum_next, &evalue)))
1644  enms.push_back(enum_type_decl::enumerator(ename, evalue));
1645 
1646  if (ctf_errno(ctf_dictionary) != ECTF_NEXT_END)
1647  {
1648  fprintf(stderr, "ERROR from ctf_enum_next\n");
1649  return result;
1650  }
1651 
1652  result.reset(new enum_type_decl(enum_name.c_str(), location(),
1653  utype, enms, enum_name.c_str()));
1654  if (result)
1655  {
1656  add_decl_to_scope(result, tunit->get_global_scope());
1657  rdr->add_type(ctf_dictionary, ctf_type, result);
1658  }
1659 
1660  return result;
1661 }
1662 
1663 /// Given a symbol name, lookup the corresponding CTF information in
1664 /// the default dictionary (CTF archive member provided by the caller)
1665 /// If the search is not success, the looks for the symbol name
1666 /// in _all_ archive members.
1667 ///
1668 /// @param ctfa the CTF archive.
1669 /// @param dict the default dictionary to looks for.
1670 /// @param sym_name the symbol name.
1671 /// @param corp the IR corpus.
1672 ///
1673 /// Note that if @ref sym_name is found in other than its default dictionary
1674 /// @ref ctf_dict will be updated and it must be explicitly closed by its
1675 /// caller.
1676 ///
1677 /// @return a valid CTF type id, if @ref sym_name was found, CTF_ERR otherwise.
1678 
1679 static ctf_id_t
1680 lookup_symbol_in_ctf_archive(ctf_archive_t *ctfa, ctf_dict_t **ctf_dict,
1681  const char *sym_name)
1682 {
1683  int ctf_err;
1684  ctf_dict_t *dict = *ctf_dict;
1685  ctf_id_t ctf_type = ctf_lookup_by_symbol_name(dict, sym_name);
1686 
1687  if (ctf_type != CTF_ERR)
1688  return ctf_type;
1689 
1690  /* Probably --ctf-variables option was used by ld, so symbol type
1691  definition must be found in the CTF Variable section. */
1692  ctf_type = ctf_lookup_variable(dict, sym_name);
1693 
1694  /* Not lucky, then, search in whole archive */
1695  if (ctf_type == CTF_ERR)
1696  {
1697  ctf_dict_t *fp;
1698  ctf_next_t *i = nullptr;
1699  const char *arcname = nullptr;
1700 
1701  while ((fp = ctf_archive_next(ctfa, &i, &arcname,
1702  /*skip_parent=*/true,
1703  &ctf_err)) != nullptr)
1704  {
1705  if ((ctf_type = ctf_lookup_by_symbol_name (fp, sym_name)) == CTF_ERR)
1706  ctf_type = ctf_lookup_variable(fp, sym_name);
1707  ctf_dict_close(fp);
1708  if (ctf_type != CTF_ERR)
1709  break;
1710  }
1711  ctf_next_destroy(i);
1712  }
1713 
1714  return ctf_type;
1715 }
1716 
1717 /// Fill a CTF section description with the information in a given ELF
1718 /// section.
1719 ///
1720 /// @param elf_section the ELF section from which to get.
1721 /// @param ctf_section the CTF section to fill with the raw data.
1722 
1723 static void
1724 fill_ctf_section(const Elf_Scn *elf_section, ctf_sect_t *ctf_section)
1725 {
1726  GElf_Shdr section_header_mem, *section_header;
1727  Elf_Data *section_data;
1728 
1729  section_header = gelf_getshdr(const_cast<Elf_Scn*>(elf_section),
1730  &section_header_mem);
1731  section_data = elf_getdata(const_cast<Elf_Scn*>(elf_section), 0);
1732 
1733  ABG_ASSERT (section_header != NULL);
1734  ABG_ASSERT (section_data != NULL);
1735 
1736  ctf_section->cts_name = ""; /* This is not actually used by libctf. */
1737  ctf_section->cts_data = (char *) section_data->d_buf;
1738  ctf_section->cts_size = section_data->d_size;
1739  ctf_section->cts_entsize = section_header->sh_entsize;
1740 }
1741 
1742 /// Create and return a new read context to process CTF information
1743 /// from a given ELF file.
1744 ///
1745 /// @param elf_path the patch of some ELF file.
1746 ///
1747 /// @param debug_info_root_paths the paths to where to find the debug
1748 /// info.
1749 ///
1750 /// @param env a libabigail IR environment.
1751 elf_based_reader_sptr
1752 create_reader(const std::string& elf_path,
1753  const vector<string>& debug_info_root_paths,
1754  environment& env)
1755 {
1756  reader_sptr result(new reader(elf_path,
1757  debug_info_root_paths,
1758  env));
1759 
1760 #ifdef WITH_DEBUG_SELF_COMPARISON
1761  if (env.self_comparison_debug_is_on())
1762  env.set_self_comparison_debug_input(result->corpus());
1763 #endif
1764 
1765  return result;
1766 }
1767 
1768 /// Re-initialize a reader so that it can re-used to read
1769 /// another binary.
1770 ///
1771 /// @param rdr the context to re-initialize.
1772 ///
1773 /// @param elf_path the path to the elf file the context is to be used
1774 /// for.
1775 ///
1776 /// @param debug_info_root_paths the paths pointing to where to find
1777 /// the debug info.
1778 void
1780  const std::string& elf_path,
1781  const vector<string>& debug_info_root_path)
1782 {
1783  ctf::reader& r = dynamic_cast<reader&>(rdr);
1784  r.initialize(elf_path, debug_info_root_path);
1785 }
1786 
1787 /// Returns a key to be use in types_map dict conformed by
1788 /// dictionary id and the CTF type id for a given type.
1789 ///
1790 /// CTF id types are unique by child dictionary, but CTF id
1791 /// types in parent dictionary are unique across the all
1792 /// dictionaries in the CTF archive, to differentiate
1793 /// one each other this member function relies in
1794 /// ctf_type_isparent function.
1795 ///
1796 /// @param dic the pointer to CTF dictionary where the @p type
1797 /// was found.
1798 ///
1799 /// @param type the id for given CTF type.
1800 static std::string
1801 dic_type_key(ctf_dict_t *dic, ctf_id_t ctf_type)
1802 {
1803  std::stringstream key;
1804 
1805  if (ctf_type_isparent (dic, ctf_type))
1806  key << std::hex << ctf_type;
1807  else
1808  key << std::hex << ctf_type << '-' << ctf_cuname(dic);
1809  return key.str();
1810 }
1811 
1812 } // End of namespace ctf
1813 } // End of namespace abigail
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
Definition: abg-ir.cc:8450
A type used to time various part of the libabigail system.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
Definition: abg-ir.cc:10807
The abstraction of an array type.
Definition: abg-ir.h:2547
The abstraction of an enumerator.
Definition: abg-ir.h:2880
void sort_functions()
Sort the set of functions exported by this corpus.
Definition: abg-corpus.cc:1449
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
Definition: abg-ir.cc:19235
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
Definition: abg-ir.cc:12445
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
Definition: abg-ir.cc:10909
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Definition: abg-ir.cc:3531
bool parse_real_type(const string &type_name, real_type &type)
Parse a real type from a string.
Definition: abg-ir.cc:16768
bool start()
Start the timer.
typedef_decl_sptr lookup_typedef_type(const interned_string &type_name, const translation_unit &tu)
Lookup a typedef type from a translation unit.
Definition: abg-ir.cc:12628
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
Definition: abg-fwd.h:208
An abstraction helper for type declarations.
Definition: abg-ir.h:2002
unordered_map< string, type_base_sptr > string_type_base_sptr_map_type
A convenience typedef for a map which key is a string and which value is a type_base_sptr.
Definition: abg-ir.h:572
#define ABG_ASSERT_NOT_REACHED
A macro that expands to aborting the program when executed.
Helper class to allow range-for loops on symtabs for C++11 and later code. It serves as a proxy for t...
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
Definition: abg-corpus.h:24
The abstraction of a qualified type.
Definition: abg-ir.h:2235
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
Definition: abg-ir.cc:11858
void sort_variables()
Sort the set of variables exported by this corpus.
Definition: abg-corpus.cc:1487
status
The status of the fe_iface::read_corpus call.
Definition: abg-fe-iface.h:37
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
Definition: abg-fwd.h:253
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
Definition: abg-ir.cc:11396
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
Definition: abg-fwd.h:133
Abstracts a class declaration.
Definition: abg-ir.h:4173
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
Definition: abg-fwd.h:164
This contains the declarations for the symtab reader.
Abstracts a variable declaration.
Definition: abg-ir.h:3067
Abstraction of a function parameter.
Definition: abg-ir.h:3334
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
Definition: abg-ir.cc:29165
void hash_and_canonicalize_types(IteratorType begin, IteratorType end, deref_lambda deref, bool do_log=false, bool show_stats=false)
Hash and canonicalize a sequence of types.
Definition: abg-ir-priv.h:1524
This status is for when the debug info could not be read.
Definition: abg-fe-iface.h:46
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
Definition: abg-ir.cc:12522
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
Definition: abg-ir.h:2798
const type_base_sptr lookup_type(const interned_string &fqn, const translation_unit &tu)
Lookup a type in a translation unit.
Definition: abg-ir.cc:12891
Abstracts a declaration for an enum type.
Definition: abg-ir.h:2784
This class is to hold the value of the bound of a subrange. The value can be either signed or unsigne...
Definition: abg-ir.h:2588
Toplevel namespace for libabigail.
const type_base_sptr & get_void_type() const
Get the unique type_decl that represents a "void" type for the current environment. This node must be the only one representing a void type in the system.
Definition: abg-ir.cc:3468
bool file_exists(const string &path)
Tests whether a path exists;.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
Definition: abg-fwd.h:266
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
Definition: abg-ir.cc:10747
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
Definition: abg-ir.cc:11100
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
Definition: abg-ir.h:3190
Abstracts a union type declaration.
Definition: abg-ir.h:4421
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Definition: abg-ir.h:3183
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Definition: abg-ir.cc:19242
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
Definition: abg-corpus.h:50
This contains the private implementation of the suppression engine of libabigail. ...
enum_type_decl_sptr lookup_enum_type(const interned_string &type_name, const translation_unit &tu)
Lookup an enum type from a translation unit.
Definition: abg-ir.cc:12590
elf_based_reader_sptr create_reader(const std::string &elf_path, const vector< string > &debug_info_root_paths, environment &env)
Create and return a new read context to process CTF information from a given ELF file.
Abstraction for a function declaration.
Definition: abg-ir.h:3164
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
Definition: abg-ir.cc:10229
The source location of a token.
Definition: abg-ir.h:306
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
Definition: abg-fwd.h:118
This file contains the declarations for an elf-based. DWARF and CTF readers can inherit this one...
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
Definition: abg-fwd.h:159
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
Definition: abg-ir.h:147
The common interface of readers based on ELF.
This file contains the declarations of the entry points to de-serialize an instance of abigail::corpu...
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
Definition: abg-fwd.h:1743
bool find_file_under_dir(const string &root_dir, const string &file_path_to_look_for, string &result)
Find a given file under a root directory and return its absolute path.
exported_decls_builder_sptr get_exported_decls_builder() const
Getter for the object that is responsible for determining what decls ought to be in the set of export...
Definition: abg-corpus.cc:1749
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Definition: abg-ir.cc:11445
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
Definition: abg-ir.cc:12123
void set_public_symbols(bool new_value=true)
Enable or disable public symbol filtering.
Abstracts the building of the set of exported variables and functions.
Definition: abg-corpus.h:336
This status is for when the symbols of the ELF binaries could not be read.
Definition: abg-fe-iface.h:54
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
Definition: abg-ir.cc:10858
The abstraction of a pointer type.
Definition: abg-ir.h:2349
virtual void initialize(const std::string &elf_path, const vector< string > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
A basic type declaration that introduces no scope.
Definition: abg-ir.h:2117
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
Definition: abg-fwd.h:172
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
Definition: abg-fwd.h:190
void initialize()
The initialization function of libxml2 abstraction layer. This function must be called prior to using...
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
Definition: abg-ir.cc:11838
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
Definition: abg-ir.cc:12485
bool dir_name(string const &path, string &dir_name, bool keep_separator_at_end)
Return the directory part of a file path.
void reset_reader(elf_based_reader &rdr, const std::string &elf_path, const vector< string > &debug_info_root_path)
Re-initialize a reader so that it can re-used to read another binary.
void set_origin(origin)
Setter for the origin of the corpus.
Definition: abg-corpus.cc:937
This contains a set of ELF utilities used by the dwarf reader.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
Definition: abg-ir.h:2569
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++...
Definition: abg-ir.h:2573
Abstraction of a group of corpora.
Definition: abg-corpus.h:385
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
Definition: abg-ir.cc:4103
origin get_origin() const
Getter for the origin of the corpus.
Definition: abg-corpus.cc:930
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
Definition: abg-ir.cc:16850
The status is in an unknown state.
Definition: abg-fe-iface.h:40
The symtab filter is the object passed to the symtab object in order to iterate over the symbols in t...
The abstraction of a typedef declaration.
Definition: abg-ir.h:2934
const type_base_sptr & get_variadic_parameter_type() const
Get a type_decl instance that represents a the type of a variadic function parameter. This node must be the only one representing a variadic parameter type in the system.
Definition: abg-ir.cc:3506
The internal representation of an integral type.
Definition: abg-ir-priv.h:48
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
Definition: abg-ir.h:2562
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
Definition: abg-fwd.h:241
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
Definition: abg-fwd.h:223
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
Definition: abg-ir.cc:11479
This status is for when the call went OK.
Definition: abg-fe-iface.h:43
const type_base_sptr & get_void_pointer_type() const
Getter of the "pointer-to-void" IR node that is shared across the ABI corpus. This node must be the o...
Definition: abg-ir.cc:3487
Abstraction of a function type.
Definition: abg-ir.h:3419
bool stop()
Stop the timer.
CV
Bit field values representing the cv qualifiers of the underlying type.
Definition: abg-ir.h:2254