PandA-2024.02
tree_helper.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
44 #include "tree_helper.hpp"
46 
48 #include "token_interface.hpp"
49 
51 #include <algorithm>
52 #include <utility>
53 
55 #include "ext_tree_node.hpp"
56 #include "math_function.hpp"
57 #include "tree_basic_block.hpp"
58 #include "tree_manager.hpp"
59 #include "tree_node.hpp"
60 #include "tree_reindex.hpp"
61 
62 #include "var_pp_functor.hpp"
63 
65 #include "dbgPrintHelper.hpp" // for DEBUG_LEVEL_
66 #include "exceptions.hpp"
67 #include "string_manipulation.hpp" // for STR
68 #include <filesystem>
69 #include <iostream>
70 #include <regex>
71 #include <set>
72 
80 
88 
91 
92 const std::set<std::string> tree_helper::SC_tmpl_class = {"sc_signal", "sc_in", "sc_out",
93  "sc_inout", "sc_port", "sc_export"};
94 
95 const std::set<std::string> tree_helper::SC_builtin_scalar_type = {
96  "sc_int", "sc_uint", "sc_biguint", "sc_bigint", "sc_lv", "sc_in_rv",
97  "sc_out_rv", "sc_inout_rv", "sc_bv", "sc_signal_rv"}; /*check "sc_fix","sc_ufix" "sc_fifo", "sc_buffer",
98  "sc_fixed", "sc_ufixed" */
99 
100 const std::set<std::string> tree_helper::TLM_SC_builtin_scalar_type = {
101  "tlm_blocking_put_if", "tlm_blocking_get_if", "tlm_nonblocking_get_if", "tlm_nonblocking_put_if",
102  "tlm_transport_if" // TLM objects
103 };
104 
106 
107 tree_helper::tree_helper() = default;
108 
109 tree_helper::~tree_helper() = default;
110 
112 static std::string sign_reduce_bitstring(std::string bitstring, bool bitstring_is_signed)
113 {
114  THROW_ASSERT(!bitstring.empty(), "");
115  while(bitstring.size() > 1)
116  {
117  if(bitstring_is_signed)
118  {
119  if(bitstring.at(0) != 'U' and (bitstring.at(0) == bitstring.at(1)))
120  {
121  bitstring = bitstring.substr(1);
122  }
123  else
124  {
125  break;
126  }
127  }
128  else
129  {
130  if((bitstring.at(0) == 'X' && bitstring.at(1) == 'X') || (bitstring.at(0) == '0' && bitstring.at(1) != 'X'))
131  {
132  bitstring = bitstring.substr(1);
133  }
134  else if(bitstring.at(0) == '0' && bitstring.at(1) == 'X')
135  {
136  bitstring = bitstring.substr(1);
137  bitstring = bitstring.substr(1);
138  bitstring = '0' + bitstring;
139  }
140  else
141  {
142  break;
143  }
144  }
145  }
146  while(bitstring.at(0) == 'X' && bitstring.size() > 1)
147  {
148  bitstring = bitstring.substr(1);
149  }
150  return bitstring;
151 }
152 
153 unsigned long long tree_helper::Size(const tree_nodeConstRef& _t)
154 {
155  const auto t = _t->get_kind() == tree_reindex_K ? GET_CONST_NODE(_t) : _t;
157  "---Getting size of " + t->get_kind_text() + " " + STR(t->index) + ": " + t->ToString());
158  switch(t->get_kind())
159  {
160  case ssa_name_K:
161  {
162  const auto sa = GetPointerS<const ssa_name>(t);
163  if(!sa->bit_values.empty())
164  {
165  if(IsRealType(sa->type))
166  {
167  return Size(sa->type);
168  }
169  const auto signed_p = IsSignedIntegerType(sa->type);
170  const auto bv_test = sign_reduce_bitstring(sa->bit_values, signed_p);
171  return bv_test.size();
172  }
173  return sa->var ? Size(sa->var) : Size(sa->type);
174  }
175  case pointer_type_K:
176  {
177  return static_cast<unsigned long long>(GetConstValue(GetPointerS<const pointer_type>(t)->size));
178  }
179  case reference_type_K:
180  {
181  return static_cast<unsigned long long>(GetConstValue(GetPointerS<const reference_type>(t)->size));
182  }
183  case array_type_K:
184  {
185  const auto at = GetPointerS<const array_type>(t);
186  if(at->size)
187  {
188  const auto ic = GetPointer<const integer_cst>(GET_CONST_NODE(at->size));
189  if(ic)
190  {
191  return static_cast<unsigned long long>(GetConstValue(at->size));
192  }
193  else
194  {
195  return 32ull;
196  }
197  }
198  else
199  {
200  return 0ull;
201  }
202  break;
203  }
204  case boolean_type_K:
205  {
206  return 1ull;
207  }
208  case void_type_K:
209  {
210  return 8ull;
211  }
212  case enumeral_type_K:
213  {
214  const auto et = GetPointerS<const enumeral_type>(t);
215  const auto retval = [&]() -> integer_cst_t {
216  if(et->min && et->max && GET_CONST_NODE(et->min)->get_kind() == integer_cst_K &&
217  GET_CONST_NODE(et->max)->get_kind() == integer_cst_K)
218  {
219  const auto max = GetConstValue(et->max, !et->unsigned_flag);
220  const auto min = GetConstValue(et->min, !et->unsigned_flag);
221  if(et->unsigned_flag)
222  {
223  return max.minBitwidth(false);
224  }
225  else
226  {
227  return std::max(min.minBitwidth(true), max.minBitwidth(true));
228  }
229  }
230  else
231  {
232  if(!GetPointerS<const type_node>(t)->size)
233  {
234  return 0;
235  }
236  return GetConstValue(GetPointerS<const type_node>(t)->size);
237  }
238  }();
239  return static_cast<unsigned long long>(retval);
240  break;
241  }
242  case vector_type_K:
243  case CharType_K:
244  case nullptr_type_K:
245  case type_pack_expansion_K:
246  case type_argument_pack_K:
247  case real_type_K:
248  case complex_type_K:
249  case function_type_K:
250  case method_type_K:
251  case union_type_K:
252  case record_type_K:
253  {
254  if(!GetPointerS<const type_node>(t)->size)
255  {
256  return 0;
257  }
258  return static_cast<unsigned long long>(GetConstValue(GetPointerS<const type_node>(t)->size));
259  }
260  case integer_type_K:
261  {
262  const auto it = GetPointerS<const integer_type>(t);
263  const auto prec = it->prec;
264  const auto algn = it->algn;
265  if(prec != algn && prec % algn)
266  {
267  return prec;
268  }
269  else
270  {
271  return static_cast<unsigned long long>(GetConstValue(it->size));
272  }
273  break;
274  }
275  case lut_expr_K:
276  {
277  return 1;
278  }
279  case integer_cst_K:
280  {
281  const auto is_signed = IsSignedIntegerType(t);
282  const auto retval = GetConstValue(t, is_signed).minBitwidth(is_signed);
283  return static_cast<unsigned long long>(retval);
284  break;
285  }
286  case field_decl_K:
287  case parm_decl_K:
288  case result_decl_K:
289  case var_decl_K:
290  case call_expr_K:
291  case aggr_init_expr_K:
295  case array_ref_K:
296  case string_cst_K:
297  case vector_cst_K:
298  case real_cst_K:
299  case complex_cst_K:
300  case constructor_K:
301  case target_mem_ref461_K:
302  {
303  return Size(CGetType(t));
304  }
305  case gimple_call_K:
306  case function_decl_K:
307  {
308  return 32ull; // static_cast<unsigned int>(CompilerWrapper::CGetPointerSize(parameters));
309  }
310  case array_range_ref_K:
311  case binfo_K:
312  case block_K:
313  case case_label_expr_K:
314  case const_decl_K:
315  case identifier_node_K:
316  case label_decl_K:
317  case lang_type_K:
318  case namespace_decl_K:
319  case offset_type_K:
320  case qual_union_type_K:
321  case set_type_K:
322  case statement_list_K:
323  case target_expr_K:
324  case target_mem_ref_K:
325  case template_type_parm_K:
326  case translation_unit_decl_K:
327  case template_decl_K:
328  case using_decl_K:
329  case tree_list_K:
330  case tree_vec_K:
331  case type_decl_K:
332  case typename_type_K:
333  case CASE_CPP_NODES:
334  case CASE_FAKE_NODES:
335  case gimple_asm_K:
336  case gimple_assign_K:
337  case gimple_bind_K:
338  case gimple_cond_K:
339  case gimple_for_K:
340  case gimple_goto_K:
341  case gimple_label_K:
342  case gimple_multi_way_if_K:
343  case gimple_nop_K:
344  case gimple_phi_K:
345  case gimple_pragma_K:
346  case gimple_predict_K:
347  case gimple_resx_K:
348  case gimple_return_K:
349  case gimple_switch_K:
350  case gimple_while_K:
351  case CASE_PRAGMA_NODES:
352  case void_cst_K:
353  case error_mark_K:
354  default:
355  {
356  THROW_UNREACHABLE(std::string("Unexpected type pattern ") + t->get_kind_text());
357  break;
358  }
359  }
360  THROW_UNREACHABLE(std::string("Unexpected type pattern ") + t->get_kind_text());
361  return 0ull;
362 }
363 
365 {
366  if(type->get_kind() == tree_reindex_K)
367  {
368  return GetTemplateTypeName(GET_CONST_NODE(type));
369  }
370  if(type->get_kind() == record_type_K)
371  {
372  const auto rect = GetPointer<const record_type>(type);
373  if(rect->tmpl_args) /*the class is a template*/
374  {
375  for(auto& list_of_fld : rect->list_of_flds)
376  {
377  if(GET_NODE(list_of_fld)->get_kind() == type_decl_K)
378  {
379  const auto td = GetPointer<const type_decl>(GET_CONST_NODE(list_of_fld));
380  if(GET_NODE(td->name)->get_kind() == identifier_node_K)
381  {
382  const auto idn = GetPointer<const identifier_node>(GET_CONST_NODE(td->name));
383  return (idn->strg);
384  }
385  }
386  }
387  }
388  }
389  return "";
390 }
391 
393 {
394  if(type->get_kind() == tree_reindex_K)
395  {
396  return GetRecordTypeName(GET_CONST_NODE(type));
397  }
398  if(type->get_kind() == record_type_K)
399  {
400  const auto rect = GetPointer<const record_type>(type);
401  if(rect->name)
402  {
403  if(GET_NODE(rect->name)->get_kind() == type_decl_K)
404  {
405  const auto td = GetPointer<const type_decl>(GET_CONST_NODE(rect->name));
406  if(GET_NODE(td->name)->get_kind() == identifier_node_K)
407  {
408  const auto idn = GetPointer<const identifier_node>(GET_CONST_NODE(td->name));
409  return (idn->strg);
410  }
411  }
412  }
413  }
414  return "";
415 }
416 
417 std::string tree_helper::name_function(const tree_managerConstRef& tm, const unsigned int index)
418 {
419  const auto t = tm->CGetTreeReindex(index);
420  return GetFunctionName(tm, t);
421 }
422 
424 {
425  if(decl->get_kind() == tree_reindex_K)
426  {
427  return GetFunctionName(TM, GET_CONST_NODE(decl));
428  }
429  if(decl->get_kind() == function_decl_K)
430  {
431  const auto fd = GetPointerS<const function_decl>(decl);
432  return print_function_name(TM, fd);
433  }
434  else if(decl->get_kind() == addr_expr_K)
435  {
436  return GetFunctionName(TM, GetPointerS<const unary_expr>(decl)->op);
437  }
438  else
439  {
440  THROW_ERROR("Node not yet supported " + decl->get_kind_text());
441  }
442  return "";
443 }
444 
446 {
447  if(fd->builtin_flag)
448  {
449  THROW_ASSERT(fd->name, "unexpected condition");
450  THROW_ASSERT(GET_CONST_NODE(fd->name)->get_kind() == identifier_node_K, "unexpected condition");
451  return NormalizeTypename(GetPointer<const identifier_node>(GET_CONST_NODE(fd->name))->strg);
452  }
453  else if(fd->mngl)
454  {
455  THROW_ASSERT(GET_CONST_NODE(fd->mngl)->get_kind() == identifier_node_K, "unexpected condition");
456  return NormalizeTypename(GetPointer<const identifier_node>(GET_CONST_NODE(fd->mngl))->strg);
457  }
458  else if(fd->name)
459  {
460  THROW_ASSERT(GET_CONST_NODE(fd->name)->get_kind() == identifier_node_K, "unexpected condition");
461  return NormalizeTypename(GetPointer<const identifier_node>(GET_CONST_NODE(fd->name))->strg);
462  }
463  THROW_ERROR("unexpected condition");
464  return "";
465 }
466 
468 {
469  tree_nodeConstRef name;
470  if(fd->builtin_flag)
471  {
472  name = GET_CONST_NODE(fd->name);
473  }
474  else if(fd->mngl)
475  {
476  name = GET_CONST_NODE(fd->mngl);
477  }
478  else
479  {
480  name = GET_CONST_NODE(fd->name);
481  }
482  std::string res;
483  if(name->get_kind() == identifier_node_K)
484  {
485  const auto in = GetPointer<const identifier_node>(name);
486  if(in->operator_flag)
487  {
488  res = "operator ";
489  for(const auto& attr : fd->list_attr)
490  {
496  {
497  continue;
498  }
500  {
501  const auto ft = GetPointer<const function_type>(GET_CONST_NODE(fd->type));
502  if(ft)
503  {
504  print_type(TM, GET_INDEX_CONST_NODE(ft->retn));
505  }
506  else
507  {
508  const auto mt = GetPointer<const method_type>(GET_CONST_NODE(fd->type));
509  print_type(TM, GET_INDEX_CONST_NODE(mt->retn));
510  }
511  }
513  {
514  res = res + ">>";
515  }
517  {
518  res = res + "<<";
519  }
521  {
522  res = res + "=";
523  }
524  else
525  {
526  res = res + TI_getTokenName(attr);
527  }
528  }
529  res = NormalizeTypename(res);
530  }
531  else
532  {
533  res = NormalizeTypename(in->strg);
534  }
535  }
536  else
537  {
538  THROW_ERROR(std::string("Node not yet supported ") + name->get_kind_text());
539  }
540  // if(fd && fd->undefined_flag && fd->builtin_flag && res.find("__builtin_") == std::string::npos)
541  // res = "__builtin_" + res;
542  if(fd->builtin_flag && fd->body && !TM->is_top_function(fd))
543  {
544  res = "__internal_" + res;
545  }
546  return res;
547 }
548 
549 std::tuple<std::string, unsigned int, unsigned int> tree_helper::GetSourcePath(const tree_nodeConstRef& _node,
550  bool& is_system)
551 {
552  is_system = false;
553  auto node = GET_CONST_NODE(_node);
554  std::string include_name;
555  unsigned int line_number = 0;
556  unsigned int column_number = 0;
557  if(GetPointer<const type_node>(node))
558  {
559  const auto tn = GetPointerS<const type_node>(node);
560  if(tn->name && GetPointer<const decl_node>(GET_CONST_NODE(tn->name)))
561  {
562  node = GET_CONST_NODE(tn->name);
563  }
564  else
565  {
566  if(GetPointer<const union_type>(node))
567  {
568  const auto& list_of_flds = GetPointerS<const union_type>(node)->list_of_flds;
569  if(!list_of_flds.empty())
570  {
571  const auto field = GET_CONST_NODE(list_of_flds[0]);
572  if(GetPointer<const decl_node>(field))
573  {
574  const auto dn = GetPointerS<const decl_node>(field);
575  include_name = dn->include_name;
576  line_number = dn->line_number;
577  column_number = dn->column_number;
578  is_system = dn->operating_system_flag or dn->library_system_flag;
579  }
580  }
581  }
582  if(GetPointer<const record_type>(node))
583  {
584  const auto& list_of_flds = GetPointerS<const record_type>(node)->list_of_flds;
585  if(!list_of_flds.empty())
586  {
587  const auto field = GET_CONST_NODE(list_of_flds.at(0));
588  if(GetPointer<const decl_node>(field))
589  {
590  const auto dn = GetPointerS<const decl_node>(field);
591  include_name = dn->include_name;
592  line_number = dn->line_number;
593  column_number = dn->column_number;
594  is_system = dn->operating_system_flag or dn->library_system_flag;
595  }
596  }
597  }
598  }
599  }
600  if(GetPointer<const decl_node>(node))
601  {
602  const auto dn = GetPointerS<const decl_node>(node);
603  include_name = dn->include_name;
604  line_number = dn->line_number;
605  column_number = dn->column_number;
606  is_system = dn->operating_system_flag or dn->library_system_flag;
607  }
608  if(include_name != "<built-in>")
609  {
610  std::error_code ec;
611  const auto canon_path = std::filesystem::weakly_canonical(include_name, ec);
612  if(!ec)
613  {
614  include_name = canon_path.string();
615  }
616  }
617  return std::tuple<std::string, unsigned int, unsigned int>(include_name, line_number, column_number);
618 }
619 
620 void tree_helper::get_used_variables(bool first_level_only, const tree_nodeConstRef& tRI,
621  CustomUnorderedSet<unsigned int>& list_of_variable)
622 {
623  if(!tRI)
624  {
625  return;
626  }
627  THROW_ASSERT(tRI->get_kind() == tree_reindex_K, "Node is not a tree reindex");
628  const auto t = GET_CONST_NODE(tRI);
629  switch(t->get_kind())
630  {
631  case result_decl_K: // tree_to_graph considers this object as particular type of variable
632  {
633  const auto rd = GetPointer<const result_decl>(t);
634  list_of_variable.insert(GET_INDEX_CONST_NODE(tRI));
635  if(rd->init)
636  {
637  get_used_variables(first_level_only, rd->init, list_of_variable);
638  }
639  break;
640  }
641  case var_decl_K:
642  {
643  const auto vd = GetPointer<const var_decl>(t);
644  list_of_variable.insert(GET_INDEX_CONST_NODE(tRI));
645  if(vd->init)
646  {
647  get_used_variables(first_level_only, vd->init, list_of_variable);
648  }
649  break;
650  }
651  case ssa_name_K:
652  {
653  const auto sn = GetPointer<const ssa_name>(t);
654  get_used_variables(first_level_only, sn->var, list_of_variable);
655  list_of_variable.insert(GET_INDEX_CONST_NODE(tRI));
656  if(sn->var)
657  {
658  const auto vd = GetPointer<const var_decl>(GET_CONST_NODE(sn->var));
659  if(vd && vd->init)
660  {
661  get_used_variables(first_level_only, vd->init, list_of_variable);
662  }
663  }
664  break;
665  }
666  case parm_decl_K:
667  list_of_variable.insert(GET_INDEX_CONST_NODE(tRI));
668  break;
669  case function_decl_K:
670  {
671  const auto fd = GetPointer<const function_decl>(t);
672  bool expand_p = !first_level_only;
673  auto vend = fd->list_of_args.end();
674  list_of_variable.insert(GET_INDEX_CONST_NODE(tRI));
675  if(fd->body && expand_p)
676  {
677  for(auto i = fd->list_of_args.begin(); i != vend; ++i)
678  {
679  get_used_variables(first_level_only, *i, list_of_variable);
680  }
681  // body analysis
682  get_used_variables(first_level_only, fd->body, list_of_variable);
683  }
684  }
685  break;
686  case statement_list_K:
687  {
688  const auto sl = GetPointer<const statement_list>(t);
689  auto end = sl->list_of_stmt.end();
690  auto i = sl->list_of_stmt.begin();
691  if(i != end)
692  {
693  for(; i != end; ++i)
694  {
695  get_used_variables(first_level_only, *i, list_of_variable);
696  }
697  }
698  else
699  {
700  auto ib_end = sl->list_of_bloc.end();
701  for(auto ib = sl->list_of_bloc.begin(); ib != ib_end; ++ib)
702  {
703  for(const auto& stmt : ib->second->CGetStmtList())
704  {
705  get_used_variables(first_level_only, stmt, list_of_variable);
706  }
707  }
708  }
709  }
710  break;
711  case tree_vec_K:
712  {
713  const auto tv = GetPointer<const tree_vec>(t);
714  auto end = tv->list_of_op.end();
715  for(auto i = tv->list_of_op.begin(); i != end; ++i)
716  {
717  get_used_variables(first_level_only, *i, list_of_variable);
718  }
719  }
720  break;
721  case gimple_cond_K:
722  {
723  const auto gc = GetPointer<const gimple_cond>(t);
724  get_used_variables(first_level_only, gc->op0, list_of_variable);
725  }
726  break;
727  case gimple_assign_K:
728  {
729  const auto me = GetPointer<const gimple_assign>(t);
730  get_used_variables(first_level_only, me->op0, list_of_variable);
731  get_used_variables(first_level_only, me->op1, list_of_variable);
732  if(me->predicate)
733  {
734  get_used_variables(first_level_only, me->predicate, list_of_variable);
735  }
736  }
737  break;
738  case gimple_return_K:
739  {
740  const auto re = GetPointer<const gimple_return>(t);
741  if(re->op)
742  {
743  get_used_variables(first_level_only, re->op, list_of_variable);
744  }
745  }
746  break;
748  {
749  const auto ue = GetPointer<const unary_expr>(t);
750  if(list_of_variable.find(GET_INDEX_CONST_NODE(ue->op)) != list_of_variable.end())
751  {
752  break;
753  }
754  get_used_variables(first_level_only, ue->op, list_of_variable);
755  break;
756  }
758  {
759  const auto be = GetPointer<const binary_expr>(t);
760  get_used_variables(first_level_only, be->op0, list_of_variable);
761  get_used_variables(first_level_only, be->op1, list_of_variable);
762  break;
763  }
765  {
766  const auto tern = GetPointer<const ternary_expr>(t);
767  get_used_variables(first_level_only, tern->op0, list_of_variable);
768  get_used_variables(first_level_only, tern->op1, list_of_variable);
769  get_used_variables(first_level_only, tern->op2, list_of_variable);
770  break;
771  }
772  /* quaternary expressions.*/
774  {
775  const auto qe = GetPointer<const quaternary_expr>(t);
776  get_used_variables(first_level_only, qe->op0, list_of_variable);
777  get_used_variables(first_level_only, qe->op1, list_of_variable);
778  get_used_variables(first_level_only, qe->op2, list_of_variable);
779  get_used_variables(first_level_only, qe->op3, list_of_variable);
780  break;
781  }
782  case lut_expr_K:
783  {
784  const auto le = GetPointer<const lut_expr>(t);
785  get_used_variables(first_level_only, le->op0, list_of_variable);
786  get_used_variables(first_level_only, le->op1, list_of_variable);
787  if(le->op2)
788  {
789  get_used_variables(first_level_only, le->op2, list_of_variable);
790  }
791  if(le->op3)
792  {
793  get_used_variables(first_level_only, le->op3, list_of_variable);
794  }
795  if(le->op4)
796  {
797  get_used_variables(first_level_only, le->op4, list_of_variable);
798  }
799  if(le->op5)
800  {
801  get_used_variables(first_level_only, le->op5, list_of_variable);
802  }
803  if(le->op6)
804  {
805  get_used_variables(first_level_only, le->op6, list_of_variable);
806  }
807  if(le->op7)
808  {
809  get_used_variables(first_level_only, le->op7, list_of_variable);
810  }
811  if(le->op8)
812  {
813  get_used_variables(first_level_only, le->op8, list_of_variable);
814  }
815  break;
816  }
817  case gimple_switch_K:
818  {
819  const auto s = GetPointer<const gimple_switch>(t);
820  get_used_variables(first_level_only, s->op0, list_of_variable);
821  break;
822  }
823  case gimple_multi_way_if_K:
824  {
825  const auto gmwi = GetPointer<const gimple_multi_way_if>(t);
826  for(const auto& cond : gmwi->list_of_cond)
827  {
828  if(cond.first)
829  {
830  get_used_variables(first_level_only, cond.first, list_of_variable);
831  }
832  }
833  break;
834  }
835  case label_decl_K:
836  case integer_cst_K:
837  case real_cst_K:
838  case string_cst_K:
839  case vector_cst_K:
840  case void_cst_K:
841  case complex_cst_K:
842  break;
843  case field_decl_K: // used to specify the displacement
844  case case_label_expr_K:
845  case gimple_label_K:
846  break;
847  case constructor_K:
848  {
849  const auto co = GetPointer<const constructor>(t);
850  for(const auto& i : co->list_of_idx_valu)
851  {
852  get_used_variables(first_level_only, i.second, list_of_variable);
853  }
854  break;
855  }
856  case call_expr_K:
857  case aggr_init_expr_K:
858  {
859  const auto ce = GetPointer<const call_expr>(t);
860  for(const auto& arg : ce->args)
861  {
862  get_used_variables(first_level_only, arg, list_of_variable);
863  }
864  break;
865  }
866  case gimple_call_K:
867  {
868  const auto ce = GetPointer<const gimple_call>(t);
869  for(const auto& arg : ce->args)
870  {
871  get_used_variables(first_level_only, arg, list_of_variable);
872  }
873  break;
874  }
875  case gimple_asm_K:
876  {
877  const auto ae = GetPointer<const gimple_asm>(t);
878  if(ae->in)
879  {
880  get_used_variables(first_level_only, ae->in, list_of_variable);
881  }
882  if(ae->out)
883  {
884  get_used_variables(first_level_only, ae->out, list_of_variable);
885  }
886  if(ae->clob)
887  {
888  get_used_variables(first_level_only, ae->clob, list_of_variable);
889  }
890  break;
891  }
892  case tree_list_K:
893  {
894  auto tl = GetPointer<const tree_list>(t);
895  std::list<const tree_list*> tl_list;
896  do
897  {
898  tl_list.push_back(tl);
899  tl = tl->chan ? GetPointer<const tree_list>(GET_CONST_NODE(tl->chan)) : nullptr;
900  } while(tl);
901  for(auto tl_current0 : tl_list)
902  {
903  if(tl_current0->purp)
904  {
905  get_used_variables(first_level_only, tl_current0->purp, list_of_variable);
906  }
907  if(tl_current0->valu)
908  {
909  get_used_variables(first_level_only, tl_current0->valu, list_of_variable);
910  }
911  }
912  break;
913  }
914  case gimple_for_K:
915  {
916  const auto fe = GetPointer<const gimple_for>(t);
917  get_used_variables(first_level_only, fe->op0, list_of_variable);
918  get_used_variables(first_level_only, fe->op1, list_of_variable);
919  get_used_variables(first_level_only, fe->op2, list_of_variable);
920  break;
921  }
922  case gimple_while_K:
923  {
924  const auto we = GetPointer<const gimple_while>(t);
925  get_used_variables(first_level_only, we->op0, list_of_variable);
926  break;
927  }
928  case binfo_K:
929  case block_K:
930  case const_decl_K:
931  case gimple_bind_K:
932  case gimple_goto_K:
933  case gimple_nop_K:
934  case gimple_phi_K:
935  case gimple_pragma_K:
936  case gimple_predict_K:
937  case gimple_resx_K:
938  case identifier_node_K:
939  case namespace_decl_K:
940  case target_expr_K:
941  case target_mem_ref_K:
942  case target_mem_ref461_K:
943  case translation_unit_decl_K:
944  case template_decl_K:
945  case using_decl_K:
946  case type_decl_K:
947  case error_mark_K:
948  case CASE_CPP_NODES:
949  case CASE_FAKE_NODES:
950  case CASE_PRAGMA_NODES:
951  case CASE_TYPE_NODES:
952  default:
953  THROW_ERROR(std::string("Node not yet supported ") + t->get_kind_text());
954  }
955 }
956 
957 bool tree_helper::look_for_binfo_inheritance(const binfo* b, const std::string& bcs)
958 {
959  if(b)
960  {
961  if(b->type)
962  {
963  const auto rt = GetPointer<const record_type>(GET_CONST_NODE(b->type));
964  if(rt && rt->get_maybe_name() == bcs)
965  {
966  return true;
967  }
968  }
969  for(unsigned int i = 0; i < b->get_baseinfo_size(); i++)
970  {
971  tree_nodeRef binf = b->get_base(i);
972  const auto bnf = GetPointer<const binfo>(GET_CONST_NODE(binf));
973  bool found = look_for_binfo_inheritance(bnf, bcs);
974  if(found)
975  {
976  return true;
977  }
978  }
979  }
980  return false;
981 }
982 
984 {
985  const auto curr_tn = GET_CONST_NODE(tn);
986  unsigned int ind = GET_INDEX_CONST_NODE(tn);
987  const auto otr = GetPointer<const obj_type_ref>(curr_tn);
988  THROW_ASSERT(otr, "tree node is not an obj_type_ref");
989  THROW_ASSERT(otr->type && otr->op1 && otr->op2, "obj_type_ref has missing fields");
991  unsigned int function_type;
992 
993  const auto t_pt = GetPointer<const pointer_type>(GET_CONST_NODE(otr->type));
994  THROW_ASSERT(t_pt, "Expected a pointer_type");
995  function_type = GET_INDEX_CONST_NODE(t_pt->ptd);
996  THROW_ASSERT(GetPointer<const method_type>(GET_CONST_NODE(t_pt->ptd)), "expected a method_type");
997  type = GET_CONST_NODE(GetPointer<const method_type>(GET_CONST_NODE(t_pt->ptd))->clas);
998 #if 0
999  var_decl* vd = GetPointer<var_decl>(GET_NODE(otr->op1));
1000  if(vd)
1001  type = vd->type;
1002  else
1003  {
1004  parm_decl* pd = GetPointer<parm_decl>(GET_NODE(otr->op1));
1005  if(pd)
1006  type = pd->type;
1007  else
1008  THROW_ERROR(std::string("not supported case for obj_type_ref(") + STR(ind) + std::string(")"));
1009  }
1010 #endif
1011  if(type)
1012  {
1013  const auto rt = GetPointer<const record_type>(type);
1014 #if 0
1015  pointer_type* pt = GetPointer<pointer_type>(GET_NODE(type));
1016  if(pt)
1017  rt = GetPointer<record_type>(GET_NODE(pt->ptd));
1018  else
1019  {
1020  reference_type * Rt = GetPointer<reference_type>(GET_NODE(type));
1021  if(Rt)
1022  rt = GetPointer<record_type>(GET_NODE(Rt->refd));
1023  else
1024  THROW_ERROR(std::string("not supported case for obj_type_ref(") + STR(ind) + std::string(")"));
1025  }
1026 #endif
1027  if(rt)
1028  {
1029  for(auto& list_of_fnc : rt->list_of_fncs)
1030  {
1031  const auto fd = GetPointer<const function_decl>(GET_CONST_NODE(list_of_fnc));
1032  if(fd && GET_INDEX_CONST_NODE(fd->type) == function_type)
1033  {
1034  return list_of_fnc;
1035  }
1036  }
1037  }
1038  else
1039  {
1040  THROW_ERROR(std::string("not supported case for obj_type_ref(") + STR(ind) + std::string(")"));
1041  }
1042  }
1043  else
1044  {
1045  THROW_ERROR(std::string("not supported case for obj_type_ref(") + STR(ind) + std::string(")"));
1046  }
1047  THROW_ERROR(std::string("obj_type_ref Function not found (") + STR(ind) + std::string(")"));
1048  return tree_nodeRef();
1049 }
1050 
1051 bool tree_helper::is_system(const tree_managerConstRef& TM, const unsigned int index)
1052 {
1053  const auto curr_tn = TM->CGetTreeReindex(index);
1054  return IsSystemType(curr_tn);
1055 }
1056 
1058 {
1059  const auto type = _type->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type) : _type;
1060  if(GetPointer<const decl_node>(type))
1061  {
1062  return GetPointer<const decl_node>(type)->operating_system_flag ||
1063  GetPointer<const decl_node>(type)->library_system_flag;
1064  }
1065  if(GetPointer<const type_node>(type))
1066  {
1067  return GetPointer<const type_node>(type)->system_flag;
1068  }
1069  return false;
1070 }
1071 
1072 bool tree_helper::IsInLibbambu(const tree_managerConstRef& TM, const unsigned int index)
1073 {
1074  const auto curr_tn = TM->CGetTreeReindex(index);
1075  return IsInLibbambu(curr_tn);
1076 }
1077 
1079 {
1080  const auto type = _type->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type) : _type;
1081  if(GetPointer<const decl_node>(type) && GetPointer<const decl_node>(type)->libbambu_flag)
1082  {
1083  return true;
1084  }
1085  if(GetPointer<const type_node>(type) && GetPointer<const type_node>(type)->libbambu_flag)
1086  {
1087  return true;
1088  }
1089  return false;
1090 }
1091 
1092 std::set<tree_nodeConstRef, TreeNodeConstSorter>
1093 tree_helper::GetTypesToBeDeclaredBefore(const tree_nodeConstRef& tn, const bool without_transformation)
1094 {
1095  std::set<tree_nodeConstRef, TreeNodeConstSorter> rt;
1096  RecursiveGetTypesToBeDeclared(rt, tn, false, without_transformation, true);
1097  return rt;
1098 }
1099 
1100 std::set<tree_nodeConstRef, TreeNodeConstSorter>
1101 tree_helper::GetTypesToBeDeclaredAfter(const tree_nodeConstRef& tn, const bool without_transformation)
1102 {
1103  std::set<tree_nodeConstRef, TreeNodeConstSorter> rt;
1104  RecursiveGetTypesToBeDeclared(rt, tn, false, without_transformation, false);
1105  return rt;
1106 }
1107 
1108 void tree_helper::RecursiveGetTypesToBeDeclared(std::set<tree_nodeConstRef, TreeNodeConstSorter>& returned_types,
1109  const tree_nodeConstRef& _type, const bool recursion,
1110  const bool without_transformation, const bool before)
1111 {
1112  const auto type = _type->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type) : _type;
1114  "-->Getting types to be declared " + STR(before ? "before " : "after ") + STR(type));
1115  switch(type->get_kind())
1116  {
1117  case pointer_type_K:
1118  {
1119  if(before)
1120  {
1121  RecursiveGetTypesToBeDeclared(returned_types, CGetPointedType(_type), true, without_transformation, true);
1122  }
1123  break;
1124  }
1125  case reference_type_K:
1126  {
1127  if(before)
1128  {
1129  const auto rt = GetPointerS<const reference_type>(type);
1130  RecursiveGetTypesToBeDeclared(returned_types, rt->refd, true, without_transformation, true);
1131  }
1132  break;
1133  }
1134  case array_type_K:
1135  case vector_type_K:
1136  {
1137  if(before)
1138  {
1139  const auto* tn = GetPointerS<const type_node>(type);
1140  if(recursion && tn->name && GET_CONST_NODE(tn->name)->get_kind() == type_decl_K)
1141  {
1143  "---Inserting " + STR(_type) + " in the types to be declared");
1144  returned_types.insert(_type);
1145  }
1146  else
1147  {
1148  RecursiveGetTypesToBeDeclared(returned_types, CGetElements(_type), true, without_transformation, before);
1149  }
1150  }
1151  break;
1152  }
1153  case record_type_K:
1154  {
1155  if(recursion)
1156  {
1157  if(before)
1158  {
1160  "---Inserting " + STR(_type) + " in the types to be declared");
1161  returned_types.insert(_type);
1162  }
1163  }
1164  else
1165  {
1166  const auto* rt = GetPointerS<const record_type>(type);
1167  if(rt->unql && (GetPointerS<const record_type>(GET_CONST_NODE(rt->unql))->name || without_transformation))
1168  {
1169  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Record type with named unqualified");
1170  if((!before && !IsAligned(_type)) || (before && IsAligned(_type)))
1171  {
1173  "---Inserting " + STR(rt->unql) + " in the types to be declared");
1174  returned_types.insert(rt->unql);
1175  }
1176  }
1177  else
1178  {
1179  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Record type without named unqualified");
1180  const auto field_types = CGetFieldTypes(_type);
1181  for(const auto& field_type : field_types)
1182  {
1184  "-->Considering field type (" + STR(field_type->index) + ") " + STR(field_type));
1185  bool pointer_to_unnamed_structure = [&]() {
1186  if(!IsPointerType(field_type))
1187  {
1188  return false;
1189  }
1190  const auto pointed_type = GET_CONST_NODE(CGetPointedType(field_type));
1191  if(GetPointer<const record_type>(pointed_type) &&
1192  GET_CONST_NODE(GetPointer<const record_type>(pointed_type)->name)->get_kind() != type_decl_K)
1193  {
1194  return true;
1195  }
1196  if(GetPointer<const union_type>(pointed_type) &&
1197  GET_CONST_NODE(GetPointer<const union_type>(pointed_type)->name)->get_kind() != type_decl_K)
1198  {
1199  return true;
1200  }
1201  return false;
1202  }();
1205  if(before)
1206  {
1207  if(!IsPointerType(field_type) || !pointer_to_unnamed_structure)
1208  {
1209  RecursiveGetTypesToBeDeclared(returned_types, field_type, true, without_transformation, true);
1210  }
1211  }
1212  else
1213  {
1214  if(pointer_to_unnamed_structure)
1215  {
1217  RecursiveGetTypesToBeDeclared(returned_types, field_type, true, without_transformation, true);
1218  }
1219  }
1221  "<--Considered field type (" + STR(field_type->index) + ") " + STR(field_type));
1222  }
1224  }
1225  }
1226  break;
1227  }
1228  case union_type_K:
1229  {
1230  if(recursion)
1231  {
1232  if(before)
1233  {
1235  "---Inserting " + STR(_type) + " in the types to be declared");
1236  returned_types.insert(_type);
1237  }
1238  }
1239  else
1240  {
1241  const auto ut = GetPointerS<const union_type>(type);
1242  if(ut->unql && (GetPointerS<const union_type>(GET_CONST_NODE(ut->unql))->name || without_transformation))
1243  {
1244  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Union type with named unqualified");
1245  if((!before && !IsAligned(_type)) || (before && IsAligned(_type)))
1246  {
1248  "---Inserting " + STR(ut->unql) + " in the types to be declared");
1249  returned_types.insert(ut->unql);
1250  }
1251  }
1252  else
1253  {
1254  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Union type without named unqualified");
1255  const auto field_types = CGetFieldTypes(_type);
1256  for(const auto& field_type : field_types)
1257  {
1259  "-->Considering field type (" + STR(field_type->index) + ") " + STR(field_type));
1260  const auto pointer_to_unnamed_structure = [&]() {
1261  if(!IsPointerType(field_type))
1262  {
1263  return false;
1264  }
1265  const auto pointed_type = CGetPointedType(field_type);
1266  if(GetPointer<const record_type>(pointed_type) &&
1267  GET_CONST_NODE(GetPointer<const record_type>(pointed_type)->name)->get_kind() != type_decl_K)
1268  {
1269  return true;
1270  }
1271  if(GetPointer<const union_type>(pointed_type) &&
1272  GET_CONST_NODE(GetPointer<const union_type>(pointed_type)->name)->get_kind() != type_decl_K)
1273  {
1274  return true;
1275  }
1276  return false;
1277  }();
1280  if(before)
1281  {
1282  if(!IsPointerType(field_type) || !pointer_to_unnamed_structure)
1283  {
1284  RecursiveGetTypesToBeDeclared(returned_types, field_type, true, without_transformation, true);
1285  }
1286  }
1287  else
1288  {
1289  if(pointer_to_unnamed_structure)
1290  {
1292  RecursiveGetTypesToBeDeclared(returned_types, field_type, true, without_transformation, true);
1293  }
1294  }
1296  "<--Considered field type (" + STR(field_type->index) + ") " + STR(field_type));
1297  }
1299  }
1300  }
1301  break;
1302  }
1303  case enumeral_type_K:
1304  {
1305  if(recursion)
1306  {
1307  if(before)
1308  {
1310  "---Inserting " + STR(_type) + " in the types to be declared");
1311  returned_types.insert(_type);
1312  }
1313  }
1314  else
1315  {
1316  const auto* et = GetPointerS<const enumeral_type>(type);
1317  if(et->unql && GetPointerS<const enumeral_type>(GET_CONST_NODE(et->unql))->name)
1318  {
1319  if(before)
1320  {
1322  "---Inserting " + STR(et->unql) + " in the types to be declared");
1323  returned_types.insert(et->unql);
1324  }
1325  }
1326  }
1327  break;
1328  }
1329  case boolean_type_K:
1330  case CharType_K:
1331  case nullptr_type_K:
1332  case type_pack_expansion_K:
1333  case complex_type_K:
1334  case integer_type_K:
1335  case real_type_K:
1336  {
1337  if(before)
1338  {
1339  const auto* tn = GetPointerS<const type_node>(type);
1340  if(tn->name && GET_CONST_NODE(tn->name)->get_kind() == type_decl_K)
1341  {
1343  "---Inserting " + STR(_type) + " in the types to be declared");
1344  returned_types.insert(_type);
1345  }
1346  }
1347  break;
1348  }
1349  case void_type_K:
1350  {
1351  break;
1352  }
1353  case method_type_K:
1354  case function_type_K:
1355  {
1356  if(before)
1357  {
1358  const auto return_type = GetFunctionReturnType(_type);
1359  if(return_type)
1360  {
1361  RecursiveGetTypesToBeDeclared(returned_types, return_type, true, without_transformation, true);
1362  }
1363  const auto parameters = GetParameterTypes(_type);
1364  for(const auto& par : parameters)
1365  {
1366  RecursiveGetTypesToBeDeclared(returned_types, par, true, without_transformation, true);
1367  }
1368  }
1369  break;
1370  }
1371  case binfo_K:
1372  case block_K:
1373  case call_expr_K:
1374  case aggr_init_expr_K:
1375  case case_label_expr_K:
1376  case constructor_K:
1377  case identifier_node_K:
1378  case lang_type_K:
1379  case offset_type_K:
1380  case qual_union_type_K:
1381  case set_type_K:
1382  case ssa_name_K:
1383  case statement_list_K:
1384  case target_expr_K:
1385  case target_mem_ref_K:
1386  case target_mem_ref461_K:
1387  case template_type_parm_K:
1388  case type_argument_pack_K:
1389  case tree_list_K:
1390  case tree_vec_K:
1391  case typename_type_K:
1392  case error_mark_K:
1393  case lut_expr_K:
1395  case CASE_CPP_NODES:
1396  case CASE_CST_NODES:
1397  case CASE_DECL_NODES:
1398  case CASE_FAKE_NODES:
1399  case CASE_GIMPLE_NODES:
1400  case CASE_PRAGMA_NODES:
1403  case CASE_UNARY_EXPRESSION:
1404  default:
1405  {
1406  THROW_UNREACHABLE("Unexpected node: " + STR(type));
1407  break;
1408  }
1409  }
1411  STR("<--Got types to be declared ") + (before ? "before" : "after") + " " + STR(type));
1412 }
1413 
1414 unsigned int tree_helper::GetRealType(const tree_managerConstRef& TM, unsigned int index)
1415 {
1416  const auto T = TM->CGetTreeReindex(index);
1417  return GET_INDEX_CONST_NODE(GetRealType(T));
1418 }
1419 
1421 {
1422  const auto utype = GetUnqualifiedType(_type);
1423  return utype ? utype : _type;
1424 }
1425 
1426 unsigned int tree_helper::get_type_index(const tree_managerConstRef& TM, const unsigned int index,
1427  long long int& vec_size, bool& is_a_pointer, bool& is_a_function)
1428 {
1429  is_a_pointer = false;
1430  is_a_function = false;
1431  vec_size = 0;
1432  const auto T = TM->CGetTreeReindex(index);
1433  THROW_ASSERT(T, "this index does not exist: " + STR(index));
1434  auto Type = CGetType(T);
1435  THROW_ASSERT(Type, "expected a type index " + STR(index) + " " + T->ToString());
1436  Type = GET_CONST_NODE(Type);
1437  const auto type_index = Type->index;
1438  if(Type->get_kind() == pointer_type_K)
1439  {
1440  is_a_pointer = true;
1441  }
1442  else if(Type->get_kind() == reference_type_K)
1443  {
1444  is_a_pointer = true; // reference objects are assimilated to pointers
1445  }
1446  else if(Type->get_kind() == array_type_K)
1447  {
1448  const auto at = GetPointer<const array_type>(Type);
1449  if(!at->domn)
1450  {
1451  is_a_pointer = true;
1452  }
1453  }
1454  else if(T->get_kind() == function_decl_K)
1455  {
1456  is_a_function = true;
1457  }
1458  return type_index;
1459 }
1460 
1462 {
1463  const auto tn = _tn->get_kind() == tree_reindex_K ? GET_CONST_NODE(_tn) : _tn;
1464  tree_nodeConstRef fun_type;
1465  switch(tn->get_kind())
1466  {
1467  case function_decl_K:
1468  {
1469  const auto fd = GetPointerS<const function_decl>(tn);
1470  fun_type = GET_CONST_NODE(fd->type);
1471  break;
1472  }
1473  case method_type_K:
1474  case function_type_K:
1475  {
1476  fun_type = tn;
1477  break;
1478  }
1479  case array_type_K:
1480  case binfo_K:
1481  case block_K:
1482  case boolean_type_K:
1483  case call_expr_K:
1484  case aggr_init_expr_K:
1485  case case_label_expr_K:
1486  case CharType_K:
1487  case nullptr_type_K:
1488  case type_pack_expansion_K:
1489  case complex_type_K:
1490  case const_decl_K:
1491  case constructor_K:
1492  case enumeral_type_K:
1493  case field_decl_K:
1494  case identifier_node_K:
1495  case integer_type_K:
1496  case label_decl_K:
1497  case lang_type_K:
1498  case namespace_decl_K:
1499  case offset_type_K:
1500  case pointer_type_K:
1501  case parm_decl_K:
1502  case qual_union_type_K:
1503  case real_type_K:
1504  case record_type_K:
1505  case reference_type_K:
1506  case result_decl_K:
1507  case set_type_K:
1508  case ssa_name_K:
1509  case statement_list_K:
1510  case target_expr_K:
1511  case target_mem_ref_K:
1512  case target_mem_ref461_K:
1513  case template_type_parm_K:
1514  case type_argument_pack_K:
1515  case translation_unit_decl_K:
1516  case template_decl_K:
1517  case using_decl_K:
1518  case tree_list_K:
1519  case tree_vec_K:
1520  case type_decl_K:
1521  case typename_type_K:
1522  case union_type_K:
1523  case vector_type_K:
1524  case void_type_K:
1525  case var_decl_K:
1526  case error_mark_K:
1527  case lut_expr_K:
1529  case CASE_CPP_NODES:
1530  case CASE_CST_NODES:
1531  case CASE_FAKE_NODES:
1532  case CASE_GIMPLE_NODES:
1533  case CASE_PRAGMA_NODES:
1536  case CASE_UNARY_EXPRESSION:
1537  default:
1538  {
1539  break;
1540  }
1541  }
1542  if(fun_type->get_kind() == function_type_K || fun_type->get_kind() == method_type_K)
1543  {
1544  const auto ft = GetPointerS<const function_type>(fun_type);
1545  THROW_ASSERT(ft, "NodeId is not related to a valid function type");
1546  if(!void_as_null || GET_CONST_NODE(ft->retn)->get_kind() != void_type_K)
1547  {
1548  return ft->retn;
1549  }
1550  else
1551  {
1552  return tree_nodeConstRef();
1553  }
1554  }
1555  THROW_UNREACHABLE("Not supported tree node type " + tn->get_kind_text());
1556  return tree_nodeConstRef();
1557 }
1558 
1559 unsigned int tree_helper::get_pointed_type(const tree_managerConstRef& TM, const int unsigned index)
1560 {
1561  const auto T = TM->CGetTreeNode(index);
1562  switch(T->get_kind())
1563  {
1564  case(pointer_type_K):
1565  {
1566  const auto pt = GetPointer<const pointer_type>(T);
1567  return GET_INDEX_CONST_NODE(pt->ptd);
1568  }
1569  case reference_type_K:
1570  {
1571  const auto rt = GetPointer<const reference_type>(T);
1572  return GET_INDEX_CONST_NODE(rt->refd);
1573  }
1574  case(function_type_K):
1575  {
1576  const auto ft = GetPointer<const function_type>(T);
1577  return get_pointed_type(TM, GET_INDEX_CONST_NODE(ft->retn));
1578  }
1579  case(method_type_K):
1580  {
1581  const auto mt = GetPointer<const method_type>(T);
1582  return get_pointed_type(TM, GET_INDEX_CONST_NODE(mt->retn));
1583  }
1584  case array_type_K:
1585  case binfo_K:
1586  case block_K:
1587  case boolean_type_K:
1588  case call_expr_K:
1589  case aggr_init_expr_K:
1590  case case_label_expr_K:
1591  case CharType_K:
1592  case nullptr_type_K:
1593  case type_pack_expansion_K:
1594  case complex_type_K:
1595  case const_decl_K:
1596  case constructor_K:
1597  case enumeral_type_K:
1598  case field_decl_K:
1599  case function_decl_K:
1600  case identifier_node_K:
1601  case integer_type_K:
1602  case label_decl_K:
1603  case lang_type_K:
1604  case namespace_decl_K:
1605  case offset_type_K:
1606  case parm_decl_K:
1607  case qual_union_type_K:
1608  case real_type_K:
1609  case record_type_K:
1610  case result_decl_K:
1611  case set_type_K:
1612  case ssa_name_K:
1613  case statement_list_K:
1614  case target_expr_K:
1615  case target_mem_ref_K:
1616  case target_mem_ref461_K:
1617  case template_type_parm_K:
1618  case type_argument_pack_K:
1619  case translation_unit_decl_K:
1620  case template_decl_K:
1621  case using_decl_K:
1622  case tree_list_K:
1623  case tree_vec_K:
1624  case type_decl_K:
1625  case typename_type_K:
1626  case union_type_K:
1627  case vector_type_K:
1628  case void_type_K:
1629  case var_decl_K:
1630  case error_mark_K:
1631  case lut_expr_K:
1633  case CASE_CPP_NODES:
1634  case CASE_CST_NODES:
1635  case CASE_FAKE_NODES:
1636  case CASE_GIMPLE_NODES:
1637  case CASE_PRAGMA_NODES:
1640  case CASE_UNARY_EXPRESSION:
1641  default:
1642  {
1643  THROW_ASSERT(false, "Index " + STR(index) + " does not correspond to a pointer type");
1644  }
1645  }
1646  return 0;
1647 }
1648 
1650 {
1651  const auto pointer = _pointer->get_kind() == tree_reindex_K ? GET_CONST_NODE(_pointer) : _pointer;
1652  switch(pointer->get_kind())
1653  {
1654  case pointer_type_K:
1655  {
1656  const auto pt = GetPointerS<const pointer_type>(pointer);
1657  return pt->ptd;
1658  }
1659  case reference_type_K:
1660  {
1661  const auto pt = GetPointerS<const reference_type>(pointer);
1662  return pt->refd;
1663  }
1664  case function_type_K:
1665  {
1666  const auto ft = GetPointerS<const function_type>(pointer);
1667  return CGetPointedType(ft->retn);
1668  }
1669  case method_type_K:
1670  {
1671  const auto mt = GetPointerS<const method_type>(pointer);
1672  return CGetPointedType(mt->retn);
1673  }
1674  case array_type_K:
1675  case binfo_K:
1676  case block_K:
1677  case boolean_type_K:
1678  case call_expr_K:
1679  case aggr_init_expr_K:
1680  case case_label_expr_K:
1681  case CharType_K:
1682  case nullptr_type_K:
1683  case type_pack_expansion_K:
1684  case complex_type_K:
1685  case constructor_K:
1686  case enumeral_type_K:
1687  case identifier_node_K:
1688  case integer_type_K:
1689  case lang_type_K:
1690  case offset_type_K:
1691  case qual_union_type_K:
1692  case real_type_K:
1693  case record_type_K:
1694  case set_type_K:
1695  case ssa_name_K:
1696  case statement_list_K:
1697  case target_expr_K:
1698  case target_mem_ref_K:
1699  case target_mem_ref461_K:
1700  case template_type_parm_K:
1701  case type_argument_pack_K:
1702  case tree_list_K:
1703  case tree_vec_K:
1704  case typename_type_K:
1705  case union_type_K:
1706  case vector_type_K:
1707  case void_type_K:
1708  case error_mark_K:
1709  case lut_expr_K:
1711  case CASE_CPP_NODES:
1712  case CASE_CST_NODES:
1713  case CASE_DECL_NODES:
1714  case CASE_FAKE_NODES:
1715  case CASE_GIMPLE_NODES:
1716  case CASE_PRAGMA_NODES:
1719  case CASE_UNARY_EXPRESSION:
1720  default:
1721  {
1722  THROW_UNREACHABLE(STR(pointer) + ":" + pointer->get_kind_text() + " does not correspond to a pointer type");
1723  }
1724  }
1725  return tree_nodeConstRef();
1726 }
1727 
1728 unsigned int tree_helper::GetElements(const tree_managerConstRef& TM, const unsigned int index)
1729 {
1730  return CGetElements(TM->CGetTreeReindex(index))->index;
1731 }
1732 
1734 {
1735  const auto type = _type->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type) : _type;
1736  const auto at = GetPointer<const array_type>(type);
1737  if(at)
1738  {
1739  return at->elts;
1740  }
1741  const auto vt = GetPointer<const vector_type>(type);
1742  if(vt)
1743  {
1744  return vt->elts;
1745  }
1746  THROW_UNREACHABLE("Tree node of type " + type->get_kind_text());
1747  return tree_nodeConstRef();
1748 }
1749 
1750 std::string tree_helper::get_type_name(const tree_managerConstRef& TM, const unsigned int index)
1751 {
1752  const auto type = GET_CONST_NODE(CGetType(TM->CGetTreeReindex(index)));
1753  unsigned int type_index = type->index;
1754  THROW_ASSERT(GetPointer<const type_node>(type), "Node type not type_node");
1755  const auto tn = GetPointer<const type_node>(type);
1756  if(tn->name)
1757  {
1758  tree_nodeRef name;
1759  if(GET_CONST_NODE(tn->name)->get_kind() == type_decl_K)
1760  {
1761  name = GetPointer<const type_decl>(GET_CONST_NODE(tn->name))->name;
1762  if(!name)
1763  {
1764  return "Internal_" + STR(type_index);
1765  }
1766  }
1767  else
1768  {
1769  name = tn->name;
1770  }
1771  THROW_ASSERT(name && GET_CONST_NODE(name)->get_kind() == identifier_node_K,
1772  "Not an identifier node:" + STR(index));
1773  const auto id = GetPointer<const identifier_node>(GET_CONST_NODE(name));
1774  return id->strg;
1775  }
1776  else
1777  {
1778  return "Internal_" + STR(type_index);
1779  }
1780 }
1781 
1783 {
1784  THROW_ASSERT(_type, "expected a type");
1785  const auto type = _type->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type) : _type;
1786  THROW_ASSERT(GetPointer<const type_node>(type) || type->get_kind() == tree_list_K,
1787  std::string("expected a type_decl got ") + type->get_kind_text());
1788 
1789  switch(type->get_kind())
1790  {
1791  case pointer_type_K:
1792  {
1793  return GetTypeName(GET_CONST_NODE((GetPointerS<const pointer_type>(type))->ptd)) + "*";
1794  }
1795  case reference_type_K:
1796  {
1797  return GetTypeName(GET_CONST_NODE((GetPointerS<const reference_type>(type))->refd)) + "&";
1798  }
1799  case record_type_K:
1800  {
1801  const auto rect = GetPointerS<const record_type>(type);
1802  std::string nt;
1803  if(rect->name)
1804  {
1805  if(GET_CONST_NODE(rect->name)->get_kind() == type_decl_K)
1806  {
1807  const auto td = GetPointerS<const type_decl>(GET_CONST_NODE(rect->name));
1808  if(GET_CONST_NODE(td->name)->get_kind() == identifier_node_K)
1809  {
1810  const auto idn = GetPointerS<const identifier_node>(GET_CONST_NODE(td->name));
1811  nt = idn->strg;
1812  }
1813  else
1814  {
1815  THROW_ERROR("unexpected record type pattern: " + STR(type));
1816  }
1817  }
1818  else if(GET_CONST_NODE(rect->name)->get_kind() == identifier_node_K)
1819  {
1820  const auto idn = GetPointerS<const identifier_node>(GET_CONST_NODE(rect->name));
1821  nt = "struct " + NormalizeTypename(idn->strg);
1822  }
1823  else
1824  {
1825  THROW_ERROR("unexpected record type pattern: " + STR(type));
1826  }
1827  }
1828  else
1829  {
1830  return "_unnamed_" + STR(type->index);
1831  }
1832  if(SC_tmpl_class.find(nt) == SC_tmpl_class.end())
1833  {
1834  return nt;
1835  }
1836  else if(rect->tmpl_args) /*the class has template parameters*/
1837  {
1838  const auto rtv = GetPointerS<const tree_vec>(GET_CONST_NODE(rect->tmpl_args));
1839  THROW_ASSERT(rtv->lngt == 1 || nt == "sc_port", "Expected just one element");
1840  return GetTypeName(GET_CONST_NODE(rtv->list_of_op[0]));
1841  }
1842  else
1843  {
1844  THROW_ERROR("Unexpected template parameter pattern");
1845  }
1846  return ""; // unreachable code
1847  }
1848  case union_type_K:
1849  {
1850  const auto unt = GetPointerS<const union_type>(type);
1851  std::string nt;
1852  if(unt->name)
1853  {
1854  if(GET_CONST_NODE(unt->name)->get_kind() == type_decl_K)
1855  {
1856  const auto td = GetPointerS<const type_decl>(GET_CONST_NODE(unt->name));
1857  if(GET_CONST_NODE(td->name)->get_kind() == identifier_node_K)
1858  {
1859  const auto idn = GetPointerS<const identifier_node>(GET_CONST_NODE(td->name));
1860  nt = idn->strg;
1861  }
1862  else
1863  {
1864  THROW_ERROR("unexpected record type pattern: " + STR(type));
1865  }
1866  }
1867  else if(GET_CONST_NODE(unt->name)->get_kind() == identifier_node_K)
1868  {
1869  const auto idn = GetPointerS<const identifier_node>(GET_CONST_NODE(unt->name));
1870  nt = "union " + idn->strg;
1871  }
1872  else
1873  {
1874  THROW_ERROR("unexpected record type pattern: " + STR(type));
1875  }
1876  }
1877  else
1878  {
1879  return "_unnamed_" + STR(type->index);
1880  }
1881  if(SC_tmpl_class.find(nt) == SC_tmpl_class.end())
1882  {
1883  return nt;
1884  }
1885  else
1886  {
1887  THROW_ERROR("Unexpected template parameter pattern");
1888  }
1889  return ""; // unreachable code
1890  }
1891  case array_type_K:
1892  {
1893  const auto at = GetPointerS<const array_type>(type);
1894  std::string vec_size_string;
1895  if(at->domn)
1896  {
1897  const auto domain = GET_CONST_NODE(at->domn);
1898  const auto it = GetPointer<const integer_type>(domain);
1899  THROW_ASSERT(it, "expected an integer type as array domain");
1900  if(it->max)
1901  {
1902  const auto ic = GetPointer<const integer_cst>(GET_CONST_NODE(it->max));
1903  if(ic)
1904  {
1905  const auto vec_size = GetConstValue(it->max) + 1;
1906  vec_size_string = "[" + STR(vec_size) + "]";
1907  }
1908  else
1909  {
1910  vec_size_string = "[]";
1911  }
1912  }
1913  }
1914  return GetTypeName(GET_CONST_NODE(at->elts)) + vec_size_string;
1915  }
1916  case enumeral_type_K:
1917  {
1918  const auto et = GetPointerS<const enumeral_type>(type);
1919  if(et->name)
1920  {
1921  if(GET_CONST_NODE(et->name)->get_kind() == type_decl_K)
1922  {
1923  const auto td = GetPointerS<const type_decl>(GET_CONST_NODE(et->name));
1924  const auto in = GetPointerS<const identifier_node>(GET_CONST_NODE(td->name));
1925  return in->strg;
1926  }
1927  else if(GET_CONST_NODE(et->name)->get_kind() == identifier_node_K)
1928  {
1929  const auto in = GetPointerS<const identifier_node>(GET_CONST_NODE(et->name));
1930  return "enum " + in->strg;
1931  }
1932  }
1933  return "enum Internal_" + STR(type->index);
1934  }
1935  case boolean_type_K:
1936  case integer_type_K:
1937  case CharType_K:
1938  case nullptr_type_K:
1939  case type_pack_expansion_K:
1940  case real_type_K:
1941  case complex_type_K:
1942  case void_type_K:
1943  case vector_type_K:
1944  {
1945  const auto tnode = GetPointerS<const type_node>(type);
1946  if(!tnode->name)
1947  {
1948  if(type->get_kind() == integer_type_K)
1949  {
1950  return "int";
1951  }
1952  return STR(type->index);
1953  }
1954  if(GET_CONST_NODE(tnode->name)->get_kind() == type_decl_K)
1955  {
1956  const auto tdecl = GetPointerS<const type_decl>(GET_CONST_NODE(tnode->name));
1957  THROW_ASSERT(GET_CONST_NODE(tdecl->name)->get_kind() == identifier_node_K, "unexpected type name pattern");
1958  const auto idn = GetPointerS<const identifier_node>(GET_CONST_NODE(tdecl->name));
1959  return idn->strg;
1960  }
1961  else if(GET_CONST_NODE(tnode->name)->get_kind() == identifier_node_K)
1962  {
1963  const auto idn = GetPointerS<const identifier_node>(GET_CONST_NODE(tnode->name));
1964  return idn->strg;
1965  }
1966  else
1967  {
1968  THROW_UNREACHABLE(std::string("unexpected builtin type pattern ") + type->get_kind_text() + " " +
1969  STR(type));
1970  }
1971  break;
1972  }
1973  case function_type_K:
1974  {
1975  std::string retn = GetTypeName(GET_CONST_NODE(GetPointerS<const function_type>(type)->retn));
1976  retn += "(*)(";
1977  if(GetPointerS<const function_type>(type)->prms)
1978  {
1979  retn += GetTypeName(GET_CONST_NODE(GetPointerS<const function_type>(type)->prms));
1980  }
1981  retn += ")";
1982  return retn;
1983  }
1984  case method_type_K:
1985  {
1986  std::string retn = GetTypeName(GET_CONST_NODE(GetPointerS<const method_type>(type)->retn));
1987  retn += "(*)(";
1988  retn += GetTypeName(GET_CONST_NODE(GetPointerS<const method_type>(type)->prms));
1989  retn += ")";
1990  return retn;
1991  }
1992  case tree_list_K:
1993  {
1994  auto tl = GetPointerS<const tree_list>(type);
1995  std::string retn;
1996  if(tl->valu)
1997  {
1998  retn = GetTypeName(GET_CONST_NODE(tl->valu));
1999  }
2000  std::list<const tree_list*> tl_list;
2001  while(tl->chan)
2002  {
2003  tl = GetPointerS<const tree_list>(GET_CONST_NODE(tl->chan));
2004  tl_list.push_back(tl);
2005  }
2006  for(const auto& valu : tl_list)
2007  {
2008  retn += "," + GetTypeName(GET_CONST_NODE(valu->valu));
2009  }
2010  return retn;
2011  }
2012  case tree_reindex_K:
2013  {
2014  return GetTypeName(GET_CONST_NODE(type));
2015  }
2016  case binfo_K:
2017  case block_K:
2018  case call_expr_K:
2019  case aggr_init_expr_K:
2020  case case_label_expr_K:
2021  case constructor_K:
2022  case identifier_node_K:
2023  case lang_type_K:
2024  case offset_type_K:
2025  case qual_union_type_K:
2026  case set_type_K:
2027  case ssa_name_K:
2028  case statement_list_K:
2029  case target_expr_K:
2030  case target_mem_ref_K:
2031  case target_mem_ref461_K:
2032  case template_type_parm_K:
2033  case type_argument_pack_K:
2034  case tree_vec_K:
2035  case typename_type_K:
2036  case error_mark_K:
2037  case lut_expr_K:
2039  case CASE_CPP_NODES:
2040  case CASE_CST_NODES:
2041  case CASE_DECL_NODES:
2042  case last_tree_K:
2043  case none_K:
2044  case placeholder_expr_K:
2045  case CASE_GIMPLE_NODES:
2046  case CASE_PRAGMA_NODES:
2049  case CASE_UNARY_EXPRESSION:
2050  default:
2051  THROW_UNREACHABLE(std::string("unexpected type pattern ") + type->get_kind_text() + " " + STR(type));
2052  return "";
2053  }
2054  return "";
2055 }
2056 
2058  std::list<unsigned int>& params)
2059 {
2060  const auto pv = GetParameterTypes(TM->CGetTreeReindex(index));
2061  std::transform(pv.begin(), pv.end(), std::back_inserter(params),
2062  [](const tree_nodeConstRef& tn) { return tn->index; });
2063 }
2064 
2065 std::vector<tree_nodeConstRef> tree_helper::GetParameterTypes(const tree_nodeConstRef& ftype)
2066 {
2067  std::vector<tree_nodeConstRef> params;
2068  const auto Type = CGetType(ftype);
2069  THROW_ASSERT(Type, "expected a type");
2070  THROW_ASSERT(GET_CONST_NODE(Type)->get_kind() == function_type_K ||
2071  GET_CONST_NODE(Type)->get_kind() == method_type_K,
2072  "Type " + STR(Type) + " from " + STR(ftype) + " does not correspond to a function type");
2073  if(GetPointerS<const function_type>(GET_CONST_NODE(Type))->prms)
2074  {
2075  auto tl =
2076  GetPointerS<const tree_list>(GET_CONST_NODE(GetPointerS<const function_type>(GET_CONST_NODE(Type))->prms));
2077  params.push_back(tl->valu);
2078  while(tl->chan)
2079  {
2080  tl = GetPointerS<const tree_list>(GET_CONST_NODE(tl->chan));
2081  params.push_back(tl->valu);
2082  }
2083  }
2084  return params;
2085 }
2086 
2088 {
2089  const auto tn0_type = GET_CONST_NODE(CGetType(tn0));
2090  const auto tn1_type = GET_CONST_NODE(CGetType(tn1));
2091  return tn0_type->get_kind() == tn1_type->get_kind() && Size(tn0_type) == Size(tn1_type) &&
2092  (tn0_type->get_kind() != integer_type_K || GetPointerS<const integer_type>(tn0_type)->unsigned_flag ==
2093  GetPointerS<const integer_type>(tn1_type)->unsigned_flag) &&
2094  (tn0_type->get_kind() != enumeral_type_K || GetPointerS<const enumeral_type>(tn0_type)->unsigned_flag ==
2095  GetPointerS<const enumeral_type>(tn1_type)->unsigned_flag);
2096 }
2097 
2098 unsigned int tree_helper::get_type_index(const tree_managerConstRef& TM, const unsigned int index)
2099 {
2100  bool is_a_pointer;
2101  bool is_a_function;
2102  long long int vec_size;
2103  return get_type_index(TM, index, vec_size, is_a_pointer, is_a_function);
2104 }
2105 
2106 std::vector<tree_nodeConstRef> tree_helper::CGetFieldTypes(const tree_nodeConstRef& _type)
2107 {
2108  const auto type = GET_CONST_NODE(_type);
2109  std::vector<tree_nodeConstRef> ret;
2110  if(type->get_kind() == record_type_K)
2111  {
2112  const auto rt = GetPointerS<const record_type>(type);
2113  for(const auto& list_of_fld : rt->list_of_flds)
2114  {
2115  if(GET_CONST_NODE(list_of_fld)->get_kind() == type_decl_K)
2116  {
2117  continue;
2118  }
2119  if(GET_CONST_NODE(list_of_fld)->get_kind() == function_decl_K)
2120  {
2121  continue;
2122  }
2123  ret.push_back(CGetType(list_of_fld));
2124  }
2125  }
2126  else if(type->get_kind() == union_type_K)
2127  {
2128  const auto ut = GetPointerS<const union_type>(type);
2129  for(const auto& list_of_fld : ut->list_of_flds)
2130  {
2131  ret.push_back(CGetType(list_of_fld));
2132  }
2133  }
2134  else
2135  {
2136  THROW_UNREACHABLE("Asking fields type of not a type. Tree node is " + type->ToString());
2137  }
2138  return ret;
2139 }
2140 
2141 unsigned int tree_helper::get_field_idx(const tree_managerConstRef& TM, const unsigned int index, unsigned int idx)
2142 {
2143  const auto node = TM->CGetTreeReindex(index);
2144  return GetFieldIdx(node, idx)->index;
2145 }
2146 
2148 {
2149  THROW_ASSERT(GetPointer<const record_type>(type) || GetPointer<const union_type>(type),
2150  "expected record or union type");
2151  const auto rt = GetPointer<const record_type>(type);
2152  const auto ut = GetPointer<const union_type>(type);
2153  if(rt)
2154  {
2155  THROW_ASSERT(idx < rt->list_of_flds.size(), "unexpected index for list of fields");
2156  return rt->list_of_flds[idx];
2157  }
2158  else if(ut)
2159  {
2160  THROW_ASSERT(idx < ut->list_of_flds.size(), "unexpected index for list of fields");
2161  return ut->list_of_flds[idx];
2162  }
2163  THROW_ERROR("unexpected behavior");
2164  return nullptr;
2165 }
2166 
2168 {
2169  const auto node = _node->get_kind() == tree_reindex_K ? GET_CONST_NODE(_node) : _node;
2170  switch(node->get_kind())
2171  {
2172  case call_expr_K:
2173  case aggr_init_expr_K:
2174  {
2175  const auto ce = GetPointerS<const call_expr>(node);
2176  return ce->type;
2177  }
2178  case gimple_asm_K:
2179  case gimple_bind_K:
2180  case gimple_return_K:
2181  case gimple_resx_K:
2182  case gimple_switch_K:
2183  case gimple_label_K:
2184  case gimple_goto_K:
2185  case gimple_nop_K:
2186  case gimple_call_K:
2187  case gimple_cond_K:
2188  case gimple_multi_way_if_K:
2189  case gimple_pragma_K:
2190  {
2191  return tree_nodeConstRef();
2192  }
2193  case lut_expr_K:
2194  case CASE_UNARY_EXPRESSION:
2198  {
2199  const auto en = GetPointerS<const expr_node>(node);
2200  THROW_ASSERT(en && en->type, std::string("this NODE does not have a type: ") + node->get_kind_text());
2201  return en->type;
2202  }
2203  case gimple_phi_K:
2204  {
2205  const auto gp = GetPointerS<const gimple_phi>(node);
2206  return CGetType(gp->res);
2207  }
2208  case gimple_assign_K:
2209  {
2210  const auto gm = GetPointerS<const gimple_assign>(node);
2211  return CGetType(gm->op0);
2212  }
2213  case integer_cst_K:
2214  {
2215  const auto ic = GetPointerS<const integer_cst>(node);
2216  return ic->type;
2217  }
2218  case real_cst_K:
2219  {
2220  const auto rc = GetPointerS<const real_cst>(node);
2221  return rc->type;
2222  }
2223  case string_cst_K:
2224  {
2225  const auto sc = GetPointerS<const string_cst>(node);
2226  return sc->type ? sc->type : _node;
2227  }
2228  case vector_cst_K:
2229  {
2230  const auto vc = GetPointerS<const vector_cst>(node);
2231  return vc->type ? vc->type : _node;
2232  }
2233  case complex_cst_K:
2234  {
2235  const auto cc = GetPointerS<const complex_cst>(node);
2236  return cc->type ? cc->type : _node;
2237  }
2238  case constructor_K:
2239  {
2240  const auto c = GetPointerS<const constructor>(node);
2241  if(c->type)
2242  {
2243  return c->type;
2244  }
2245  else
2246  {
2247  return tree_nodeConstRef();
2248  }
2249  }
2250  case CASE_DECL_NODES:
2251  {
2252  const auto dn = GetPointerS<const decl_node>(node);
2253  return dn->type;
2254  }
2255  case ssa_name_K:
2256  {
2257  const auto sa = GetPointerS<const ssa_name>(node);
2258  return sa->type;
2259  }
2260  case target_mem_ref_K:
2261  {
2262  const auto tm = GetPointerS<const target_mem_ref>(node);
2263  return CGetType(tm->orig);
2264  }
2265  case target_mem_ref461_K:
2266  {
2267  const auto tm = GetPointerS<const target_mem_ref461>(node);
2268  return tm->type;
2269  }
2270  case gimple_for_K:
2271  case gimple_while_K:
2272  {
2273  const auto gw = GetPointerS<const gimple_while>(node);
2274  return CGetType(gw->op0);
2275  }
2276  case CASE_TYPE_NODES:
2277  {
2278  return _node;
2279  }
2280  case binfo_K:
2281  case block_K:
2282  case case_label_expr_K:
2283  case gimple_predict_K:
2284  case identifier_node_K:
2285  case statement_list_K:
2286  case target_expr_K:
2287  case tree_list_K:
2288  case tree_vec_K:
2289  case CASE_CPP_NODES:
2290  case CASE_FAKE_NODES:
2291  case CASE_PRAGMA_NODES:
2292  case void_cst_K:
2293  case error_mark_K:
2294  default:
2295  {
2296  THROW_ERROR_CODE(NODE_NOT_YET_SUPPORTED_EC, std::string("Node not yet supported ") + node->get_kind_text());
2297  }
2298  }
2299  return _node;
2300 }
2301 
2302 bool tree_helper::is_an_enum(const tree_managerConstRef& TM, const unsigned int index)
2303 {
2304  const auto T = TM->CGetTreeReindex(index);
2305  return IsEnumType(T);
2306 }
2307 
2309 {
2310  const auto Type = CGetType(type);
2311  THROW_ASSERT(Type, "expected a type");
2312  return GET_CONST_NODE(Type)->get_kind() == enumeral_type_K;
2313 }
2314 
2315 bool tree_helper::is_a_struct(const tree_managerConstRef& TM, const unsigned int index)
2316 {
2317  const auto T = TM->CGetTreeReindex(index);
2318  return IsStructType(T);
2319 }
2320 
2322 {
2323  const auto Type = CGetType(type);
2324  THROW_ASSERT(Type, "expected a type");
2325  return GET_CONST_NODE(Type)->get_kind() == record_type_K;
2326 }
2327 
2328 bool tree_helper::is_an_union(const tree_managerConstRef& TM, const unsigned int index)
2329 {
2330  const auto T = TM->CGetTreeReindex(index);
2331  return IsUnionType(T);
2332 }
2333 
2335 {
2336  const auto Type = CGetType(type);
2337  THROW_ASSERT(Type, "expected a type");
2338  return GET_CONST_NODE(Type)->get_kind() == union_type_K;
2339 }
2340 
2341 bool tree_helper::is_a_complex(const tree_managerConstRef& TM, const unsigned int index)
2342 {
2343  const auto T = TM->CGetTreeReindex(index);
2344  return IsComplexType(T);
2345 }
2346 
2348 {
2349  const auto Type = CGetType(type);
2350  THROW_ASSERT(Type, "expected a type");
2351  return GET_CONST_NODE(Type)->get_kind() == complex_type_K;
2352 }
2353 
2354 static void getBuiltinFieldTypes(const tree_nodeConstRef& _type, std::list<tree_nodeConstRef>& listOfTypes,
2355  CustomUnorderedSet<unsigned int>& already_visited)
2356 {
2357  if(already_visited.count(_type->index))
2358  {
2359  return;
2360  }
2361  already_visited.insert(_type->index);
2362  const auto type = GET_CONST_NODE(_type);
2363  if(type->get_kind() == record_type_K)
2364  {
2365  const auto rt = GetPointerS<const record_type>(type);
2366  for(const auto& fld : rt->list_of_flds)
2367  {
2368  if(GET_CONST_NODE(fld)->get_kind() == type_decl_K)
2369  {
2370  continue;
2371  }
2372  if(GET_CONST_NODE(fld)->get_kind() == function_decl_K)
2373  {
2374  continue;
2375  }
2376  const auto fdType = tree_helper::CGetType(fld);
2377  getBuiltinFieldTypes(fdType, listOfTypes, already_visited);
2378  }
2379  }
2380  else if(type->get_kind() == union_type_K)
2381  {
2382  const auto ut = GetPointerS<const union_type>(type);
2383  for(const auto& fld : ut->list_of_flds)
2384  {
2385  const auto fdType = tree_helper::CGetType(fld);
2386  getBuiltinFieldTypes(fdType, listOfTypes, already_visited);
2387  }
2388  }
2389  else if(type->get_kind() == array_type_K)
2390  {
2391  const auto at = GetPointerS<const array_type>(type);
2392  THROW_ASSERT(at->elts, "elements type expected");
2393  getBuiltinFieldTypes(at->elts, listOfTypes, already_visited);
2394  }
2395  else if(type->get_kind() == vector_type_K)
2396  {
2397  const auto vt = GetPointerS<const vector_type>(type);
2398  THROW_ASSERT(vt->elts, "elements type expected");
2399  getBuiltinFieldTypes(vt->elts, listOfTypes, already_visited);
2400  }
2401  else
2402  {
2403  listOfTypes.push_back(_type);
2404  }
2405 }
2406 
2408 {
2409  std::list<tree_nodeConstRef> listOfTypes;
2410  CustomUnorderedSet<unsigned int> already_visited;
2411  getBuiltinFieldTypes(t, listOfTypes, already_visited);
2412  if(listOfTypes.empty())
2413  {
2414  return false;
2415  }
2417  {
2418  for(const auto& fld : GetPointerS<const record_type>(GET_CONST_NODE(t))->list_of_flds)
2419  {
2420  if(GetPointerS<const field_decl>(GET_CONST_NODE(fld))->is_bitfield())
2421  {
2422  return false;
2423  }
2424  }
2425  }
2426 
2427  const auto sizeFlds = tree_helper::Size(listOfTypes.front());
2428  if(ceil_pow2(sizeFlds) != sizeFlds)
2429  {
2430  return false;
2431  }
2432  for(const auto& fldType : listOfTypes)
2433  {
2434  if(sizeFlds != tree_helper::Size(fldType))
2435  {
2436  return false;
2437  }
2438  }
2439  return true;
2440 }
2441 
2442 bool tree_helper::is_an_array(const tree_managerConstRef& TM, const unsigned int index)
2443 {
2444  const auto T = TM->CGetTreeReindex(index);
2445  return IsArrayEquivType(T);
2446 }
2447 
2449 {
2450  const auto type = CGetType(_type);
2451  THROW_ASSERT(type, "expected a type index");
2452  if(GET_CONST_NODE(type)->get_kind() == array_type_K)
2453  {
2454  return true;
2455  }
2456  else if(GET_CONST_NODE(type)->get_kind() == record_type_K || GET_CONST_NODE(type)->get_kind() == union_type_K)
2457  {
2458  return same_size_fields(type);
2459  }
2460  return false;
2461 }
2462 
2464 {
2465  const auto type = CGetType(_type);
2466  THROW_ASSERT(type, "expected a type index");
2467  return GET_CONST_NODE(type)->get_kind() == array_type_K;
2468 }
2469 
2471 {
2472  std::list<tree_nodeConstRef> listOfTypes;
2473  CustomUnorderedSet<unsigned int> already_visited;
2474  const auto Type = CGetType(type);
2475  THROW_ASSERT(Type, "expected a type");
2476  getBuiltinFieldTypes(Type, listOfTypes, already_visited);
2477  THROW_ASSERT(!listOfTypes.empty(), "at least one type is expected");
2478  return listOfTypes.front();
2479 }
2480 
2481 bool tree_helper::is_a_pointer(const tree_managerConstRef& TM, const unsigned int index)
2482 {
2483  return IsPointerType(TM->CGetTreeReindex(index));
2484 }
2485 
2487 {
2488  const auto Type = CGetType(type);
2489  THROW_ASSERT(Type, "expected a type");
2490  if(GET_CONST_NODE(Type)->get_kind() == pointer_type_K)
2491  {
2492  return true;
2493  }
2494  else if(GET_CONST_NODE(Type)->get_kind() == reference_type_K)
2495  {
2496  return true; // reference objects are assimilated to pointers
2497  }
2498  else if(GET_CONST_NODE(Type)->get_kind() == array_type_K)
2499  {
2500  const auto at = GetPointerS<const array_type>(GET_CONST_NODE(Type));
2501  if(!at->domn)
2502  {
2503  return true;
2504  }
2505  }
2506  return false;
2507 }
2508 
2509 bool tree_helper::is_a_function(const tree_managerConstRef& TM, const unsigned int index)
2510 {
2511  return IsFunctionDeclaration(TM->CGetTreeReindex(index));
2512 }
2513 
2515 {
2516  THROW_ASSERT(type, "expected a type ");
2517  if(type->get_kind() == tree_reindex_K)
2518  {
2519  return GET_CONST_NODE(type)->get_kind() == function_decl_K;
2520  }
2521  return type->get_kind() == function_decl_K;
2522 }
2523 
2524 bool tree_helper::is_a_vector(const tree_managerConstRef& TM, const unsigned int index)
2525 {
2526  const auto T = TM->CGetTreeReindex(index);
2527  return IsVectorType(T);
2528 }
2529 
2531 {
2532  const auto Type = CGetType(type);
2533  THROW_ASSERT(Type, "expected a type");
2534  return GET_CONST_NODE(Type)->get_kind() == vector_type_K;
2535 }
2536 
2538 {
2539  const auto T = TM->CGetTreeReindex(index);
2540  THROW_ASSERT(T, "this index does not exist: " + STR(index));
2541  if(!IsVectorType(T))
2542  {
2543  return false;
2544  }
2545  if(GetPointer<const misaligned_indirect_ref>(GET_CONST_NODE(T)))
2546  {
2547  return true;
2548  }
2549  const auto Type = CGetType(T);
2550  THROW_ASSERT(Type, "expected a type index");
2551  const auto vt = GetPointer<const vector_type>(GET_CONST_NODE(Type));
2552  THROW_ASSERT(vt, "expected a vector type");
2553  return vt->algn != Size(Type);
2554 }
2555 
2556 bool tree_helper::is_an_addr_expr(const tree_managerConstRef& TM, const unsigned int index)
2557 {
2558  return TM->CGetTreeNode(index)->get_kind() == addr_expr_K;
2559 }
2560 
2562 {
2563  const auto type = _type->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type) : _type;
2564  THROW_ASSERT(GetPointer<const type_node>(type),
2565  "Tree node " + STR(type) + " is not a type_node but " + type->get_kind_text());
2566  if(GetPointer<const type_node>(type)->name)
2567  {
2568  const auto name = GET_CONST_NODE(GetPointer<const type_node>(type)->name);
2569  if(name->get_kind() == type_decl_K)
2570  {
2571  const auto td = GetPointer<const type_decl>(name);
2572  if(td->include_name == "<built-in>")
2573  {
2574  return false;
2575  }
2576  if(GetPointer<const complex_type>(type))
2577  {
2578  const auto name1 = PrintType(TM, type);
2579  std::vector<std::string> splitted = SplitString(name1, " ");
2580  if(splitted.size() > 1 &&
2581  (splitted[0] == "_Complex" || splitted[0] == "__complex__" || splitted[0] == "complex"))
2582  {
2583  return false;
2584  }
2585  }
2586  return true;
2587  }
2588  }
2589  return type->get_kind() == record_type_K || type->get_kind() == union_type_K || type->get_kind() == enumeral_type_K;
2590 }
2591 
2592 bool tree_helper::is_function_type(const tree_managerConstRef& TM, const unsigned int index)
2593 {
2594  return IsFunctionType(TM->CGetTreeReindex(index));
2595 }
2596 
2598 {
2599  const auto Type = CGetType(type);
2600  THROW_ASSERT(Type, "expected a type");
2601  return GET_CONST_NODE(Type)->get_kind() == function_type_K || GET_CONST_NODE(Type)->get_kind() == method_type_K;
2602 }
2603 
2605 {
2606  const auto T = TM->CGetTreeReindex(index);
2607  return IsFunctionPointerType(T);
2608 }
2609 
2611 {
2612  const auto Type = CGetType(type);
2613  THROW_ASSERT(Type, "expected a type");
2614  if(GET_CONST_NODE(Type)->get_kind() == pointer_type_K)
2615  {
2616  const auto ptd = GET_CONST_NODE(GetPointerS<const pointer_type>(Type)->ptd);
2617  if(GET_CONST_NODE(ptd)->get_kind() == function_type_K || GET_CONST_NODE(ptd)->get_kind() == method_type_K)
2618  {
2619  return true;
2620  }
2621  }
2622  return false;
2623 }
2624 
2625 bool tree_helper::is_bool(const tree_managerConstRef& TM, const unsigned int index)
2626 {
2627  const auto T = TM->CGetTreeReindex(index);
2628  return IsBooleanType(T);
2629 }
2630 
2632 {
2633  const auto Type = CGetType(type);
2634  THROW_ASSERT(Type, "expected a type");
2635  if(GET_CONST_NODE(Type)->get_kind() == boolean_type_K)
2636  {
2637  return true;
2638  }
2639  const auto type_name = GetTypeName(Type);
2640  return type_name == "sc_logic" || type_name == "sc_in_resolved" || type_name == "sc_inout_resolved" ||
2641  type_name == "sc_out_resolved" || type_name == "sc_in_clk" || type_name == "sc_inout_clk" ||
2642  type_name == "sc_out_clk" || type_name == "sc_bit" || type_name == "sc_clock";
2643 }
2644 
2645 bool tree_helper::is_a_void(const tree_managerConstRef& TM, const unsigned int index)
2646 {
2647  const auto T = TM->CGetTreeReindex(index);
2648  return IsVoidType(T);
2649 }
2650 
2652 {
2653  const auto Type = CGetType(type);
2654  THROW_ASSERT(Type, "expected a type");
2655  return GET_CONST_NODE(Type)->get_kind() == void_type_K;
2656 }
2657 
2658 bool tree_helper::is_natural(const tree_managerConstRef& TM, const unsigned int index)
2659 {
2660  const auto var = TM->CGetTreeReindex(index);
2661  return IsPositiveIntegerValue(var);
2662 }
2663 
2665 {
2666  const auto type = _type->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type) : _type;
2667  if(GetPointer<const ssa_name>(type) && GetPointer<const ssa_name>(type)->min)
2668  {
2669  const auto& minimum = GetPointer<const ssa_name>(type)->min;
2670  THROW_ASSERT(GET_CONST_NODE(minimum)->get_kind() == integer_cst_K, "expected an integer const: " + STR(type));
2671  const auto min_value = GetConstValue(minimum);
2672  return min_value >= 0;
2673  }
2674  return false;
2675 }
2676 
2677 bool tree_helper::is_int(const tree_managerConstRef& TM, const unsigned int index)
2678 {
2679  const auto T = TM->CGetTreeReindex(index);
2680  return IsSignedIntegerType(T);
2681 }
2682 
2684 {
2685  const auto Type = CGetType(type);
2686  THROW_ASSERT(Type, "expected a type");
2687  if(GET_CONST_NODE(Type)->get_kind() == enumeral_type_K)
2688  {
2689  return !GetPointerS<const enumeral_type>(GET_CONST_NODE(Type))->unsigned_flag;
2690  }
2691  if(GET_CONST_NODE(Type)->get_kind() == integer_type_K)
2692  {
2693  return !GetPointerS<const integer_type>(GET_CONST_NODE(Type))->unsigned_flag;
2694  }
2695  const auto type_name = GetTypeName(Type);
2696  return type_name == "sc_int";
2697 }
2698 
2699 bool tree_helper::is_real(const tree_managerConstRef& TM, const unsigned int index)
2700 {
2701  const auto T = TM->CGetTreeReindex(index);
2702  return IsRealType(T);
2703 }
2704 
2706 {
2707  const auto Type = CGetType(type);
2708  THROW_ASSERT(Type, "expected a type");
2709  return GET_CONST_NODE(Type)->get_kind() == real_type_K;
2710 }
2711 
2712 bool tree_helper::is_unsigned(const tree_managerConstRef& TM, const unsigned int index)
2713 {
2714  const auto T = TM->CGetTreeReindex(index);
2715  return IsUnsignedIntegerType(T);
2716 }
2717 
2719 {
2720  const auto Type = CGetType(type);
2721  THROW_ASSERT(Type, "expected a type");
2722  if(GET_CONST_NODE(Type)->get_kind() == enumeral_type_K)
2723  {
2724  return GetPointerS<const enumeral_type>(GET_CONST_NODE(Type))->unsigned_flag;
2725  }
2726  if(GET_CONST_NODE(Type)->get_kind() == integer_type_K)
2727  {
2728  return GetPointerS<const integer_type>(GET_CONST_NODE(Type))->unsigned_flag;
2729  }
2730  const auto type_name = GetTypeName(Type);
2731  return type_name == "sc_uint" || type_name == "sc_lv" || type_name == "sc_in_rv" || type_name == "sc_out_rv" ||
2732  type_name == "sc_inout_rv" || type_name == "sc_bv" || type_name == "sc_signal_rv";
2733 }
2734 
2735 bool tree_helper::is_scalar(const tree_managerConstRef& TM, const unsigned int var)
2736 {
2737  return IsScalarType(TM->CGetTreeReindex(var));
2738 }
2739 
2741 {
2742  return IsSignedIntegerType(type) || IsRealType(type) || IsUnsignedIntegerType(type) || IsBooleanType(type);
2743 }
2744 
2745 bool tree_helper::is_module(const tree_managerConstRef& TM, const unsigned int index)
2746 {
2747  THROW_ASSERT(index > 0, "expected positive non zero numbers");
2748  const std::string mod_st = "sc_module";
2749  const std::string mod_name_st = "sc_module_name";
2750  const std::string ifc_st = "sc_interface";
2751  const auto* rt = GetPointer<const record_type>(TM->CGetTreeNode(index));
2752  if(rt && rt->binf)
2753  {
2754  const auto bi = GetPointer<const binfo>(GET_CONST_NODE(rt->binf));
2755  if(bi && look_for_binfo_inheritance(bi, mod_st) && !look_for_binfo_inheritance(bi, mod_name_st) &&
2756  !look_for_binfo_inheritance(bi, ifc_st))
2757  {
2758  return true;
2759  }
2760  }
2761  return false;
2762 }
2763 
2765 {
2766  THROW_ASSERT(GetPointer<const record_type>(TM->CGetTreeNode(index)), "a record type is expected");
2767  std::string rec_name = GetRecordTypeName(TM->CGetTreeReindex(index));
2768  return rec_name == "sc_fifo" || rec_name == "tlm_fifo" || rec_name == "sc_mutex" || rec_name == "sc_semaphore";
2769 }
2770 
2771 bool tree_helper::is_channel(const tree_managerConstRef& TM, const unsigned int index)
2772 {
2773  THROW_ASSERT(index > 0, "expected positive non zero numbers");
2774  const std::string mod_st = "sc_module";
2775  const std::string ifc_st = "sc_interface";
2776  const auto* rt = GetPointer<const record_type>(TM->CGetTreeNode(index));
2777  if(rt && rt->binf)
2778  {
2779  const auto bi = GetPointer<const binfo>(GET_CONST_NODE(rt->binf));
2780  if(bi && look_for_binfo_inheritance(bi, mod_st) && look_for_binfo_inheritance(bi, ifc_st))
2781  {
2782  return true;
2783  }
2784  else
2785  {
2786  return is_builtin_channel(TM, index);
2787  }
2788  }
2789  else if(rt)
2790  {
2791  return is_builtin_channel(TM, index);
2792  }
2793  return false;
2794 }
2795 
2796 #if 0
2797 rt->get_maybe_name().find("sc_signal<") == 0 ||
2798  rt->get_maybe_name().find("sc_signal_resolved") == 0 || // inherit from sc_signal
2799  rt->get_maybe_name().find("sc_signal_rv<") == 0 || // inherit from sc_signal
2800  rt->get_maybe_name().find("sc_buffer") == 0) // inherit from sc_signal
2801 #endif
2802 bool tree_helper::is_signal(const tree_managerConstRef& TM, const unsigned int index)
2803 {
2804  THROW_ASSERT(index > 0, "expected positive non zero numbers");
2805  const std::string ifc_st = "sc_interface";
2806  const std::string pch_st = "sc_prim_channel";
2807  const std::string sig_st = "sc_signal";
2808  const std::string clock_st = "sc_clock";
2809  const auto* rt = GetPointer<const record_type>(TM->CGetTreeNode(index));
2810  if(rt && rt->binf)
2811  {
2812  const auto bi = GetPointer<const binfo>(GET_CONST_NODE(rt->binf));
2813  if(bi && look_for_binfo_inheritance(bi, pch_st) &&
2814  ((look_for_binfo_inheritance(bi, sig_st) && look_for_binfo_inheritance(bi, ifc_st))) &&
2815  rt->get_maybe_name() != clock_st)
2816  {
2817  return true;
2818  }
2819  }
2820  return false;
2821 }
2822 
2823 bool tree_helper::is_clock(const tree_managerConstRef& TM, const unsigned int index)
2824 {
2825  THROW_ASSERT(index > 0, "expected positive non zero numbers");
2826  const std::string ifc_st = "sc_interface";
2827  const std::string pch_st = "sc_prim_channel";
2828  const std::string clock_st = "sc_clock";
2829  const auto* rt = GetPointer<const record_type>(TM->CGetTreeNode(index));
2830  if(rt && rt->binf)
2831  {
2832  const auto bi = GetPointer<const binfo>(GET_CONST_NODE(rt->binf));
2833  if(bi && (look_for_binfo_inheritance(bi, ifc_st) && look_for_binfo_inheritance(bi, pch_st) &&
2834  rt->get_maybe_name() == clock_st))
2835  {
2836  return true;
2837  }
2838  }
2839  return false;
2840 }
2841 
2842 bool tree_helper::is_SC_BIND_PROXY_NIL(const tree_managerConstRef& TM, const unsigned int index)
2843 {
2844  THROW_ASSERT(index > 0, "expected positive non zero numbers");
2845  auto curr_tn = TM->CGetTreeNode(index);
2846  if(curr_tn->get_kind() == addr_expr_K)
2847  {
2848  curr_tn = GET_CONST_NODE(GetPointer<const addr_expr>(curr_tn)->op);
2849  }
2850  if(curr_tn->get_kind() == var_decl_K)
2851  {
2852  const auto vd = GetPointer<const var_decl>(curr_tn);
2853  if(vd->name && GET_CONST_NODE(vd->name)->get_kind() == identifier_node_K)
2854  {
2855  const auto id = GetPointer<const identifier_node>(GET_CONST_NODE(vd->name));
2856  std::string strg = id->strg;
2857  return strg.find("SC_BIND_PROXY_NIL") != std::string::npos;
2858  }
2859  }
2860  return false;
2861 }
2862 
2863 #if 0
2864 rt->get_maybe_name().find("sc_in<") == 0 || //inherit from sc_port
2865  rt->get_maybe_name().find("sc_in_rv<") == 0 || //inherit from sc_in
2866  rt->get_maybe_name().find("sc_in_resolved") == 0 || //inherit from sc_in
2867  rt->get_maybe_name().find("sc_in_clk") == 0 || // equal to sc_in<bool>
2868  rt->get_maybe_name().find("sc_out<") == 0 || //inherit from sc_port
2869  rt->get_maybe_name().find("sc_out_rv<") == 0 || //inherit from sc_inout_rv
2870  rt->get_maybe_name().find("sc_out_resolved") == 0 || //inherit from sc_inout_resolved
2871  rt->get_maybe_name().find("sc_out_clk") == 0 || //equal to sc_out<bool>
2872  rt->get_maybe_name().find("sc_inout<") == 0 || //inherit from sc_port
2873  rt->get_maybe_name().find("sc_inout_rv<") == 0 || //inherit from sc_inout
2874  rt->get_maybe_name().find("sc_inout_resolved") == 0 || //inherit from sc_inout
2875  rt->get_maybe_name().find("sc_inout_clk") == 0 || //equal to sc_inout<bool>
2876  rt->get_maybe_name().find("sc_fifo_in<") == 0 || //inherit from sc_port
2877  rt->get_maybe_name().find("sc_fifo_out<") == 0 //inherit from sc_port
2878 #endif
2879 bool tree_helper::is_port(const tree_managerConstRef& TM, const unsigned int index)
2880 {
2881  THROW_ASSERT(index > 0, "expected positive non zero numbers");
2882  const std::string port_st = "sc_port";
2883  const std::string sc_export_st = "sc_export";
2884  const auto* rt = GetPointer<const record_type>(TM->CGetTreeNode(index));
2885  if(rt && rt->binf)
2886  {
2887  const auto bi = GetPointer<const binfo>(GET_CONST_NODE(rt->binf));
2888  if(bi && (look_for_binfo_inheritance(bi, port_st) || rt->get_maybe_name().find(sc_export_st) == 0))
2889  {
2890  return true;
2891  }
2892  }
2893  return false;
2894 }
2895 
2896 bool tree_helper::is_in_port(const tree_managerConstRef& TM, const unsigned int index)
2897 {
2898  THROW_ASSERT(index > 0, "expected positive non zero numbers");
2899  const std::string sc_in_st = "sc_in";
2900  const auto* rt = GetPointer<const record_type>(TM->CGetTreeNode(index));
2901  if(rt && rt->binf)
2902  {
2903  const auto bi = GetPointer<const binfo>(GET_CONST_NODE(rt->binf));
2904  if(bi && look_for_binfo_inheritance(bi, sc_in_st))
2905  {
2906  return true;
2907  }
2908  }
2909  return false;
2910 }
2911 
2912 bool tree_helper::is_out_port(const tree_managerConstRef& TM, const unsigned int index)
2913 {
2914  THROW_ASSERT(index > 0, "expected positive non zero numbers");
2915  const std::string sc_out_st =
2916  "sc_out"; // several out port are actually inout port (e.g., sc_out_resolved and sc_out_rv)
2917  const auto* rt = GetPointer<const record_type>(TM->CGetTreeNode(index));
2918  if(rt && rt->binf)
2919  {
2920  const auto bi = GetPointer<const binfo>(GET_CONST_NODE(rt->binf));
2921  if(bi && look_for_binfo_inheritance(bi, sc_out_st))
2922  {
2923  return true;
2924  }
2925  }
2926  return false;
2927 }
2928 
2929 bool tree_helper::is_inout_port(const tree_managerConstRef& TM, const unsigned int index)
2930 {
2931  THROW_ASSERT(index > 0, "expected positive non zero numbers");
2932  const std::string sc_inout_st = "sc_inout";
2933  const auto* rt = GetPointer<const record_type>(TM->CGetTreeNode(index));
2934  if(rt && rt->binf)
2935  {
2936  const auto bi = GetPointer<const binfo>(GET_CONST_NODE(rt->binf));
2937  if(bi && look_for_binfo_inheritance(bi, sc_inout_st))
2938  {
2939  return true;
2940  }
2941  }
2942  return false;
2943 }
2944 
2945 bool tree_helper::is_event(const tree_managerConstRef& TM, const unsigned int index)
2946 {
2947  THROW_ASSERT(index > 0, "expected positive non zero numbers");
2948  const std::string event_st = "sc_event";
2949  const auto* rt = GetPointer<const record_type>(TM->CGetTreeNode(index));
2950  if(rt && rt->binf)
2951  {
2952  const auto bi = GetPointer<const binfo>(GET_CONST_NODE(rt->binf));
2953  if(bi && look_for_binfo_inheritance(bi, event_st))
2954  {
2955  return true;
2956  }
2957  }
2958  return false;
2959 }
2960 
2961 bool tree_helper::is_a_variable(const tree_managerConstRef& TM, const unsigned int index)
2962 {
2963  const auto node = TM->CGetTreeReindex(index);
2964  return IsVariableType(node);
2965 }
2966 
2968 {
2969  const auto node_kind = node->get_kind() == tree_reindex_K ? GET_CONST_NODE(node)->get_kind() : node->get_kind();
2970  switch(node_kind)
2971  {
2972  case integer_cst_K:
2973  case real_cst_K:
2974  case complex_cst_K:
2975  case vector_cst_K:
2976  case void_cst_K:
2977  case ssa_name_K:
2978  case function_decl_K:
2979  case var_decl_K:
2980  case parm_decl_K:
2981  case label_decl_K:
2982  case result_decl_K:
2983  case call_expr_K:
2984  case aggr_init_expr_K:
2985  return true;
2987  case binfo_K:
2988  case block_K:
2989  case case_label_expr_K:
2990  case const_decl_K:
2991  case constructor_K:
2992  case field_decl_K:
2993  case identifier_node_K:
2994  case namespace_decl_K:
2995  case statement_list_K:
2996  case string_cst_K:
2997  case target_expr_K:
2998  case target_mem_ref_K:
2999  case target_mem_ref461_K:
3000  case translation_unit_decl_K:
3001  case template_decl_K:
3002  case using_decl_K:
3003  case tree_list_K:
3004  case tree_vec_K:
3005  case type_decl_K:
3006  case error_mark_K:
3007  case lut_expr_K:
3009  case CASE_CPP_NODES:
3010  case CASE_FAKE_NODES:
3011  case CASE_GIMPLE_NODES:
3012  case CASE_PRAGMA_NODES:
3015  case CASE_TYPE_NODES:
3016  case CASE_UNARY_EXPRESSION:
3017  return false;
3018  default:
3020  "tree_helper::is_a_variable - variable is not supported: " + tree_node::GetString(node_kind));
3021  }
3022  return true;
3023 }
3024 
3026 {
3027  switch(GET_CONST_NODE(node)->get_kind())
3028  {
3029  case gimple_assign_K:
3030  {
3031  const auto ga = GetPointerS<const gimple_assign>(GET_CONST_NODE(node));
3032  if(ga->temporary_address)
3033  {
3034  const auto ae = GetPointer<const addr_expr>(GET_CONST_NODE(ga->op1));
3035  if(ae)
3036  {
3037  return check_for_simple_pointer_arithmetic(ae->op);
3038  }
3039  else
3040  {
3041  const auto ppe = GetPointer<const pointer_plus_expr>(GET_CONST_NODE(ga->op1));
3042  if(ppe)
3043  {
3044  return check_for_simple_pointer_arithmetic(ppe->op0);
3045  }
3046  else
3047  {
3048  const auto ne = GetPointer<const nop_expr>(GET_CONST_NODE(ga->op1));
3049  if(ne)
3050  {
3051  return check_for_simple_pointer_arithmetic(ne->op);
3052  }
3053  else
3054  {
3055  const auto vce = GetPointer<const view_convert_expr>(GET_CONST_NODE(ga->op1));
3056  if(vce)
3057  {
3058  return check_for_simple_pointer_arithmetic(vce->op);
3059  }
3060  else
3061  {
3062  return check_for_simple_pointer_arithmetic(ga->op1);
3063  }
3064  }
3065  }
3066  }
3067  }
3068  else if(GetPointer<const pointer_plus_expr>(GET_CONST_NODE(ga->op1)))
3069  {
3070  const auto ppe = GetPointer<const pointer_plus_expr>(GET_CONST_NODE(ga->op1));
3071  return check_for_simple_pointer_arithmetic(ppe->op0);
3072  }
3073  else if(GetPointer<const nop_expr>(GET_CONST_NODE(ga->op1)))
3074  {
3075  const auto ne = GetPointer<const nop_expr>(GET_CONST_NODE(ga->op1));
3076  return check_for_simple_pointer_arithmetic(ne->op);
3077  }
3078  else if(GetPointer<const view_convert_expr>(GET_CONST_NODE(ga->op1)))
3079  {
3080  const auto vce = GetPointer<const view_convert_expr>(GET_CONST_NODE(ga->op1));
3081  return check_for_simple_pointer_arithmetic(vce->op);
3082  }
3083  else
3084  {
3085  return tree_nodeConstRef();
3086  }
3087  }
3088  case mem_ref_K:
3089  {
3090  const auto mr = GetPointer<const mem_ref>(GET_CONST_NODE(node));
3091  return check_for_simple_pointer_arithmetic(mr->op0);
3092  }
3093  case target_mem_ref461_K:
3094  {
3095  const auto tmr = GetPointer<const target_mem_ref461>(GET_CONST_NODE(node));
3096  return check_for_simple_pointer_arithmetic(tmr->base);
3097  }
3098  case component_ref_K:
3099  {
3100  const auto cr = GetPointer<const component_ref>(GET_CONST_NODE(node));
3101  return check_for_simple_pointer_arithmetic(cr->op0);
3102  }
3103  case realpart_expr_K:
3104  {
3105  const auto rpe = GetPointer<const realpart_expr>(GET_CONST_NODE(node));
3106  return check_for_simple_pointer_arithmetic(rpe->op);
3107  }
3108  case imagpart_expr_K:
3109  {
3110  const auto rpe = GetPointer<const imagpart_expr>(GET_CONST_NODE(node));
3111  return check_for_simple_pointer_arithmetic(rpe->op);
3112  }
3113  case bit_field_ref_K:
3114  {
3115  const auto bfr = GetPointer<const bit_field_ref>(GET_CONST_NODE(node));
3116  return check_for_simple_pointer_arithmetic(bfr->op0);
3117  }
3118  case pointer_plus_expr_K:
3119  {
3120  const auto ppe = GetPointer<const pointer_plus_expr>(GET_CONST_NODE(node));
3121  return check_for_simple_pointer_arithmetic(ppe->op0);
3122  }
3123  case view_convert_expr_K:
3124  {
3125  const auto vce = GetPointer<const view_convert_expr>(GET_CONST_NODE(node));
3126  return check_for_simple_pointer_arithmetic(vce->op);
3127  }
3128  case addr_expr_K:
3129  {
3130  const auto ae = GetPointer<const addr_expr>(GET_CONST_NODE(node));
3131  return check_for_simple_pointer_arithmetic(ae->op);
3132  }
3133  case array_ref_K:
3134  {
3135  const auto ar = GetPointer<const array_ref>(GET_CONST_NODE(node));
3136  return check_for_simple_pointer_arithmetic(ar->op0);
3137  }
3138  case parm_decl_K:
3139  case var_decl_K:
3140  case ssa_name_K:
3141  return node;
3142 
3143  case binfo_K:
3144  case block_K:
3145  case call_expr_K:
3146  case aggr_init_expr_K:
3147  case case_label_expr_K:
3148  case constructor_K:
3149  case identifier_node_K:
3150  case statement_list_K:
3151  case target_mem_ref_K:
3152  case tree_list_K:
3153  case tree_vec_K:
3154  case assert_expr_K:
3155  case bit_and_expr_K:
3156  case bit_ior_expr_K:
3157  case bit_xor_expr_K:
3158  case catch_expr_K:
3159  case ceil_div_expr_K:
3160  case ceil_mod_expr_K:
3161  case complex_expr_K:
3162  case compound_expr_K:
3163  case eh_filter_expr_K:
3164  case eq_expr_K:
3165  case exact_div_expr_K:
3166  case fdesc_expr_K:
3167  case floor_div_expr_K:
3168  case floor_mod_expr_K:
3169  case ge_expr_K:
3170  case gt_expr_K:
3171  case goto_subroutine_K:
3172  case in_expr_K:
3173  case init_expr_K:
3174  case le_expr_K:
3175  case lrotate_expr_K:
3176  case lshift_expr_K:
3177  case lt_expr_K:
3178  case max_expr_K:
3179  case min_expr_K:
3180  case minus_expr_K:
3181  case modify_expr_K:
3182  case mult_expr_K:
3183  case mult_highpart_expr_K:
3184  case ne_expr_K:
3185  case ordered_expr_K:
3186  case plus_expr_K:
3187  case postdecrement_expr_K:
3188  case postincrement_expr_K:
3189  case predecrement_expr_K:
3190  case preincrement_expr_K:
3191  case range_expr_K:
3192  case rdiv_expr_K:
3193  case round_div_expr_K:
3194  case round_mod_expr_K:
3195  case rrotate_expr_K:
3196  case rshift_expr_K:
3197  case set_le_expr_K:
3198  case trunc_div_expr_K:
3199  case trunc_mod_expr_K:
3200  case truth_and_expr_K:
3201  case truth_andif_expr_K:
3202  case truth_or_expr_K:
3203  case truth_orif_expr_K:
3204  case truth_xor_expr_K:
3205  case try_catch_expr_K:
3206  case try_finally_K:
3207  case uneq_expr_K:
3208  case ltgt_expr_K:
3209  case unge_expr_K:
3210  case ungt_expr_K:
3211  case unle_expr_K:
3212  case unlt_expr_K:
3213  case unordered_expr_K:
3214  case widen_sum_expr_K:
3215  case widen_mult_expr_K:
3216  case with_size_expr_K:
3217  case vec_lshift_expr_K:
3218  case vec_rshift_expr_K:
3219  case widen_mult_hi_expr_K:
3220  case widen_mult_lo_expr_K:
3221  case vec_pack_trunc_expr_K:
3222  case vec_pack_sat_expr_K:
3223  case vec_pack_fix_trunc_expr_K:
3224  case vec_extracteven_expr_K:
3225  case vec_extractodd_expr_K:
3226  case vec_interleavehigh_expr_K:
3227  case vec_interleavelow_expr_K:
3228  case extract_bit_expr_K:
3229  case CASE_CPP_NODES:
3230  case CASE_CST_NODES:
3231  case const_decl_K:
3232  case field_decl_K:
3233  case function_decl_K:
3234  case label_decl_K:
3235  case namespace_decl_K:
3236  case result_decl_K:
3237  case translation_unit_decl_K:
3238  case template_decl_K:
3239  case using_decl_K:
3240  case type_decl_K:
3241  case CASE_FAKE_NODES:
3242  case gimple_asm_K:
3243  case gimple_bind_K:
3244  case gimple_call_K:
3245  case gimple_cond_K:
3246  case gimple_for_K:
3247  case gimple_goto_K:
3248  case gimple_label_K:
3249  case gimple_multi_way_if_K:
3250  case gimple_nop_K:
3251  case gimple_phi_K:
3252  case gimple_pragma_K:
3253  case gimple_predict_K:
3254  case gimple_resx_K:
3255  case gimple_return_K:
3256  case gimple_switch_K:
3257  case gimple_while_K:
3258  case CASE_PRAGMA_NODES:
3259  case vtable_ref_K:
3260  case with_cleanup_expr_K:
3261  case obj_type_ref_K:
3262  case save_expr_K:
3263  case cond_expr_K:
3264  case vec_cond_expr_K:
3265  case vec_perm_expr_K:
3266  case dot_prod_expr_K:
3267  case ternary_plus_expr_K:
3268  case ternary_pm_expr_K:
3269  case ternary_mp_expr_K:
3270  case ternary_mm_expr_K:
3271  case fshl_expr_K:
3272  case fshr_expr_K:
3273  case bit_ior_concat_expr_K:
3274  case abs_expr_K:
3275  case alignof_expr_K:
3276  case arrow_expr_K:
3277  case bit_not_expr_K:
3278  case buffer_ref_K:
3279  case card_expr_K:
3280  case cleanup_point_expr_K:
3281  case conj_expr_K:
3282  case convert_expr_K:
3283  case exit_expr_K:
3284  case fix_ceil_expr_K:
3285  case fix_floor_expr_K:
3286  case fix_round_expr_K:
3287  case fix_trunc_expr_K:
3288  case float_expr_K:
3289  case indirect_ref_K:
3290  case misaligned_indirect_ref_K:
3291  case loop_expr_K:
3292  case lut_expr_K:
3293  case negate_expr_K:
3294  case non_lvalue_expr_K:
3295  case nop_expr_K:
3296  case reference_expr_K:
3297  case reinterpret_cast_expr_K:
3298  case sizeof_expr_K:
3299  case static_cast_expr_K:
3300  case throw_expr_K:
3301  case truth_not_expr_K:
3302  case unsave_expr_K:
3303  case va_arg_expr_K:
3304  case reduc_max_expr_K:
3305  case reduc_min_expr_K:
3306  case reduc_plus_expr_K:
3307  case vec_unpack_hi_expr_K:
3308  case vec_unpack_lo_expr_K:
3309  case vec_unpack_float_hi_expr_K:
3310  case vec_unpack_float_lo_expr_K:
3311  case CASE_TYPE_NODES:
3312  case array_range_ref_K:
3313  case error_mark_K:
3314  case target_expr_K:
3315  case paren_expr_K:
3316  case sat_plus_expr_K:
3317  case sat_minus_expr_K:
3318  case extractvalue_expr_K:
3319  case insertvalue_expr_K:
3320  case extractelement_expr_K:
3321  case insertelement_expr_K:
3322  case frem_expr_K:
3323  {
3324  return tree_nodeConstRef();
3325  }
3326  default:
3327  THROW_UNREACHABLE("");
3328  return tree_nodeConstRef();
3329  }
3330  return tree_nodeConstRef();
3331 }
3332 
3333 unsigned int tree_helper::get_base_index(const tree_managerConstRef& TM, const unsigned int index)
3334 {
3335  const auto node = TM->CGetTreeReindex(index);
3336  const auto var = GetBaseVariable(node);
3337  return var ? GET_INDEX_CONST_NODE(var) : 0;
3338 }
3339 
3341 {
3342  THROW_ASSERT(_node && _node->get_kind() == tree_reindex_K, "expected valid tree node reindex");
3343  const auto node = GET_CONST_NODE(_node);
3344  switch(node->get_kind())
3345  {
3346  case ssa_name_K:
3347  {
3348  const auto sn = GetPointerS<const ssa_name>(node);
3349  if(sn->use_set->is_a_singleton())
3350  {
3351  if(GET_CONST_NODE(sn->use_set->variables.front())->get_kind() == function_decl_K)
3352  {
3353  return sn->use_set->variables.front();
3354  }
3355  else
3356  {
3357  return GetBaseVariable(sn->use_set->variables.front());
3358  }
3359  }
3360  const auto base = check_for_simple_pointer_arithmetic(sn->CGetDefStmt());
3361  if(base)
3362  {
3363  return GetBaseVariable(base);
3364  }
3365 
3366  if(sn->var)
3367  {
3368  if(GET_CONST_NODE(sn->var)->get_kind() == function_decl_K)
3369  {
3370  return sn->var;
3371  }
3372  else
3373  {
3374  return GetBaseVariable(sn->var);
3375  }
3376  }
3377  else
3378  {
3379  return _node;
3380  }
3381  }
3382  case result_decl_K:
3383  case parm_decl_K:
3384  case var_decl_K:
3385  case string_cst_K:
3386  case integer_cst_K:
3387  {
3388  return _node;
3389  }
3390  case indirect_ref_K:
3391  {
3392  const auto ir = GetPointerS<const indirect_ref>(node);
3393  return GetBaseVariable(ir->op);
3394  }
3395  case misaligned_indirect_ref_K:
3396  {
3397  const auto mir = GetPointerS<const misaligned_indirect_ref>(node);
3398  return GetBaseVariable(mir->op);
3399  }
3400  case mem_ref_K:
3401  {
3402  const auto mr = GetPointerS<const mem_ref>(node);
3403  return GetBaseVariable(mr->op0);
3404  }
3405  case array_ref_K:
3406  {
3407  const auto ar = GetPointerS<const array_ref>(node);
3408  return GetBaseVariable(ar->op0);
3409  }
3410  case component_ref_K:
3411  {
3412  const auto cr = GetPointerS<const component_ref>(node);
3413  return GetBaseVariable(cr->op0);
3414  }
3415  case realpart_expr_K:
3416  {
3417  const auto rpe = GetPointerS<const realpart_expr>(node);
3418  return GetBaseVariable(rpe->op);
3419  }
3420  case imagpart_expr_K:
3421  {
3422  const auto rpe = GetPointerS<const imagpart_expr>(node);
3423  return GetBaseVariable(rpe->op);
3424  }
3425  case bit_field_ref_K:
3426  {
3427  const auto bfr = GetPointerS<const bit_field_ref>(node);
3428  return GetBaseVariable(bfr->op0);
3429  }
3430  case target_mem_ref_K:
3431  {
3432  const auto tmr = GetPointerS<const target_mem_ref>(node);
3433  if(tmr->symbol)
3434  {
3435  return GetBaseVariable(tmr->symbol);
3436  }
3437  else if(tmr->base)
3438  {
3439  return GetBaseVariable(tmr->base);
3440  }
3441  else if(tmr->idx)
3442  {
3443  return GetBaseVariable(tmr->idx);
3444  }
3445  else
3446  {
3448  "tree_helper::GetBaseVariable::target_mem_ref_K - variable type pattern not supported: " +
3449  STR(node));
3450  }
3451  break;
3452  }
3453  case target_mem_ref461_K:
3454  {
3455  const auto tmr = GetPointerS<const target_mem_ref461>(node);
3456  if(tmr->base)
3457  {
3458  return GetBaseVariable(tmr->base);
3459  }
3460  else if(tmr->idx)
3461  {
3462  return GetBaseVariable(tmr->idx);
3463  }
3464  else if(tmr->idx2)
3465  {
3466  return GetBaseVariable(tmr->idx2);
3467  }
3468  else
3469  {
3472  "tree_helper::GetBaseVariable::target_mem_ref461_K - variable type pattern not supported: " +
3473  STR(node));
3474  }
3475  break;
3476  }
3477  case addr_expr_K:
3478  {
3479  const auto ae = GetPointerS<const addr_expr>(node);
3480  const auto addr_expr_op = GET_CONST_NODE(ae->op);
3481 
3482  switch(addr_expr_op->get_kind())
3483  {
3484  case ssa_name_K:
3485  case var_decl_K:
3486  case parm_decl_K:
3487  case string_cst_K:
3488  case result_decl_K:
3489  {
3490  return ae->op;
3491  }
3492  case array_ref_K:
3493  {
3494  const auto ar = GetPointerS<const array_ref>(addr_expr_op);
3495  if(GET_CONST_NODE(ar->op1)->get_kind() == integer_cst_K && GetConstValue(ar->op1) == 0)
3496  {
3497  switch(GET_CONST_NODE(ar->op0)->get_kind())
3498  {
3499  case ssa_name_K:
3500  case var_decl_K:
3501  case parm_decl_K:
3502  case string_cst_K:
3503  {
3504  return ar->op0;
3505  }
3506  case binfo_K:
3507  case block_K:
3508  case call_expr_K:
3509  case aggr_init_expr_K:
3510  case case_label_expr_K:
3511  case complex_cst_K:
3512  case const_decl_K:
3513  case constructor_K:
3514  case field_decl_K:
3515  case function_decl_K:
3516  case identifier_node_K:
3517  case integer_cst_K:
3518  case label_decl_K:
3519  case namespace_decl_K:
3520  case real_cst_K:
3521  case result_decl_K:
3522  case statement_list_K:
3523  case target_expr_K:
3524  case target_mem_ref_K:
3525  case target_mem_ref461_K:
3526  case translation_unit_decl_K:
3527  case template_decl_K:
3528  case using_decl_K:
3529  case tree_list_K:
3530  case tree_vec_K:
3531  case type_decl_K:
3532  case vector_cst_K:
3533  case void_cst_K:
3534  case error_mark_K:
3535  case lut_expr_K:
3537  case CASE_CPP_NODES:
3538  case CASE_FAKE_NODES:
3539  case CASE_GIMPLE_NODES:
3540  case CASE_PRAGMA_NODES:
3543  case CASE_TYPE_NODES:
3544  case CASE_UNARY_EXPRESSION:
3545  default:
3546  THROW_ERROR("addr_expr-array_ref[0] pattern not supported: " +
3547  std::string(addr_expr_op->get_kind_text()) + " @" + STR(node));
3548  }
3549  }
3550  else
3551  {
3552  return _node;
3553  }
3554  break;
3555  }
3556  case array_range_ref_K:
3557  case binfo_K:
3558  case block_K:
3559  case call_expr_K:
3560  case aggr_init_expr_K:
3561  case case_label_expr_K:
3562  case complex_cst_K:
3563  case const_decl_K:
3564  case constructor_K:
3565  case field_decl_K:
3566  case function_decl_K:
3567  case identifier_node_K:
3568  case integer_cst_K:
3569  case label_decl_K:
3570  case namespace_decl_K:
3571  case real_cst_K:
3572  case statement_list_K:
3573  case target_expr_K:
3574  case target_mem_ref_K:
3575  case target_mem_ref461_K:
3576  case translation_unit_decl_K:
3577  case template_decl_K:
3578  case using_decl_K:
3579  case tree_list_K:
3580  case tree_vec_K:
3581  case type_decl_K:
3582  case vector_cst_K:
3583  case void_cst_K:
3584  case error_mark_K:
3585  case lut_expr_K:
3587  case CASE_CPP_NODES:
3588  case CASE_FAKE_NODES:
3589  case CASE_GIMPLE_NODES:
3590  case CASE_PRAGMA_NODES:
3592  case CASE_TYPE_NODES:
3593  case CASE_UNARY_EXPRESSION:
3594  default:
3595  THROW_ERROR("addr_expr pattern not supported: " + std::string(addr_expr_op->get_kind_text()) + " @" +
3596  STR(node));
3597  }
3598  break;
3599  }
3600  case view_convert_expr_K:
3601  {
3602  const auto vc = GetPointerS<const view_convert_expr>(node);
3603  const auto vc_expr_op = GET_CONST_NODE(vc->op);
3604 
3605  switch(vc_expr_op->get_kind())
3606  {
3607  case ssa_name_K:
3608  {
3609  const auto sn = GetPointerS<const ssa_name>(GET_CONST_NODE(vc->op));
3610  if(!sn->var)
3611  {
3612  return tree_nodeConstRef();
3613  }
3614  const auto pd = GetPointer<const parm_decl>(GET_CONST_NODE(sn->var));
3615  if(pd)
3616  {
3617  return sn->var;
3618  }
3619  else
3620  {
3621  THROW_ERROR("view_convert_expr pattern currently not supported: " +
3622  GET_NODE(vc->op)->get_kind_text() + " @" + STR(node));
3623  }
3624  break;
3625  }
3626  case var_decl_K:
3627  {
3628  return vc->op;
3629  }
3630  case integer_cst_K:
3631  {
3632  return _node;
3633  }
3634  case complex_cst_K:
3635  case real_cst_K:
3636  case string_cst_K:
3637  case vector_cst_K:
3638  case void_cst_K:
3639  case binfo_K:
3640  case block_K:
3641  case call_expr_K:
3642  case aggr_init_expr_K:
3643  case case_label_expr_K:
3644  case const_decl_K:
3645  case constructor_K:
3646  case field_decl_K:
3647  case function_decl_K:
3648  case identifier_node_K:
3649  case label_decl_K:
3650  case namespace_decl_K:
3651  case parm_decl_K:
3652  case result_decl_K:
3653  case statement_list_K:
3654  case target_expr_K:
3655  case translation_unit_decl_K:
3656  case template_decl_K:
3657  case using_decl_K:
3658  case target_mem_ref_K:
3659  case target_mem_ref461_K:
3660  case tree_list_K:
3661  case tree_vec_K:
3662  case type_decl_K:
3663  case error_mark_K:
3664  case lut_expr_K:
3666  case CASE_CPP_NODES:
3667  case CASE_FAKE_NODES:
3668  case CASE_GIMPLE_NODES:
3669  case CASE_PRAGMA_NODES:
3672  case CASE_TYPE_NODES:
3673  case CASE_UNARY_EXPRESSION:
3674  default:
3675  THROW_ERROR("view_convert_expr pattern not supported: " + std::string(vc_expr_op->get_kind_text()) +
3676  " @" + STR(node));
3677  }
3678  break;
3679  }
3680  case binfo_K:
3681  case block_K:
3682  case call_expr_K:
3683  case aggr_init_expr_K:
3684  case case_label_expr_K:
3685  case constructor_K:
3686  case identifier_node_K:
3687  case statement_list_K:
3688  case tree_list_K:
3689  case tree_vec_K:
3690  case assert_expr_K:
3691  case bit_and_expr_K:
3692  case bit_ior_expr_K:
3693  case bit_xor_expr_K:
3694  case catch_expr_K:
3695  case ceil_div_expr_K:
3696  case ceil_mod_expr_K:
3697  case complex_expr_K:
3698  case compound_expr_K:
3699  case eh_filter_expr_K:
3700  case eq_expr_K:
3701  case exact_div_expr_K:
3702  case fdesc_expr_K:
3703  case floor_div_expr_K:
3704  case floor_mod_expr_K:
3705  case ge_expr_K:
3706  case gt_expr_K:
3707  case goto_subroutine_K:
3708  case in_expr_K:
3709  case init_expr_K:
3710  case le_expr_K:
3711  case lrotate_expr_K:
3712  case lshift_expr_K:
3713  case lt_expr_K:
3714  case max_expr_K:
3715  case min_expr_K:
3716  case minus_expr_K:
3717  case modify_expr_K:
3718  case mult_expr_K:
3719  case mult_highpart_expr_K:
3720  case ne_expr_K:
3721  case ordered_expr_K:
3722  case plus_expr_K:
3723  case pointer_plus_expr_K:
3724  case postdecrement_expr_K:
3725  case postincrement_expr_K:
3726  case predecrement_expr_K:
3727  case preincrement_expr_K:
3728  case range_expr_K:
3729  case rdiv_expr_K:
3730  case round_div_expr_K:
3731  case round_mod_expr_K:
3732  case rrotate_expr_K:
3733  case rshift_expr_K:
3734  case set_le_expr_K:
3735  case trunc_div_expr_K:
3736  case trunc_mod_expr_K:
3737  case truth_and_expr_K:
3738  case truth_andif_expr_K:
3739  case truth_or_expr_K:
3740  case truth_orif_expr_K:
3741  case truth_xor_expr_K:
3742  case try_catch_expr_K:
3743  case try_finally_K:
3744  case uneq_expr_K:
3745  case ltgt_expr_K:
3746  case unge_expr_K:
3747  case ungt_expr_K:
3748  case unle_expr_K:
3749  case unlt_expr_K:
3750  case unordered_expr_K:
3751  case widen_sum_expr_K:
3752  case widen_mult_expr_K:
3753  case with_size_expr_K:
3754  case vec_cond_expr_K:
3755  case vec_perm_expr_K:
3756  case vec_lshift_expr_K:
3757  case vec_rshift_expr_K:
3758  case widen_mult_hi_expr_K:
3759  case widen_mult_lo_expr_K:
3760  case vec_pack_trunc_expr_K:
3761  case vec_pack_sat_expr_K:
3762  case vec_pack_fix_trunc_expr_K:
3763  case vec_extracteven_expr_K:
3764  case vec_extractodd_expr_K:
3765  case vec_interleavehigh_expr_K:
3766  case vec_interleavelow_expr_K:
3767  case complex_cst_K:
3768  case real_cst_K:
3769  case vector_cst_K:
3770  case void_cst_K:
3771  case const_decl_K:
3772  case field_decl_K:
3773  case function_decl_K:
3774  case label_decl_K:
3775  case namespace_decl_K:
3776  case translation_unit_decl_K:
3777  case template_decl_K:
3778  case using_decl_K:
3779  case type_decl_K:
3780  case array_range_ref_K:
3781  case target_expr_K:
3782  case vtable_ref_K:
3783  case with_cleanup_expr_K:
3784  case obj_type_ref_K:
3785  case save_expr_K:
3786  case cond_expr_K:
3787  case dot_prod_expr_K:
3788  case ternary_plus_expr_K:
3789  case ternary_pm_expr_K:
3790  case ternary_mp_expr_K:
3791  case ternary_mm_expr_K:
3792  case fshl_expr_K:
3793  case fshr_expr_K:
3794  case bit_ior_concat_expr_K:
3795  case abs_expr_K:
3796  case alignof_expr_K:
3797  case arrow_expr_K:
3798  case bit_not_expr_K:
3799  case buffer_ref_K:
3800  case card_expr_K:
3801  case cleanup_point_expr_K:
3802  case conj_expr_K:
3803  case convert_expr_K:
3804  case exit_expr_K:
3805  case fix_ceil_expr_K:
3806  case fix_floor_expr_K:
3807  case fix_round_expr_K:
3808  case fix_trunc_expr_K:
3809  case float_expr_K:
3810  case loop_expr_K:
3811  case lut_expr_K:
3812  case negate_expr_K:
3813  case non_lvalue_expr_K:
3814  case nop_expr_K:
3815  case reference_expr_K:
3816  case reinterpret_cast_expr_K:
3817  case sizeof_expr_K:
3818  case static_cast_expr_K:
3819  case throw_expr_K:
3820  case truth_not_expr_K:
3821  case unsave_expr_K:
3822  case va_arg_expr_K:
3823  case reduc_max_expr_K:
3824  case reduc_min_expr_K:
3825  case reduc_plus_expr_K:
3826  case vec_unpack_hi_expr_K:
3827  case vec_unpack_lo_expr_K:
3828  case vec_unpack_float_hi_expr_K:
3829  case vec_unpack_float_lo_expr_K:
3830  case error_mark_K:
3831  case paren_expr_K:
3832  case extract_bit_expr_K:
3833  case sat_plus_expr_K:
3834  case sat_minus_expr_K:
3835  case extractvalue_expr_K:
3836  case insertvalue_expr_K:
3837  case extractelement_expr_K:
3838  case insertelement_expr_K:
3839  case frem_expr_K:
3840  case CASE_CPP_NODES:
3841  case CASE_FAKE_NODES:
3842  case CASE_GIMPLE_NODES:
3843  case CASE_PRAGMA_NODES:
3844  case CASE_TYPE_NODES:
3845  default:
3846  THROW_ERROR_CODE(NODE_NOT_YET_SUPPORTED_EC, "tree_helper::GetBaseVariable - variable type is not supported: " +
3847  STR(node) + "-" + std::string(_node->get_kind_text()));
3848  }
3849  return tree_nodeConstRef();
3850 }
3851 
3852 bool tree_helper::is_fully_resolved(const tree_managerConstRef& TM, const unsigned int index,
3854 {
3855  const auto node = TM->CGetTreeReindex(index);
3856  return IsPointerResolved(node, res_set);
3857 }
3858 
3860 {
3861  THROW_ASSERT(_node, "expected positive non zero numbers");
3862  const auto node = _node->get_kind() == tree_reindex_K ? GET_CONST_NODE(_node) : _node;
3863  switch(node->get_kind())
3864  {
3865  case ssa_name_K:
3866  {
3867  const auto sn = GetPointerS<const ssa_name>(node);
3868  if(sn->use_set->is_fully_resolved())
3869  {
3870  for(const auto& v : sn->use_set->variables)
3871  {
3872  res_set.insert(v->index);
3873  }
3874  return true;
3875  }
3876  else
3877  {
3878  const auto base = check_for_simple_pointer_arithmetic(sn->CGetDefStmt());
3879  if(base)
3880  {
3881  return IsPointerResolved(base, res_set);
3882  }
3883  else
3884  {
3885  return false;
3886  }
3887  }
3888  }
3889  case result_decl_K:
3890  case parm_decl_K:
3891  case var_decl_K:
3892  case string_cst_K:
3893  case integer_cst_K:
3894  {
3895  return false;
3896  }
3897  case indirect_ref_K:
3898  {
3899  const auto ir = GetPointerS<const indirect_ref>(node);
3900  return IsPointerResolved(ir->op, res_set);
3901  }
3902  case misaligned_indirect_ref_K:
3903  {
3904  const auto mir = GetPointerS<const misaligned_indirect_ref>(node);
3905  return IsPointerResolved(mir->op, res_set);
3906  }
3907  case mem_ref_K:
3908  {
3909  const auto mr = GetPointerS<const mem_ref>(node);
3910  return IsPointerResolved(mr->op0, res_set);
3911  }
3912  case array_ref_K:
3913  {
3914  const auto ar = GetPointerS<const array_ref>(node);
3915  return IsPointerResolved(ar->op0, res_set);
3916  }
3917  case component_ref_K:
3918  {
3919  const auto cr = GetPointerS<const component_ref>(node);
3920  return IsPointerResolved(cr->op0, res_set);
3921  }
3922  case realpart_expr_K:
3923  {
3924  const auto rpe = GetPointerS<const realpart_expr>(node);
3925  return IsPointerResolved(rpe->op, res_set);
3926  }
3927  case imagpart_expr_K:
3928  {
3929  const auto rpe = GetPointerS<const imagpart_expr>(node);
3930  return IsPointerResolved(rpe->op, res_set);
3931  }
3932  case bit_field_ref_K:
3933  {
3934  const auto bfr = GetPointerS<const bit_field_ref>(node);
3935  return IsPointerResolved(bfr->op0, res_set);
3936  }
3937  case target_mem_ref_K:
3938  {
3939  const auto tmr = GetPointerS<const target_mem_ref>(node);
3940  if(tmr->symbol)
3941  {
3942  return IsPointerResolved(tmr->symbol, res_set);
3943  }
3944  else if(tmr->base)
3945  {
3946  return IsPointerResolved(tmr->base, res_set);
3947  }
3948  else
3949  {
3950  return false;
3951  }
3952  }
3953  case target_mem_ref461_K:
3954  {
3955  const auto tmr = GetPointerS<const target_mem_ref461>(node);
3956  if(tmr->base)
3957  {
3958  return IsPointerResolved(tmr->base, res_set);
3959  }
3960  else
3961  {
3962  return false;
3963  }
3964  }
3965  case addr_expr_K:
3966  {
3967  const auto ae = GetPointerS<const addr_expr>(node);
3968  return IsPointerResolved(ae->op, res_set);
3969  }
3970  case view_convert_expr_K:
3971  {
3972  const auto vc = GetPointerS<const view_convert_expr>(node);
3973  return IsPointerResolved(vc->op, res_set);
3974  }
3975  case binfo_K:
3976  case block_K:
3977  case call_expr_K:
3978  case aggr_init_expr_K:
3979  case case_label_expr_K:
3980  case constructor_K:
3981  case identifier_node_K:
3982  case statement_list_K:
3983  case tree_list_K:
3984  case tree_vec_K:
3985  case assert_expr_K:
3986  case bit_and_expr_K:
3987  case bit_ior_expr_K:
3988  case bit_xor_expr_K:
3989  case catch_expr_K:
3990  case ceil_div_expr_K:
3991  case ceil_mod_expr_K:
3992  case complex_expr_K:
3993  case compound_expr_K:
3994  case eh_filter_expr_K:
3995  case eq_expr_K:
3996  case exact_div_expr_K:
3997  case fdesc_expr_K:
3998  case floor_div_expr_K:
3999  case floor_mod_expr_K:
4000  case ge_expr_K:
4001  case gt_expr_K:
4002  case goto_subroutine_K:
4003  case in_expr_K:
4004  case init_expr_K:
4005  case le_expr_K:
4006  case lrotate_expr_K:
4007  case lshift_expr_K:
4008  case lt_expr_K:
4009  case max_expr_K:
4010  case min_expr_K:
4011  case minus_expr_K:
4012  case modify_expr_K:
4013  case mult_expr_K:
4014  case mult_highpart_expr_K:
4015  case ne_expr_K:
4016  case ordered_expr_K:
4017  case plus_expr_K:
4018  case pointer_plus_expr_K:
4019  case postdecrement_expr_K:
4020  case postincrement_expr_K:
4021  case predecrement_expr_K:
4022  case preincrement_expr_K:
4023  case range_expr_K:
4024  case rdiv_expr_K:
4025  case round_div_expr_K:
4026  case round_mod_expr_K:
4027  case rrotate_expr_K:
4028  case rshift_expr_K:
4029  case set_le_expr_K:
4030  case trunc_div_expr_K:
4031  case trunc_mod_expr_K:
4032  case truth_and_expr_K:
4033  case truth_andif_expr_K:
4034  case truth_or_expr_K:
4035  case truth_orif_expr_K:
4036  case truth_xor_expr_K:
4037  case try_catch_expr_K:
4038  case try_finally_K:
4039  case uneq_expr_K:
4040  case ltgt_expr_K:
4041  case unge_expr_K:
4042  case ungt_expr_K:
4043  case unle_expr_K:
4044  case unlt_expr_K:
4045  case unordered_expr_K:
4046  case widen_sum_expr_K:
4047  case widen_mult_expr_K:
4048  case with_size_expr_K:
4049  case vec_cond_expr_K:
4050  case vec_perm_expr_K:
4051  case vec_lshift_expr_K:
4052  case vec_rshift_expr_K:
4053  case widen_mult_hi_expr_K:
4054  case widen_mult_lo_expr_K:
4055  case vec_pack_trunc_expr_K:
4056  case vec_pack_sat_expr_K:
4057  case vec_pack_fix_trunc_expr_K:
4058  case vec_extracteven_expr_K:
4059  case vec_extractodd_expr_K:
4060  case vec_interleavehigh_expr_K:
4061  case vec_interleavelow_expr_K:
4062  case complex_cst_K:
4063  case real_cst_K:
4064  case vector_cst_K:
4065  case void_cst_K:
4066  case const_decl_K:
4067  case field_decl_K:
4068  case function_decl_K:
4069  case label_decl_K:
4070  case namespace_decl_K:
4071  case translation_unit_decl_K:
4072  case template_decl_K:
4073  case using_decl_K:
4074  case type_decl_K:
4075  case array_range_ref_K:
4076  case target_expr_K:
4077  case vtable_ref_K:
4078  case with_cleanup_expr_K:
4079  case obj_type_ref_K:
4080  case save_expr_K:
4081  case cond_expr_K:
4082  case dot_prod_expr_K:
4083  case ternary_plus_expr_K:
4084  case ternary_pm_expr_K:
4085  case ternary_mp_expr_K:
4086  case ternary_mm_expr_K:
4087  case fshl_expr_K:
4088  case fshr_expr_K:
4089  case bit_ior_concat_expr_K:
4090  case abs_expr_K:
4091  case alignof_expr_K:
4092  case arrow_expr_K:
4093  case bit_not_expr_K:
4094  case buffer_ref_K:
4095  case card_expr_K:
4096  case cleanup_point_expr_K:
4097  case conj_expr_K:
4098  case convert_expr_K:
4099  case exit_expr_K:
4100  case fix_ceil_expr_K:
4101  case fix_floor_expr_K:
4102  case fix_round_expr_K:
4103  case fix_trunc_expr_K:
4104  case float_expr_K:
4105  case loop_expr_K:
4106  case lut_expr_K:
4107  case negate_expr_K:
4108  case non_lvalue_expr_K:
4109  case nop_expr_K:
4110  case reference_expr_K:
4111  case reinterpret_cast_expr_K:
4112  case sizeof_expr_K:
4113  case static_cast_expr_K:
4114  case throw_expr_K:
4115  case truth_not_expr_K:
4116  case unsave_expr_K:
4117  case va_arg_expr_K:
4118  case reduc_max_expr_K:
4119  case reduc_min_expr_K:
4120  case reduc_plus_expr_K:
4121  case vec_unpack_hi_expr_K:
4122  case vec_unpack_lo_expr_K:
4123  case vec_unpack_float_hi_expr_K:
4124  case vec_unpack_float_lo_expr_K:
4125  case error_mark_K:
4126  case extract_bit_expr_K:
4127  case sat_plus_expr_K:
4128  case sat_minus_expr_K:
4129  case extractvalue_expr_K:
4130  case insertvalue_expr_K:
4131  case extractelement_expr_K:
4132  case insertelement_expr_K:
4133  case frem_expr_K:
4134  case CASE_CPP_NODES:
4135  case CASE_FAKE_NODES:
4136  case CASE_GIMPLE_NODES:
4137  case CASE_PRAGMA_NODES:
4138  case CASE_TYPE_NODES:
4139  case paren_expr_K:
4140  default:
4142  "tree_helper::IsPointerResolved - variable type is not supported: " + STR(node) + "-" +
4143  std::string(node->get_kind_text()));
4144  }
4145  return false;
4146 }
4147 
4148 bool tree_helper::is_volatile(const tree_managerConstRef& TM, const unsigned int index)
4149 {
4150  return IsVolatile(TM->CGetTreeReindex(index));
4151 }
4152 
4154 {
4155  const auto node = _node->get_kind() == tree_reindex_K ? GET_CONST_NODE(_node) : _node;
4156  const auto sa = GetPointer<const ssa_name>(node);
4157  if(!sa)
4158  {
4159  // variable or indirect ref
4160  const auto n = CGetType(_node);
4161  const auto tn = GetPointerS<const type_node>(GET_CONST_NODE(n));
4165  }
4166  return sa->volatile_flag;
4167 }
4168 
4169 bool tree_helper::is_parameter(const tree_managerConstRef& TM, const unsigned int index)
4170 {
4171  THROW_ASSERT(index > 0, "expected positive non zero numbers");
4172  tree_nodeRef node = TM->get_tree_node_const(index);
4173  if(GetPointer<parm_decl>(node))
4174  {
4175  return true;
4176  }
4177  const auto sn = GetPointer<ssa_name>(node);
4178  if(!sn)
4179  {
4180  return false;
4181  }
4182  return GET_NODE(sn->CGetDefStmt())->get_kind() == gimple_nop_K && sn->var &&
4183  GET_NODE(sn->var)->get_kind() == parm_decl_K;
4184 }
4185 
4186 bool tree_helper::is_ssa_name(const tree_managerConstRef& TM, const unsigned int index)
4187 {
4188  THROW_ASSERT(index > 0, "expected positive non zero numbers");
4189  tree_nodeRef node = TM->get_tree_node_const(index);
4190  const auto sn = GetPointer<ssa_name>(node);
4191  return sn != nullptr;
4192 }
4193 
4194 bool tree_helper::is_virtual(const tree_managerConstRef& TM, const unsigned int index)
4195 {
4196  THROW_ASSERT(index > 0, "expected positive non zero numbers");
4197  tree_nodeRef node = TM->get_tree_node_const(index);
4198  const auto sn = GetPointer<ssa_name>(node);
4199  if(!sn)
4200  {
4201  return false;
4202  }
4203  return sn->virtual_flag;
4204 }
4205 
4206 bool tree_helper::is_static(const tree_managerConstRef& TM, const unsigned int index)
4207 {
4208  return IsStaticDeclaration(TM->CGetTreeReindex(index));
4209 }
4210 
4212 {
4213  const auto decl = _decl->get_kind() == tree_reindex_K ? GET_CONST_NODE(_decl) : _decl;
4214  const auto vd = GetPointer<const var_decl>(decl);
4215  if(!vd)
4216  {
4217  const auto fd = GetPointer<const function_decl>(decl);
4218  if(!fd)
4219  {
4220  return false;
4221  }
4222  else
4223  {
4224  return fd->static_flag;
4225  }
4226  }
4227  return vd->static_flag;
4228 }
4229 
4230 bool tree_helper::is_extern(const tree_managerConstRef& TM, const unsigned int index)
4231 {
4232  return IsExternDeclaration(TM->CGetTreeReindex(index));
4233 }
4234 
4236 {
4237  const auto decl = _decl->get_kind() == tree_reindex_K ? GET_CONST_NODE(_decl) : _decl;
4238  const auto vd = GetPointer<const var_decl>(decl);
4239  if(!vd)
4240  {
4241  const auto fd = GetPointer<const function_decl>(decl);
4242  if(!fd)
4243  {
4244  return false;
4245  }
4246  else
4247  {
4248  return fd->undefined_flag;
4249  }
4250  }
4251  return vd->extern_flag;
4252 }
4253 
4254 bool tree_helper::is_const_type(const tree_managerConstRef& TM, const unsigned int index)
4255 {
4256  const auto T = TM->CGetTreeReindex(index);
4257  return IsConstType(T);
4258 }
4259 
4261 {
4262  const auto Type = CGetType(type);
4263  THROW_ASSERT(Type, "expected a type");
4264  const auto quals = GetPointer<const type_node>(GET_CONST_NODE(Type))->qual;
4269 }
4270 
4272 {
4274  {
4275  return "r_";
4276  }
4278  {
4279  return "v_";
4280  }
4282  {
4283  return "vr_";
4284  }
4286  {
4287  return "c_";
4288  }
4290  {
4291  return "cr_";
4292  }
4294  {
4295  return "cv_";
4296  }
4298  {
4299  return "cvr_";
4300  }
4301  THROW_UNREACHABLE("not supported qualifier " + STR(static_cast<unsigned int>(quals)));
4302  return "";
4303 }
4304 
4306 {
4308  {
4309  return "";
4310  }
4312  {
4313  return "__restrict__ ";
4314  }
4316  {
4317  return "volatile ";
4318  }
4320  {
4321  return "volatile __restrict__ ";
4322  }
4324  {
4325  return real_const ? "const " : "/*const*/ ";
4326  }
4328  {
4329  return (real_const ? "const" : "/*const*/") + std::string(" __restrict__ ");
4330  }
4332  {
4333  return (real_const ? "const" : "/*const*/") + std::string(" volatile ");
4334  }
4336  {
4337  return (real_const ? "const" : "/*const*/") + std::string(" volatile __restrict__ ");
4338  }
4339  THROW_UNREACHABLE("not supported qualifier " + STR(static_cast<unsigned int>(quals)));
4340  return "";
4341 }
4342 
4344 {
4345  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Getting integer const value");
4346  THROW_ASSERT(ic != nullptr, "unexpected condition");
4347  THROW_ASSERT(ic->type, "Something wrong");
4348  const auto type = GET_CONST_NODE(ic->type);
4349  THROW_ASSERT(GetPointer<integer_type>(type) || type->get_kind() == pointer_type_K ||
4350  type->get_kind() == reference_type_K || type->get_kind() == boolean_type_K ||
4351  type->get_kind() == enumeral_type_K,
4352  "Expected a integer_type, pointer_type, reference_type, boolean_type, enumeral_type. Found: " +
4353  STR(GET_INDEX_CONST_NODE(ic->type)) + " " + type->get_kind_text());
4354  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Constant is " + STR(ic->value));
4355  return ic->value;
4356 }
4357 
4359 {
4360  THROW_ASSERT(tn != nullptr, "unexpected condition");
4361  if(tn->get_kind() == tree_reindex_K)
4362  {
4363  return GetConstValue(GET_CONST_NODE(tn), is_signed);
4364  }
4365  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Getting integer const value");
4366  const auto ic = GetPointer<const integer_cst>(tn);
4367  THROW_ASSERT(ic, "unexpected condition");
4368  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Constant is " + STR(ic->value));
4369  if(!is_signed)
4370  {
4371  const auto bitwidth = Size(ic->type);
4372  return ic->value & ((integer_cst_t(1) << bitwidth) - 1);
4373  }
4374  return ic->value;
4375 }
4376 
4377 unsigned int tree_helper::get_array_var(const tree_managerConstRef& TM, const unsigned int index, bool is_written,
4378  bool& two_dim_p)
4379 {
4380  THROW_ASSERT(index > 0, "expected positive non zero numbers");
4381  tree_nodeRef node = TM->get_tree_node_const(index);
4382  const auto gms = GetPointer<gimple_assign>(node);
4383  array_ref* ar;
4384  if(is_written)
4385  {
4386  ar = GetPointer<array_ref>(GET_NODE(gms->op0));
4387  }
4388  else
4389  {
4390  ar = GetPointer<array_ref>(GET_NODE(gms->op1));
4391  }
4392  two_dim_p = false;
4393  if(ar)
4394  {
4395  if(GetPointer<array_ref>(GET_NODE(ar->op0)))
4396  {
4397  ar = GetPointer<array_ref>(GET_NODE(ar->op0));
4398  if(GetPointer<array_ref>(GET_NODE(ar->op0)))
4399  {
4400  THROW_ERROR("n-dimension array not yet supported (n > 2)");
4401  }
4402  two_dim_p = true;
4403  return GET_INDEX_CONST_NODE(ar->op0);
4404  }
4405  else
4406  {
4407  return GET_INDEX_CONST_NODE(ar->op0);
4408  }
4409  }
4410  target_mem_ref* tmr;
4411  if(is_written)
4412  {
4413  tmr = GetPointer<target_mem_ref>(GET_NODE(gms->op0));
4414  }
4415  else
4416  {
4417  tmr = GetPointer<target_mem_ref>(GET_NODE(gms->op1));
4418  }
4419  if(tmr)
4420  {
4421  if(tmr->symbol)
4422  {
4423  return GET_INDEX_CONST_NODE(tmr->symbol);
4424  }
4425  else if(tmr->base)
4426  {
4427  return GET_INDEX_CONST_NODE(tmr->base);
4428  }
4429  else
4430  {
4431  THROW_ERROR("Unexpected pattern");
4432  }
4433  }
4434  target_mem_ref461* tmr461;
4435  if(is_written)
4436  {
4437  tmr461 = GetPointer<target_mem_ref461>(GET_NODE(gms->op0));
4438  }
4439  else
4440  {
4441  tmr461 = GetPointer<target_mem_ref461>(GET_NODE(gms->op1));
4442  }
4443  if(tmr461)
4444  {
4445  if(tmr461->base)
4446  {
4447  return GET_INDEX_CONST_NODE(tmr461->base);
4448  }
4449  else
4450  {
4451  THROW_ERROR("Unexpected pattern");
4452  }
4453  }
4454  auto ae = GetPointer<addr_expr>(GET_NODE(gms->op1));
4455  if(ae)
4456  {
4457  ar = GetPointer<array_ref>(GET_NODE(ae->op));
4458  if(ar)
4459  {
4460  if(GetPointer<array_ref>(GET_NODE(ar->op0)))
4461  {
4462  ar = GetPointer<array_ref>(GET_NODE(ar->op0));
4463  if(GetPointer<array_ref>(GET_NODE(ar->op0)))
4464  {
4465  THROW_ERROR("n-dimension array not yet supported (n > 2)");
4466  }
4467  two_dim_p = true;
4468  return GET_INDEX_CONST_NODE(ar->op0);
4469  }
4470  else
4471  {
4472  return GET_INDEX_CONST_NODE(ar->op0);
4473  }
4474  }
4475  else
4476  {
4477  THROW_ERROR("Unexpected pattern " + STR(index));
4478  return 0;
4479  }
4480  }
4481  const auto ne = GetPointer<nop_expr>(GET_NODE(gms->op1));
4482  if(ne)
4483  {
4484  ae = GetPointer<addr_expr>(GET_NODE(ne->op));
4485  if(ae)
4486  {
4487  ar = GetPointer<array_ref>(GET_NODE(ae->op));
4488  if(ar)
4489  {
4490  if(GetPointer<array_ref>(GET_NODE(ar->op0)))
4491  {
4492  ar = GetPointer<array_ref>(GET_NODE(ar->op0));
4493  if(GetPointer<array_ref>(GET_NODE(ar->op0)))
4494  {
4495  THROW_ERROR("n-dimension array not yet supported (n > 2)");
4496  }
4497  two_dim_p = true;
4498  return GET_INDEX_CONST_NODE(ar->op0);
4499  }
4500  else
4501  {
4502  return GET_INDEX_CONST_NODE(ar->op0);
4503  }
4504  }
4505  const auto vd = GetPointer<var_decl>(GET_NODE(ae->op));
4506  if(vd)
4507  {
4508  return GET_INDEX_CONST_NODE(ae->op);
4509  }
4510  else
4511  {
4512  THROW_ERROR("Unexpected pattern " + STR(index));
4513  return 0;
4514  }
4515  }
4516  }
4517  THROW_ERROR("Unexpected pattern " + STR(index));
4518  return 0;
4519 }
4520 
4521 bool tree_helper::is_concat_bit_ior_expr(const tree_managerConstRef& TM, const unsigned int index)
4522 {
4523  tree_nodeRef node = TM->get_tree_node_const(index);
4524  const auto ga = GetPointer<gimple_assign>(node);
4525  if(ga)
4526  {
4527  const auto bie = GetPointer<bit_ior_expr>(GET_NODE(ga->op1));
4528  if(bie)
4529  {
4530  tree_nodeRef op0 = GET_NODE(bie->op0);
4531  tree_nodeRef op1 = GET_NODE(bie->op1);
4532  if(op0->get_kind() == ssa_name_K && op1->get_kind() == ssa_name_K)
4533  {
4534  const auto op0_ssa = GetPointer<ssa_name>(op0);
4535  const auto op1_ssa = GetPointer<ssa_name>(op1);
4536  if(!op0_ssa->bit_values.empty() && !op1_ssa->bit_values.empty())
4537  {
4538  std::string::const_reverse_iterator it0 = op0_ssa->bit_values.rbegin();
4539  std::string::const_reverse_iterator it1 = op1_ssa->bit_values.rbegin();
4540  std::string::const_reverse_iterator it0_end = op0_ssa->bit_values.rend();
4541  std::string::const_reverse_iterator it1_end = op1_ssa->bit_values.rend();
4542  for(; it0 != it0_end && it1 != it1_end; ++it0, ++it1)
4543  {
4544  if(*it0 != '0' && *it1 != '0')
4545  {
4546  return false;
4547  }
4548  }
4549  return true;
4550  }
4551  }
4552  }
4553  }
4554  return false;
4555 }
4556 
4557 bool tree_helper::is_simple_pointer_plus_test(const tree_managerConstRef& TM, const unsigned int index)
4558 {
4559  tree_nodeRef node = TM->get_tree_node_const(index);
4560  const auto ga = GetPointer<gimple_assign>(node);
4561  if(ga)
4562  {
4563  const auto ppe = GetPointer<pointer_plus_expr>(GET_NODE(ga->op1));
4564  if(ppe)
4565  {
4566  tree_nodeRef op1 = GET_NODE(ppe->op1);
4567  if(op1->get_kind() == integer_cst_K)
4568  {
4569  tree_nodeRef op0 = GET_NODE(ppe->op0);
4570  if(op0->get_kind() == addr_expr_K)
4571  {
4572  return true;
4573  }
4574  else if(op0->get_kind() == ssa_name_K)
4575  {
4576  auto temp_def = GET_NODE(GetPointer<const ssa_name>(op0)->CGetDefStmt());
4577  const auto ga_def = GetPointer<gimple_assign>(temp_def);
4578  if(ga_def)
4579  {
4580  if(GET_NODE(ga_def->op1)->get_kind() == addr_expr_K)
4581  {
4582  return true;
4583  }
4584  }
4585  }
4586  }
4587  }
4588  }
4589  return false;
4590 }
4591 
4592 bool tree_helper::is_constant(const tree_managerConstRef& TM, const unsigned int index)
4593 {
4594  const auto node = TM->CGetTreeReindex(index);
4595  return IsConstant(node);
4596 }
4597 
4599 {
4600  const auto node = _node->get_kind() == tree_reindex_K ? GET_CONST_NODE(_node) : _node;
4601  switch(node->get_kind())
4602  {
4603  case CASE_CST_NODES:
4604  return true;
4605  case binfo_K:
4606  case block_K:
4607  case call_expr_K:
4608  case aggr_init_expr_K:
4609  case case_label_expr_K:
4610  case constructor_K:
4611  case identifier_node_K:
4612  case ssa_name_K:
4613  case statement_list_K:
4614  case target_expr_K:
4615  case target_mem_ref_K:
4616  case target_mem_ref461_K:
4617  case tree_list_K:
4618  case tree_vec_K:
4619  case error_mark_K:
4620  case lut_expr_K:
4622  case CASE_CPP_NODES:
4623  case CASE_DECL_NODES:
4624  case CASE_FAKE_NODES:
4625  case CASE_GIMPLE_NODES:
4626  case CASE_PRAGMA_NODES:
4629  case CASE_TYPE_NODES:
4630  case CASE_UNARY_EXPRESSION:
4631  default:
4632  return false;
4633  }
4634  return false;
4635 }
4636 
4638 {
4639  return op_symbol(op.get());
4640 }
4641 
4642 std::string tree_helper::op_symbol(const tree_node* op)
4643 {
4644  THROW_ASSERT(op, "Null tree node");
4645  switch(op->get_kind())
4646  {
4647  case modify_expr_K:
4648  return "=";
4649 
4650  case truth_or_expr_K:
4651  case truth_orif_expr_K:
4652  return "||";
4653 
4654  case truth_and_expr_K:
4655  case truth_andif_expr_K:
4656  return "&&";
4657 
4658  case bit_ior_expr_K:
4659  return "|";
4660 
4661  case truth_xor_expr_K:
4662  case bit_xor_expr_K:
4663  return "^";
4664 
4665  case addr_expr_K:
4666  case bit_and_expr_K:
4667  {
4668  if(dynamic_cast<const addr_expr*>(op))
4669  {
4670  const auto ae = static_cast<const addr_expr*>(op);
4671  const auto tn = GET_CONST_NODE(ae->op);
4672  if(GetPointer<const array_ref>(tn))
4673  {
4674  const auto ar = GetPointerS<const array_ref>(tn);
4675  if(GET_CONST_NODE(ar->op0)->get_kind() == string_cst_K &&
4676  GET_CONST_NODE(ar->op1)->get_kind() == integer_cst_K && !GetConstValue(ar->op1))
4677  {
4678  return "";
4679  }
4680  }
4681  if(GetPointer<const string_cst>(tn))
4682  {
4683  return "";
4684  }
4685  }
4686  return "&";
4687  }
4688 
4689  case eq_expr_K:
4690  return "==";
4691 
4692  case ne_expr_K:
4693  return "!=";
4694 
4695  case lt_expr_K:
4696  case lut_expr_K:
4697  case unlt_expr_K:
4698  return "<";
4699 
4700  case le_expr_K:
4701  case unle_expr_K:
4702  return "<=";
4703 
4704  case gt_expr_K:
4705  case ungt_expr_K:
4706  return ">";
4707 
4708  case ge_expr_K:
4709  case unge_expr_K:
4710  return ">=";
4711 
4712  case vec_lshift_expr_K:
4713  case lshift_expr_K:
4714  return "<<";
4715 
4716  case vec_rshift_expr_K:
4717  case rshift_expr_K:
4718  return ">>";
4719 
4720  case plus_expr_K:
4721  case pointer_plus_expr_K:
4722  case widen_sum_expr_K:
4723  return "+";
4724 
4725  case negate_expr_K:
4726  case minus_expr_K:
4727  return "-";
4728 
4729  case bit_not_expr_K:
4730  return "~";
4731 
4732  case truth_not_expr_K:
4733  return "!";
4734 
4735  case mult_expr_K:
4736  case mult_highpart_expr_K:
4737  case indirect_ref_K:
4738  case misaligned_indirect_ref_K:
4739  case widen_mult_expr_K:
4740  return "*";
4741 
4742  case trunc_div_expr_K:
4743  case ceil_div_expr_K:
4744  case floor_div_expr_K:
4745  case round_div_expr_K:
4746  case rdiv_expr_K:
4747  case exact_div_expr_K:
4748  return "/";
4749 
4750  case trunc_mod_expr_K:
4751  case ceil_mod_expr_K:
4752  case floor_mod_expr_K:
4753  case round_mod_expr_K:
4754  return "%";
4755 
4756  case predecrement_expr_K:
4757  return " --";
4758 
4759  case preincrement_expr_K:
4760  return " ++";
4761 
4762  case postdecrement_expr_K:
4763  return "-- ";
4764 
4765  case postincrement_expr_K:
4766  return "+=";
4767 
4768  case reference_expr_K:
4769  return "";
4770  case realpart_expr_K:
4771  return "__real__ ";
4772  case imagpart_expr_K:
4773  return "__imag__ ";
4774  case fix_trunc_expr_K:
4775  case min_expr_K:
4776  return "";
4777  case abs_expr_K:
4778  case alignof_expr_K:
4779  case arrow_expr_K:
4780  case assert_expr_K:
4781  case binfo_K:
4782  case block_K:
4783  case buffer_ref_K:
4784  case call_expr_K:
4785  case aggr_init_expr_K:
4786  case card_expr_K:
4787  case case_label_expr_K:
4788  case catch_expr_K:
4789  case cleanup_point_expr_K:
4790  case complex_expr_K:
4791  case compound_expr_K:
4792  case conj_expr_K:
4793  case constructor_K:
4794  case convert_expr_K:
4795  case eh_filter_expr_K:
4796  case exit_expr_K:
4797  case fix_ceil_expr_K:
4798  case fix_floor_expr_K:
4799  case fix_round_expr_K:
4800  case fdesc_expr_K:
4801  case float_expr_K:
4802  case goto_subroutine_K:
4803  case identifier_node_K:
4804  case in_expr_K:
4805  case init_expr_K:
4806  case loop_expr_K:
4807  case ltgt_expr_K:
4808  case lrotate_expr_K:
4809  case max_expr_K:
4810  case mem_ref_K:
4811  case non_lvalue_expr_K:
4812  case nop_expr_K:
4813  case ordered_expr_K:
4814  case range_expr_K:
4815  case reduc_max_expr_K:
4816  case reduc_min_expr_K:
4817  case reduc_plus_expr_K:
4818  case reinterpret_cast_expr_K:
4819  case rrotate_expr_K:
4820  case set_le_expr_K:
4821  case sizeof_expr_K:
4822  case ssa_name_K:
4823  case static_cast_expr_K:
4824  case statement_list_K:
4825  case target_expr_K:
4826  case target_mem_ref_K:
4827  case target_mem_ref461_K:
4828  case throw_expr_K:
4829  case tree_list_K:
4830  case tree_vec_K:
4831  case try_catch_expr_K:
4832  case try_finally_K:
4833  case uneq_expr_K:
4834  case unordered_expr_K:
4835  case unsave_expr_K:
4836  case va_arg_expr_K:
4837  case vec_extracteven_expr_K:
4838  case vec_extractodd_expr_K:
4839  case vec_interleavehigh_expr_K:
4840  case vec_interleavelow_expr_K:
4841  case vec_pack_fix_trunc_expr_K:
4842  case vec_pack_sat_expr_K:
4843  case vec_pack_trunc_expr_K:
4844  case vec_unpack_float_hi_expr_K:
4845  case vec_unpack_float_lo_expr_K:
4846  case vec_unpack_hi_expr_K:
4847  case vec_unpack_lo_expr_K:
4848  case view_convert_expr_K:
4849  case widen_mult_hi_expr_K:
4850  case widen_mult_lo_expr_K:
4851  case with_size_expr_K:
4852  case error_mark_K:
4853  case paren_expr_K:
4854  case extract_bit_expr_K:
4855  case sat_plus_expr_K:
4856  case sat_minus_expr_K:
4857  case extractvalue_expr_K:
4858  case extractelement_expr_K:
4859  case frem_expr_K:
4860  case CASE_CPP_NODES:
4861  case CASE_CST_NODES:
4862  case CASE_DECL_NODES:
4863  case CASE_FAKE_NODES:
4864  case CASE_GIMPLE_NODES:
4865  case CASE_PRAGMA_NODES:
4868  case CASE_TYPE_NODES:
4869  default:
4870  THROW_ERROR(std::string("op_symbol not yet supported ") + op->get_kind_text() + " in node " + STR(op->index));
4871  return "";
4872  }
4873 }
4874 
4875 unsigned long long tree_helper::get_array_data_bitsize(const tree_managerConstRef& TM, const unsigned int index)
4876 {
4877  const auto node = TM->CGetTreeReindex(index);
4878  return GetArrayElementSize(node);
4879 }
4880 
4881 unsigned long long tree_helper::GetArrayElementSize(const tree_nodeConstRef& _node)
4882 {
4883  const auto node = _node->get_kind() == tree_reindex_K ? GET_CONST_NODE(_node) : _node;
4884  if(node->get_kind() == record_type_K)
4885  {
4886  const auto rt = GetPointerS<const record_type>(node);
4887  auto fd = GET_CONST_NODE(rt->list_of_flds[0]);
4888  THROW_ASSERT(fd->get_kind() == field_decl_K, "expected a field_decl");
4889  return GetArrayElementSize(GetPointerS<const field_decl>(fd)->type);
4890  }
4891  if(node->get_kind() == union_type_K)
4892  {
4893  const auto ut = GetPointerS<const union_type>(node);
4894  const auto fd = GET_CONST_NODE(ut->list_of_flds[0]);
4895  THROW_ASSERT(fd->get_kind() == field_decl_K, "expected a field_decl");
4896  return GetArrayElementSize(GetPointerS<const field_decl>(fd)->type);
4897  }
4898  if(node->get_kind() != array_type_K)
4899  {
4900  return Size(node);
4901  }
4902  const auto at = GetPointerS<const array_type>(node);
4903  THROW_ASSERT(at->elts, "elements type expected");
4904  const auto elts = GET_CONST_NODE(at->elts);
4905  unsigned long long return_value;
4906  if(elts->get_kind() == array_type_K)
4907  {
4908  return_value = GetArrayElementSize(at->elts);
4909  }
4910  else
4911  {
4912  const auto type = CGetType(at->elts);
4913  return_value = Size(type);
4914  const auto fd = GetPointer<const field_decl>(GET_CONST_NODE(type));
4915  if(!fd || !fd->is_bitfield())
4916  {
4917  return_value = std::max(8ull, return_value);
4918  }
4919  }
4920  return return_value;
4921 }
4922 
4923 void tree_helper::get_array_dim_and_bitsize(const tree_managerConstRef& TM, const unsigned int index,
4924  std::vector<unsigned long long>& dims, unsigned long long& elts_bitsize)
4925 {
4926  tree_nodeRef node = TM->get_tree_node_const(index);
4927  if(node->get_kind() == record_type_K || node->get_kind() == union_type_K)
4928  {
4929  elts_bitsize = get_array_data_bitsize(TM, index);
4930  dims.push_back(Size(node) / elts_bitsize);
4931  return;
4932  }
4933  THROW_ASSERT(node->get_kind() == array_type_K, "array_type expected: @" + STR(index));
4934  const auto at = GetPointer<array_type>(node);
4935  if(!at->domn)
4936  {
4937  dims.push_back(1); // at least one element is expected
4938  }
4939  else
4940  {
4941  tree_nodeRef domn = GET_NODE(at->domn);
4942  THROW_ASSERT(domn->get_kind() == integer_type_K, "expected an integer type as domain");
4943  const auto it = GetPointer<integer_type>(domn);
4944  integer_cst_t min_value = 0;
4945  integer_cst_t max_value = 0;
4946  if(it->min)
4947  {
4948  min_value = GetConstValue(it->min);
4949  }
4950  if(it->max)
4951  {
4952  max_value = GetConstValue(it->max);
4953  }
4954  const auto range_domain = max_value - min_value + 1;
4955  THROW_ASSERT(range_domain >= 0, "Negative range not expected");
4956  dims.push_back(static_cast<unsigned long long>(range_domain));
4957  }
4958  THROW_ASSERT(at->elts, "elements type expected");
4959  tree_nodeRef elts = GET_NODE(at->elts);
4960  if(elts->get_kind() == array_type_K)
4961  {
4962  get_array_dim_and_bitsize(TM, GET_INDEX_CONST_NODE(at->elts), dims, elts_bitsize);
4963  }
4964  else
4965  {
4966  const auto etype = CGetType(at->elts);
4967  elts_bitsize = Size(etype);
4968  const auto fd = GetPointer<const field_decl>(GET_CONST_NODE(etype));
4969  if(!fd || !fd->is_bitfield())
4970  {
4971  elts_bitsize = std::max(8ull, elts_bitsize);
4972  }
4973  }
4974 }
4975 
4976 void tree_helper::get_array_dimensions(const tree_managerConstRef& TM, const unsigned int index,
4977  std::vector<unsigned long long>& dims)
4978 {
4979  const auto node = TM->CGetTreeReindex(index);
4980  dims = GetArrayDimensions(node);
4981 }
4982 
4983 std::vector<unsigned long long> tree_helper::GetArrayDimensions(const tree_nodeConstRef& node)
4984 {
4985  std::vector<unsigned long long> dims;
4986  std::function<void(const tree_nodeConstRef&)> get_array_dim_recurse;
4987  get_array_dim_recurse = [&](const tree_nodeConstRef& tn) -> void {
4988  if(tn->get_kind() == record_type_K || tn->get_kind() == union_type_K)
4989  {
4990  auto elmt_bitsize = GetArrayElementSize(tn);
4991  dims.push_back(Size(tn) / elmt_bitsize);
4992  return;
4993  }
4994  THROW_ASSERT(tn->get_kind() == array_type_K, "array_type expected: @" + STR(tn));
4995  const auto at = GetPointerS<const array_type>(tn);
4996  const auto domn = GET_CONST_NODE(at->domn);
4997  THROW_ASSERT(domn->get_kind() == integer_type_K, "expected an integer type as domain");
4998  const auto it = GetPointerS<const integer_type>(domn);
4999  integer_cst_t min_value = 0;
5000  integer_cst_t max_value = 0;
5001  if(it->min && GET_CONST_NODE(it->min)->get_kind() == integer_cst_K && it->max &&
5002  GET_CONST_NODE(it->max)->get_kind() == integer_cst_K)
5003  {
5004  if(it->min)
5005  {
5006  min_value = GetConstValue(it->min);
5007  }
5008  if(it->max)
5009  {
5010  max_value = GetConstValue(it->max);
5011  }
5012  THROW_ASSERT(max_value >= min_value, "");
5013  const auto range_domain = static_cast<unsigned long long>(max_value - min_value) + 1;
5014  dims.push_back(range_domain);
5015  }
5016  else
5017  {
5018  dims.push_back(0); // variable size array may fall in this case
5019  }
5020  THROW_ASSERT(at->elts, "elements type expected");
5021  const auto elts = GET_CONST_NODE(at->elts);
5022  if(elts->get_kind() == array_type_K)
5023  {
5024  get_array_dim_recurse(GET_CONST_NODE(at->elts));
5025  }
5026  };
5027  get_array_dim_recurse(node->get_kind() == tree_reindex_K ? GET_CONST_NODE(node) : node);
5028  return dims;
5029 }
5030 
5031 unsigned long long tree_helper::get_array_num_elements(const tree_managerConstRef& TM, const unsigned int index)
5032 {
5033  const auto node = TM->CGetTreeReindex(index);
5034  return GetArrayTotalSize(node);
5035 }
5036 
5037 unsigned long long tree_helper::GetArrayTotalSize(const tree_nodeConstRef& node)
5038 {
5039  auto num_elements = 1ull;
5040  for(const auto& i : GetArrayDimensions(node))
5041  {
5042  num_elements *= i;
5043  }
5044  return num_elements;
5045 }
5046 
5047 void tree_helper::extract_array_indexes(const tree_managerConstRef& TM, const unsigned int index,
5048  std::vector<unsigned long long>& indexes,
5049  std::vector<unsigned long long>& size_indexes, unsigned int& base_object)
5050 {
5051  const auto node = TM->CGetTreeNode(index);
5052  THROW_ASSERT(node->get_kind() == array_ref_K, "array_ref expected: @" + STR(index));
5053  const auto ar = GetPointerS<const array_ref>(node);
5054  base_object = GET_INDEX_CONST_NODE(ar->op0);
5055  if(GET_CONST_NODE(ar->op0)->get_kind() == array_ref_K)
5056  {
5057  const auto nested_ar = GetPointerS<const array_ref>(GET_CONST_NODE(ar->op0));
5058  const auto at = GetPointerS<const array_type>(GET_CONST_NODE(nested_ar->type));
5059  const auto domn = GET_CONST_NODE(at->domn);
5060  THROW_ASSERT(domn->get_kind() == integer_type_K, "expected an integer type as domain");
5061  const auto it = GetPointerS<const integer_type>(domn);
5062  integer_cst_t min_value = 0;
5063  integer_cst_t max_value = 0;
5064  if(it->min)
5065  {
5066  min_value = GetConstValue(it->min);
5067  }
5068  if(it->max)
5069  {
5070  max_value = GetConstValue(it->max);
5071  }
5072  THROW_ASSERT(max_value >= min_value, "");
5073  const auto range_domain = static_cast<unsigned long long>(max_value - min_value) + 1;
5074  size_indexes.push_back(range_domain);
5075  extract_array_indexes(TM, base_object, indexes, size_indexes, base_object);
5076  indexes.push_back(GET_INDEX_CONST_NODE(nested_ar->op1));
5077  }
5078 }
5079 
5080 unsigned int tree_helper::GetUnqualified(const tree_managerConstRef& TM, unsigned int type)
5081 {
5082  const auto utype = GetUnqualifiedType(TM->CGetTreeNode(type));
5083  return utype ? utype->index : 0;
5084 }
5085 
5087 {
5088  const auto type = _type->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type) : _type;
5089  if(GetPointer<const type_node>(type) && GetPointerS<const type_node>(type)->unql)
5090  {
5091  return GetPointerS<const type_node>(type)->unql;
5092  }
5093  return nullptr;
5094 }
5095 
5096 bool tree_helper::IsAligned(const tree_managerConstRef& TM, unsigned int type)
5097 {
5098  return IsAligned(TM->CGetTreeReindex(type));
5099 }
5100 
5102 {
5103  const auto type = _type->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type) : _type;
5104  const auto tn = GetPointer<const type_node>(type);
5105  THROW_ASSERT(tn, "Tree node " + STR(type) + " is of type " + type->get_kind_text());
5106  return tn->unql && tn->algn != GetPointerS<const type_node>(GET_CONST_NODE(tn->unql))->algn;
5107 }
5108 
5109 unsigned int tree_helper::get_var_alignment(const tree_managerConstRef& TM, unsigned int var)
5110 {
5111  const auto varnode = TM->CGetTreeNode(var);
5112  const auto vd = GetPointer<const var_decl>(varnode);
5113  if(vd)
5114  {
5115  return vd->algn < 8 ? 1 : (vd->algn / 8);
5116  }
5117  return 1;
5118 }
5119 
5120 std::string tree_helper::NormalizeTypename(const std::string& id)
5121 {
5122  static const std::regex rbase("[.:$]+");
5123  static const std::regex rtmpl("[*&<>\\-]|[, ]+");
5124  std::string norm_typename;
5125  std::regex_replace(std::back_inserter(norm_typename), id.cbegin(), id.cend(), rbase, "_");
5126  const auto tmpl_start = norm_typename.find_first_of('<');
5127  if(tmpl_start != std::string::npos)
5128  {
5129  const auto tmpl_end = norm_typename.find_last_of('>');
5130  THROW_ASSERT(tmpl_end != std::string::npos, "");
5131  auto norm_template = norm_typename.substr(0, tmpl_start);
5132  std::regex_replace(std::back_inserter(norm_template), norm_typename.cbegin() + static_cast<long int>(tmpl_start),
5133  norm_typename.cbegin() + static_cast<long int>(tmpl_end + 1U), rtmpl, "_");
5134  return norm_template;
5135  }
5136  return norm_typename;
5137 }
5138 
5139 std::string tree_helper::print_type(const tree_managerConstRef& TM, unsigned int original_type, bool global,
5140  bool print_qualifiers, bool print_storage, unsigned int var,
5141  const var_pp_functorConstRef& vppf, const std::string& prefix,
5142  const std::string& tail)
5143 {
5144  const auto t = TM->CGetTreeReindex(original_type);
5145  return PrintType(TM, t, global, print_qualifiers, print_storage,
5146  var ? TM->CGetTreeReindex(var) : tree_nodeConstRef(), vppf, prefix, tail);
5147 }
5148 
5149 std::string tree_helper::PrintType(const tree_managerConstRef& TM, const tree_nodeConstRef& original_type, bool global,
5150  bool print_qualifiers, bool print_storage, const tree_nodeConstRef& var,
5151  const var_pp_functorConstRef& vppf, const std::string& prefix,
5152  const std::string& tail)
5153 {
5154  bool skip_var_printing = false;
5155  const auto node_type = GET_CONST_NODE(GetRealType(
5156  original_type->get_kind() != tree_reindex_K ? TM->CGetTreeReindex(original_type->index) : original_type));
5158  "-->Printing type " + STR(original_type) + "(" + STR(node_type) + ") - Var " + STR(var));
5159  std::string res;
5160  tree_nodeConstRef node_var = nullptr;
5161  if(var)
5162  {
5163  node_var = var->get_kind() == tree_reindex_K ? GET_CONST_NODE(var) : var;
5164  if(node_var->get_kind() == var_decl_K)
5165  {
5166  const auto vd = GetPointerS<const var_decl>(node_var);
5167  if(print_storage)
5168  {
5169  if(vd->extern_flag)
5170  {
5171  res += "extern ";
5172  }
5173  if(vd->static_flag || vd->static_static_flag)
5174  {
5175  res += "static ";
5176  }
5177  }
5178  }
5179  }
5180  switch(node_type->get_kind())
5181  {
5182  case function_decl_K:
5183  {
5184  const auto fd = GetPointerS<const function_decl>(node_type);
5185  const auto function_name = print_function_name(TM, fd);
5186  if(fd->undefined_flag)
5187  {
5188  res = "extern ";
5189  }
5190  else if(fd->static_flag)
5191  {
5192  res = "static ";
5193  }
5194  else if(fd->mngl && function_name != "main")
5195  {
5196  res = "\n#ifdef __cplusplus\nextern \"C\"\n#endif\n";
5197  }
5198  const auto dn = GetPointer<const decl_node>(node_type);
5199  THROW_ASSERT(dn, "expected a declaration node");
5200  tree_nodeRef ftype = GET_NODE(dn->type);
5201  /* Print type declaration. */
5202  if(ftype->get_kind() == function_type_K || ftype->get_kind() == method_type_K)
5203  {
5204  const auto ft = GetPointerS<const function_type>(ftype);
5205  res += PrintType(TM, ft->retn, global);
5206  }
5207  else
5208  {
5209  THROW_ERROR(std::string("tree node not currently supported ") + node_type->get_kind_text());
5210  }
5211  res += " ";
5212 
5213  /* Print function name. */
5214  THROW_ASSERT(dn->name, "expected a name");
5215  res += function_name;
5216  res += "(";
5217  if(!fd->list_of_args.empty())
5218  {
5219  for(unsigned int i = 0; i < (fd->list_of_args.size()); i++)
5220  {
5221  if(i > 0)
5222  {
5223  res += ", ";
5224  }
5225  res += PrintType(TM, CGetType(fd->list_of_args[i]), global, print_qualifiers, print_storage,
5226  fd->list_of_args[i], vppf);
5227  }
5228  }
5229  else if(TM->get_implementation_node(node_type->index) &&
5230  TM->get_implementation_node(node_type->index) != node_type->index)
5231  {
5232  skip_var_printing = true;
5233  const auto type = TM->CGetTreeReindex(TM->get_implementation_node(node_type->index));
5234  res = PrintType(TM, type, global, print_qualifiers, print_storage, nullptr, vppf);
5235  break;
5236  }
5237  else if(GetPointer<const function_type>(ftype)->prms)
5238  {
5239  if(ftype->get_kind() == function_type_K)
5240  {
5241  const auto ft = GetPointerS<const function_type>(ftype);
5242  res += PrintType(TM, ft->prms, global);
5243  }
5244  else if(ftype->get_kind() == method_type_K)
5245  {
5246  const auto mt = GetPointerS<const method_type>(ftype);
5247  res += PrintType(TM, mt->prms, global);
5248  }
5249  else
5250  {
5251  THROW_ERROR(std::string("tree node not currently supported ") + node_type->get_kind_text());
5252  }
5253  }
5254  if((!fd->list_of_args.empty() || GetPointerS<const function_type>(ftype)->prms) &&
5255  GetPointerS<const function_type>(ftype)->varargs_flag)
5256  {
5257  res += ", ... ";
5258  }
5259  res += ")";
5260  break;
5261  }
5262  case type_decl_K:
5263  {
5264  const auto td = GetPointerS<const type_decl>(node_type);
5265  if(td->name)
5266  {
5267  const auto name = GET_CONST_NODE(td->name);
5268  if(name->get_kind() == identifier_node_K)
5269  {
5270  const auto in = GetPointerS<const identifier_node>(name);
5272  std::string typename_value = NormalizeTypename(in->strg);
5273  if(typename_value == "char" && GetPointer<const integer_type>(GET_CONST_NODE(td->type)) &&
5274  GetPointer<const integer_type>(GET_CONST_NODE(td->type))->unsigned_flag)
5275  {
5276  res += "unsigned " + typename_value;
5278  }
5279  else if(typename_value == "__va_list_tag")
5280  {
5281  res += "va_list";
5282  }
5283  else if(GET_CONST_NODE(td->type)->get_kind() == complex_type_K)
5284  {
5285  const auto splitted = SplitString(typename_value, " ");
5286  if((splitted[0] == "_Complex" || splitted[0] == "__complex__" || splitted[0] == "complex"))
5287  {
5288  res += "__complex__";
5289  for(unsigned int ci = 1u; ci < splitted.size(); ci++)
5290  {
5291  res += " " + splitted[ci];
5292  }
5293  }
5294  else
5295  {
5296  res += typename_value;
5297  }
5298  }
5299  else
5300  {
5301  res += typename_value;
5302  }
5303  }
5304  else
5305  {
5306  THROW_ERROR(std::string("Node not yet supported: ") + node_type->get_kind_text());
5307  }
5308  }
5309  else
5310  {
5311  THROW_ERROR(std::string("Node not yet supported: ") + node_type->get_kind_text());
5312  }
5313  skip_var_printing = true;
5314  break;
5315  }
5316  case identifier_node_K:
5317  {
5318  const auto in = GetPointerS<const identifier_node>(node_type);
5319  res += NormalizeTypename(in->strg);
5320  skip_var_printing = true;
5321  break;
5322  }
5323  case void_type_K:
5324  case integer_type_K:
5325  case real_type_K:
5326  case complex_type_K:
5327  case vector_type_K:
5328  case boolean_type_K:
5329  case CharType_K:
5330  case nullptr_type_K:
5331  case type_pack_expansion_K:
5332  {
5333  const auto tn = GetPointerS<const type_node>(node_type);
5334  /* const internally are not considered as constant...*/
5335  if(node_var && !tn->name)
5336  {
5337  const auto is_global_var =
5338  GetPointer<const var_decl>(node_var) &&
5339  (!(GetPointer<const var_decl>(node_var)->scpe) ||
5340  (GET_CONST_NODE(GetPointer<const var_decl>(node_var)->scpe)->get_kind() == translation_unit_decl_K));
5341  res += return_C_qualifiers(tn->qual, is_global_var);
5342  }
5343  else if(global || print_qualifiers)
5344  {
5345  res += return_C_qualifiers(tn->qual, true);
5346  }
5347  if(tn->name && (GET_CONST_NODE(tn->name)->get_kind() != type_decl_K || !tn->system_flag))
5348  {
5349  const auto name = GET_CONST_NODE(tn->name);
5350  if(name->get_kind() == identifier_node_K)
5351  {
5352  const auto in = GetPointerS<const identifier_node>(name);
5353  res += NormalizeTypename(in->strg);
5354  }
5355  else if(name->get_kind() == type_decl_K)
5356  {
5357  res += PrintType(TM, tn->name, global);
5358  }
5359  else
5360  {
5361  THROW_ERROR(std::string("Node not yet supported: ") +
5362  node_type->get_kind_text()); // p_string(buffer, get_unnamed(node));
5363  }
5364  }
5365  else if(node_type->get_kind() == complex_type_K)
5366  {
5367  const auto ct = GetPointerS<const complex_type>(node_type);
5368  if(ct->unql)
5369  {
5370  res += PrintType(TM, ct->unql, global);
5371  }
5372  else
5373  {
5374  res += "_Complex ";
5375  if(GetPointer<const complex_type>(node_type)->unsigned_flag)
5376  {
5377  res += "unsigned ";
5378  }
5379  if(GetPointer<const complex_type>(node_type)->real_flag)
5380  {
5381  if(tn->algn == 32)
5382  {
5383  res += "float";
5384  }
5385  else if(tn->algn == 64)
5386  {
5387  res += "double";
5388  }
5389  else if(tn->algn == 80)
5390  {
5391  res += "__float80";
5392  }
5393  else if(tn->algn == 128)
5394  {
5395  res += "__float128";
5396  }
5397  else
5398  {
5399  THROW_ERROR(std::string("Complex Real type not yet supported ") + STR(original_type));
5400  }
5401  }
5402  else
5403  {
5404  if(tn->algn == 8)
5405  {
5406  res += "char";
5407  }
5408  else if(tn->algn == 16)
5409  {
5410  res += "short";
5411  }
5412  else if(tn->algn == 32)
5413  {
5414  res += "int";
5415  }
5416  else if(tn->algn == 64)
5417  {
5418  res += "long long";
5419  }
5420  else
5421  {
5422  THROW_ERROR(std::string("Node not yet supported: ") + node_type->get_kind_text() + STR(node_var));
5423  }
5424  }
5425  }
5426  }
5427  else if(node_type->get_kind() == vector_type_K)
5428  {
5429  const auto vt = GetPointerS<const vector_type>(node_type);
5430  if(vt->unql)
5431  {
5432  res += PrintType(TM, vt->unql, global);
5433  }
5434  else
5435  {
5437  if(GET_CONST_NODE(vt->elts)->get_kind() == boolean_type_K)
5438  {
5439  res += "int __attribute__((vector_size(" + STR(Size(node_type) * 4) + ")))";
5440  }
5441  else
5442  {
5443  // THROW_ERROR(std::string("Node not yet supported:<unnamed type> ") +
5444  // node_type->get_kind_text()+STR(type));
5445  THROW_ASSERT(vt->elts, "expected the type of the elements of the vector");
5446  res += PrintType(TM, vt->elts, global);
5447  const auto vector_size = [&]() -> unsigned int {
5448  unsigned int v = vt->algn / 8;
5449  v--;
5450  v |= v >> 1;
5451  v |= v >> 2;
5452  v |= v >> 4;
5453  v |= v >> 8;
5454  v |= v >> 16;
5455  v++;
5456  return v;
5457  }();
5458  res += " __attribute__((vector_size(" + STR(vector_size) + ")))";
5459  }
5460  }
5461  }
5462  else
5463  {
5464  switch(node_type->get_kind())
5465  {
5466  case integer_type_K:
5467  {
5468  const auto it = GetPointerS<const integer_type>(node_type);
5469  if(it->unsigned_flag)
5470  {
5471  res += "unsigned ";
5472  }
5473  if(it->prec != tn->algn)
5474  {
5475  if(it->prec > 64)
5476  {
5477  res += "int __attribute__((vector_size(16)))";
5478  }
5479  else if(it->prec > 32)
5480  {
5481  res += "long long int";
5482  }
5483  else if(it->prec > 16)
5484  {
5485  res += "int";
5486  }
5487  else if(it->prec > 8)
5488  {
5489  res += "short";
5490  }
5491  else
5492  {
5493  res += "char";
5494  }
5495  }
5496  else if(tn->algn == 8)
5497  {
5498  res += "char";
5499  }
5500  else if(tn->algn == 16)
5501  {
5502  res += "short";
5503  }
5504  else if(tn->algn == 32)
5505  {
5506  res += "int";
5507  }
5508  else if(tn->algn == 64)
5509  {
5510  res += "long long";
5511  }
5512  else if(tn->algn == 128)
5513  {
5514  res += "int __attribute__((vector_size(16)))";
5515  }
5516  else
5517  {
5518  res += "_BitInt(" + STR(tn->algn) + ")";
5519  }
5520  break;
5521  }
5522  case enumeral_type_K:
5523  break;
5524  case void_type_K:
5525  res += "void";
5526  break;
5527  case boolean_type_K:
5528  res += "_Bool";
5529  break;
5530  case real_type_K:
5531  {
5532  const auto rt = GetPointerS<const real_type>(node_type);
5533  if(rt->prec == 32)
5534  {
5535  res += "float";
5536  }
5537  else if(rt->prec == 64)
5538  {
5539  res += "double";
5540  }
5541  else if(rt->prec == 80)
5542  {
5543  res += "__float80";
5544  }
5545  else if(rt->prec == 128)
5546  {
5547  res += "__float128";
5548  }
5549  else
5550  {
5551  THROW_ERROR(std::string("Real type not yet supported ") + STR(original_type));
5552  }
5553  break;
5554  }
5555  case type_pack_expansion_K:
5556  {
5557  res += "<type_pack_expansion>";
5558  break;
5559  }
5560  case array_type_K:
5561  case binfo_K:
5562  case block_K:
5563  case call_expr_K:
5564  case aggr_init_expr_K:
5565  case case_label_expr_K:
5566  case CharType_K:
5567  case nullptr_type_K:
5568  case complex_type_K:
5569  case constructor_K:
5570  case function_type_K:
5571  case identifier_node_K:
5572  case lang_type_K:
5573  case method_type_K:
5574  case offset_type_K:
5575  case pointer_type_K:
5576  case qual_union_type_K:
5577  case record_type_K:
5578  case reference_type_K:
5579  case set_type_K:
5580  case ssa_name_K:
5581  case statement_list_K:
5582  case target_expr_K:
5583  case target_mem_ref_K:
5584  case target_mem_ref461_K:
5585  case template_type_parm_K:
5586  case type_argument_pack_K:
5587  case tree_list_K:
5588  case tree_vec_K:
5589  case typename_type_K:
5590  case union_type_K:
5591  case vector_type_K:
5592  case error_mark_K:
5593  case lut_expr_K:
5595  case CASE_CPP_NODES:
5596  case CASE_CST_NODES:
5597  case CASE_DECL_NODES:
5598  case CASE_FAKE_NODES:
5599  case CASE_GIMPLE_NODES:
5600  case CASE_PRAGMA_NODES:
5603  case CASE_UNARY_EXPRESSION:
5604  default:
5605  THROW_ERROR(std::string("Node not yet supported ") + node_type->get_kind_text() + " " +
5606  STR(original_type));
5607  }
5608  }
5609  break;
5610  }
5611  case pointer_type_K:
5612  case reference_type_K:
5613  {
5614  if(node_type->get_kind() == pointer_type_K)
5615  {
5616  const auto tree_type = GetPointerS<const pointer_type>(node_type);
5617  if(tree_type->name && GET_CONST_NODE(tree_type->name)->get_kind() == type_decl_K)
5618  {
5619  const auto td = GetPointerS<const type_decl>(GET_CONST_NODE(tree_type->name));
5620  if(td->name && GET_CONST_NODE(td->name)->get_kind() == identifier_node_K)
5621  {
5622  const auto id = GetPointerS<const identifier_node>(GET_CONST_NODE(td->name));
5623  if(id->strg == "va_list")
5624  {
5625  res = "va_list";
5626  break;
5627  }
5628  }
5629  }
5630  const auto rt = GetPointerS<const record_type>(GET_CONST_NODE(tree_type->ptd));
5631  if(tree_type->ptd && GET_NODE(tree_type->ptd)->get_kind() == record_type_K && rt->name &&
5632  GET_CONST_NODE(rt->name)->get_kind() == type_decl_K)
5633  {
5634  const auto td = GetPointerS<const type_decl>(GET_CONST_NODE(rt->name));
5635  if(td->name && GET_CONST_NODE(td->name)->get_kind() == identifier_node_K)
5636  {
5637  const auto id = GetPointerS<const identifier_node>(GET_CONST_NODE(td->name));
5638  if(id->strg == "va_list" || id->strg == "__va_list_tag")
5639  {
5640  res = "va_list";
5641  break;
5642  }
5643  }
5644  }
5645  res = "*";
5646  /* const internally are not considered as constant...*/
5647  res += return_C_qualifiers(tree_type->qual, var && print_qualifiers);
5648  res = PrintType(TM, tree_type->ptd, global, print_qualifiers, print_storage, var, vppf, prefix + res, tail);
5649  skip_var_printing = true;
5650  break;
5651  }
5652  else
5653  {
5654  res = "/*&*/*";
5655  const auto tree_type = GetPointerS<const reference_type>(node_type);
5656  res =
5657  PrintType(TM, tree_type->refd, global, print_qualifiers, print_storage, var, vppf, prefix + res, tail);
5658  skip_var_printing = true;
5659  break;
5660  }
5661  break;
5662  }
5663  case function_type_K:
5664  {
5665  const auto ft = GetPointerS<const function_type>(node_type);
5666  res += PrintType(TM, ft->retn, global, true);
5667  res += "(" + prefix;
5668  if(node_var)
5669  {
5670  THROW_ASSERT(vppf, "expected a functor");
5671  res += " " + (*vppf)(node_var->index);
5672  }
5673  res += tail + ")(";
5674  if(ft->prms)
5675  {
5676  res += PrintType(TM, ft->prms, global, true);
5677  }
5678  if(ft->varargs_flag && ft->prms)
5679  {
5680  res += ", ... ";
5681  }
5682  else if(ft->varargs_flag)
5683  {
5684  THROW_ERROR("ISO C requires a named parameter before '...'");
5685  }
5686  res += ")";
5687  skip_var_printing = true;
5688  break;
5689  }
5690  case method_type_K:
5691  {
5692  const auto mt = GetPointerS<const method_type>(node_type);
5693  res += PrintType(TM, mt->clas, global);
5694  res += "::";
5695  res += PrintType(TM, mt->retn, global);
5696  res += "(" + prefix;
5697  if(node_var)
5698  {
5699  THROW_ASSERT(vppf, "expected a functor");
5700  res += " " + (*vppf)(node_var->index);
5701  }
5702  res += tail + ")(";
5703  if(mt->prms)
5704  {
5705  res += PrintType(TM, mt->prms, global);
5706  }
5707  res += ")";
5708  skip_var_printing = true;
5709  break;
5710  }
5711  case array_type_K:
5712  {
5713  const auto at = GetPointerS<const array_type>(node_type);
5714  if(at->name)
5715  {
5716  res += PrintType(TM, at->name);
5717  }
5718  else
5719  {
5720  std::string local_prefix;
5721  std::string local_tail;
5722  /* Print array's type */
5724  if(at->size)
5725  {
5726  const auto array_length = GET_CONST_NODE(at->size);
5727  if(array_length->get_kind() == integer_cst_K)
5728  {
5729  const auto tn = GetPointerS<const type_node>(GET_CONST_NODE(at->elts));
5730  local_tail += "[";
5731  local_tail += STR(GetConstValue(at->size) / GetConstValue(tn->size));
5732  local_tail += "]";
5733  }
5734  else if(array_length->get_kind() == var_decl_K)
5735  {
5736  local_tail += "[";
5737  local_tail += "]";
5738  }
5739  else
5740  {
5741  THROW_ERROR("array print_type not supported " + STR(GET_INDEX_CONST_NODE(at->size)));
5742  }
5743  }
5744  else
5745  {
5746  local_tail += "[]";
5747  }
5748  if(!prefix.empty())
5749  {
5750  local_prefix += "(" + prefix;
5751  }
5752  if(node_var)
5753  {
5754  THROW_ASSERT(vppf, "expected a functor");
5755  local_prefix += " " + (*vppf)(node_var->index);
5756  }
5757  if(!prefix.empty())
5758  {
5759  local_tail = ")" + local_tail;
5760  }
5761 
5762  res += PrintType(TM, at->elts, global, print_qualifiers, print_storage, nullptr, nullptr, "",
5763  local_prefix + tail + local_tail);
5765  if(node_var && node_var->get_kind() == field_decl_K)
5766  {
5767  unsigned int type_align = at->algn;
5768  unsigned int var_align;
5769  bool is_a_pointerP = false;
5770  bool is_static = false;
5771  switch(node_var->get_kind())
5772  {
5773  case field_decl_K:
5774  {
5775  const auto fd = GetPointerS<const field_decl>(node_var);
5776  var_align = fd->algn;
5777  is_a_pointerP = GET_CONST_NODE(fd->type)->get_kind() == pointer_type_K ||
5778  GET_CONST_NODE(fd->type)->get_kind() == reference_type_K;
5779  break;
5780  }
5781  case parm_decl_K:
5782  // var_align = GetPointer<parm_decl>(node_var)->algn;
5783  var_align = type_align;
5784  break;
5785  case result_decl_K:
5786  // var_align = GetPointer<result_decl>(node_var)->algn;
5787  var_align = type_align;
5788  break;
5789  case var_decl_K:
5790  {
5791  const auto vd = GetPointerS<const var_decl>(node_var);
5792  var_align = vd->algn;
5793  is_a_pointerP = GET_CONST_NODE(vd->type)->get_kind() == pointer_type_K ||
5794  GET_CONST_NODE(vd->type)->get_kind() == reference_type_K;
5795  is_static = vd->static_flag;
5796  break;
5797  }
5798  case binfo_K:
5799  case block_K:
5800  case call_expr_K:
5801  case aggr_init_expr_K:
5802  case case_label_expr_K:
5803  case const_decl_K:
5804  case constructor_K:
5805  case function_decl_K:
5806  case identifier_node_K:
5807  case label_decl_K:
5808  case namespace_decl_K:
5809  case ssa_name_K:
5810  case statement_list_K:
5811  case target_expr_K:
5812  case target_mem_ref_K:
5813  case target_mem_ref461_K:
5814  case translation_unit_decl_K:
5815  case template_decl_K:
5816  case using_decl_K:
5817  case tree_list_K:
5818  case tree_vec_K:
5819  case type_decl_K:
5820  case error_mark_K:
5821  case lut_expr_K:
5823  case CASE_CPP_NODES:
5824  case CASE_CST_NODES:
5825  case CASE_FAKE_NODES:
5826  case CASE_GIMPLE_NODES:
5827  case CASE_PRAGMA_NODES:
5830  case CASE_TYPE_NODES:
5831  case CASE_UNARY_EXPRESSION:
5832  default:
5833  var_align = type_align;
5834  break;
5835  }
5836  if(var_align > type_align && !is_a_pointerP && !is_static)
5837  {
5838  res += " __attribute__((aligned(" + STR(var_align / 8) + ")))";
5839  }
5840  }
5841  skip_var_printing = true;
5842  }
5843  break;
5844  }
5845  case component_ref_K:
5846  {
5847  const auto cr = GetPointer<const component_ref>(node_type);
5848  res += PrintType(TM, cr->type, global);
5849  break;
5850  }
5851  case enumeral_type_K:
5852  {
5853  const auto et = GetPointer<const enumeral_type>(node_type);
5854  if(et->name && (GET_CONST_NODE(et->name)->get_kind() == type_decl_K || et->unql))
5855  {
5856  res += PrintType(TM, et->name, global);
5857  }
5858  else if(et->name)
5859  {
5860  res += "enum " + PrintType(TM, et->name, global);
5861  }
5862  else if(et->unql)
5863  {
5864  res += "Internal_" + STR(node_type->index);
5865  }
5866  else
5867  {
5868  res += "enum Internal_" + STR(node_type->index);
5869  }
5870  break;
5871  }
5872  case record_type_K:
5873  {
5874  const auto rt = GetPointerS<const record_type>(node_type);
5875  res += return_C_qualifiers(rt->qual, print_qualifiers);
5876  if(rt->name && (GET_CONST_NODE(rt->name)->get_kind() == type_decl_K || (rt->unql && !rt->system_flag)))
5877  {
5878  res += (rt->unql ? "" : "struct ") + PrintType(TM, rt->name, global);
5879  }
5880  else if(rt->name)
5881  {
5882  const auto struct_name = PrintType(TM, rt->name, global);
5883  if(struct_name == "_IO_FILE")
5884  {
5885  res += "FILE";
5886  }
5887  else
5888  {
5889  res += "struct " + NormalizeTypename(struct_name);
5890  }
5891  }
5892  else if(rt->unql)
5893  {
5894  res += "Internal_" + STR(node_type->index);
5895  }
5896  else
5897  {
5898  res += "struct Internal_" + STR(node_type->index);
5899  }
5900  if(rt->tmpl_args)
5901  {
5902  std::stringstream ss;
5903  const auto& tmpl_args = GetPointerS<const tree_vec>(GET_CONST_NODE(rt->tmpl_args))->list_of_op;
5904  for(const auto& targ : tmpl_args)
5905  {
5906  ss << "_" << targ;
5907  }
5908  res += NormalizeTypename(ss.str());
5909  }
5910  break;
5911  }
5912  case union_type_K:
5913  {
5914  const auto ut = GetPointerS<const union_type>(node_type);
5915  res += return_C_qualifiers(ut->qual, print_qualifiers);
5916  if(ut->name && (GET_NODE(ut->name)->get_kind() == type_decl_K || (ut->unql && !ut->system_flag)))
5917  {
5918  res += PrintType(TM, ut->name, global);
5919  }
5920  else if(ut->name)
5921  {
5922  res += "union " + PrintType(TM, ut->name, global);
5923  }
5924  else if(ut->unql)
5925  {
5926  res += "Internal_" + STR(node_type->index);
5927  }
5928  else
5929  {
5930  res += "union Internal_" + STR(node_type->index);
5931  }
5932  break;
5933  }
5934  case tree_list_K:
5935  {
5936  THROW_ASSERT(!node_var, "Received something of unexpected");
5937  auto lnode = GetPointer<const tree_list>(node_type);
5938  res += PrintType(TM, lnode->valu, global, print_qualifiers);
5941  std::list<tree_nodeRef> prmtrs;
5942  while(lnode->chan)
5943  {
5944  lnode = GetPointer<const tree_list>(GET_CONST_NODE(lnode->chan));
5945  if(!GetPointer<const void_type>(GET_CONST_NODE(lnode->valu)))
5946  {
5947  prmtrs.push_back(lnode->valu);
5948  }
5949  }
5950  for(const auto& valu : prmtrs)
5951  {
5952  res += "," + PrintType(TM, valu, global, print_qualifiers);
5953  }
5954  break;
5955  }
5956  case template_type_parm_K:
5957  {
5958  const auto ttp = GetPointer<const template_type_parm>(node_type);
5959  res += PrintType(TM, ttp->name, global, print_qualifiers);
5960  break;
5961  }
5962  case typename_type_K:
5963  {
5964  const auto tt = GetPointer<const typename_type>(node_type);
5965  res += PrintType(TM, tt->name, global, print_qualifiers);
5966  break;
5967  }
5968  case template_decl_K:
5969  {
5970  const auto td = GetPointer<const template_decl>(node_type);
5971  res += print_type(TM, GET_INDEX_NODE(td->name), global, print_qualifiers);
5972  break;
5973  }
5974  case parm_decl_K:
5975  {
5976  const auto pd = GetPointer<const parm_decl>(node_type);
5977  if(pd->readonly_flag)
5978  {
5979  res += print_qualifiers ? "const " : "/*const*/ ";
5980  }
5981  res += PrintType(TM, pd->type, global, print_qualifiers);
5982  break;
5983  }
5984  case binfo_K:
5985  case block_K:
5986  case call_expr_K:
5987  case aggr_init_expr_K:
5988  case case_label_expr_K:
5989  case const_decl_K:
5990  case constructor_K:
5991  case field_decl_K:
5992  case label_decl_K:
5993  case lang_type_K:
5994  case namespace_decl_K:
5995  case offset_type_K:
5996  case qual_union_type_K:
5997  case result_decl_K:
5998  case set_type_K:
5999  case ssa_name_K:
6000  case statement_list_K:
6001  case target_expr_K:
6002  case target_mem_ref_K:
6003  case target_mem_ref461_K:
6004  case type_argument_pack_K:
6005  case translation_unit_decl_K:
6006  case using_decl_K:
6007  case tree_vec_K:
6008  case var_decl_K:
6009  case vec_cond_expr_K:
6010  case vec_perm_expr_K:
6011  case bit_field_ref_K:
6012  case vtable_ref_K:
6013  case with_cleanup_expr_K:
6014  case obj_type_ref_K:
6015  case save_expr_K:
6016  case cond_expr_K:
6017  case dot_prod_expr_K:
6018  case ternary_plus_expr_K:
6019  case ternary_pm_expr_K:
6020  case ternary_mp_expr_K:
6021  case ternary_mm_expr_K:
6022  case fshl_expr_K:
6023  case fshr_expr_K:
6024  case bit_ior_concat_expr_K:
6025  case error_mark_K:
6026  case lut_expr_K:
6027  case insertvalue_expr_K:
6028  case insertelement_expr_K:
6030  case CASE_CPP_NODES:
6031  case CASE_CST_NODES:
6032  case CASE_FAKE_NODES:
6033  case CASE_GIMPLE_NODES:
6034  case CASE_PRAGMA_NODES:
6036  case CASE_UNARY_EXPRESSION:
6037  default:
6038  THROW_UNREACHABLE("Type not yet supported " + STR(original_type) + " " + node_type->get_kind_text() + " " +
6039  (node_var ? STR(node_var) : ""));
6040  }
6041  if(!skip_var_printing)
6042  {
6043  res += prefix;
6044  if(node_var)
6045  {
6046  THROW_ASSERT(vppf, "expected a functor");
6047  res += " " + (*vppf)(node_var->index);
6048  }
6049  res += tail;
6050  }
6051  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Printed type " + STR(original_type) + ": " + res);
6052  return res;
6053 }
6054 
6056 {
6057  if(no_serialize.find(name) != no_serialize.end())
6058  {
6059  return none;
6060  }
6061  if(internal_serialize.find(name) != internal_serialize.end())
6062  {
6063  return internal;
6064  }
6065  return total;
6066 }
6067 
6068 bool FunctionExpander::is_transparent(const std::string& name) const
6069 {
6070  return (transparent.find(name) != transparent.end());
6071 }
6072 
6074 {
6075  tree_nodeRef curr_tn;
6076  if(var->get_kind() == tree_reindex_K)
6077  {
6078  curr_tn = GET_NODE(var);
6079  }
6080  else
6081  {
6082  curr_tn = var;
6083  }
6084  THROW_ASSERT(GetPointer<decl_node>(curr_tn), "Checking type of not a decl_node");
6085  const auto dn = GetPointer<decl_node>(curr_tn);
6086  std::string include_name = dn->include_name;
6087  auto it_end = headers.end();
6088  for(auto it = headers.begin(); it != it_end; ++it)
6089  {
6090  if(include_name.find(*it) != std::string::npos && dn->type)
6091  {
6092  if(GetPointer<type_node>(GET_NODE(dn->type)))
6093  {
6094  lib_types.insert(GET_NODE(dn->type));
6095  const auto tn = GetPointer<type_node>(GET_NODE(dn->type));
6096  if(tn && tn->unql)
6097  {
6098  lib_types.insert(GET_NODE(tn->unql));
6099  }
6100  }
6101  }
6102  }
6103 }
6104 
6106 {
6107  tree_nodeRef curr_tn;
6108  if(tn->get_kind() == tree_reindex_K)
6109  {
6110  curr_tn = GET_NODE(tn);
6111  }
6112  else
6113  {
6114  curr_tn = tn;
6115  }
6116  THROW_ASSERT(GetPointer<type_node>(curr_tn) || GetPointer<function_decl>(curr_tn),
6117  "tn is not a node of type type_node nor function_decl");
6118  if(lib_types.find(curr_tn) != lib_types.end())
6119  {
6120  return false;
6121  }
6122  if(curr_tn->get_kind() == record_type_K)
6123  {
6124  const auto rt = GetPointer<record_type>(curr_tn);
6125  if(rt->ptrmem_flag)
6126  {
6127  return false;
6128  }
6129  }
6130  const auto type = GetPointer<type_node>(curr_tn);
6131  if(type && type->name)
6132  {
6133  const auto td = GetPointer<type_decl>(GET_NODE(type->name));
6134  if(td)
6135  {
6136  std::string include_name = td->include_name;
6137  auto it_end = headers.end();
6138  for(auto it = headers.begin(); it != it_end; ++it)
6139  {
6140  if(include_name.find(*it) != std::string::npos)
6141  {
6142  return false;
6143  }
6144  }
6145  }
6146  }
6147  return true;
6148 }
6149 
6151 {
6152  internal_serialize.insert("printf");
6153  transparent.insert("__builtin_va_start");
6154  headers.insert("stdio.h");
6155 }
6156 
6158 {
6159  const auto obj = _obj->get_kind() == tree_reindex_K ? GET_CONST_NODE(_obj) : _obj;
6160  if(obj->get_kind() == gimple_call_K)
6161  {
6162  const auto gc = GetPointerS<const gimple_call>(obj);
6163  THROW_ASSERT(gc->fn, "unexpected condition");
6164 
6165  const auto fn_type = GET_CONST_NODE(CGetType(gc->fn));
6166  if(fn_type->get_kind() == pointer_type_K)
6167  {
6168  const auto pt = GetPointerS<const pointer_type>(fn_type);
6169  THROW_ASSERT(pt->ptd, "unexpected pattern");
6170  const auto ft = GetPointer<const function_type>(GET_CONST_NODE(pt->ptd));
6171  if(ft && ft->varargs_flag)
6172  {
6173  return tree_nodeConstRef();
6174  }
6175  else if(ft && ft->prms)
6176  {
6177  auto tl = GetPointerS<const tree_list>(GET_CONST_NODE(ft->prms));
6178  THROW_ASSERT(tl, "unexpected condition");
6179  unsigned int ith = 0;
6180  if(parm_index == ith)
6181  {
6182  return tl->valu;
6183  }
6184  while(tl->chan)
6185  {
6186  ++ith;
6187  tl = GetPointerS<const tree_list>(GET_CONST_NODE(tl->chan));
6188  if(parm_index == ith)
6189  {
6190  return tl->valu;
6191  }
6192  }
6193  THROW_ERROR("unexpected pattern");
6194  return tree_nodeConstRef();
6195  }
6196  else
6197  {
6198  const auto fn_node = GET_CONST_NODE(gc->fn);
6200  THROW_ASSERT(fn_node->get_kind() == addr_expr_K, "Unexpected pattern");
6201  const auto ue = GetPointerS<const unary_expr>(fn_node);
6202  const auto fn = GET_CONST_NODE(ue->op);
6203  THROW_ASSERT(fn->get_kind() == function_decl_K, "Unexpected pattern");
6204  return GetFormalIth(fn, parm_index);
6205  }
6206  }
6207  else
6208  {
6209  THROW_ERROR("unexpected pattern");
6210  return tree_nodeConstRef();
6211  }
6212  }
6213  else if(obj->get_kind() == gimple_assign_K)
6214  {
6215  const auto ga = GetPointerS<const gimple_assign>(obj);
6216  return GetFormalIth(GET_CONST_NODE(ga->op1), parm_index);
6217  }
6218  else if(obj->get_kind() == call_expr_K || obj->get_kind() == aggr_init_expr_K)
6219  {
6220  const auto ce = GetPointerS<const call_expr>(obj);
6221  const auto fn_type = GET_CONST_NODE(CGetType(ce->fn));
6222  if(fn_type->get_kind() == pointer_type_K)
6223  {
6224  const auto pt = GetPointerS<const pointer_type>(fn_type);
6225  THROW_ASSERT(pt->ptd, "unexpected pattern");
6226  const auto ft = GetPointer<const function_type>(GET_CONST_NODE(pt->ptd));
6227  if(ft && ft->varargs_flag)
6228  {
6229  return tree_nodeConstRef();
6230  }
6231  else if(ft && ft->prms)
6232  {
6233  auto tl = GetPointerS<const tree_list>(GET_CONST_NODE(ft->prms));
6234  unsigned int ith = 0;
6235  if(parm_index == ith)
6236  {
6237  return tl->valu;
6238  }
6239  while(tl->chan)
6240  {
6241  ++ith;
6242  tl = GetPointerS<const tree_list>(GET_CONST_NODE(tl->chan));
6243  if(parm_index == ith)
6244  {
6245  return tl->valu;
6246  }
6247  }
6248  THROW_ERROR("unexpected pattern");
6249  return tree_nodeConstRef();
6250  }
6251  else
6252  {
6253  const auto fn_node = GET_CONST_NODE(ce->fn);
6255  THROW_ASSERT(fn_node->get_kind() == addr_expr_K, "Unexpected pattern");
6256  const auto ue = GetPointerS<const unary_expr>(fn_node);
6257  const auto fn = GET_CONST_NODE(ue->op);
6258  THROW_ASSERT(fn->get_kind(), "Unexpected pattern");
6259  return GetFormalIth(fn, parm_index);
6260  }
6261  }
6262  else
6263  {
6264  THROW_ERROR("unexpected pattern");
6265  return tree_nodeConstRef();
6266  }
6267  }
6268  else if(obj->get_kind() == function_decl_K)
6269  {
6270  const auto fd = GetPointerS<const function_decl>(obj);
6271  unsigned int ith = 0;
6272  for(const auto& i : fd->list_of_args)
6273  {
6274  if(parm_index == ith)
6275  {
6276  return CGetType(i);
6277  }
6278  ++ith;
6279  }
6280  }
6281  return tree_nodeConstRef();
6282 }
6283 
6284 unsigned int tree_helper::get_formal_ith(const tree_managerConstRef& TM, unsigned int index_obj,
6285  unsigned int parm_index)
6286 {
6287  const auto t = GetFormalIth(TM->CGetTreeReindex(index_obj), parm_index);
6288  return t ? t->index : 0;
6289 }
6290 
6291 bool tree_helper::is_packed(const tree_managerConstRef& TreeM, unsigned int node_index)
6292 {
6293  const auto node = TreeM->CGetTreeReindex(node_index);
6294  return IsPackedType(node);
6295 }
6296 
6298 {
6299  const auto type = _type->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type) : _type;
6300  THROW_ASSERT(GetPointer<const decl_node>(type), "unexpected pattern" + type->get_kind_text());
6301  if(GetPointer<const decl_node>(type)->packed_flag)
6302  {
6303  return true;
6304  }
6305  auto node_type = GET_CONST_NODE(GetPointer<const decl_node>(type)->type);
6306  if(GetPointer<const type_decl>(node_type))
6307  {
6308  node_type = GET_CONST_NODE(GetPointer<const type_decl>(node_type)->type);
6309  }
6310  switch(node_type->get_kind())
6311  {
6312  case record_type_K:
6313  {
6314  auto rt = GetPointerS<const record_type>(node_type);
6315  if(rt->unql)
6316  {
6317  rt = GetPointerS<const record_type>(GET_CONST_NODE(rt->unql));
6318  }
6319  THROW_ASSERT(!rt->unql, "unexpected pattern");
6320  if(rt->packed_flag)
6321  {
6322  return true;
6323  }
6324  for(auto& list_of_fld : rt->list_of_flds)
6325  {
6326  const auto fd = GetPointer<const field_decl>(GET_CONST_NODE(list_of_fld));
6327  if(fd && fd->packed_flag)
6328  {
6329  return true;
6330  }
6331  }
6332  break;
6333  }
6334  case union_type_K:
6335  {
6336  auto ut = GetPointerS<const union_type>(node_type);
6337  if(ut->unql)
6338  {
6339  ut = GetPointerS<const union_type>(GET_CONST_NODE(ut->unql));
6340  }
6341  THROW_ASSERT(!ut->unql, "unexpected pattern");
6342  if(ut->packed_flag)
6343  {
6344  return true;
6345  }
6346 
6348  for(const auto& list_of_fld : ut->list_of_flds)
6349  {
6350  const auto fd = GetPointerS<const field_decl>(GET_CONST_NODE(list_of_fld));
6351  if(fd->packed_flag)
6352  {
6353  return true;
6354  }
6355  }
6356  break;
6357  }
6358  case enumeral_type_K:
6359  {
6360  auto et = GetPointerS<const enumeral_type>(node_type);
6361  if(et->unql)
6362  {
6363  et = GetPointerS<const enumeral_type>(GET_CONST_NODE(et->unql));
6364  }
6365  THROW_ASSERT(!et->unql, "unexpected pattern");
6366  if(et->packed_flag)
6367  {
6368  return true;
6369  }
6370  break;
6371  }
6372  case array_type_K:
6373  case pointer_type_K:
6374  case boolean_type_K:
6375  case CharType_K:
6376  case nullptr_type_K:
6377  case type_pack_expansion_K:
6378  case complex_type_K:
6379  case function_type_K:
6380  case integer_type_K:
6381  case lang_type_K:
6382  case method_type_K:
6383  case offset_type_K:
6384  case qual_union_type_K:
6385  case real_type_K:
6386  case reference_type_K:
6387  case set_type_K:
6388  case template_type_parm_K:
6389  case type_argument_pack_K:
6390  case typename_type_K:
6391  case vector_type_K:
6392  case void_type_K:
6393  {
6394  break;
6395  }
6396  case binfo_K:
6397  case block_K:
6398  case call_expr_K:
6399  case aggr_init_expr_K:
6400  case case_label_expr_K:
6401  case constructor_K:
6402  case identifier_node_K:
6403  case ssa_name_K:
6404  case statement_list_K:
6405  case target_expr_K:
6406  case target_mem_ref_K:
6407  case target_mem_ref461_K:
6408  case tree_list_K:
6409  case tree_vec_K:
6410  case error_mark_K:
6411  case lut_expr_K:
6413  case CASE_CPP_NODES:
6414  case CASE_CST_NODES:
6415  case CASE_DECL_NODES:
6416  case CASE_FAKE_NODES:
6417  case CASE_GIMPLE_NODES:
6418  case CASE_PRAGMA_NODES:
6421  case CASE_UNARY_EXPRESSION:
6422  default:
6423  {
6424  THROW_UNREACHABLE("Unexpected type " + node_type->get_kind_text());
6425  }
6426  }
6427  return false;
6428 }
6429 
6430 bool tree_helper::is_packed_access(const tree_managerConstRef& TreeM, unsigned int node_index)
6431 {
6432  const auto t = TreeM->CGetTreeNode(node_index);
6433  bool res = false;
6434  switch(t->get_kind())
6435  {
6436  case mem_ref_K:
6437  {
6438  const auto mr = GetPointer<const mem_ref>(t);
6439  return is_packed_access(TreeM, GET_INDEX_CONST_NODE(mr->op0));
6440  }
6441  case target_mem_ref461_K:
6442  {
6443  const auto tmr = GetPointer<const target_mem_ref461>(t);
6444  return is_packed_access(TreeM, GET_INDEX_CONST_NODE(tmr->base));
6445  }
6446  case component_ref_K:
6447  {
6448  const auto cr = GetPointer<const component_ref>(t);
6449  const auto fd = GET_CONST_NODE(cr->op1);
6450  if(GetPointer<const field_decl>(fd) && GetPointer<const field_decl>(fd)->packed_flag)
6451  {
6452  res = true;
6453  }
6454  break;
6455  }
6456  case realpart_expr_K:
6457  case imagpart_expr_K:
6458  case bit_field_ref_K:
6459  case array_ref_K:
6460  {
6461  res = false;
6462  break;
6463  }
6464  case addr_expr_K:
6465  {
6466  const auto ae = GetPointer<const addr_expr>(t);
6467  return is_packed_access(TreeM, GET_INDEX_CONST_NODE(ae->op));
6468  }
6469  case ssa_name_K:
6470  {
6471  const auto sn = GetPointer<const ssa_name>(t);
6472  const auto def_stmt = sn->CGetDefStmt();
6473  if(GET_CONST_NODE(def_stmt)->get_kind() == gimple_assign_K)
6474  {
6475  const auto ga = GetPointer<const gimple_assign>(GET_CONST_NODE(def_stmt));
6476  if(ga->temporary_address)
6477  {
6478  return is_packed_access(TreeM, GET_INDEX_CONST_NODE(ga->op1));
6479  }
6480  }
6481  res = false;
6482  break;
6483  }
6484  case var_decl_K:
6485  case binfo_K:
6486  case block_K:
6487  case call_expr_K:
6488  case aggr_init_expr_K:
6489  case case_label_expr_K:
6490  case constructor_K:
6491  case identifier_node_K:
6492  case statement_list_K:
6493  case target_mem_ref_K:
6494  case tree_list_K:
6495  case tree_vec_K:
6496  case assert_expr_K:
6497  case bit_and_expr_K:
6498  case bit_ior_expr_K:
6499  case bit_xor_expr_K:
6500  case catch_expr_K:
6501  case ceil_div_expr_K:
6502  case ceil_mod_expr_K:
6503  case complex_expr_K:
6504  case compound_expr_K:
6505  case eh_filter_expr_K:
6506  case eq_expr_K:
6507  case exact_div_expr_K:
6508  case fdesc_expr_K:
6509  case floor_div_expr_K:
6510  case floor_mod_expr_K:
6511  case ge_expr_K:
6512  case gt_expr_K:
6513  case goto_subroutine_K:
6514  case in_expr_K:
6515  case init_expr_K:
6516  case le_expr_K:
6517  case lrotate_expr_K:
6518  case lshift_expr_K:
6519  case lt_expr_K:
6520  case max_expr_K:
6521  case min_expr_K:
6522  case minus_expr_K:
6523  case modify_expr_K:
6524  case mult_expr_K:
6525  case mult_highpart_expr_K:
6526  case ne_expr_K:
6527  case ordered_expr_K:
6528  case paren_expr_K:
6529  case plus_expr_K:
6530  case pointer_plus_expr_K:
6531  case postdecrement_expr_K:
6532  case postincrement_expr_K:
6533  case predecrement_expr_K:
6534  case preincrement_expr_K:
6535  case range_expr_K:
6536  case rdiv_expr_K:
6537  case round_div_expr_K:
6538  case round_mod_expr_K:
6539  case rrotate_expr_K:
6540  case rshift_expr_K:
6541  case set_le_expr_K:
6542  case trunc_div_expr_K:
6543  case trunc_mod_expr_K:
6544  case truth_and_expr_K:
6545  case truth_andif_expr_K:
6546  case truth_or_expr_K:
6547  case truth_orif_expr_K:
6548  case truth_xor_expr_K:
6549  case try_catch_expr_K:
6550  case try_finally_K:
6551  case uneq_expr_K:
6552  case ltgt_expr_K:
6553  case unge_expr_K:
6554  case ungt_expr_K:
6555  case unle_expr_K:
6556  case unlt_expr_K:
6557  case unordered_expr_K:
6558  case widen_sum_expr_K:
6559  case widen_mult_expr_K:
6560  case with_size_expr_K:
6561  case vec_lshift_expr_K:
6562  case vec_rshift_expr_K:
6563  case widen_mult_hi_expr_K:
6564  case widen_mult_lo_expr_K:
6565  case vec_pack_trunc_expr_K:
6566  case vec_pack_sat_expr_K:
6567  case vec_pack_fix_trunc_expr_K:
6568  case vec_extracteven_expr_K:
6569  case vec_extractodd_expr_K:
6570  case vec_interleavehigh_expr_K:
6571  case vec_interleavelow_expr_K:
6572  case CASE_CPP_NODES:
6573  case CASE_CST_NODES:
6574  case const_decl_K:
6575  case field_decl_K:
6576  case function_decl_K:
6577  case label_decl_K:
6578  case namespace_decl_K:
6579  case parm_decl_K:
6580  case result_decl_K:
6581  case translation_unit_decl_K:
6582  case template_decl_K:
6583  case using_decl_K:
6584  case type_decl_K:
6585  case CASE_FAKE_NODES:
6586  case CASE_GIMPLE_NODES:
6587  case CASE_PRAGMA_NODES:
6588  case vtable_ref_K:
6589  case with_cleanup_expr_K:
6590  case obj_type_ref_K:
6591  case save_expr_K:
6592  case cond_expr_K:
6593  case vec_cond_expr_K:
6594  case vec_perm_expr_K:
6595  case dot_prod_expr_K:
6596  case ternary_plus_expr_K:
6597  case ternary_pm_expr_K:
6598  case ternary_mp_expr_K:
6599  case ternary_mm_expr_K:
6600  case fshl_expr_K:
6601  case fshr_expr_K:
6602  case bit_ior_concat_expr_K:
6603  case abs_expr_K:
6604  case alignof_expr_K:
6605  case arrow_expr_K:
6606  case bit_not_expr_K:
6607  case buffer_ref_K:
6608  case card_expr_K:
6609  case cleanup_point_expr_K:
6610  case conj_expr_K:
6611  case convert_expr_K:
6612  case exit_expr_K:
6613  case fix_ceil_expr_K:
6614  case fix_floor_expr_K:
6615  case fix_round_expr_K:
6616  case fix_trunc_expr_K:
6617  case float_expr_K:
6618  case indirect_ref_K:
6619  case misaligned_indirect_ref_K:
6620  case loop_expr_K:
6621  case lut_expr_K:
6622  case negate_expr_K:
6623  case non_lvalue_expr_K:
6624  case nop_expr_K:
6625  case reference_expr_K:
6626  case reinterpret_cast_expr_K:
6627  case sizeof_expr_K:
6628  case static_cast_expr_K:
6629  case throw_expr_K:
6630  case truth_not_expr_K:
6631  case unsave_expr_K:
6632  case va_arg_expr_K:
6633  case view_convert_expr_K:
6634  case reduc_max_expr_K:
6635  case reduc_min_expr_K:
6636  case reduc_plus_expr_K:
6637  case vec_unpack_hi_expr_K:
6638  case vec_unpack_lo_expr_K:
6639  case vec_unpack_float_hi_expr_K:
6640  case vec_unpack_float_lo_expr_K:
6641  case CASE_TYPE_NODES:
6642  case array_range_ref_K:
6643  case target_expr_K:
6644  case error_mark_K:
6645  case extract_bit_expr_K:
6646  case sat_plus_expr_K:
6647  case sat_minus_expr_K:
6648  case frem_expr_K:
6649  {
6650  res = false;
6651  break;
6652  }
6653  case extractvalue_expr_K:
6654  case insertvalue_expr_K:
6655  case extractelement_expr_K:
6656  case insertelement_expr_K:
6657  {
6658  res = true;
6659  break;
6660  }
6661  default:
6662  THROW_ERROR("elements not yet supported: " + t->get_kind_text());
6663  }
6664 
6665  return res;
6666 }
6667 
6668 unsigned long long tree_helper::AccessedMaximumBitsize(const tree_nodeConstRef& _type_node, unsigned long long bitsize)
6669 {
6670  const auto type_node = _type_node->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type_node) : _type_node;
6671  switch(type_node->get_kind())
6672  {
6673  case array_type_K:
6674  {
6675  const auto atype = GetPointerS<const array_type>(type_node);
6676  return AccessedMaximumBitsize(atype->elts, bitsize);
6677  }
6678  case record_type_K:
6679  {
6680  const auto rt = GetPointerS<const record_type>(type_node);
6681  for(const auto& fli : rt->list_of_flds)
6682  {
6683  if(GET_CONST_NODE(fli)->get_kind() == type_decl_K)
6684  {
6685  continue;
6686  }
6687  if(GET_CONST_NODE(fli)->get_kind() == const_decl_K)
6688  {
6689  continue;
6690  }
6691  if(GET_CONST_NODE(fli)->get_kind() == template_decl_K)
6692  {
6693  continue;
6694  }
6695  if(GET_CONST_NODE(fli)->get_kind() == function_decl_K)
6696  {
6697  continue;
6698  }
6699  if(GET_CONST_NODE(fli)->get_kind() == var_decl_K)
6700  {
6701  bitsize = AccessedMaximumBitsize(GetPointerS<const var_decl>(GET_CONST_NODE(fli))->type, bitsize);
6702  }
6703  else
6704  {
6705  bitsize = AccessedMaximumBitsize(fli, bitsize);
6706  }
6707  }
6708  return bitsize;
6709  }
6710  case union_type_K:
6711  {
6712  const auto ut = GetPointerS<const union_type>(type_node);
6713  for(const auto& fli : ut->list_of_flds)
6714  {
6715  bitsize = AccessedMaximumBitsize(fli, bitsize);
6716  }
6717  return bitsize;
6718  }
6719  case field_decl_K:
6720  {
6721  const auto fd_type_node = CGetType(type_node);
6722  return AccessedMaximumBitsize(fd_type_node, bitsize);
6723  }
6724  case complex_type_K:
6725  {
6726  return std::max(bitsize, Size(type_node) / 2);
6727  }
6728  case real_type_K:
6729  case integer_type_K:
6730  case enumeral_type_K:
6731  case pointer_type_K:
6732  case reference_type_K:
6733  case void_type_K:
6734  case vector_type_K:
6735  {
6736  return std::max(bitsize, Size(type_node));
6737  }
6738  case function_decl_K:
6739  case function_type_K:
6740  case method_type_K:
6741  {
6742  return 32;
6743  }
6744  case boolean_type_K:
6745  {
6746  return 8;
6747  }
6748  case binfo_K:
6749  case block_K:
6750  case call_expr_K:
6751  case aggr_init_expr_K:
6752  case case_label_expr_K:
6753  case CharType_K:
6754  case nullptr_type_K:
6755  case type_pack_expansion_K:
6756  case const_decl_K:
6757  case constructor_K:
6758  case identifier_node_K:
6759  case label_decl_K:
6760  case lang_type_K:
6761  case namespace_decl_K:
6762  case offset_type_K:
6763  case parm_decl_K:
6764  case qual_union_type_K:
6765  case result_decl_K:
6766  case set_type_K:
6767  case ssa_name_K:
6768  case statement_list_K:
6769  case target_expr_K:
6770  case target_mem_ref_K:
6771  case target_mem_ref461_K:
6772  case template_type_parm_K:
6773  case type_argument_pack_K:
6774  case translation_unit_decl_K:
6775  case template_decl_K:
6776  case using_decl_K:
6777  case tree_list_K:
6778  case tree_vec_K:
6779  case type_decl_K:
6780  case typename_type_K:
6781  case var_decl_K:
6782  case error_mark_K:
6783  case lut_expr_K:
6785  case CASE_CPP_NODES:
6786  case CASE_CST_NODES:
6787  case CASE_FAKE_NODES:
6788  case CASE_GIMPLE_NODES:
6789  case CASE_PRAGMA_NODES:
6792  case CASE_UNARY_EXPRESSION:
6793  default:
6794  THROW_ERROR("elements not yet supported: " + type_node->get_kind_text() + " " + STR(type_node->index));
6795  }
6796  return 0;
6797 }
6798 
6799 unsigned long long tree_helper::AccessedMinimunBitsize(const tree_nodeConstRef& _type_node, unsigned long long bitsize)
6800 {
6801  const auto type_node = _type_node->get_kind() == tree_reindex_K ? GET_CONST_NODE(_type_node) : _type_node;
6802  switch(type_node->get_kind())
6803  {
6804  case array_type_K:
6805  {
6806  const auto atype = GetPointerS<const array_type>(type_node);
6807  return AccessedMinimunBitsize(atype->elts, bitsize);
6808  }
6809  case record_type_K:
6810  {
6811  const auto rt = GetPointerS<const record_type>(type_node);
6812  for(const auto& fli : rt->list_of_flds)
6813  {
6814  if(GET_CONST_NODE(fli)->get_kind() == type_decl_K)
6815  {
6816  continue;
6817  }
6818  if(GET_CONST_NODE(fli)->get_kind() == const_decl_K)
6819  {
6820  continue;
6821  }
6822  if(GET_CONST_NODE(fli)->get_kind() == template_decl_K)
6823  {
6824  continue;
6825  }
6826  if(GET_CONST_NODE(fli)->get_kind() == function_decl_K)
6827  {
6828  continue;
6829  }
6830  if(GET_CONST_NODE(fli)->get_kind() == var_decl_K)
6831  {
6832  bitsize = AccessedMinimunBitsize(GetPointerS<const var_decl>(GET_CONST_NODE(fli))->type, bitsize);
6833  }
6834  else
6835  {
6836  bitsize = AccessedMinimunBitsize(fli, bitsize);
6837  }
6838  }
6839  return bitsize;
6840  }
6841  case union_type_K:
6842  {
6843  const auto ut = GetPointerS<const union_type>(type_node);
6844  for(const auto& fli : ut->list_of_flds)
6845  {
6846  bitsize = AccessedMinimunBitsize(fli, bitsize);
6847  }
6848  return bitsize;
6849  }
6850  case field_decl_K:
6851  {
6852  const auto fd_type_node = CGetType(type_node);
6853  return AccessedMinimunBitsize(fd_type_node, bitsize);
6854  }
6855  case complex_type_K:
6856  {
6857  return std::min(bitsize, Size(type_node) / 2);
6858  }
6859  case real_type_K:
6860  case integer_type_K:
6861  case enumeral_type_K:
6862  case pointer_type_K:
6863  case reference_type_K:
6864  case void_type_K:
6865  case vector_type_K:
6866  {
6867  return std::min(bitsize, Size(type_node));
6868  }
6869  case boolean_type_K:
6870  {
6871  return 8;
6872  }
6873  case binfo_K:
6874  case block_K:
6875  case call_expr_K:
6876  case aggr_init_expr_K:
6877  case case_label_expr_K:
6878  case CharType_K:
6879  case nullptr_type_K:
6880  case type_pack_expansion_K:
6881  case const_decl_K:
6882  case constructor_K:
6883  case function_decl_K:
6884  case function_type_K:
6885  case identifier_node_K:
6886  case label_decl_K:
6887  case lang_type_K:
6888  case method_type_K:
6889  case namespace_decl_K:
6890  case offset_type_K:
6891  case parm_decl_K:
6892  case qual_union_type_K:
6893  case result_decl_K:
6894  case set_type_K:
6895  case ssa_name_K:
6896  case statement_list_K:
6897  case target_expr_K:
6898  case target_mem_ref_K:
6899  case target_mem_ref461_K:
6900  case template_type_parm_K:
6901  case type_argument_pack_K:
6902  case translation_unit_decl_K:
6903  case template_decl_K:
6904  case using_decl_K:
6905  case tree_list_K:
6906  case tree_vec_K:
6907  case type_decl_K:
6908  case typename_type_K:
6909  case var_decl_K:
6910  case error_mark_K:
6911  case lut_expr_K:
6913  case CASE_CPP_NODES:
6914  case CASE_CST_NODES:
6915  case CASE_FAKE_NODES:
6916  case CASE_GIMPLE_NODES:
6917  case CASE_PRAGMA_NODES:
6920  case CASE_UNARY_EXPRESSION:
6921  default:
6922  THROW_ERROR("elements not yet supported: " + type_node->get_kind_text());
6923  }
6924  return 0;
6925 }
6926 
6928 {
6929  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Analyzing " + parameter->ToString());
6930  switch(parameter->get_kind())
6931  {
6932  case(addr_expr_K):
6933  {
6934  const auto ae = GetPointer<const addr_expr>(parameter);
6937  const tree_nodeRef addr_expr_argument = GET_NODE(ae->op);
6938  switch(addr_expr_argument->get_kind())
6939  {
6940  case(array_ref_K):
6941  {
6942  const array_ref* ar = GetPointer<array_ref>(addr_expr_argument);
6943  const size_t byte_parameter_size = AllocatedMemorySize(GET_NODE(ar->op0));
6945  "<--Analyzed " + parameter->ToString() + " - Size is " + STR(byte_parameter_size));
6946  return byte_parameter_size;
6947  }
6948  case(component_ref_K):
6949  case(mem_ref_K):
6950  case(parm_decl_K):
6951  case(string_cst_K):
6952  case(var_decl_K):
6953  {
6954  const size_t byte_parameter_size = AllocatedMemorySize(addr_expr_argument);
6956  "<--Analyzed " + parameter->ToString() + " - Size is " + STR(byte_parameter_size));
6957  return byte_parameter_size;
6958  }
6959  case array_range_ref_K:
6960  case binfo_K:
6961  case block_K:
6962  case call_expr_K:
6963  case aggr_init_expr_K:
6964  case case_label_expr_K:
6965  case complex_cst_K:
6966  case constructor_K:
6967  case identifier_node_K:
6968  case integer_cst_K:
6969  case real_cst_K:
6970  case ssa_name_K:
6971  case statement_list_K:
6972  case target_expr_K:
6973  case target_mem_ref_K:
6974  case target_mem_ref461_K:
6975  case tree_list_K:
6976  case tree_vec_K:
6977  case vector_cst_K:
6978  case void_cst_K:
6979  case const_decl_K:
6980  case field_decl_K:
6981  case function_decl_K:
6982  case label_decl_K:
6983  case namespace_decl_K:
6984  case result_decl_K:
6985  case translation_unit_decl_K:
6986  case template_decl_K:
6987  case using_decl_K:
6988  case type_decl_K:
6989  case bit_field_ref_K:
6990  case vtable_ref_K:
6991  case with_cleanup_expr_K:
6992  case obj_type_ref_K:
6993  case save_expr_K:
6994  case cond_expr_K:
6995  case dot_prod_expr_K:
6996  case ternary_plus_expr_K:
6997  case ternary_pm_expr_K:
6998  case ternary_mp_expr_K:
6999  case ternary_mm_expr_K:
7000  case fshl_expr_K:
7001  case fshr_expr_K:
7002  case bit_ior_concat_expr_K:
7003  case assert_expr_K:
7004  case bit_and_expr_K:
7005  case bit_ior_expr_K:
7006  case bit_xor_expr_K:
7007  case catch_expr_K:
7008  case ceil_div_expr_K:
7009  case ceil_mod_expr_K:
7010  case complex_expr_K:
7011  case compound_expr_K:
7012  case eh_filter_expr_K:
7013  case eq_expr_K:
7014  case exact_div_expr_K:
7015  case fdesc_expr_K:
7016  case floor_div_expr_K:
7017  case floor_mod_expr_K:
7018  case ge_expr_K:
7019  case gt_expr_K:
7020  case goto_subroutine_K:
7021  case in_expr_K:
7022  case init_expr_K:
7023  case le_expr_K:
7024  case lrotate_expr_K:
7025  case lshift_expr_K:
7026  case lt_expr_K:
7027  case lut_expr_K:
7028  case max_expr_K:
7029  case min_expr_K:
7030  case minus_expr_K:
7031  case modify_expr_K:
7032  case mult_expr_K:
7033  case mult_highpart_expr_K:
7034  case ne_expr_K:
7035  case ordered_expr_K:
7036  case plus_expr_K:
7037  case pointer_plus_expr_K:
7038  case postdecrement_expr_K:
7039  case postincrement_expr_K:
7040  case predecrement_expr_K:
7041  case preincrement_expr_K:
7042  case range_expr_K:
7043  case rdiv_expr_K:
7044  case round_div_expr_K:
7045  case round_mod_expr_K:
7046  case rrotate_expr_K:
7047  case rshift_expr_K:
7048  case set_le_expr_K:
7049  case trunc_div_expr_K:
7050  case trunc_mod_expr_K:
7051  case truth_and_expr_K:
7052  case truth_andif_expr_K:
7053  case truth_or_expr_K:
7054  case truth_orif_expr_K:
7055  case truth_xor_expr_K:
7056  case try_catch_expr_K:
7057  case try_finally_K:
7058  case uneq_expr_K:
7059  case ltgt_expr_K:
7060  case unge_expr_K:
7061  case ungt_expr_K:
7062  case unle_expr_K:
7063  case unlt_expr_K:
7064  case unordered_expr_K:
7065  case widen_sum_expr_K:
7066  case widen_mult_expr_K:
7067  case with_size_expr_K:
7068  case vec_lshift_expr_K:
7069  case vec_rshift_expr_K:
7070  case widen_mult_hi_expr_K:
7071  case widen_mult_lo_expr_K:
7072  case vec_cond_expr_K:
7073  case vec_pack_trunc_expr_K:
7074  case vec_pack_sat_expr_K:
7075  case vec_pack_fix_trunc_expr_K:
7076  case vec_perm_expr_K:
7077  case vec_extracteven_expr_K:
7078  case vec_extractodd_expr_K:
7079  case vec_interleavehigh_expr_K:
7080  case vec_interleavelow_expr_K:
7081  case error_mark_K:
7082  case extract_bit_expr_K:
7083  case sat_plus_expr_K:
7084  case sat_minus_expr_K:
7085  case extractvalue_expr_K:
7086  case insertvalue_expr_K:
7087  case extractelement_expr_K:
7088  case insertelement_expr_K:
7089  case frem_expr_K:
7090  case CASE_CPP_NODES:
7091  case CASE_FAKE_NODES:
7092  case CASE_GIMPLE_NODES:
7093  case CASE_PRAGMA_NODES:
7094  case CASE_TYPE_NODES:
7095  case CASE_UNARY_EXPRESSION:
7096  default:
7097  {
7098  THROW_UNREACHABLE("Unsupported addr_expr argument " + addr_expr_argument->get_kind_text());
7099  }
7100  }
7101  break;
7102  }
7103  case(array_type_K):
7104  {
7105  const auto at = GetPointer<const array_type>(parameter);
7107  AllocatedMemorySize(GET_NODE(at->elts));
7108  const size_t bit_parameter_size = Size(parameter);
7110  const size_t byte_parameter_size = bit_parameter_size / 8;
7112  "<--Analyzed " + parameter->ToString() + " - Size is " + STR(byte_parameter_size));
7113  return byte_parameter_size;
7114  }
7115  case(record_type_K):
7116  {
7117  size_t fields_pointed_size = 0;
7118  const auto rt = GetPointer<const record_type>(parameter);
7119  const std::vector<tree_nodeRef>& list_of_fields = rt->list_of_flds;
7121  std::vector<tree_nodeRef>::const_iterator field, field_end = list_of_fields.end();
7122  for(field = list_of_fields.begin(); field != field_end; ++field)
7123  {
7124  if(GET_NODE(*field)->get_kind() == type_decl_K)
7125  {
7126  continue;
7127  }
7128  if(GET_NODE(*field)->get_kind() == function_decl_K)
7129  {
7130  continue;
7131  }
7132  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Analyzing field " + (*field)->ToString());
7133  AllocatedMemorySize(CGetType(*field));
7134  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Analyzed field " + (*field)->ToString());
7135  }
7136  const size_t bit_parameter_size = Size(parameter) + fields_pointed_size;
7138  const size_t byte_parameter_size = bit_parameter_size / 8;
7140  "<--Analyzed " + parameter->ToString() + " - Size is " + STR(byte_parameter_size));
7141  return byte_parameter_size;
7142  }
7143  case(component_ref_K):
7144  {
7145  const auto cr = GetPointer<const component_ref>(parameter);
7146  if(GetPointer<const union_type>(GET_CONST_NODE(CGetType(cr->op0))))
7147  {
7148  THROW_ERROR("Offloading fields of union is not supported");
7149  }
7150  const size_t byte_parameter_size = AllocatedMemorySize(GET_NODE(cr->op1));
7152  "<--Analyzed " + parameter->ToString() + " - Size is " + STR(byte_parameter_size));
7153  return byte_parameter_size;
7154  }
7155  case(field_decl_K):
7156  {
7157  const size_t byte_parameter_size = AllocatedMemorySize(CGetType(parameter));
7159  "<--Analyzed " + parameter->ToString() + " - Size is " + STR(byte_parameter_size));
7160  return byte_parameter_size;
7161  }
7162  case(enumeral_type_K):
7163  case(integer_type_K):
7164  case(real_type_K):
7165  case(string_cst_K):
7166  {
7167  const size_t bit_parameter_size = Size(parameter);
7169  const size_t byte_parameter_size = bit_parameter_size / 8;
7171  "<--Analyzed " + parameter->ToString() + " - Size is " + STR(byte_parameter_size));
7172  return byte_parameter_size;
7173  }
7174  case(mem_ref_K):
7175  {
7176  const auto mr = GetPointer<const mem_ref>(parameter);
7177  const size_t byte_parameter_size = AllocatedMemorySize(GET_NODE(mr->op0));
7179  "<--Analyzed " + parameter->ToString() + " - Size is " + STR(byte_parameter_size));
7180  return byte_parameter_size;
7181  }
7182  case(parm_decl_K):
7183  case(ssa_name_K):
7184  case(var_decl_K):
7185  {
7186  const auto sn = GetPointer<const ssa_name>(parameter);
7187  if(sn && (GET_NODE(sn->var)->get_kind() == parm_decl_K) && sn->CGetDefStmts().empty())
7188  {
7189  return AllocatedMemorySize(GET_NODE(sn->var));
7190  }
7191 
7192  const auto ptype = CGetType(parameter);
7193  const auto byte_parameter_size = AllocatedMemorySize(IsPointerType(ptype) ? CGetPointedType(ptype) : ptype);
7195  "<--Analyzed " + parameter->ToString() + " - Size is " + STR(byte_parameter_size));
7196  return byte_parameter_size;
7197  }
7198  case binfo_K:
7199  case bit_field_ref_K:
7200  case block_K:
7201  case boolean_type_K:
7202  case call_expr_K:
7203  case aggr_init_expr_K:
7204  case case_label_expr_K:
7205  case CharType_K:
7206  case nullptr_type_K:
7207  case type_pack_expansion_K:
7208  case complex_cst_K:
7209  case complex_type_K:
7210  case cond_expr_K:
7211  case const_decl_K:
7212  case constructor_K:
7213  case dot_prod_expr_K:
7214  case ternary_plus_expr_K:
7215  case ternary_pm_expr_K:
7216  case ternary_mp_expr_K:
7217  case ternary_mm_expr_K:
7218  case fshl_expr_K:
7219  case fshr_expr_K:
7220  case bit_ior_concat_expr_K:
7221  case function_decl_K:
7222  case identifier_node_K:
7223  case integer_cst_K:
7224  case label_decl_K:
7225  case lang_type_K:
7226  case method_type_K:
7227  case namespace_decl_K:
7228  case obj_type_ref_K:
7229  case offset_type_K:
7230  case paren_expr_K:
7231  case pointer_type_K:
7232  case qual_union_type_K:
7233  case real_cst_K:
7234  case result_decl_K:
7235  case save_expr_K:
7236  case set_type_K:
7237  case statement_list_K:
7238  case target_expr_K:
7239  case target_mem_ref_K:
7240  case target_mem_ref461_K:
7241  case template_type_parm_K:
7242  case type_argument_pack_K:
7243  case translation_unit_decl_K:
7244  case template_decl_K:
7245  case using_decl_K:
7246  case tree_list_K:
7247  case tree_vec_K:
7248  case type_decl_K:
7249  case typename_type_K:
7250  case union_type_K:
7251  case vector_cst_K:
7252  case void_cst_K:
7253  case void_type_K:
7254  case vtable_ref_K:
7255  case with_cleanup_expr_K:
7256  case function_type_K:
7257  case reference_type_K:
7258  case vector_type_K:
7259  case abs_expr_K:
7260  case alignof_expr_K:
7261  case arrow_expr_K:
7262  case bit_not_expr_K:
7263  case buffer_ref_K:
7264  case card_expr_K:
7265  case cleanup_point_expr_K:
7266  case conj_expr_K:
7267  case convert_expr_K:
7268  case exit_expr_K:
7269  case fix_ceil_expr_K:
7270  case fix_floor_expr_K:
7271  case fix_round_expr_K:
7272  case fix_trunc_expr_K:
7273  case float_expr_K:
7274  case imagpart_expr_K:
7275  case indirect_ref_K:
7276  case misaligned_indirect_ref_K:
7277  case loop_expr_K:
7278  case lut_expr_K:
7279  case negate_expr_K:
7280  case non_lvalue_expr_K:
7281  case nop_expr_K:
7282  case realpart_expr_K:
7283  case reference_expr_K:
7284  case reinterpret_cast_expr_K:
7285  case sizeof_expr_K:
7286  case static_cast_expr_K:
7287  case throw_expr_K:
7288  case truth_not_expr_K:
7289  case unsave_expr_K:
7290  case va_arg_expr_K:
7291  case view_convert_expr_K:
7292  case reduc_max_expr_K:
7293  case reduc_min_expr_K:
7294  case reduc_plus_expr_K:
7295  case vec_unpack_hi_expr_K:
7296  case vec_unpack_lo_expr_K:
7297  case vec_unpack_float_hi_expr_K:
7298  case vec_unpack_float_lo_expr_K:
7299  case assert_expr_K:
7300  case bit_and_expr_K:
7301  case bit_ior_expr_K:
7302  case bit_xor_expr_K:
7303  case catch_expr_K:
7304  case ceil_div_expr_K:
7305  case ceil_mod_expr_K:
7306  case complex_expr_K:
7307  case compound_expr_K:
7308  case eh_filter_expr_K:
7309  case eq_expr_K:
7310  case exact_div_expr_K:
7311  case fdesc_expr_K:
7312  case floor_div_expr_K:
7313  case floor_mod_expr_K:
7314  case ge_expr_K:
7315  case gt_expr_K:
7316  case goto_subroutine_K:
7317  case in_expr_K:
7318  case init_expr_K:
7319  case le_expr_K:
7320  case lrotate_expr_K:
7321  case lshift_expr_K:
7322  case lt_expr_K:
7323  case max_expr_K:
7324  case min_expr_K:
7325  case minus_expr_K:
7326  case modify_expr_K:
7327  case mult_expr_K:
7328  case mult_highpart_expr_K:
7329  case ne_expr_K:
7330  case ordered_expr_K:
7331  case plus_expr_K:
7332  case pointer_plus_expr_K:
7333  case postdecrement_expr_K:
7334  case postincrement_expr_K:
7335  case predecrement_expr_K:
7336  case preincrement_expr_K:
7337  case range_expr_K:
7338  case rdiv_expr_K:
7339  case round_div_expr_K:
7340  case round_mod_expr_K:
7341  case rrotate_expr_K:
7342  case rshift_expr_K:
7343  case set_le_expr_K:
7344  case trunc_div_expr_K:
7345  case trunc_mod_expr_K:
7346  case truth_and_expr_K:
7347  case truth_andif_expr_K:
7348  case truth_or_expr_K:
7349  case truth_orif_expr_K:
7350  case truth_xor_expr_K:
7351  case try_catch_expr_K:
7352  case try_finally_K:
7353  case uneq_expr_K:
7354  case ltgt_expr_K:
7355  case unge_expr_K:
7356  case ungt_expr_K:
7357  case unle_expr_K:
7358  case unlt_expr_K:
7359  case unordered_expr_K:
7360  case vec_cond_expr_K:
7361  case vec_perm_expr_K:
7362  case widen_sum_expr_K:
7363  case widen_mult_expr_K:
7364  case with_size_expr_K:
7365  case vec_lshift_expr_K:
7366  case vec_rshift_expr_K:
7367  case widen_mult_hi_expr_K:
7368  case widen_mult_lo_expr_K:
7369  case vec_pack_trunc_expr_K:
7370  case vec_pack_sat_expr_K:
7371  case vec_pack_fix_trunc_expr_K:
7372  case vec_extracteven_expr_K:
7373  case vec_extractodd_expr_K:
7374  case vec_interleavehigh_expr_K:
7375  case vec_interleavelow_expr_K:
7376  case error_mark_K:
7377  case extract_bit_expr_K:
7378  case sat_plus_expr_K:
7379  case sat_minus_expr_K:
7380  case extractvalue_expr_K:
7381  case insertvalue_expr_K:
7382  case extractelement_expr_K:
7383  case insertelement_expr_K:
7384  case frem_expr_K:
7385  case CASE_CPP_NODES:
7386  case CASE_FAKE_NODES:
7387  case CASE_GIMPLE_NODES:
7388  case CASE_PRAGMA_NODES:
7390  default:
7391  {
7392  THROW_UNREACHABLE("Unsupported tree node type " + parameter->get_kind_text() + " (" + parameter->ToString() +
7393  ")");
7394  }
7395  }
7396  return 0;
7397 }
7398 
7400 {
7401  const auto tn = _tn->get_kind() == tree_reindex_K ? GET_CONST_NODE(_tn) : _tn;
7402  size_t counter = 0;
7403  switch(tn->get_kind())
7404  {
7405  case enumeral_type_K:
7406  case integer_type_K:
7407  case real_type_K:
7408  {
7409  return 0;
7410  }
7411  case field_decl_K:
7412  case parm_decl_K:
7413  {
7414  return CountPointers(CGetType(tn));
7415  }
7416  case reference_type_K:
7417  case pointer_type_K:
7418  {
7419  return 1;
7420  }
7421  case record_type_K:
7422  {
7423  const auto rt = GetPointer<const record_type>(tn);
7424  const std::vector<tree_nodeRef> list_of_fields = rt->list_of_flds;
7425  std::vector<tree_nodeRef>::const_iterator field, field_end = list_of_fields.end();
7426  for(field = list_of_fields.begin(); field != field_end; ++field)
7427  {
7428  if(GET_NODE(*field)->get_kind() == type_decl_K)
7429  {
7430  continue;
7431  }
7432  if(GET_NODE(*field)->get_kind() == function_decl_K)
7433  {
7434  continue;
7435  }
7436  counter += CountPointers(GET_NODE(*field));
7437  }
7438  return counter;
7439  }
7440  case binfo_K:
7441  case block_K:
7442  case call_expr_K:
7443  case aggr_init_expr_K:
7444  case case_label_expr_K:
7445  case constructor_K:
7446  case identifier_node_K:
7447  case lang_type_K:
7448  case offset_type_K:
7449  case qual_union_type_K:
7450  case set_type_K:
7451  case ssa_name_K:
7452  case statement_list_K:
7453  case target_mem_ref_K:
7454  case target_mem_ref461_K:
7455  case template_type_parm_K:
7456  case type_argument_pack_K:
7457  case tree_list_K:
7458  case tree_vec_K:
7459  case typename_type_K:
7460  case const_decl_K:
7461  case function_decl_K:
7462  case label_decl_K:
7463  case namespace_decl_K:
7464  case result_decl_K:
7465  case translation_unit_decl_K:
7466  case template_decl_K:
7467  case using_decl_K:
7468  case type_decl_K:
7469  case var_decl_K:
7470  case array_type_K:
7471  case boolean_type_K:
7472  case CharType_K:
7473  case nullptr_type_K:
7474  case type_pack_expansion_K:
7475  case complex_type_K:
7476  case function_type_K:
7477  case method_type_K:
7478  case union_type_K:
7479  case vector_type_K:
7480  case void_type_K:
7481  case target_expr_K:
7482  case error_mark_K:
7483  case lut_expr_K:
7485  case CASE_CPP_NODES:
7486  case CASE_CST_NODES:
7487  case CASE_FAKE_NODES:
7488  case CASE_GIMPLE_NODES:
7489  case CASE_PRAGMA_NODES:
7492  case CASE_UNARY_EXPRESSION:
7493  default:
7494  {
7495  THROW_UNREACHABLE("Unsupported type node " + tn->get_kind_text());
7496  }
7497  }
7498  return counter;
7499 }
7500 
7501 unsigned int tree_helper::get_multi_way_if_pos(const tree_managerConstRef& TM, unsigned int node_id,
7502  unsigned int looked_for_cond)
7503 {
7504  const auto t = TM->CGetTreeNode(node_id);
7505  const auto gmwi = GetPointer<const gimple_multi_way_if>(t);
7506  unsigned int pos = 0;
7507  for(auto const& cond : gmwi->list_of_cond)
7508  {
7509  if(cond.first && cond.first->index == looked_for_cond)
7510  {
7511  return pos;
7512  }
7513  pos++;
7514  }
7515  THROW_ERROR("cond not found in gimple_multi_way_if " + t->ToString() + " looked_for_cond " + STR(looked_for_cond));
7516  return pos;
7517 }
7518 
7521 {
7522  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->compute_ssa_uses_rec_ptr " + curr_tn->ToString());
7523  const auto gn = GetPointer<const gimple_node>(curr_tn);
7524  if(gn)
7525  {
7526  if(gn->memuse)
7527  {
7528  compute_ssa_uses_rec_ptr(gn->memuse, ssa_uses);
7529  }
7530  if(!gn->vuses.empty())
7531  {
7532  for(const auto& vuse : gn->vuses)
7533  {
7534  compute_ssa_uses_rec_ptr(vuse, ssa_uses);
7535  }
7536  }
7537  }
7538  switch(curr_tn->get_kind())
7539  {
7540  case tree_reindex_K:
7541  {
7542  compute_ssa_uses_rec_ptr(GET_CONST_NODE(curr_tn), ssa_uses);
7543  break;
7544  }
7545  case gimple_return_K:
7546  {
7547  const auto re = GetPointer<const gimple_return>(curr_tn);
7548  if(re->op)
7549  {
7550  compute_ssa_uses_rec_ptr(re->op, ssa_uses);
7551  }
7552  break;
7553  }
7554  case gimple_assign_K:
7555  {
7556  const auto me = GetPointer<const gimple_assign>(curr_tn);
7557  if(GET_NODE(me->op0)->get_kind() != ssa_name_K)
7558  {
7559  compute_ssa_uses_rec_ptr(me->op0, ssa_uses);
7560  }
7561  compute_ssa_uses_rec_ptr(me->op1, ssa_uses);
7562  if(me->predicate)
7563  {
7564  compute_ssa_uses_rec_ptr(me->predicate, ssa_uses);
7565  }
7566  break;
7567  }
7568  case gimple_nop_K:
7569  {
7570  break;
7571  }
7572  case call_expr_K:
7573  case aggr_init_expr_K:
7574  {
7575  const auto ce = GetPointer<const call_expr>(curr_tn);
7576  compute_ssa_uses_rec_ptr(ce->fn, ssa_uses);
7577  for(const auto& arg : ce->args)
7578  {
7579  compute_ssa_uses_rec_ptr(arg, ssa_uses);
7580  }
7581  break;
7582  }
7583  case gimple_call_K:
7584  {
7585  const auto ce = GetPointer<const gimple_call>(curr_tn);
7586  compute_ssa_uses_rec_ptr(ce->fn, ssa_uses);
7587  for(const auto& arg : ce->args)
7588  {
7589  compute_ssa_uses_rec_ptr(arg, ssa_uses);
7590  }
7591  break;
7592  }
7593  case gimple_cond_K:
7594  {
7595  const auto gc = GetPointer<const gimple_cond>(curr_tn);
7596  compute_ssa_uses_rec_ptr(gc->op0, ssa_uses);
7597  break;
7598  }
7599  /* Unary expressions. */
7600  case CASE_UNARY_EXPRESSION:
7601  {
7602  const auto ue = GetPointer<const unary_expr>(curr_tn);
7603  compute_ssa_uses_rec_ptr(ue->op, ssa_uses);
7604  break;
7605  }
7607  {
7608  const auto be = GetPointer<const binary_expr>(curr_tn);
7609  compute_ssa_uses_rec_ptr(be->op0, ssa_uses);
7610  compute_ssa_uses_rec_ptr(be->op1, ssa_uses);
7611  break;
7612  }
7613  /*ternary expressions*/
7614  case gimple_switch_K:
7615  {
7616  const auto se = GetPointer<const gimple_switch>(curr_tn);
7617  compute_ssa_uses_rec_ptr(se->op0, ssa_uses);
7618  break;
7619  }
7621  {
7622  const auto te = GetPointer<const ternary_expr>(curr_tn);
7623  compute_ssa_uses_rec_ptr(te->op0, ssa_uses);
7624  compute_ssa_uses_rec_ptr(te->op1, ssa_uses);
7625  if(te->op2)
7626  {
7627  compute_ssa_uses_rec_ptr(te->op2, ssa_uses);
7628  }
7629  break;
7630  }
7632  {
7633  const auto qe = GetPointer<const quaternary_expr>(curr_tn);
7634  compute_ssa_uses_rec_ptr(qe->op0, ssa_uses);
7635  compute_ssa_uses_rec_ptr(qe->op1, ssa_uses);
7636  if(qe->op2)
7637  {
7638  compute_ssa_uses_rec_ptr(qe->op2, ssa_uses);
7639  }
7640  if(qe->op3)
7641  {
7642  compute_ssa_uses_rec_ptr(qe->op3, ssa_uses);
7643  }
7644  break;
7645  }
7646  case lut_expr_K:
7647  {
7648  const auto le = GetPointer<const lut_expr>(curr_tn);
7649  compute_ssa_uses_rec_ptr(le->op0, ssa_uses);
7650  compute_ssa_uses_rec_ptr(le->op1, ssa_uses);
7651  if(le->op2)
7652  {
7653  compute_ssa_uses_rec_ptr(le->op2, ssa_uses);
7654  }
7655  if(le->op3)
7656  {
7657  compute_ssa_uses_rec_ptr(le->op3, ssa_uses);
7658  }
7659  if(le->op4)
7660  {
7661  compute_ssa_uses_rec_ptr(le->op4, ssa_uses);
7662  }
7663  if(le->op5)
7664  {
7665  compute_ssa_uses_rec_ptr(le->op5, ssa_uses);
7666  }
7667  if(le->op6)
7668  {
7669  compute_ssa_uses_rec_ptr(le->op6, ssa_uses);
7670  }
7671  if(le->op7)
7672  {
7673  compute_ssa_uses_rec_ptr(le->op7, ssa_uses);
7674  }
7675  if(le->op8)
7676  {
7677  compute_ssa_uses_rec_ptr(le->op8, ssa_uses);
7678  }
7679  break;
7680  }
7681  case constructor_K:
7682  {
7683  const auto c = GetPointer<const constructor>(curr_tn);
7684  for(const auto& iv : c->list_of_idx_valu)
7685  {
7686  compute_ssa_uses_rec_ptr(iv.second, ssa_uses);
7687  }
7688  break;
7689  }
7690  case var_decl_K:
7691  {
7693  // const auto vd = GetPointer<const var_decl>(curr_tn);
7694  // if(vd->init)
7695  // compute_ssa_uses_rec_ptr(vd->init, ssa_uses);
7696  break;
7697  }
7698  case gimple_asm_K:
7699  {
7700  const auto ae = GetPointer<const gimple_asm>(curr_tn);
7701  // if(ae->out)
7702  // compute_ssa_uses_rec_ptr(ae->out, ssa_uses);
7703  if(ae->in)
7704  {
7705  compute_ssa_uses_rec_ptr(ae->in, ssa_uses);
7706  }
7707  if(ae->clob)
7708  {
7709  compute_ssa_uses_rec_ptr(ae->in, ssa_uses);
7710  }
7711  break;
7712  }
7713  case gimple_goto_K:
7714  {
7715  const auto ge = GetPointer<const gimple_goto>(curr_tn);
7716  compute_ssa_uses_rec_ptr(ge->op, ssa_uses);
7717  break;
7718  }
7719  case tree_list_K:
7720  {
7721  auto tl = GetPointer<const tree_list>(curr_tn);
7722  std::list<const tree_list*> tl_list;
7723  do
7724  {
7725  tl_list.push_back(tl);
7726  tl = tl->chan ? GetPointer<const tree_list>(GET_CONST_NODE(tl->chan)) : nullptr;
7727  } while(tl);
7728  for(const auto& tl_current0 : tl_list)
7729  {
7730  if(tl_current0->purp)
7731  {
7732  compute_ssa_uses_rec_ptr(tl_current0->purp, ssa_uses);
7733  }
7734  if(tl_current0->valu)
7735  {
7736  compute_ssa_uses_rec_ptr(tl_current0->valu, ssa_uses);
7737  }
7738  }
7739  break;
7740  }
7741  case gimple_multi_way_if_K:
7742  {
7743  const auto gmwi = GetPointer<const gimple_multi_way_if>(curr_tn);
7744  for(const auto& cond : gmwi->list_of_cond)
7745  {
7746  if(cond.first)
7747  {
7748  compute_ssa_uses_rec_ptr(cond.first, ssa_uses);
7749  }
7750  }
7751  break;
7752  }
7753  case gimple_phi_K:
7754  case result_decl_K:
7755  case parm_decl_K:
7756  case function_decl_K:
7757  case integer_cst_K:
7758  case real_cst_K:
7759  case string_cst_K:
7760  case vector_cst_K:
7761  case void_cst_K:
7762  case complex_cst_K:
7763  case field_decl_K:
7764  case label_decl_K:
7765  case gimple_label_K:
7766  case CASE_PRAGMA_NODES:
7767  {
7768  break;
7769  }
7770  case target_mem_ref_K:
7771  {
7772  const auto tmr = GetPointer<const target_mem_ref>(curr_tn);
7773  if(tmr->base)
7774  {
7775  compute_ssa_uses_rec_ptr(tmr->base, ssa_uses);
7776  }
7777  if(tmr->symbol)
7778  {
7779  compute_ssa_uses_rec_ptr(tmr->symbol, ssa_uses);
7780  }
7781  if(tmr->idx)
7782  {
7783  compute_ssa_uses_rec_ptr(tmr->idx, ssa_uses);
7784  }
7786  break;
7787  }
7788  case target_mem_ref461_K:
7789  {
7790  const auto tmr = GetPointer<const target_mem_ref461>(curr_tn);
7791  if(tmr->base)
7792  {
7793  compute_ssa_uses_rec_ptr(tmr->base, ssa_uses);
7794  }
7795  if(tmr->idx)
7796  {
7797  compute_ssa_uses_rec_ptr(tmr->idx, ssa_uses);
7798  }
7799  if(tmr->idx2)
7800  {
7801  compute_ssa_uses_rec_ptr(tmr->idx2, ssa_uses);
7802  }
7804  break;
7805  }
7806  case ssa_name_K:
7807  {
7808  ssa_uses.insert(GetPointer<const ssa_name>(curr_tn));
7809  break;
7810  }
7811  case binfo_K:
7812  case block_K:
7813  case case_label_expr_K:
7814  case CASE_CPP_NODES:
7815  case const_decl_K:
7816  case last_tree_K:
7817  case none_K:
7818  case placeholder_expr_K:
7819  case gimple_for_K:
7820  case gimple_bind_K:
7821  case gimple_predict_K:
7822  case gimple_resx_K:
7823  case gimple_pragma_K:
7824  case identifier_node_K:
7825  case namespace_decl_K:
7826  case statement_list_K:
7827  case target_expr_K:
7828  case translation_unit_decl_K:
7829  case using_decl_K:
7830  case tree_vec_K:
7831  case type_decl_K:
7832  case CASE_TYPE_NODES:
7833  case error_mark_K:
7834  case gimple_while_K:
7835  case template_decl_K:
7836  {
7837  THROW_UNREACHABLE("Node is " + curr_tn->get_kind_text());
7838  break;
7839  }
7840  default:
7841  {
7842  THROW_UNREACHABLE("");
7843  }
7844  }
7845  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--computed_ssa_uses_rec_ptr " + curr_tn->ToString());
7846 }
7847 
7849 {
7850  TreeNodeMap<size_t> ret_value;
7851  ComputeSsaUses(tn, ret_value);
7852  return ret_value;
7853 }
7854 
7856 {
7857  THROW_ASSERT(tn->get_kind() == tree_reindex_K, "Node is not a tree reindex");
7858  const auto curr_tn = GET_NODE(tn);
7860  "-->Computing ssa uses in " + curr_tn->ToString() + " (" + curr_tn->get_kind_text() + ")");
7861  const auto gn = GetPointer<const gimple_node>(curr_tn);
7862  if(gn)
7863  {
7864  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Computing virtual ssa uses");
7865  if(gn->memuse)
7866  {
7867  ComputeSsaUses(gn->memuse, ssa_uses);
7868  }
7869  for(const auto& vuse : gn->vuses)
7870  {
7871  ComputeSsaUses(vuse, ssa_uses);
7872  }
7873  for(const auto& vover : gn->vovers)
7874  {
7875  ComputeSsaUses(vover, ssa_uses);
7876  }
7877  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Computed virtual ssa uses");
7878  }
7879 
7880  switch(curr_tn->get_kind())
7881  {
7882  case gimple_return_K:
7883  {
7884  const auto re = GetPointerS<gimple_return>(curr_tn);
7885  if(re->op)
7886  {
7887  ComputeSsaUses(re->op, ssa_uses);
7888  }
7889  break;
7890  }
7891  case gimple_assign_K:
7892  {
7893  const auto me = GetPointerS<gimple_assign>(curr_tn);
7894  if(GET_NODE(me->op0)->get_kind() != ssa_name_K)
7895  {
7896  ComputeSsaUses(me->op0, ssa_uses);
7897  }
7898  ComputeSsaUses(me->op1, ssa_uses);
7899  if(me->predicate)
7900  {
7901  ComputeSsaUses(me->predicate, ssa_uses);
7902  }
7903  break;
7904  }
7905  case gimple_nop_K:
7906  {
7907  break;
7908  }
7909  case call_expr_K:
7910  case aggr_init_expr_K:
7911  {
7912  const auto ce = GetPointerS<call_expr>(curr_tn);
7913  ComputeSsaUses(ce->fn, ssa_uses);
7914  for(const auto& arg : ce->args)
7915  {
7916  ComputeSsaUses(arg, ssa_uses);
7917  }
7918  break;
7919  }
7920  case gimple_call_K:
7921  {
7922  const auto ce = GetPointerS<gimple_call>(curr_tn);
7923  ComputeSsaUses(ce->fn, ssa_uses);
7924  for(const auto& arg : ce->args)
7925  {
7926  ComputeSsaUses(arg, ssa_uses);
7927  }
7928  break;
7929  }
7930  case gimple_cond_K:
7931  {
7932  const auto gc = GetPointerS<gimple_cond>(curr_tn);
7933  ComputeSsaUses(gc->op0, ssa_uses);
7934  break;
7935  }
7936  /* Unary expressions. */
7937  case CASE_UNARY_EXPRESSION:
7938  {
7939  const auto ue = GetPointerS<unary_expr>(curr_tn);
7940  if(GET_NODE(ue->op)->get_kind() != function_decl_K)
7941  {
7942  ComputeSsaUses(ue->op, ssa_uses);
7943  }
7944  break;
7945  }
7947  {
7948  const auto be = GetPointerS<binary_expr>(curr_tn);
7949  ComputeSsaUses(be->op0, ssa_uses);
7950  ComputeSsaUses(be->op1, ssa_uses);
7951  break;
7952  }
7953  /*ternary expressions*/
7954  case gimple_switch_K:
7955  {
7956  const auto se = GetPointerS<gimple_switch>(curr_tn);
7957  ComputeSsaUses(se->op0, ssa_uses);
7958  break;
7959  }
7961  {
7962  const auto te = GetPointerS<ternary_expr>(curr_tn);
7963  ComputeSsaUses(te->op0, ssa_uses);
7964  ComputeSsaUses(te->op1, ssa_uses);
7965  if(te->op2)
7966  {
7967  ComputeSsaUses(te->op2, ssa_uses);
7968  }
7969  break;
7970  }
7972  {
7973  const auto qe = GetPointerS<quaternary_expr>(curr_tn);
7974  ComputeSsaUses(qe->op0, ssa_uses);
7975  ComputeSsaUses(qe->op1, ssa_uses);
7976  if(qe->op2)
7977  {
7978  ComputeSsaUses(qe->op2, ssa_uses);
7979  }
7980  if(qe->op3)
7981  {
7982  ComputeSsaUses(qe->op3, ssa_uses);
7983  }
7984  break;
7985  }
7986  case lut_expr_K:
7987  {
7988  const auto le = GetPointerS<lut_expr>(curr_tn);
7989  ComputeSsaUses(le->op0, ssa_uses);
7990  ComputeSsaUses(le->op1, ssa_uses);
7991  if(le->op2)
7992  {
7993  ComputeSsaUses(le->op2, ssa_uses);
7994  }
7995  if(le->op3)
7996  {
7997  ComputeSsaUses(le->op3, ssa_uses);
7998  }
7999  if(le->op4)
8000  {
8001  ComputeSsaUses(le->op4, ssa_uses);
8002  }
8003  if(le->op5)
8004  {
8005  ComputeSsaUses(le->op5, ssa_uses);
8006  }
8007  if(le->op6)
8008  {
8009  ComputeSsaUses(le->op6, ssa_uses);
8010  }
8011  if(le->op7)
8012  {
8013  ComputeSsaUses(le->op7, ssa_uses);
8014  }
8015  if(le->op8)
8016  {
8017  ComputeSsaUses(le->op8, ssa_uses);
8018  }
8019  break;
8020  }
8021  case constructor_K:
8022  {
8023  const auto c = GetPointerS<constructor>(curr_tn);
8024  for(const auto& iv : c->list_of_idx_valu)
8025  {
8026  ComputeSsaUses(iv.second, ssa_uses);
8027  }
8028  break;
8029  }
8030  case var_decl_K:
8031  {
8033  // const auto vd = GetPointerS<var_decl>(curr_tn);
8034  // if(vd->init)
8035  // {
8036  // ComputeSsaUses(vd->init, ssa_uses);
8037  // }
8038  break;
8039  }
8040  case gimple_asm_K:
8041  {
8042  const auto ae = GetPointerS<gimple_asm>(curr_tn);
8043  if(ae->out)
8044  {
8045  ComputeSsaUses(ae->out, ssa_uses);
8046  }
8047  if(ae->in)
8048  {
8049  ComputeSsaUses(ae->in, ssa_uses);
8050  }
8051  if(ae->clob)
8052  {
8053  ComputeSsaUses(ae->clob, ssa_uses);
8054  }
8055  break;
8056  }
8057  case gimple_goto_K:
8058  {
8059  const auto ge = GetPointerS<gimple_goto>(curr_tn);
8060  ComputeSsaUses(ge->op, ssa_uses);
8061  break;
8062  }
8063  case tree_list_K:
8064  {
8065  auto tl = GetPointerS<const tree_list>(curr_tn);
8066  std::list<const tree_list*> tl_list;
8067  do
8068  {
8069  tl_list.push_back(tl);
8070  tl = tl->chan ? GetPointerS<const tree_list>(GET_CONST_NODE(tl->chan)) : nullptr;
8071  } while(tl);
8072  for(const auto tl_current0 : tl_list)
8073  {
8074  if(tl_current0->purp)
8075  {
8076  ComputeSsaUses(tl_current0->purp, ssa_uses);
8077  }
8078  if(tl_current0->valu)
8079  {
8080  ComputeSsaUses(tl_current0->valu, ssa_uses);
8081  }
8082  }
8083  break;
8084  }
8085  case gimple_multi_way_if_K:
8086  {
8087  const auto gmwi = GetPointerS<gimple_multi_way_if>(curr_tn);
8088  for(const auto& cond : gmwi->list_of_cond)
8089  {
8090  if(cond.first)
8091  {
8092  ComputeSsaUses(cond.first, ssa_uses);
8093  }
8094  }
8095  break;
8096  }
8097  case gimple_phi_K:
8098  {
8099  const auto gp = GetPointerS<gimple_phi>(curr_tn);
8100  for(const auto& def_edge : gp->CGetDefEdgesList())
8101  {
8102  ComputeSsaUses(def_edge.first, ssa_uses);
8103  }
8104  break;
8105  }
8106  case result_decl_K:
8107  case parm_decl_K:
8108  case function_decl_K:
8109  case integer_cst_K:
8110  case real_cst_K:
8111  case string_cst_K:
8112  case vector_cst_K:
8113  case void_cst_K:
8114  case complex_cst_K:
8115  case field_decl_K:
8116  case label_decl_K:
8117  case gimple_label_K:
8118  case CASE_PRAGMA_NODES:
8119  {
8120  break;
8121  }
8122  case target_mem_ref_K:
8123  {
8124  const auto tmr = GetPointerS<target_mem_ref>(curr_tn);
8125  if(tmr->base)
8126  {
8127  ComputeSsaUses(tmr->base, ssa_uses);
8128  }
8129  if(tmr->symbol)
8130  {
8131  ComputeSsaUses(tmr->symbol, ssa_uses);
8132  }
8133  if(tmr->idx)
8134  {
8135  ComputeSsaUses(tmr->idx, ssa_uses);
8136  }
8138  break;
8139  }
8140  case target_mem_ref461_K:
8141  {
8142  const auto tmr = GetPointerS<target_mem_ref461>(curr_tn);
8143  if(tmr->base)
8144  {
8145  ComputeSsaUses(tmr->base, ssa_uses);
8146  }
8147  if(tmr->idx)
8148  {
8149  ComputeSsaUses(tmr->idx, ssa_uses);
8150  }
8151  if(tmr->idx2)
8152  {
8153  ComputeSsaUses(tmr->idx2, ssa_uses);
8154  }
8156  break;
8157  }
8158  case ssa_name_K:
8159  {
8160  ssa_uses[tn]++;
8161  break;
8162  }
8163  case gimple_pragma_K:
8164  {
8165  break;
8166  }
8167  case binfo_K:
8168  case block_K:
8169  case case_label_expr_K:
8170  case CASE_CPP_NODES:
8171  case const_decl_K:
8172  case CASE_FAKE_NODES:
8173  case gimple_for_K:
8174  case gimple_predict_K:
8175  case gimple_resx_K:
8176  case gimple_bind_K:
8177  case identifier_node_K:
8178  case namespace_decl_K:
8179  case statement_list_K:
8180  case target_expr_K:
8181  case translation_unit_decl_K:
8182  case template_decl_K:
8183  case using_decl_K:
8184  case tree_vec_K:
8185  case type_decl_K:
8186  case CASE_TYPE_NODES:
8187  case gimple_while_K:
8188  case error_mark_K:
8189  {
8190  THROW_UNREACHABLE("Node is " + curr_tn->get_kind_text());
8191  break;
8192  }
8193  default:
8194  {
8195  THROW_UNREACHABLE("");
8196  }
8197  }
8198  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Computed ssa uses in @" + STR(GET_INDEX_CONST_NODE(tn)));
8199 }
8200 
8202 {
8203  if(fd->body)
8204  {
8205  const auto sl = GetPointerS<const statement_list>(GET_CONST_NODE(fd->body));
8206  if(!sl->list_of_stmt.empty())
8207  {
8208  return false;
8209  }
8210  else if(!sl->list_of_bloc.empty())
8211  {
8212  auto bb_number = sl->list_of_bloc.size();
8213  if(sl->list_of_bloc.count(bloc::ENTRY_BLOCK_ID))
8214  {
8215  --bb_number;
8216  }
8217  if(sl->list_of_bloc.count(bloc::EXIT_BLOCK_ID))
8218  {
8219  --bb_number;
8220  }
8221  if(bb_number > 1)
8222  {
8223  return false;
8224  }
8225  if(bb_number == 0)
8226  {
8227  return true;
8228  }
8229  blocRef single_bb;
8230  for(const auto& lob_it : sl->list_of_bloc)
8231  {
8232  if(lob_it.first != bloc::ENTRY_BLOCK_ID && lob_it.first != bloc::EXIT_BLOCK_ID)
8233  {
8234  single_bb = lob_it.second;
8235  }
8236  }
8237  THROW_ASSERT(single_bb, "unexpected condition");
8238  if(!single_bb->CGetStmtList().empty())
8239  {
8240  const auto stmt_number = single_bb->CGetStmtList().size();
8241  if(stmt_number > 1)
8242  {
8243  return false;
8244  }
8245  const auto& single_stmt = single_bb->CGetStmtList().front();
8246  const auto gr = GetPointer<const gimple_return>(GET_CONST_NODE(single_stmt));
8247  if(gr)
8248  {
8249  return !gr->op;
8250  }
8251  else
8252  {
8253  return false;
8254  }
8255  }
8256  else
8257  {
8258  return true;
8259  }
8260  }
8261  else
8262  {
8263  return true;
8264  }
8265  }
8266  else
8267  {
8268  return false;
8269  }
8270 }
8271 
8272 void tree_helper::get_required_values(std::vector<std::tuple<unsigned int, unsigned int>>& required,
8273  const tree_nodeRef& _tn)
8274 {
8275  const auto tn = _tn->get_kind() == tree_reindex_K ? GET_NODE(_tn) : _tn;
8276  auto tn_kind = tn->get_kind();
8277  switch(tn_kind)
8278  {
8279  case constructor_K:
8280  {
8281  const auto co = GetPointerS<const constructor>(tn);
8282  if(IsVectorType(co->type))
8283  {
8284  for(const auto& iv : co->list_of_idx_valu)
8285  {
8286  required.emplace_back(GET_INDEX_CONST_NODE(iv.second), 0);
8287  }
8288  }
8289  else
8290  {
8291  required.emplace_back(tn->index, 0);
8292  }
8293  break;
8294  }
8295  case ssa_name_K:
8296  case string_cst_K:
8297  case real_cst_K:
8298  case integer_cst_K:
8299  case vector_cst_K:
8300  case void_cst_K:
8301  case complex_cst_K:
8302  case var_decl_K:
8303  case parm_decl_K:
8304  case result_decl_K:
8305  {
8306  required.emplace_back(tn->index, 0);
8307  break;
8308  }
8309  case gimple_while_K:
8310  {
8311  const auto we = GetPointerS<const gimple_while>(tn);
8312  get_required_values(required, we->op0);
8313  break;
8314  }
8316  {
8317  const auto be = GetPointerS<const binary_expr>(tn);
8318  get_required_values(required, be->op0);
8319  if(tn->get_kind() != assert_expr_K)
8320  {
8321  get_required_values(required, be->op1);
8322  }
8323  break;
8324  }
8325  case CASE_UNARY_EXPRESSION:
8326  {
8327  const auto ue = GetPointerS<const unary_expr>(tn);
8328  if(tn->get_kind() == addr_expr_K /*|| tn->get_kind() == imagpart_expr_K || tn->get_kind() == realpart_expr_K*/)
8329  {
8330  required.emplace_back(tn->index, 0);
8331  }
8332  else
8333  {
8334  get_required_values(required, ue->op);
8335  }
8336  break;
8337  }
8339  {
8340  if(tn_kind == component_ref_K)
8341  {
8342  const auto cr = GetPointerS<const component_ref>(tn);
8343  required.emplace_back(GET_INDEX_CONST_NODE(cr->op0), 0);
8344  get_required_values(required, cr->op1);
8345  }
8346  else if(tn_kind == bit_field_ref_K)
8347  {
8348  const auto te = GetPointerS<const ternary_expr>(tn);
8349  required.emplace_back(GET_INDEX_CONST_NODE(te->op0), 0);
8350  get_required_values(required, te->op1);
8351  get_required_values(required, te->op2);
8352  }
8353  else if(tn_kind == obj_type_ref_K || tn_kind == save_expr_K || tn_kind == vtable_ref_K ||
8354  tn_kind == with_cleanup_expr_K)
8355  {
8356  THROW_ERROR("Operation not yet supported: " + std::string(tn->get_kind_text()));
8357  }
8358  else
8359  {
8360  const auto te = GetPointerS<const ternary_expr>(tn);
8361  get_required_values(required, te->op0);
8362  get_required_values(required, te->op1);
8363  get_required_values(required, te->op2);
8364  }
8365  break;
8366  }
8367  case lut_expr_K:
8368  {
8369  const auto le = GetPointerS<const lut_expr>(tn);
8370  get_required_values(required, le->op0);
8371  get_required_values(required, le->op1);
8372  if(le->op2)
8373  {
8374  get_required_values(required, le->op2);
8375  }
8376  if(le->op3)
8377  {
8378  get_required_values(required, le->op3);
8379  }
8380  if(le->op4)
8381  {
8382  get_required_values(required, le->op4);
8383  }
8384  if(le->op5)
8385  {
8386  get_required_values(required, le->op5);
8387  }
8388  if(le->op6)
8389  {
8390  get_required_values(required, le->op6);
8391  }
8392  if(le->op7)
8393  {
8394  get_required_values(required, le->op7);
8395  }
8396  if(le->op8)
8397  {
8398  get_required_values(required, le->op8);
8399  }
8400  break;
8401  }
8402  case gimple_cond_K:
8403  {
8404  const auto gc = GetPointerS<const gimple_cond>(tn);
8405  get_required_values(required, gc->op0);
8406  break;
8407  }
8408  case gimple_switch_K:
8409  {
8410  const auto se = GetPointerS<const gimple_switch>(tn);
8411  get_required_values(required, se->op0);
8412  break;
8413  }
8414  case gimple_multi_way_if_K:
8415  {
8416  const auto gmwi = GetPointerS<const gimple_multi_way_if>(tn);
8417  for(const auto& cond : gmwi->list_of_cond)
8418  {
8419  if(cond.first)
8420  {
8421  get_required_values(required, cond.first);
8422  }
8423  }
8424  break;
8425  }
8426  case array_ref_K:
8427  {
8428  const auto ar = GetPointerS<const array_ref>(tn);
8429  required.emplace_back(GET_INDEX_CONST_NODE(ar->op0), 0);
8430  get_required_values(required, ar->op1);
8431  break;
8432  }
8433  case target_mem_ref_K:
8434  {
8435  const auto tmr = GetPointerS<const target_mem_ref>(tn);
8436  if(tmr->symbol)
8437  {
8438  required.emplace_back(GET_INDEX_CONST_NODE(tmr->symbol), 0);
8439  }
8440  else
8441  {
8442  required.emplace_back(0, 0);
8443  }
8444  if(tmr->base)
8445  {
8446  required.emplace_back(GET_INDEX_CONST_NODE(tmr->base), 0);
8447  }
8448  else
8449  {
8450  required.emplace_back(0, 0);
8451  }
8452  if(tmr->idx)
8453  {
8454  required.emplace_back(GET_INDEX_CONST_NODE(tmr->idx), 0);
8455  }
8456  else
8457  {
8458  required.emplace_back(0, 0);
8459  }
8460  if(tmr->step)
8461  {
8462  required.emplace_back(GET_INDEX_CONST_NODE(tmr->step), 0);
8463  }
8464  else
8465  {
8466  required.emplace_back(0, 0);
8467  }
8468  if(tmr->offset)
8469  {
8470  required.emplace_back(GET_INDEX_CONST_NODE(tmr->offset), 0);
8471  }
8472  else
8473  {
8474  required.emplace_back(0, 0);
8475  }
8476  break;
8477  }
8478  case target_mem_ref461_K:
8479  {
8480  const auto tmr = GetPointerS<const target_mem_ref461>(tn);
8481  if(tmr->base)
8482  {
8483  required.emplace_back(GET_INDEX_CONST_NODE(tmr->base), 0);
8484  }
8485  else
8486  {
8487  required.emplace_back(0, 0);
8488  }
8489  if(tmr->idx)
8490  {
8491  required.emplace_back(GET_INDEX_CONST_NODE(tmr->idx), 0);
8492  }
8493  else
8494  {
8495  required.emplace_back(0, 0);
8496  }
8497  if(tmr->step)
8498  {
8499  required.emplace_back(GET_INDEX_CONST_NODE(tmr->step), 0);
8500  }
8501  else
8502  {
8503  required.emplace_back(0, 0);
8504  }
8505  if(tmr->idx2)
8506  {
8507  required.emplace_back(GET_INDEX_CONST_NODE(tmr->idx2), 0);
8508  }
8509  else
8510  {
8511  required.emplace_back(0, 0);
8512  }
8513  if(tmr->offset)
8514  {
8515  required.emplace_back(GET_INDEX_CONST_NODE(tmr->offset), 0);
8516  }
8517  else
8518  {
8519  required.emplace_back(0, 0);
8520  }
8521  break;
8522  }
8523  case gimple_assign_K:
8524  {
8525  const auto gm = GetPointerS<const gimple_assign>(tn);
8526  if(!gm->init_assignment && !gm->clobber)
8527  {
8528  const auto op0_kind = GET_CONST_NODE(gm->op0)->get_kind();
8529  const auto op1_kind = GET_CONST_NODE(gm->op1)->get_kind();
8530 
8531  if(op0_kind == component_ref_K || op0_kind == indirect_ref_K || op0_kind == misaligned_indirect_ref_K ||
8532  op0_kind == mem_ref_K || op0_kind == array_ref_K || op0_kind == target_mem_ref_K ||
8533  op0_kind == target_mem_ref461_K || op0_kind == bit_field_ref_K)
8534  {
8535  get_required_values(required, gm->op1);
8536  get_required_values(required, gm->op0);
8537  }
8538  else
8539  {
8540  bool is_a_vector_bitfield = false;
8541  if(op1_kind == bit_field_ref_K)
8542  {
8543  const auto bfr = GetPointerS<const bit_field_ref>(GET_CONST_NODE(gm->op1));
8544  if(IsVectorType(bfr->op0))
8545  {
8546  is_a_vector_bitfield = true;
8547  }
8548  }
8549  if(op1_kind == component_ref_K || op1_kind == indirect_ref_K || op1_kind == misaligned_indirect_ref_K ||
8550  op1_kind == mem_ref_K || op1_kind == array_ref_K || op1_kind == target_mem_ref_K ||
8551  op1_kind == target_mem_ref461_K || (op1_kind == bit_field_ref_K && !is_a_vector_bitfield))
8552  {
8553  required.emplace_back(0, 0);
8554  }
8555  get_required_values(required, gm->op1);
8556  }
8557  if(gm->predicate)
8558  {
8559  get_required_values(required, gm->predicate);
8560  }
8561  }
8562  break;
8563  }
8564  case gimple_return_K:
8565  {
8566  const auto rt = GetPointerS<const gimple_return>(tn);
8567  if(rt->op)
8568  {
8569  get_required_values(required, rt->op);
8570  }
8571  break;
8572  }
8573  case gimple_phi_K:
8574  {
8575  const auto gp = GetPointerS<const gimple_phi>(tn);
8576  for(const auto& def_edge : gp->CGetDefEdgesList())
8577  {
8578  required.emplace_back(GET_INDEX_CONST_NODE(def_edge.first), 0);
8579  }
8580  break;
8581  }
8582  case label_decl_K:
8583  case gimple_label_K:
8584  case gimple_goto_K:
8585  case gimple_nop_K:
8586  case gimple_pragma_K:
8587  case CASE_PRAGMA_NODES:
8588  {
8590  break;
8591  }
8592  case call_expr_K:
8593  case aggr_init_expr_K:
8594  {
8595  const auto ce = GetPointerS<const call_expr>(tn);
8596  for(const auto& arg : ce->args)
8597  {
8598  required.emplace_back(GET_INDEX_CONST_NODE(arg), 0);
8599  }
8600  break;
8601  }
8602  case gimple_call_K:
8603  {
8604  const auto ce = GetPointerS<const gimple_call>(tn);
8605  const function_decl* fd = nullptr;
8606  if(GET_CONST_NODE(ce->fn)->get_kind() == addr_expr_K)
8607  {
8608  const auto ue = GetPointerS<const unary_expr>(GET_CONST_NODE(ce->fn));
8609  fd = GetPointerS<const function_decl>(GET_CONST_NODE(ue->op));
8610  }
8611  else if(GET_CONST_NODE(ce->fn)->get_kind() == obj_type_ref_K)
8612  {
8613  const auto temp_node = find_obj_type_ref_function(ce->fn);
8614  fd = GetPointerS<const function_decl>(GET_CONST_NODE(temp_node));
8615  }
8616  if(!fd || !is_a_nop_function_decl(fd))
8617  {
8618  for(const auto& arg : ce->args)
8619  {
8620  required.emplace_back(GET_INDEX_CONST_NODE(arg), 0);
8621  }
8622  }
8623  break;
8624  }
8625  case tree_list_K:
8626  {
8627  auto tl = GetPointerS<const tree_list>(tn);
8628  std::list<const tree_list*> tl_list;
8629  do
8630  {
8631  tl_list.push_back(tl);
8632  tl = tl->chan ? GetPointer<const tree_list>(GET_CONST_NODE(tl->chan)) : nullptr;
8633  } while(tl);
8634  for(const auto tl_current0 : tl_list)
8635  {
8636  required.emplace_back(GET_INDEX_CONST_NODE(tl_current0->valu), 0);
8637  }
8638  break;
8639  }
8640  case field_decl_K:
8641  {
8642  const auto fd = GetPointerS<const field_decl>(tn);
8643  THROW_ASSERT(GetPointerS<const integer_cst>(GET_CONST_NODE(fd->bpos)),
8644  "non-constant field offset (variable lenght object) currently not supported: " +
8645  STR(GET_INDEX_CONST_NODE(fd->bpos)));
8646  const auto ull_value = GetConstValue(fd->bpos);
8647  THROW_ASSERT(ull_value >= 0, "");
8648  required.emplace_back(0, static_cast<unsigned int>(ull_value / 8));
8649  if(ull_value % 8 != 0)
8650  {
8651  THROW_ERROR("bitfields are not yet supported: " + fd->ToString());
8652  }
8653  break;
8654  }
8655  case gimple_asm_K:
8656  {
8657  const auto ga = GetPointerS<const gimple_asm>(tn);
8658  if(ga->in)
8659  {
8660  get_required_values(required, ga->in);
8661  }
8662  break;
8663  }
8664  case array_range_ref_K:
8665  case binfo_K:
8666  case block_K:
8667  case case_label_expr_K:
8668  case const_decl_K:
8669  case function_decl_K:
8670  case identifier_node_K:
8671  case namespace_decl_K:
8672  case statement_list_K:
8673  case target_expr_K:
8674  case translation_unit_decl_K:
8675  case template_decl_K:
8676  case using_decl_K:
8677  case tree_vec_K:
8678  case type_decl_K:
8679  case CASE_CPP_NODES:
8680  case CASE_FAKE_NODES:
8681  case CASE_TYPE_NODES:
8682  case gimple_bind_K:
8683  case gimple_for_K:
8684  case gimple_predict_K:
8685  case gimple_resx_K:
8686  case error_mark_K:
8687  {
8688  THROW_ERROR("Operation not yet supported: " + std::string(tn->get_kind_text()));
8689  break;
8690  }
8691  default:
8692  THROW_UNREACHABLE("");
8693  }
8694 }
8695 
8697 {
8698  switch(statement->get_kind())
8699  {
8700  case tree_reindex_K:
8701  {
8702  if(GET_CONST_NODE(statement))
8703  {
8704  return LastStatement(GET_CONST_NODE(statement));
8705  }
8706  else
8707  {
8708  return false;
8709  }
8710  }
8711  case gimple_asm_K:
8712  case gimple_assign_K:
8713  case gimple_bind_K:
8714  case gimple_call_K:
8715  case gimple_label_K:
8716  case gimple_nop_K:
8717  case gimple_predict_K:
8718  case gimple_resx_K:
8719  {
8720  return false;
8721  }
8722  case gimple_cond_K:
8723  case gimple_for_K:
8724  case gimple_goto_K:
8725  case gimple_multi_way_if_K:
8726  case gimple_phi_K:
8727  case gimple_pragma_K:
8728  case gimple_return_K:
8729  case gimple_switch_K:
8730  case gimple_while_K:
8731  {
8732  return true;
8733  }
8734  case binfo_K:
8735  case block_K:
8736  case call_expr_K:
8737  case aggr_init_expr_K:
8738  case case_label_expr_K:
8739  case constructor_K:
8740  case identifier_node_K:
8741  case ssa_name_K:
8742  case statement_list_K:
8743  case target_expr_K:
8744  case target_mem_ref_K:
8745  case target_mem_ref461_K:
8746  case tree_list_K:
8747  case tree_vec_K:
8748  case last_tree_K:
8749  case none_K:
8750  case placeholder_expr_K:
8751  case error_mark_K:
8752  case lut_expr_K:
8754  case CASE_CPP_NODES:
8755  case CASE_CST_NODES:
8756  case CASE_DECL_NODES:
8757  case CASE_PRAGMA_NODES:
8760  case CASE_TYPE_NODES:
8761  case CASE_UNARY_EXPRESSION:
8762  {
8763  THROW_UNREACHABLE("Unexpected statement: " + statement->ToString());
8764  break;
8765  }
8766  default:
8767  {
8768  THROW_UNREACHABLE("");
8769  }
8770  }
8771  return true;
8772 }
8773 
8774 size_t tree_helper::GetFunctionSize(const tree_managerConstRef& TM, const unsigned int function_index)
8775 {
8776  const auto tn = TM->get_tree_node_const(function_index);
8777  const auto fd = GetPointer<const function_decl>(tn);
8778  THROW_ASSERT(fd, tn->ToString());
8779  THROW_ASSERT(fd->body, "Function " + fd->ToString() + " is without body");
8780  const auto sl = GetPointer<const statement_list>(GET_NODE(fd->body));
8781  size_t ret_value = 0;
8782  for(const auto& block : sl->list_of_bloc)
8783  {
8784  ret_value += block.second->CGetStmtList().size();
8785  ret_value += block.second->CGetPhiList().size();
8786  }
8787  return ret_value;
8788 }
8789 
8790 std::string tree_helper::get_asm_string(const tree_managerConstRef& TM, const unsigned int node_index)
8791 {
8792  const auto tn = TM->get_tree_node_const(node_index);
8793  const auto gasm = GetPointer<const gimple_asm>(tn);
8794  THROW_ASSERT(gasm, tn->ToString());
8795  return gasm->str;
8796 }
8797 
8799 {
8800  const auto tn = _tn->get_kind() == tree_reindex_K ? GET_CONST_NODE(_tn) : _tn;
8801  const auto ga = GetPointer<const gimple_assign>(tn);
8802  if(!ga)
8803  {
8804  return false;
8805  }
8806  const auto op0_kind = GET_CONST_NODE(ga->op0)->get_kind();
8807  auto store_candidate = op0_kind == bit_field_ref_K || op0_kind == component_ref_K || op0_kind == indirect_ref_K ||
8808  op0_kind == misaligned_indirect_ref_K || op0_kind == mem_ref_K || op0_kind == array_ref_K ||
8809  op0_kind == target_mem_ref_K || op0_kind == target_mem_ref461_K ||
8810  fun_mem_data.count(ga->op0->index);
8811  if(op0_kind == realpart_expr_K || op0_kind == imagpart_expr_K)
8812  {
8813  const auto op = GetPointerS<const unary_expr>(GET_CONST_NODE(ga->op0))->op;
8814  const auto code0 = GET_CONST_NODE(op)->get_kind();
8815  if(code0 == bit_field_ref_K || code0 == component_ref_K || code0 == indirect_ref_K ||
8816  code0 == misaligned_indirect_ref_K || code0 == mem_ref_K || code0 == array_ref_K ||
8817  code0 == target_mem_ref_K || code0 == target_mem_ref461_K)
8818  {
8819  store_candidate = true;
8820  }
8821  if(code0 == var_decl_K && fun_mem_data.count(op->index))
8822  {
8823  store_candidate = true;
8824  }
8825  }
8826 
8827  if(GET_CONST_NODE(ga->op1)->get_kind() == view_convert_expr_K)
8828  {
8829  const auto op0_type = GET_CONST_NODE(CGetType(ga->op0));
8830  const auto vc = GetPointerS<const view_convert_expr>(GET_CONST_NODE(ga->op1));
8831  if(op0_type->get_kind() == record_type_K || op0_type->get_kind() == union_type_K)
8832  {
8833  store_candidate = true;
8834  }
8835  const auto vc_op_type = GET_CONST_NODE(CGetType(vc->op));
8836  if(vc_op_type->get_kind() == vector_type_K && op0_type->get_kind() == array_type_K)
8837  {
8838  store_candidate = true;
8839  }
8840  }
8841  return store_candidate;
8842 }
8843 
8845 {
8846  const auto tn = _tn->get_kind() == tree_reindex_K ? GET_CONST_NODE(_tn) : _tn;
8847  const auto ga = GetPointer<const gimple_assign>(tn);
8848  if(!ga)
8849  {
8850  return false;
8851  }
8852  const auto op1_kind = GET_CONST_NODE(ga->op1)->get_kind();
8853  bool is_a_vector_bitfield = false;
8855  if(op1_kind == bit_field_ref_K)
8856  {
8857  const auto bfr = GetPointerS<const bit_field_ref>(GET_CONST_NODE(ga->op1));
8858  if(IsVectorType(bfr->op0))
8859  {
8860  is_a_vector_bitfield = true;
8861  }
8862  }
8863  auto load_candidate = (op1_kind == bit_field_ref_K && !is_a_vector_bitfield) || op1_kind == component_ref_K ||
8864  op1_kind == indirect_ref_K || op1_kind == misaligned_indirect_ref_K || op1_kind == mem_ref_K ||
8865  op1_kind == array_ref_K || op1_kind == target_mem_ref_K || op1_kind == target_mem_ref461_K ||
8866  fun_mem_data.count(ga->op1->index);
8867  if(op1_kind == realpart_expr_K || op1_kind == imagpart_expr_K)
8868  {
8869  const auto op = GetPointerS<const unary_expr>(GET_CONST_NODE(ga->op1))->op;
8870  const auto code1 = GET_CONST_NODE(op)->get_kind();
8871  if((code1 == bit_field_ref_K && !is_a_vector_bitfield) || code1 == component_ref_K || code1 == indirect_ref_K ||
8872  code1 == bit_field_ref_K || code1 == misaligned_indirect_ref_K || code1 == mem_ref_K || code1 == array_ref_K ||
8873  code1 == target_mem_ref_K || code1 == target_mem_ref461_K)
8874  {
8875  load_candidate = true;
8876  }
8877  if(code1 == var_decl_K && fun_mem_data.count(op->index))
8878  {
8879  load_candidate = true;
8880  }
8881  }
8882 
8883  if(op1_kind == view_convert_expr_K)
8884  {
8885  const auto vc = GetPointerS<const view_convert_expr>(GET_CONST_NODE(ga->op1));
8886  const auto vc_op_type = GET_CONST_NODE(CGetType(vc->op));
8887  if(vc_op_type->get_kind() == record_type_K || vc_op_type->get_kind() == union_type_K)
8888  {
8889  load_candidate = true;
8890  }
8891  const auto op0_type = GET_CONST_NODE(CGetType(ga->op0));
8892  if(vc_op_type->get_kind() == array_type_K && op0_type->get_kind() == vector_type_K)
8893  {
8894  load_candidate = true;
8895  }
8896  }
8897  return load_candidate;
8898 }
8899 
8901 {
8902  const auto tn = _tn->get_kind() == tree_reindex_K ? GET_CONST_NODE(_tn) : _tn;
8903  const auto ga = GetPointer<const gimple_assign>(tn);
8904  if(!ga)
8905  {
8906  return false;
8907  }
8908  const auto op1 = GET_CONST_NODE(ga->op1);
8909  return op1->get_kind() == lut_expr_K;
8910 }
8911 
8913 {
8914  THROW_ASSERT(sl, "");
8915  for(const auto& block : sl->list_of_bloc)
8916  {
8917  for(const auto& stmt : block.second->CGetStmtList())
8918  {
8919  const auto gp = GetPointer<const gimple_pragma>(GET_NODE(stmt));
8920  if(gp && gp->scope && GetPointer<const omp_pragma>(GET_NODE(gp->scope)))
8921  {
8922  const auto sp = GetPointer<const omp_simd_pragma>(GET_NODE(gp->directive));
8923  if(sp)
8924  {
8925  return true;
8926  }
8927  }
8928  }
8929  }
8930  return false;
8931 }
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:343
static bool IsSameType(const tree_nodeConstRef &tn0, const tree_nodeConstRef &tn1)
Given two nodes tells if they have same base type (const is not considered: const double == double) ...
static bool IsStore(const tree_nodeConstRef &tn, const CustomOrderedSet< unsigned int > &fun_mem_data)
Return true if the tree node is a gimple_assign writing something which will be allocated in memory...
static bool is_a_struct(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is a record.
This struct specifies the integer_cst node.
Definition: tree_node.hpp:3242
static std::vector< tree_nodeConstRef > CGetFieldTypes(const tree_nodeConstRef &type)
Return the fields type of a variable of type struct.
static tree_nodeConstRef GetFormalIth(const tree_nodeConstRef &obj, unsigned int parm_index)
Return the type of the ith formal parameter in case index_obj is a call_expr.
integer_cst_t value
The value of the integer cast.
Definition: tree_node.hpp:3253
static const std::set< std::string > TLM_SC_builtin_scalar_type
store the set of TLM SystemC class for which the size corresponds to the sum of the size of template ...
Definition: tree_helper.hpp:88
static bool IsUnionType(const tree_nodeConstRef &type)
Return if treenode is an union.
void check_lib_type(const tree_nodeRef &var)
Check if variable is defined in a c system library header; if yes adds its type to library type...
static bool IsComplexType(const tree_nodeConstRef &type)
Return if treenode is a complex.
static bool is_a_nop_function_decl(const function_decl *fd)
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
static int debug_level
debug level (set by Parameter)
static std::string name_function(const tree_managerConstRef &tm, const unsigned int index)
Return the name of the function.
static bool is_a_variable(const tree_managerConstRef &TM, const unsigned int index)
FIXME: to be remove after substitution with IsVariableType.
static std::vector< unsigned long long > GetArrayDimensions(const tree_nodeConstRef &node)
Return the dimension of the array.
static unsigned int GetElements(const tree_managerConstRef &TM, const unsigned int index)
Given an array or a vector return the element type.
static size_t CountPointers(const tree_nodeConstRef &)
Computes how many pointers are included in a tree node.
static unsigned long long AccessedMaximumBitsize(const tree_nodeConstRef &type_node, unsigned long long bitsize)
return the maximum bitsize associated with the elements accessible through type_node ...
File containing functions and utilities to support the printing of debug messagges.
static unsigned long long get_array_num_elements(const tree_managerConstRef &TM, const unsigned int index)
Return the total number of elements of the the base type in the array.
static bool IsExternDeclaration(const tree_nodeConstRef &decl)
static bool is_out_port(const tree_managerConstRef &TM, const unsigned int index)
This function test if a given index is a SystemC output port.
static unsigned int get_field_idx(const tree_managerConstRef &TM, const unsigned int index, unsigned int idx)
Return the idx element of the fields declared in an union or a record type.
static bool IsFunctionPointerType(const tree_nodeConstRef &type)
Return true if the treenode is of type function pointer type.
static bool is_int(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of integer type.
std::string ToString() const
Print this node as string in gimple format.
static bool IsConstant(const tree_nodeConstRef &node)
Return if a tree node is a constant object.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
Definition: tree_node.hpp:463
static std::set< tree_nodeConstRef, TreeNodeConstSorter > GetTypesToBeDeclaredAfter(const tree_nodeConstRef &tn, const bool without_transformation)
Return the types to be declared after declaring index type.
const tree_nodeRef CGetTreeReindex(const unsigned int i) const
Return a tree_reindex wrapping the i-th tree_node.
static unsigned int get_var_alignment(const tree_managerConstRef &TM, unsigned int var)
Return the var alignment.
tree_nodeRef get_base(size_t i) const
return the i-th element of baseinfo
Definition: tree_node.hpp:1736
char base
This version is stamped on May 10, 2016.
Definition: nussinov.c:24
static std::string get_asm_string(const tree_managerConstRef &TM, const unsigned int node_index)
return the string associated with the gimple_asm
This struct specifies the statement_list node.
Definition: tree_node.hpp:4662
static bool LastStatement(const tree_nodeConstRef &statement)
Return true if statement must be the last of a basic block.
static bool is_unsigned(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of unsigned integer type.
tree_nodeRef name
name field contains an identifier_node used to represent a name.
Definition: tree_node.hpp:883
const std::vector< std::string > SplitString(const std::string &input, const std::string &separators)
Function which splits a string into tokens.
static tree_nodeConstRef CGetArrayBaseType(const tree_nodeConstRef &type)
static bool IsArrayEquivType(const tree_nodeConstRef &type)
Return true if treenode is an array or it is equivalent to an array (record recursively having a sing...
#define CASE_DECL_NODES
NOTE that cast_expr is a unary expression but it could not be included in the CASE_UNARY_EXPRESSION b...
Definition: tree_node.hpp:672
static bool is_a_misaligned_vector(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode index is a a misaligned access to a vector data object.
static std::string print_type(const tree_managerConstRef &TM, unsigned int type, bool global=false, bool print_qualifiers=false, bool print_storage=false, unsigned int var=0, const var_pp_functorConstRef &vppf=var_pp_functorConstRef(), const std::string &prefix="", const std::string &tail="")
Print a type and its variable in case var is not zero.
static bool is_builtin_channel(const tree_managerConstRef &TM, const unsigned int index)
This function test if a given index is a SystemC builtin channel.
static bool is_real(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of real type.
struct definition of the function_decl tree node.
Definition: tree_node.hpp:2759
mathematical utility function not provided by standard libraries
static std::string return_C_qualifiers(const TreeVocabularyTokenTypes_TokenEnum quals, bool real_const)
return the qualifiers in C format
static bool is_static(const tree_managerConstRef &TM, const unsigned int index)
FIXME: to be remove after substitution with IsStaticDeclaration.
static std::string GetString(const enum kind k)
Given a kind, return the corresponding string.
Definition: tree_node.cpp:120
static tree_nodeConstRef CGetElements(const tree_nodeConstRef &type)
Given an array or a vector return the element type.
tree_nodeRef refd
refd field references to the node for the type referenced to.
Definition: tree_node.hpp:4233
static bool is_clock(const tree_managerConstRef &TM, const unsigned int index)
This function test if a given index as parm is a SystemC sc_clock.
static bool is_natural(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is a ssa_name greater or equal to zero.
tree_nodeRef mngl
mngl field contains the name of the object as the assembler will see it.
Definition: tree_node.hpp:890
exceptions managed by PandA
static bool is_parameter(const tree_managerConstRef &TM, const unsigned int index)
return true in case the index corresponds to a parameter in ssa form or not
static bool IsFunctionDeclaration(const tree_nodeConstRef &type)
Return true if treenode is a function_decl.
A simple interface to token object of the raw files.
static bool IsVoidType(const tree_nodeConstRef &type)
Return true if the treenode is of void type.
static bool is_channel(const tree_managerConstRef &TM, const unsigned int index)
This function test if a given index is a SystemC channel.
static bool IsVolatile(const tree_nodeConstRef &tn)
return true in case the tree node corresponds to a volatile variable
static unsigned long long GetArrayElementSize(const tree_nodeConstRef &node)
Return the size (in bits) of the base element of the array.
std::map< unsigned int, blocRef > list_of_bloc
list_of_bloc field is the list of basic block. If this field is null then the list_of_stmt field is n...
Definition: tree_node.hpp:4673
static const unsigned int EXIT_BLOCK_ID
constant identifying the exit basic block
tree_nodeRef base
BASE register.
Definition: tree_node.hpp:4949
#define GET_INDEX_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:361
#define min(x, y)
static std::string print_function_name(const tree_managerConstRef &TM, const function_decl *fd)
Return the name of the function in a string.
struct definition of the function_type tree node.
Definition: tree_node.hpp:2960
Node not yet supported.
Definition: exceptions.hpp:323
struct definition of the parm_decl tree node.
Definition: tree_node.hpp:3660
Data structure describing a basic block at tree level.
static unsigned int get_multi_way_if_pos(const tree_managerConstRef &TM, unsigned int node_id, unsigned int cond)
return the position of con in the gimple_multi_way_if conditions
static const std::set< std::string > SC_tmpl_class
store the set of SystemC class for which the type correspond to the template parameter ...
Definition: tree_helper.hpp:82
static unsigned int get_type_index(const tree_managerConstRef &TM, const unsigned int index, long long int &vec_size, bool &is_a_pointer, bool &is_a_function)
Return the treenode index of the type of index.
This struct specifies the binfo node.
Definition: tree_node.hpp:1713
static bool is_an_enum(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is an enumeral type.
static void get_required_values(std::vector< std::tuple< unsigned int, unsigned int >> &required, const tree_nodeRef &tn)
CustomOrderedSet< TreeVocabularyTokenTypes_TokenEnum > list_attr
list of TOKEN, represented as int, associated to the tree_node
Definition: tree_node.hpp:777
static bool is_packed_access(const tree_managerConstRef &TreeM, unsigned int node_index)
Check if the access is on a packed data structure or not.
static void get_used_variables(bool first_level_only, const tree_nodeConstRef &t, CustomUnorderedSet< unsigned int > &list_of_variable)
Return the list of tree nodes associated with the variable used by the node t.
static bool IsEnumType(const tree_nodeConstRef &type)
Return if treenode index is an enumeral type.
static bool is_a_function(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is a function_decl.
static bool is_packed(const tree_managerConstRef &TreeM, unsigned int node_index)
FIXME: to be remove after substitution with IsPackedType.
const tree_nodeConstRef CGetTreeNode(const unsigned int i) const
static bool IsInLibbambu(const tree_managerConstRef &TM, const unsigned int index)
Return true if the decl node or type is in libbambu.
Abstract pure class for the tree structure.
Definition: tree_node.hpp:139
bool builtin_flag
flag true when the function is a builtin
Definition: tree_node.hpp:2853
static std::string GetMangledFunctionName(const function_decl *fd)
Return the mangled function name.
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define STR(s)
Macro which performs a lexical_cast to a string.
Auxiliary methods for manipulating string.
static bool IsVariableType(const tree_nodeConstRef &node)
Return true if the treenode is a valid variable.
struct definition of the label_decl tree node.
Definition: tree_node.hpp:5659
#define max
Definition: backprop.h:17
static std::string GetTemplateTypeName(const tree_nodeConstRef &type)
Return the name of template without parameters.
bw_t minBitwidth(bool sign) const
Definition: APInt.cpp:395
static tree_nodeConstRef GetUnqualifiedType(const tree_nodeConstRef &type)
Return the unqualified version of a type.
static bool IsScalarType(const tree_nodeConstRef &type)
Return true if the treenode is an int, an unsigned, a real or a Boolean data type.
static bool HasToBeDeclared(const tree_managerConstRef &TM, const tree_nodeConstRef &type)
Return true if the type has to be declared.
const std::string TI_getTokenName(const TreeVocabularyTokenTypes_TokenEnum i)
Return the name associated with the token.
static bool IsUnsignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of unsigned integer type.
const tree_nodeRef get_tree_node_const(unsigned int i) const
Return the reference to the i-th tree_node Constant version of get_tree_node.
static bool is_system(const tree_managerConstRef &TM, const unsigned int index)
Return true if variable or type is a system one.
static bool IsSignedIntegerType(const tree_nodeConstRef &type)
Return true if the treenode is of integer type.
static bool IsArrayType(const tree_nodeConstRef &type)
Return true if treenode is an array.
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
virtual std::string get_kind_text() const =0
Virtual function returning the name of the actual class.
bool is_top_function(const function_decl *fd) const
is_top_function checks if a function is one of the application top functions.
size_t get_baseinfo_size() const
return the size of baseinfo vector
Definition: tree_node.hpp:1742
static unsigned long long AccessedMinimunBitsize(const tree_nodeConstRef &type_node, unsigned long long bitsize)
return the minimum bitsize associated with the elements accessible through type_node ...
static unsigned long long get_array_data_bitsize(const tree_managerConstRef &TM, const unsigned int index)
Return the size (in bits) of the base element of the array.
static void getBuiltinFieldTypes(const tree_nodeConstRef &_type, std::list< tree_nodeConstRef > &listOfTypes, CustomUnorderedSet< unsigned int > &already_visited)
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
static bool same_size_fields(const tree_nodeConstRef &t)
static unsigned int GetUnqualified(const tree_managerConstRef &TM, unsigned int type)
Return the unqualified version of a type.
static bool is_const_type(const tree_managerConstRef &TM, const unsigned int index)
Return if the treenode is of const type.
static bool IsBooleanType(const tree_nodeConstRef &type)
Return true if the treenode is of bool type.
static bool IsSystemType(const tree_nodeConstRef &type)
Return true if variable or type is a system one.
APInt integer_cst_t
Definition: panda_types.hpp:47
static bool is_signal(const tree_managerConstRef &TM, const unsigned int index)
This function test if a given index is a SystemC sc_signal.
tree_nodeRef type
type field is the actual data type node being inherited in this basetype.(BINFO_TYPE) ...
Definition: tree_node.hpp:1721
static tree_nodeRef GetFieldIdx(const tree_nodeConstRef &type, unsigned int idx)
Return the element of the fields declared in an union or a record type.
static void compute_ssa_uses_rec_ptr(const tree_nodeConstRef &tn, CustomOrderedSet< const ssa_name *> &ssa_uses)
recursively compute the pointers to the ssa_name variables used in a statement
static std::set< tree_nodeConstRef, TreeNodeConstSorter > GetTypesToBeDeclaredBefore(const tree_nodeConstRef &tn, const bool without_transformation)
Return the types to be declared before declaring index type.
#define CASE_QUATERNARY_EXPRESSION
This macro collects all case labels for quaternary_expr objects.
Definition: tree_node.hpp:574
#define CASE_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
Definition: tree_node.hpp:371
static bool is_virtual(const tree_managerConstRef &TM, const unsigned int index)
return true in case the ssa_name is virtual
static std::string sign_reduce_bitstring(std::string bitstring, bool bitstring_is_signed)
function slightly different than BitLatticeManipulator::sign_reduce_bitstring
static bool is_module(const tree_managerConstRef &TM, unsigned int index)
This function test if a given index is a SystemC module.
static std::tuple< std::string, unsigned int, unsigned int > GetSourcePath(const tree_nodeConstRef &node, bool &is_system)
Return where a function or a type is defined.
static integer_cst_t get_integer_cst_value(const integer_cst *ic)
Convert a integer_cst in a long long value.
const unsigned int index
Represent the index read from the raw file and the index-1 of the vector of tree_node associated to t...
Definition: tree_node.hpp:146
static bool IsFunctionType(const tree_nodeConstRef &type)
Return true if the treenode is of type function type.
Low-level memory addressing.
Definition: tree_node.hpp:4938
static bool is_a_void(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of void type.
static bool is_scalar(const tree_managerConstRef &TM, const unsigned int var)
Return true if the treenode is an int, an unsigned, a real or a Boolean data type.
tree_nodeRef body
body field is the saved representation of the body of the entire function.
Definition: tree_node.hpp:2870
#define index(x, y)
Definition: Keccak.c:74
static std::string return_qualifier_prefix(const TreeVocabularyTokenTypes_TokenEnum quals)
return the prefix given a qualifier
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
tree_nodeRef base
BASE register.
Definition: tree_node.hpp:4879
static std::string GetRecordTypeName(const tree_nodeConstRef &type)
Return the name of the class.
unsigned int get_implementation_node(unsigned int decl_node) const
Return the index of function_decl node that implements the declaration node.
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
serialization get_serialization(const std::string &name) const
Return which type of serialization the given function must have.
refcount< const tree_node > tree_nodeConstRef
Definition: tree_node.hpp:213
Classes specification of the tree_node data structures.
static std::string NormalizeTypename(const std::string &id)
Return normalized name of types and variables.
struct definition of the field attr on function_decl, field_decl, var_decl tree node.
Definition: tree_node.hpp:774
static bool IsStaticDeclaration(const tree_nodeConstRef &decl)
serialization
Specify the type of serialization that a function must have.
static bool is_function_type(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of type function type.
static bool is_a_pointer(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is a pointer.
#define THROW_ERROR(str_expr)
helper function used to throw an error in a standard way
Definition: exceptions.hpp:263
static bool has_omp_simd(const statement_list *sl)
Check if omp simd pragmas are present in given statement list.
struct definition of the pointer_type tree node.
Definition: tree_node.hpp:3896
static size_t AllocatedMemorySize(const tree_nodeConstRef &parameter)
Compute the memory (in bytes) to be allocated to store a parameter or a variable. ...
This struct specifies the block node.
Definition: tree_node.hpp:1820
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
Definition: tree_node.hpp:581
This file collects some utility functions.
static unsigned int GetRealType(const tree_managerConstRef &TM, unsigned int index)
Return the real type.
static tree_nodeConstRef check_for_simple_pointer_arithmetic(const tree_nodeConstRef &node)
() label_decl()() modop_expr() new_expr() placeholder_expr() type_node
Definition: tree_node.cpp:166
static bool is_an_addr_expr(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is an address expression.
TreeVocabularyTokenTypes_TokenEnum
static bool is_volatile(const tree_managerConstRef &TM, const unsigned int index)
return true in case the index corresponds to a volatile variable
static tree_nodeRef find_obj_type_ref_function(const tree_nodeConstRef &tn)
Given the tree_node of an obj_type_ref return the tree_node of the called function.
~tree_helper()
Destructor.
struct definition of the reference_type tree node.
Definition: tree_node.hpp:4220
Definition: APInt.hpp:53
static bool is_ssa_name(const tree_managerConstRef &TM, const unsigned int index)
Return true in case index is a ssa_name.
static bool is_event(const tree_managerConstRef &TM, const unsigned int index)
This function test if a given index is a SystemC event.
static bool is_port(const tree_managerConstRef &TM, const unsigned int index)
This function test if a given index is a SystemC port.
static std::string op_symbol(const tree_nodeConstRef &op)
Function return the symbol related with the operator op passed as parameter.
static unsigned int get_formal_ith(const tree_managerConstRef &TM, unsigned int index_obj, unsigned int parm_index)
return the type of the ith formal parameter in case index_obj is a call_expr
static bool look_for_binfo_inheritance(const binfo *b, const std::string &bcs)
Look for inheritance of a class.
static size_t GetFunctionSize(const tree_managerConstRef &TM, const unsigned int function_index)
Return the number of statement + the number of phi in the function.
static bool IsPackedType(const tree_nodeConstRef &type)
static bool is_function_pointer_type(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of type function pointer type.
static tree_nodeConstRef GetBaseVariable(const tree_nodeConstRef &mem)
Retrun the base variable of a memory access.
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
Definition: tree_node.hpp:689
struct definition of the type node structures.
Definition: tree_node.hpp:1318
FunctionExpander()
Constructor.
Class specification of the tree_reindex support class.
static const unsigned int ENTRY_BLOCK_ID
constant identifying the entry basic block
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
Definition: tree_node.hpp:635
static bool is_an_union(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is an union.
static bool is_concat_bit_ior_expr(const tree_managerConstRef &TM, const unsigned int index)
check if a given tree node is a concatenation operation
static void get_array_dimensions(const tree_managerConstRef &TM, const unsigned int index, std::vector< unsigned long long > &dims)
Return the dimension of the array.
static bool is_fully_resolved(const tree_managerConstRef &TM, const unsigned int index, CustomOrderedSet< unsigned int > &res_set)
FIXME: to be remove after substitution with IsPointerResolved.
static bool is_simple_pointer_plus_test(const tree_managerConstRef &TM, const unsigned int index)
check if a given tree node is a simple pointer plus expression
static std::string PrintType(const tree_managerConstRef &TM, const tree_nodeConstRef &type, bool global=false, bool print_qualifiers=false, bool print_storage=false, const tree_nodeConstRef &var=nullptr, const var_pp_functorConstRef &vppf=var_pp_functorConstRef(), const std::string &prefix="", const std::string &tail="")
Print a type and its variable in case var is not zero.
static bool is_a_complex(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is a complex.
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
T * get() const
Definition: refcount.hpp:169
static bool IsStructType(const tree_nodeConstRef &type)
Return true if treenode is a record.
#define THROW_ERROR_CODE(code, str_expr)
helper function used to throw an error with a code error
Definition: exceptions.hpp:266
static bool is_extern(const tree_managerConstRef &TM, const unsigned int index)
FIXME: to be remove after substitution with IsExternDeclaration.
static bool is_inout_port(const tree_managerConstRef &TM, const unsigned int index)
This function test if a given index is a SystemC in-output port.
tree_nodeRef type
type field holds the data type of the object, when relevant.
Definition: tree_node.hpp:907
static tree_nodeConstRef CGetPointedType(const tree_nodeConstRef &pointer)
Return the pointed type of a pointer object.
#define DEBUG_LEVEL_PARANOIC
paranoid level debugging print is performed.
Classes specification of the tree_node data structures not present in the gcc.
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
Definition: tree_node.hpp:644
Low-level memory addressing.
Definition: tree_node.hpp:4865
static bool is_bool(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of bool type.
static unsigned int get_base_index(const tree_managerConstRef &TM, const unsigned int index)
Retrun the base address of a memory access.
static bool IsLut(const tree_nodeConstRef &tn)
Return true in case the right operation is a lut_expr.
static std::string get_type_name(const tree_managerConstRef &TM, const unsigned int index)
Return name of the type.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
Definition: tree_node.hpp:212
void rect(int left, int top, int right, int bottom, unsigned int color)
Definition: main.c:154
static std::string GetFunctionName(const tree_managerConstRef &TM, const tree_nodeConstRef &decl)
Return the name of the function.
static bool is_a_vector(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode index is a vector.
unsigned counter[N_THREADS]
Definition: data.c:3
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
Definition: tree_node.hpp:700
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
static unsigned int get_array_var(const tree_managerConstRef &TM, const unsigned int index, bool is_written, bool &two_dim_p)
Return the tree node index of the array variable written or read.
virtual bool operator()(const tree_nodeRef &t) const
check membership to c library function
static bool IsAligned(const tree_managerConstRef &TM, unsigned int type)
Return true if type has not default alignment.
#define GET_INDEX_CONST_NODE(t)
Definition: tree_node.hpp:363
static void extract_array_indexes(const tree_managerConstRef &TM, const unsigned int index, std::vector< unsigned long long > &indexes, std::vector< unsigned long long > &size_indexes, unsigned int &base_object)
Return the indexes of the array_ref.
tree_nodeRef type
type field is the type of the node
Definition: tree_node.hpp:1439
static bool is_constant(const tree_managerConstRef &TM, const unsigned int index)
Return if a tree node is a constant object.
bool is_transparent(const std::string &name) const
Return if function has to be considered transparent even if we haven&#39;t body.
static bool IsPointerType(const tree_nodeConstRef &type)
Return true if treenode index is a pointer.
static std::string GetTypeName(const tree_nodeConstRef &type)
Return name of the type.
tree_helper()
Constructor.
static bool IsPointerResolved(const tree_nodeConstRef &ptr, CustomOrderedSet< unsigned int > &res_set)
static tree_nodeConstRef GetFunctionReturnType(const tree_nodeConstRef &function, bool void_as_null=true)
Return the return type of a function.
static void RecursiveGetTypesToBeDeclared(std::set< tree_nodeConstRef, TreeNodeConstSorter > &returned_types, const tree_nodeConstRef &type, const bool recursion, const bool without_transformation, const bool before)
Return the types to be declared before/after declaring type.
static void ComputeSsaUses(const tree_nodeRef &, TreeNodeMap< size_t > &uses)
recursively compute the references to the ssa_name variables used in a statement
static unsigned int get_pointed_type(const tree_managerConstRef &TM, const unsigned int index)
Return the tree_node index of the pointed type of a pointer object;.
tree_nodeRef symbol
static or global variable
Definition: tree_node.hpp:4876
static bool is_SC_BIND_PROXY_NIL(const tree_managerConstRef &TM, const unsigned int index)
This function test if a given index as parm is a SC_BIND_PROXY_NIL.
static std::vector< tree_nodeConstRef > GetParameterTypes(const tree_nodeConstRef &ftype)
Return the tree node of parameter types.
static bool IsLoad(const tree_nodeConstRef &tn, const CustomOrderedSet< unsigned int > &fun_mem_data)
Return true if the tree node is a gimple_assign reading something which will be allocated in memory...
static bool IsConstType(const tree_nodeConstRef &type)
Return true if the treenode is of const type.
static bool IsPositiveIntegerValue(const tree_nodeConstRef &type)
Return true if the treenode is a ssa_name greater or equal to zero.
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
Definition: tree_node.hpp:550
static void get_parameter_types(const tree_managerConstRef &TM, const unsigned int index, std::list< unsigned int > &params)
Return the tree node of parameter types.
Class specification of the manager of the tree structures extracted from the raw file.
static unsigned long long GetArrayTotalSize(const tree_nodeConstRef &node)
Return the total number of elements of the the base type in the array.
static const std::set< std::string > SC_builtin_scalar_type
store the set of SystemC class for which the template parameter correspond to the bit size of the typ...
Definition: tree_helper.hpp:85
static bool is_an_array(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is an array or it is equivalent to an array (record recursively having a sin...
static bool IsRealType(const tree_nodeConstRef &type)
Return true if the treenode is of real type.
static bool is_in_port(const tree_managerConstRef &TM, const unsigned int index)
This function test if a given index is a SystemC input port.
int sl
Definition: adpcm.c:105
static void get_array_dim_and_bitsize(const tree_managerConstRef &TM, const unsigned int index, std::vector< unsigned long long > &dims, unsigned long long &elts_bitsize)
Return the dimension of the array.
#define CASE_PRAGMA_NODES
This macro collects all case labels for pragma objects.
Definition: tree_node.hpp:610
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

Generated on Mon Feb 12 2024 13:02:55 for PandA-2024.02 by doxygen 1.8.13