PandA-2024.02
behavioral_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  */
43 #include "behavioral_helper.hpp"
44 
45 #include "Parameter.hpp"
46 #include "application_manager.hpp"
47 #include "cdfg_edge_info.hpp"
48 #include "compiler_constants.hpp"
49 #include "custom_map.hpp"
50 #include "dbgPrintHelper.hpp"
51 #include "exceptions.hpp"
52 #include "ext_tree_node.hpp"
53 #include "function_behavior.hpp"
54 #include "op_graph.hpp"
55 #include "string_manipulation.hpp"
56 #include "token_interface.hpp"
57 #include "tree_basic_block.hpp"
58 #include "tree_helper.hpp"
59 #include "tree_manager.hpp"
60 #include "tree_manipulation.hpp"
61 #include "tree_reindex.hpp"
62 #include "type_casting.hpp"
63 #include "var_pp_functor.hpp"
64 
65 #if HAVE_FROM_PRAGMA_BUILT
66 #include "pragma_constants.hpp"
67 #endif
68 
69 #include "config_HAVE_ASSERTS.hpp"
70 #include "config_HAVE_FROM_PRAGMA_BUILT.hpp"
71 #include "config_RELEASE.hpp"
72 
73 #include <boost/algorithm/string/replace.hpp>
74 
75 #include <cstddef>
76 #include <string>
77 #include <vector>
78 
79 std::map<std::string, unsigned int> BehavioralHelper::used_name;
80 
81 std::map<unsigned int, std::string> BehavioralHelper::vars_symbol_table;
82 
83 std::map<unsigned int, std::string> BehavioralHelper::vars_renaming_table;
84 
86 #define MAX_ROW_LENGTH 128
87 
88 BehavioralHelper::BehavioralHelper(const application_managerRef _AppM, unsigned int _index, bool _body,
89  const ParameterConstRef _parameters)
90  : AppM(application_managerRef(_AppM.get(), null_deleter())),
91  TM(_AppM->get_tree_manager()),
92  Param(_parameters),
93  debug_level(Param->get_class_debug_level("BehavioralHelper", DEBUG_LEVEL_NONE)),
94  function_index(_index),
95  function_name(tree_helper::GetFunctionName(TM, TM->CGetTreeReindex(function_index))),
96  body(_body),
97  opaque(!_body)
98 {
99 }
100 
102 
103 std::tuple<std::string, unsigned int, unsigned int> BehavioralHelper::get_definition(unsigned int index,
104  bool& is_system) const
105 {
106  THROW_ASSERT(index, "expected a meaningful index");
107  return tree_helper::GetSourcePath(TM->CGetTreeReindex(index), is_system);
108 }
109 
111  bool dot) const
112 {
113  const auto node = g->CGetOpNodeInfo(v)->node;
114  std::string res;
115  if(node && GET_CONST_NODE(node)->get_kind() != gimple_nop_K)
116  {
117  res = PrintNode(node, v, vppf);
118  switch(GET_CONST_NODE(node)->get_kind())
119  {
120  case gimple_assign_K:
121  case gimple_call_K:
122  case gimple_asm_K:
123  case gimple_goto_K:
124  res += ";";
125  break;
126  case binfo_K:
127  case block_K:
128  case call_expr_K:
129  case aggr_init_expr_K:
130  case case_label_expr_K:
131  case constructor_K:
132  case gimple_bind_K:
133  case gimple_cond_K:
134  case gimple_for_K:
135  case gimple_label_K:
136  case gimple_multi_way_if_K:
137  case gimple_nop_K:
138  case gimple_phi_K:
139  case gimple_pragma_K:
140  case gimple_predict_K:
141  case gimple_resx_K:
142  case gimple_return_K:
143  case gimple_switch_K:
144  case gimple_while_K:
145  case identifier_node_K:
146  case ssa_name_K:
147  case statement_list_K:
148  case target_expr_K:
149  case target_mem_ref_K:
150  case target_mem_ref461_K:
151  case tree_list_K:
152  case tree_vec_K:
153  case error_mark_K:
154  case lut_expr_K:
156  case CASE_CPP_NODES:
157  case CASE_CST_NODES:
158  case CASE_DECL_NODES:
159  case CASE_FAKE_NODES:
160  case CASE_PRAGMA_NODES:
163  case CASE_TYPE_NODES:
165  default:
166  break;
167  }
168  }
169  if(dot)
170  {
171  boost::replace_all(res, "\\\"", "&quot;");
172  std::string ret;
173  for(const auto& re : res)
174  {
175  if(re == '\"')
176  {
177  ret += "\\\"";
178  }
179  else if(re != '\n')
180  {
181  ret += re;
182  }
183  else
184  {
185  ret += "\\\n";
186  }
187  }
188  ret += "\\n";
189  return ret;
190  }
191  else if(res != "")
192  {
193  res += "\n";
194  }
195  return res;
196 }
197 
198 std::string BehavioralHelper::PrintInit(const tree_nodeConstRef& _node, const var_pp_functorConstRef vppf) const
199 {
200  const auto node = _node->get_kind() == tree_reindex_K ? GET_CONST_NODE(_node) : _node;
201  std::string res;
202  switch(node->get_kind())
203  {
204  case constructor_K:
205  {
206  const auto constr = GetPointerS<const constructor>(node);
207  bool designated_initializers_needed = false;
208  res += '{';
209  auto i = constr->list_of_idx_valu.begin();
210  const auto vend = constr->list_of_idx_valu.end();
212  const auto firstnode = i != vend ? constr->list_of_idx_valu.front().first : tree_nodeRef();
213  if(firstnode && GET_CONST_NODE(firstnode)->get_kind() == field_decl_K)
214  {
215  const auto fd = GetPointerS<const field_decl>(GET_CONST_NODE(firstnode));
216  const auto scpe = GET_CONST_NODE(fd->scpe);
217  std::vector<tree_nodeRef> field_list;
218  if(scpe->get_kind() == record_type_K)
219  {
220  field_list = GetPointerS<const record_type>(scpe)->list_of_flds;
221  }
222  else if(scpe->get_kind() == union_type_K)
223  {
224  field_list = GetPointerS<const union_type>(scpe)->list_of_flds;
225  }
226  else
227  {
228  THROW_ERROR("expected a record_type or a union_type");
229  }
230  auto fli = field_list.begin();
231  const auto flend = field_list.end();
232  for(; fli != flend && i != vend; ++i, ++fli)
233  {
234  if(i->first && GET_INDEX_NODE(i->first) != GET_INDEX_NODE(*fli))
235  {
236  break;
237  }
238  }
239  if(fli != flend && i != vend)
240  {
241  designated_initializers_needed = true;
242  }
243  }
244  else
245  {
246  designated_initializers_needed = true;
247  }
248 
249  auto current_length = res.size();
250  for(i = constr->list_of_idx_valu.begin(); i != vend;)
251  {
252  std::string current;
253  if(designated_initializers_needed && i->first && GET_CONST_NODE(i->first)->get_kind() == field_decl_K)
254  {
255  current += ".";
256  current += PrintVariable(GET_INDEX_NODE(i->first));
257  current += "=";
258  }
259  auto val = GET_CONST_NODE(i->second);
260  THROW_ASSERT(val, "Something of unexpected happen");
261  if(val->get_kind() == addr_expr_K)
262  {
263  const auto ae = GetPointerS<const addr_expr>(val);
264  const auto op = GET_CONST_NODE(ae->op);
265  if(op->get_kind() == function_decl_K)
266  {
267  val = GET_CONST_NODE(ae->op);
268  THROW_ASSERT(val, "Something of unexpected happen");
269  }
270  }
271  if(val->get_kind() == function_decl_K)
272  {
273  current += tree_helper::print_function_name(TM, GetPointerS<const function_decl>(val));
274  }
275  else if(val->get_kind() == constructor_K)
276  {
277  current += PrintInit(i->second, vppf);
278  }
279  else if(val->get_kind() == var_decl_K)
280  {
281  current += PrintVariable(GET_INDEX_NODE(i->second));
282  }
283  else if(val->get_kind() == ssa_name_K)
284  {
285  current += PrintVariable(GET_INDEX_NODE(i->second));
286  }
287  else
288  {
289  current += PrintNode(i->second, vertex(), vppf);
290  }
291  ++i;
292  if(i != vend)
293  {
294  current += ", ";
295  }
296  if((current.size() + current_length) > MAX_ROW_LENGTH)
297  {
298  current_length = current.size();
299  res += "\n" + current;
300  }
301  else
302  {
303  current_length += current.size();
304  res += current;
305  }
306  }
307  res += '}';
308  break;
309  }
310  case addr_expr_K:
311  case nop_expr_K:
312  case integer_cst_K:
313  case real_cst_K:
314  case string_cst_K:
315  case vector_cst_K:
316  case void_cst_K:
317  case complex_cst_K:
318  {
319  res = PrintConstant(node, vppf);
320  break;
321  }
322  case pointer_plus_expr_K:
323  case plus_expr_K:
324  {
325  vertex dummy_vertex = NULL_VERTEX;
326  res += PrintNode(node, dummy_vertex, vppf);
327  break;
328  }
329  case var_decl_K:
330  {
331  const auto vd = GetPointerS<const var_decl>(node);
332  THROW_ASSERT(vd->init, "expected a initialization value: " + STR(node));
333  res += PrintInit(vd->init, vppf);
334  break;
335  }
336  case binfo_K:
337  case block_K:
338  case call_expr_K:
339  case aggr_init_expr_K:
340  case case_label_expr_K:
341  case ssa_name_K:
342  case statement_list_K:
343  case target_mem_ref_K:
344  case target_mem_ref461_K:
345  case tree_list_K:
346  case tree_vec_K:
347  case bit_not_expr_K:
348  case buffer_ref_K:
349  case card_expr_K:
350  case cleanup_point_expr_K:
351  case conj_expr_K:
352  case convert_expr_K:
353  case exit_expr_K:
354  case fix_ceil_expr_K:
355  case fix_floor_expr_K:
356  case fix_round_expr_K:
357  case fix_trunc_expr_K:
358  case float_expr_K:
359  case imagpart_expr_K:
360  case indirect_ref_K:
361  case misaligned_indirect_ref_K:
362  case loop_expr_K:
363  case lut_expr_K:
364  case negate_expr_K:
365  case non_lvalue_expr_K:
366  case paren_expr_K:
367  case realpart_expr_K:
368  case reinterpret_cast_expr_K:
369  case sizeof_expr_K:
370  case static_cast_expr_K:
371  case throw_expr_K:
372  case truth_not_expr_K:
373  case unsave_expr_K:
374  case va_arg_expr_K:
375  case view_convert_expr_K:
376  case reduc_max_expr_K:
377  case reduc_min_expr_K:
378  case reduc_plus_expr_K:
379  case vec_unpack_hi_expr_K:
380  case vec_unpack_lo_expr_K:
381  case vec_unpack_float_hi_expr_K:
382  case vec_unpack_float_lo_expr_K:
383  case assert_expr_K:
384  case bit_and_expr_K:
385  case bit_ior_expr_K:
386  case bit_xor_expr_K:
387  case catch_expr_K:
388  case ceil_div_expr_K:
389  case ceil_mod_expr_K:
390  case complex_expr_K:
391  case compound_expr_K:
392  case eh_filter_expr_K:
393  case eq_expr_K:
394  case exact_div_expr_K:
395  case fdesc_expr_K:
396  case floor_div_expr_K:
397  case floor_mod_expr_K:
398  case ge_expr_K:
399  case gt_expr_K:
400  case goto_subroutine_K:
401  case in_expr_K:
402  case init_expr_K:
403  case le_expr_K:
404  case lrotate_expr_K:
405  case lshift_expr_K:
406  case lt_expr_K:
407  case max_expr_K:
408  case mem_ref_K:
409  case min_expr_K:
410  case minus_expr_K:
411  case modify_expr_K:
412  case mult_expr_K:
413  case mult_highpart_expr_K:
414  case ne_expr_K:
415  case ordered_expr_K:
416  case postdecrement_expr_K:
417  case postincrement_expr_K:
418  case predecrement_expr_K:
419  case preincrement_expr_K:
420  case range_expr_K:
421  case rdiv_expr_K:
422  case round_div_expr_K:
423  case round_mod_expr_K:
424  case rrotate_expr_K:
425  case rshift_expr_K:
426  case set_le_expr_K:
427  case trunc_div_expr_K:
428  case trunc_mod_expr_K:
429  case truth_and_expr_K:
430  case truth_andif_expr_K:
431  case truth_or_expr_K:
432  case truth_orif_expr_K:
433  case truth_xor_expr_K:
434  case try_catch_expr_K:
435  case try_finally_K:
436  case uneq_expr_K:
437  case ltgt_expr_K:
438  case unge_expr_K:
439  case ungt_expr_K:
440  case unle_expr_K:
441  case unlt_expr_K:
442  case unordered_expr_K:
443  case widen_sum_expr_K:
444  case widen_mult_expr_K:
445  case with_size_expr_K:
446  case vec_lshift_expr_K:
447  case vec_rshift_expr_K:
448  case widen_mult_hi_expr_K:
449  case widen_mult_lo_expr_K:
450  case vec_pack_trunc_expr_K:
451  case vec_pack_sat_expr_K:
452  case vec_pack_fix_trunc_expr_K:
453  case vec_extracteven_expr_K:
454  case vec_extractodd_expr_K:
455  case vec_interleavehigh_expr_K:
456  case vec_interleavelow_expr_K:
457  case const_decl_K:
458  case field_decl_K:
459  case function_decl_K:
460  case label_decl_K:
461  case namespace_decl_K:
462  case parm_decl_K:
463  case result_decl_K:
464  case translation_unit_decl_K:
465  case template_decl_K:
466  case error_mark_K:
467  case using_decl_K:
468  case type_decl_K:
469  case identifier_node_K:
470  case alignof_expr_K:
471  case arrow_expr_K:
472  case reference_expr_K:
473  case abs_expr_K:
474  case CASE_CPP_NODES:
475  case CASE_FAKE_NODES:
476  case CASE_GIMPLE_NODES:
477  case CASE_PRAGMA_NODES:
480  case CASE_TYPE_NODES:
481  case target_expr_K:
482  case extract_bit_expr_K:
483  case sat_plus_expr_K:
484  case sat_minus_expr_K:
485  case extractvalue_expr_K:
486  case extractelement_expr_K:
487  case frem_expr_K:
488  default:
489  THROW_ERROR("Currently not supported nodeID " + STR(node));
490  }
491  return res;
492 }
493 
494 std::string BehavioralHelper::print_attributes(unsigned int var, const var_pp_functorConstRef vppf, bool first) const
495 {
496  std::string res;
497  if(first)
498  {
499  res += "__attribute__ (";
500  }
501  auto tl = GetPointerS<const tree_list>(TM->CGetTreeNode(var));
502  if(tl->purp)
503  {
504  res += "(" + PrintVariable(GET_INDEX_NODE(tl->purp));
505  }
506  if(tl->valu && GET_CONST_NODE(tl->valu)->get_kind() == tree_list_K)
507  {
508  res += print_attributes(GET_INDEX_NODE(tl->valu), vppf, false);
509  }
510  else if(tl->valu && (GET_CONST_NODE(tl->valu)->get_kind() == string_cst_K ||
511  GET_CONST_NODE(tl->valu)->get_kind() == integer_cst_K))
512  {
513  res += "(" + PrintConstant(tl->valu) + ")";
514  }
515  else if(tl->valu)
516  {
517  THROW_ERROR("Not yet supported: " + std::string(GET_NODE(tl->valu)->get_kind_text()));
518  }
519  if(tl->purp)
520  {
521  res += ")";
522  }
523  if(tl->chan)
524  {
525  res += " " + print_attributes(GET_INDEX_NODE(tl->chan), vppf, false);
526  }
527  if(first)
528  {
529  res += ")";
530  }
531  return res;
532 }
533 
534 std::string BehavioralHelper::PrintVariable(unsigned int var) const
535 {
536  if(vars_renaming_table.find(var) != vars_renaming_table.end())
537  {
538  return vars_renaming_table.find(var)->second;
539  }
540  if(vars_symbol_table[var] != "")
541  {
542  return vars_symbol_table[var];
543  }
544  if(var == default_COND)
545  {
546  return "default";
547  }
548  const auto var_node = TM->CGetTreeNode(var);
549  if(var_node->get_kind() == indirect_ref_K)
550  {
551  const auto ir = GetPointerS<const indirect_ref>(var_node);
552  auto pointer = GET_INDEX_NODE(ir->op);
553  std::string pointer_name = PrintVariable(pointer);
554  vars_symbol_table[var] = "*" + pointer_name;
555  return vars_symbol_table[var];
556  }
557  if(var_node->get_kind() == misaligned_indirect_ref_K)
558  {
559  const auto mir = GetPointerS<const misaligned_indirect_ref>(var_node);
560  auto pointer = GET_INDEX_NODE(mir->op);
561  std::string pointer_name = PrintVariable(pointer);
562  vars_symbol_table[var] = "*" + pointer_name;
563  return vars_symbol_table[var];
564  }
565  if(var_node->get_kind() == mem_ref_K)
566  {
567  const auto mr = GetPointerS<const mem_ref>(var_node);
568  const auto offset = tree_helper::GetConstValue(mr->op1);
569  const tree_manipulationRef tm(new tree_manipulation(AppM->get_tree_manager(), Param, AppM));
570  const auto pointer_type = tm->GetPointerType(mr->type, 8);
571  const auto type_string = tree_helper::PrintType(TM, pointer_type);
572  if(offset == 0)
573  {
574  vars_symbol_table[var] = "*((" + type_string + ")(" + PrintVariable(GET_INDEX_NODE(mr->op0)) + "))";
575  }
576  else
577  {
578  vars_symbol_table[var] = "*((" + type_string + ")(((unsigned char*)" + PrintVariable(GET_INDEX_NODE(mr->op0)) +
579  ") + " + STR(offset) + "))";
580  }
581  return vars_symbol_table[var];
582  }
583  if(var_node->get_kind() == identifier_node_K)
584  {
585  const auto in = GetPointerS<const identifier_node>(var_node);
586  vars_symbol_table[var] = in->strg;
587  return vars_symbol_table[var];
588  }
589  if(var_node->get_kind() == field_decl_K)
590  {
591  const auto fd = GetPointerS<const field_decl>(var_node);
592  if(fd->name)
593  {
594  const auto id = GetPointerS<const identifier_node>(GET_NODE(fd->name));
595  return tree_helper::NormalizeTypename(id->strg);
596  }
597  else
598  {
599  return INTERNAL + STR(var);
600  }
601  }
602  if(var_node->get_kind() == function_decl_K)
603  {
604  const auto fd = GetPointerS<const function_decl>(var_node);
606  }
607  if(var_node->get_kind() == ssa_name_K)
608  {
609  const auto sa = GetPointerS<const ssa_name>(var_node);
610  std::string name;
611  if(sa->var)
612  {
613  name = PrintVariable(GET_INDEX_NODE(sa->var));
614  }
615  THROW_ASSERT(sa->volatile_flag || sa->CGetDefStmts().size(), sa->ToString() + " has not define statement");
616  if(sa->virtual_flag || (!sa->volatile_flag && GET_CONST_NODE(sa->CGetDefStmt())->get_kind() != gimple_nop_K))
617  {
618  name += ("_" + STR(sa->vers));
619  }
620  else
621  {
622  THROW_ASSERT(sa->var, "the name has to be defined for volatile or parameters");
623  }
624  // if(sa->min && sa->max) name += "/*[" + PrintConstant(sa->min) + "," + PrintConstant(sa->max) + "]*/";
625  return name;
626  }
627  if(var_node->get_kind() == var_decl_K || var_node->get_kind() == parm_decl_K)
628  {
629  const auto dn = GetPointerS<const decl_node>(var_node);
630  if(dn->name)
631  {
632  const auto id = GetPointerS<const identifier_node>(GET_CONST_NODE(dn->name));
634  return vars_symbol_table[var];
635  }
636  }
637  if(is_a_constant(var))
638  {
639  vars_symbol_table[var] = PrintConstant(var_node);
640  }
641  if(vars_symbol_table[var] == "")
642  {
643  vars_symbol_table[var] = INTERNAL + STR(var);
644  }
645  return vars_symbol_table[var];
646 }
647 
649 {
650  const auto node = _node->get_kind() == tree_reindex_K ? GET_CONST_NODE(_node) : _node;
651  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Printing constant " + STR(_node));
652  THROW_ASSERT(is_a_constant(node->index), std::string("Object is not a constant ") + STR(node));
653  if(node->index == default_COND)
654  {
655  return "default";
656  }
657  std::string res;
658  switch(node->get_kind())
659  {
660  case integer_cst_K:
661  {
662  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->integer_cst");
663  const auto ic = GetPointerS<const integer_cst>(node);
664  const auto type = GET_CONST_NODE(ic->type);
665  const auto it = GetPointer<const integer_type>(type);
666  const auto unsigned_flag = (it && it->unsigned_flag) || type->get_kind() == pointer_type_K ||
667  type->get_kind() == reference_type_K || type->get_kind() == boolean_type_K;
668 #if 0
669  if (it)
671  {
672  std::string predicted_type;
673  if (it->unsigned_flag)
674  predicted_type += "unsigned ";
675  if (it->algn == 8)
676  predicted_type += "char";
677  else if (it->algn == 16)
678  predicted_type += "short";
679  else if (it->algn == 32)
680  predicted_type += "int";
681  else if (it->algn == 64)
682  predicted_type += "auto int";
683  std::string actual_type = tree_helper::PrintType(TM, ic->type);
684  if (predicted_type != actual_type && actual_type != "bit_size_type")
685  res = "(" + actual_type + ")";
686  }
687 #endif
688  THROW_ASSERT(ic, "");
689  auto value = tree_helper::GetConstValue(node, !unsigned_flag);
691  // TODO: fix for bitwidth greater than 64 bits
692  if((it && it->prec == 64) && (value == (static_cast<long long int>(-0x08000000000000000LL))))
693  {
694  res = "(long long int)-0x08000000000000000";
695  }
696  else if((it && it->prec == 32) && (value == (static_cast<long int>(-0x080000000L))))
697  {
698  res = "(long int)-0x080000000";
699  }
700  else
701  {
702  if(it && it->unsigned_flag)
703  {
704  res += STR(value & ((integer_cst_t(1) << it->prec) - 1));
705  }
706  else
707  {
708  res += STR(value);
709  }
710  }
711  if(it && it->prec > 32)
712  {
713  if(it && it->unsigned_flag)
714  {
715  res += "LLU";
716  }
717  else
718  {
719  res += "LL";
720  }
721  }
722  else
723  {
724  if(unsigned_flag)
725  {
726  res += "u";
727  }
728  else if(type->get_kind() == pointer_type_K || type->get_kind() == reference_type_K)
729  {
730  res += "/*B*/";
731  }
732  }
734  break;
735  }
736  case real_cst_K:
737  {
738  const auto rc = GetPointerS<const real_cst>(node);
739  if(rc->overflow_flag)
740  {
741  res += " overflow";
742  }
743  if(tree_helper::IsRealType(rc->type))
744  {
745  if(GetPointerS<const real_type>(GET_CONST_NODE(rc->type))->prec == 80)
746  {
747  if(strcasecmp(rc->valr.data(), "Inf") == 0)
748  {
749  if(rc->valx[0] == '-')
750  {
751  res += "-";
752  }
753  res += "__builtin_infl()";
754  }
755  else if(strcasecmp(rc->valr.data(), "Nan") == 0)
756  {
757  if(rc->valx[0] == '-')
758  {
759  res += "-";
760  }
761  res += "__builtin_nanl(\"\")";
762  }
763  else
764  {
765  res += rc->valr;
766  res += "L";
767  }
768  }
769  else if(GetPointerS<const real_type>(GET_CONST_NODE(rc->type))->prec == 64)
770  {
771  if(strcasecmp(rc->valr.data(), "Inf") == 0)
772  {
773  if(rc->valx[0] == '-')
774  {
775  res += "-";
776  }
777  res += "__builtin_inf()";
778  }
779  else if(strcasecmp(rc->valr.data(), "Nan") == 0)
780  {
781  if(rc->valx[0] == '-')
782  {
783  res += "-";
784  }
785  res += "__builtin_nan(\"\")";
786  }
787  else
788  {
789  res += rc->valr;
790  }
791  }
792  else if(strcasecmp(rc->valr.data(), "Inf") == 0)
793  {
794  if(rc->valx[0] == '-')
795  {
796  res += "-";
797  }
798  res += "__builtin_inff()";
799  }
800  else if(strcasecmp(rc->valr.data(), "Nan") == 0)
801  {
802  if(rc->valx[0] == '-')
803  {
804  res += "-";
805  }
806  res += "__builtin_nanf(\"\")";
807  }
808  else
809  {
811  res += /*"(float)" +*/ rc->valr;
812  }
813  }
814  else
815  {
816  THROW_ERROR(std::string("Node not yet supported: ") + node->get_kind_text());
817  }
818  break;
819  }
820  case complex_cst_K:
821  {
822  const auto cc = GetPointerS<const complex_cst>(node);
823  res += "(";
824  res += PrintConstant(cc->real, vppf);
825  res += "+";
826  res += PrintConstant(cc->imag, vppf);
827  res += "*1i)";
828  break;
829  }
830  case string_cst_K:
831  {
832  const auto sc = GetPointerS<const string_cst>(node);
833  if(sc->type)
834  {
835  const auto at = GetPointer<const array_type>(GET_CONST_NODE(sc->type));
836  THROW_ASSERT(at, "Expected an array type");
837  const auto elts = GetPointerS<const integer_type>(GET_CONST_NODE(at->elts));
838  if(elts->prec == 32) // wide char string
839  {
840  if(elts->unsigned_flag && !tree_helper::IsSystemType(at->elts))
841  {
842  THROW_ERROR_CODE(C_EC, "Unsigned wide char not supported");
843  }
844  res = "L";
845  }
846  }
847  res += "\"" + sc->strg + "\"";
848  break;
849  }
850  case vector_cst_K:
851  {
852  const auto vc = GetPointerS<const vector_cst>(node);
853  THROW_ASSERT(GET_CONST_NODE(vc->type)->get_kind() == vector_type_K,
854  "Vector constant of type " + GET_CONST_NODE(vc->type)->get_kind_text());
855  if(GET_NODE(GetPointerS<const vector_type>(GET_CONST_NODE(vc->type))->elts)->get_kind() != pointer_type_K)
856  {
857  res += "(" + tree_helper::PrintType(TM, vc->type, false, true) + ") ";
858  }
859  res += "{ ";
860  for(unsigned int i = 0; i < (vc->list_of_valu).size(); i++) // vector elements
861  {
862  res += PrintConstant(vc->list_of_valu[i], vppf);
863  if(i != vc->list_of_valu.size() - 1)
864  { // not the last element element
865  res += ", ";
866  }
867  }
868  res += " }";
869  break;
870  }
871  case case_label_expr_K:
872  {
873  const auto cl = GetPointerS<const case_label_expr>(node);
874  if(cl->default_flag)
875  {
876  res += "default";
877  }
878  else
879  {
880  if(cl->op1)
881  {
882  THROW_ASSERT(GetPointer<integer_cst>(GET_CONST_NODE(cl->op0)),
883  "Case label expression " + STR(node) + " does not use integer_cst");
884  THROW_ASSERT(GetPointer<integer_cst>(GET_CONST_NODE(cl->op1)),
885  "Case label expression " + STR(node) + " does not use integer_cst");
886  auto low = tree_helper::GetConstValue(cl->op0);
887  auto high = tree_helper::GetConstValue(cl->op1);
888  while(low < high)
889  {
890  res += STR(low) + "u : case ";
891  low++;
892  }
893  res += STR(low) + "u";
894  }
895  else
896  {
897  res += PrintConstant(cl->op0, vppf);
898  }
899  }
900  break;
901  }
902  case label_decl_K:
903  {
904  const auto ld = GetPointerS<const label_decl>(node);
905  THROW_ASSERT(ld->name, "name expected in a label_decl");
906  const auto id = GetPointer<const identifier_node>(GET_CONST_NODE(ld->name));
907  THROW_ASSERT(id, "expected an identifier_node");
908  res += id->strg;
909  break;
910  }
911  case nop_expr_K:
912  {
913  const auto ue = GetPointerS<const unary_expr>(node);
914  if(!(GET_CONST_NODE(ue->op)->get_kind() == addr_expr_K &&
915  GET_NODE(GetPointerS<const addr_expr>(GET_CONST_NODE(ue->op))->op)->get_kind() == label_decl_K))
916  {
917  res += "(" + tree_helper::PrintType(TM, ue->type) + ") ";
918  }
919  res += PrintConstant(ue->op, vppf);
920  break;
921  }
922  case addr_expr_K:
923  {
924  const auto ue = GetPointerS<const unary_expr>(node);
925  if(is_a_constant(GET_INDEX_NODE(ue->op)))
926  {
927  res += "(&(" + PrintConstant(ue->op) + "))";
928  }
929  else if(GET_CONST_NODE(ue->op)->get_kind() == function_decl_K)
930  {
931  res += tree_helper::print_function_name(TM, GetPointerS<const function_decl>(GET_CONST_NODE(ue->op)));
932  }
933  else
934  {
935  if(vppf)
936  {
937  res += "(&(" + (*vppf)(GET_INDEX_NODE(ue->op)) + "))";
938  }
939  else
940  {
941  res += "(&(" + PrintVariable(GET_INDEX_NODE(ue->op)) + "))";
942  }
943  }
944  break;
945  }
946  case binfo_K:
947  case block_K:
948  case call_expr_K:
949  case aggr_init_expr_K:
950  case constructor_K:
951  case identifier_node_K:
952  case ssa_name_K:
953  case statement_list_K:
954  case target_expr_K:
955  case target_mem_ref_K:
956  case target_mem_ref461_K:
957  case tree_list_K:
958  case tree_vec_K:
959  case const_decl_K:
960  case field_decl_K:
961  case function_decl_K:
962  case namespace_decl_K:
963  case parm_decl_K:
964  case result_decl_K:
965  case translation_unit_decl_K:
966  case using_decl_K:
967  case type_decl_K:
968  case var_decl_K:
969  case template_decl_K:
970  case abs_expr_K:
971  case alignof_expr_K:
972  case arrow_expr_K:
973  case bit_not_expr_K:
974  case buffer_ref_K:
975  case card_expr_K:
976  case cleanup_point_expr_K:
977  case conj_expr_K:
978  case convert_expr_K:
979  case exit_expr_K:
980  case fix_ceil_expr_K:
981  case fix_floor_expr_K:
982  case fix_round_expr_K:
983  case fix_trunc_expr_K:
984  case float_expr_K:
985  case imagpart_expr_K:
986  case indirect_ref_K:
987  case misaligned_indirect_ref_K:
988  case loop_expr_K:
989  case negate_expr_K:
990  case non_lvalue_expr_K:
991  case paren_expr_K:
992  case realpart_expr_K:
993  case reference_expr_K:
994  case reinterpret_cast_expr_K:
995  case sizeof_expr_K:
996  case static_cast_expr_K:
997  case throw_expr_K:
998  case truth_not_expr_K:
999  case unsave_expr_K:
1000  case va_arg_expr_K:
1001  case view_convert_expr_K:
1002  case reduc_max_expr_K:
1003  case reduc_min_expr_K:
1004  case reduc_plus_expr_K:
1005  case vec_unpack_hi_expr_K:
1006  case vec_unpack_lo_expr_K:
1007  case vec_unpack_float_hi_expr_K:
1008  case vec_unpack_float_lo_expr_K:
1009  case error_mark_K:
1010  case lut_expr_K:
1012  case CASE_CPP_NODES:
1013  case CASE_FAKE_NODES:
1014  case CASE_GIMPLE_NODES:
1015  case CASE_PRAGMA_NODES:
1018  case CASE_TYPE_NODES:
1019  case void_cst_K:
1020  default:
1021  THROW_ERROR("Var object is not a constant " + STR(node) + " " + node->get_kind_text());
1022  }
1023  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Printed constant " + res);
1024  return res;
1025 }
1026 
1027 unsigned long long BehavioralHelper::get_size(unsigned int var) const
1028 {
1029  return tree_helper::Size(TM->CGetTreeReindex(var));
1030 }
1031 
1033 {
1034  return function_name;
1035 }
1036 
1038 {
1039  return tree_helper::GetMangledFunctionName(GetPointerS<const function_decl>(TM->CGetTreeNode(function_index)));
1040 }
1041 
1043 {
1044  return function_index;
1045 }
1046 
1047 unsigned int BehavioralHelper::GetFunctionReturnType(unsigned int function) const
1048 {
1049  const auto return_type = tree_helper::GetFunctionReturnType(TM->CGetTreeReindex(function));
1050  if(return_type)
1051  {
1052  return return_type->index;
1053  }
1054  else
1055  {
1056  return 0;
1057  }
1058 }
1059 
1060 const std::list<unsigned int> BehavioralHelper::get_parameters() const
1061 {
1062  std::list<unsigned int> parameters;
1063  const auto fun = TM->CGetTreeNode(function_index);
1064  const auto fd = GetPointerS<const function_decl>(fun);
1065  const auto& list_of_args = fd->list_of_args;
1066  if(fd->list_of_args.size())
1067  {
1068  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Parameter list size: " + STR(list_of_args.size()));
1069  for(const auto& list_of_arg : list_of_args)
1070  {
1071  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Adding parameter " + STR(GET_INDEX_NODE(list_of_arg)));
1072  parameters.push_back(GET_INDEX_NODE(list_of_arg));
1073  }
1074  }
1075  else
1076  {
1077  const auto ft = GetPointerS<const function_type>(GET_CONST_NODE(fd->type));
1078  if(ft->prms)
1079  {
1080  auto currentp = ft->prms;
1081  while(currentp)
1082  {
1083  const auto tl = GetPointerS<const tree_list>(GET_CONST_NODE(currentp));
1085  "---Adding parameter " + STR(GET_INDEX_CONST_NODE(tl->valu)));
1086  if(GET_NODE(tl->valu)->get_kind() != void_type_K)
1087  {
1088  parameters.push_back(GET_INDEX_NODE(tl->valu));
1089  }
1090  currentp = tl->chan;
1091  }
1092  }
1093  }
1094  return parameters;
1095 }
1096 
1097 std::vector<tree_nodeRef> BehavioralHelper::GetParameters() const
1098 {
1099  const auto fun = TM->CGetTreeNode(function_index);
1100  const auto fd = GetPointerS<const function_decl>(fun);
1101  if(fd->list_of_args.size())
1102  {
1103  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "---Parameter list size: " + STR(fd->list_of_args.size()));
1104  return fd->list_of_args;
1105  }
1106 
1107  std::vector<tree_nodeRef> parameters;
1108  const auto ft = GetPointerS<const function_type>(GET_CONST_NODE(fd->type));
1109  if(ft->prms)
1110  {
1111  auto currentp = ft->prms;
1112  while(currentp)
1113  {
1114  const auto tl = GetPointerS<const tree_list>(GET_CONST_NODE(currentp));
1116  "---Adding parameter " + STR(GET_INDEX_CONST_NODE(tl->valu)));
1117  if(GET_CONST_NODE(tl->valu)->get_kind() != void_type_K)
1118  {
1119  parameters.push_back(tl->valu);
1120  }
1121  currentp = tl->chan;
1122  }
1123  }
1124  return parameters;
1125 }
1126 
1128 {
1129  return body;
1130 }
1131 
1132 void BehavioralHelper::add_initialization(unsigned int var, unsigned int init)
1133 {
1134  initializations[var] = init;
1135 }
1136 
1138 {
1139  opaque = true;
1140 }
1141 
1143 {
1144  opaque = false;
1145 }
1146 
1148 {
1149  return opaque;
1150 }
1151 
1152 unsigned int BehavioralHelper::get_type(const unsigned int var) const
1153 {
1154  return tree_helper::get_type_index(TM, var);
1155 }
1156 
1157 unsigned int BehavioralHelper::get_pointed_type(const unsigned int type) const
1158 {
1160 }
1161 
1162 unsigned int BehavioralHelper::GetElements(const unsigned int type) const
1163 {
1165 }
1166 
1168  bool init_has_to_be_printed) const
1169 {
1170  std::string return_value;
1171  const auto curr_tn = TM->CGetTreeNode(var);
1172  THROW_ASSERT(GetPointer<const decl_node>(curr_tn) || GetPointer<const ssa_name>(curr_tn),
1173  "Call pparameter_type_indexrint_var_declaration on node " + STR(var) + " which is of type " +
1174  curr_tn->get_kind_text());
1175  const decl_node* dn = nullptr;
1176  if(GetPointer<const decl_node>(curr_tn))
1177  {
1178  dn = GetPointerS<const decl_node>(curr_tn);
1179  }
1181  if(!dn || !(dn->operating_system_flag || dn->library_system_flag) || tree_helper::IsInLibbambu(curr_tn))
1182  {
1183  return_value += tree_helper::PrintType(TM, tree_helper::CGetType(curr_tn), false, false, init_has_to_be_printed,
1184  curr_tn, vppf);
1185  auto attributes = get_attributes(var);
1186  CustomUnorderedSet<unsigned int> list_of_variables;
1187  const unsigned int init = GetInit(var, list_of_variables);
1188  if(attributes)
1189  {
1190  return_value += " " + print_attributes(attributes, vppf);
1191  }
1192  if(dn && dn->packed_flag)
1193  {
1194  return_value += " __attribute__((packed))";
1195  }
1196  if(dn &&
1197  ((dn->orig && (GetPointer<const var_decl>(curr_tn)) &&
1198  (GetPointer<const var_decl>(GET_CONST_NODE(dn->orig))) &&
1199  (GetPointer<const var_decl>(curr_tn)->algn != GetPointer<const var_decl>(GET_CONST_NODE(dn->orig))->algn)) ||
1200  ((GetPointer<const var_decl>(curr_tn)) && (GetPointer<const var_decl>(curr_tn)->algn == 128))))
1201  {
1202  return_value += " __attribute__ ((aligned (" + STR(GetPointerS<const var_decl>(curr_tn)->algn / 8) + "))) ";
1203  }
1204  if(init && init_has_to_be_printed)
1205  {
1206  return_value += " = " + PrintInit(TM->CGetTreeReindex(init), vppf);
1207  }
1208  }
1209  return return_value;
1210 }
1211 
1213 {
1215  THROW_ASSERT(tn->get_kind() == function_decl_K, "function_index is not a function decl");
1216  tn = GET_NODE(GetPointer<function_decl>(tn)->type);
1217  return GetPointer<function_type>(tn)->varargs_flag;
1218 }
1219 
1220 std::string BehavioralHelper::PrintNode(unsigned int _node, vertex v, const var_pp_functorConstRef vppf) const
1221 {
1222  const auto node = TM->CGetTreeNode(_node);
1223  return PrintNode(node, v, vppf);
1224 }
1225 
1227  const var_pp_functorConstRef vppf) const
1228 {
1229  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Printing node " + STR(_node));
1230  std::string res = "";
1231  const auto node = _node->get_kind() == tree_reindex_K ? GET_CONST_NODE(_node) : _node;
1232  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Type is " + std::string(node->get_kind_text()));
1233  switch(node->get_kind())
1234  {
1235  /* Binary arithmetic and logic expressions. */
1236  case sat_plus_expr_K:
1237  {
1238  const auto be = GetPointerS<const binary_expr>(node);
1239  const auto res_size = tree_helper::Size(be->type);
1240  std::string left, right;
1241  left = ("(" + PrintNode(be->op0, v, vppf) + ")");
1242  right = ("(" + PrintNode(be->op1, v, vppf) + ")");
1243  if(tree_helper::IsSignedIntegerType(be->type))
1244  {
1245  const auto op_size = tree_helper::Size(be->op0);
1246  res += "((((" + left + " & " + STR(1ULL << (op_size - 1)) + "ULL) ^ (" + right + " & " +
1247  STR(1ULL << (op_size - 1)) +
1248  "ULL)) |"
1249  "((" +
1250  left + " & " + STR(1ULL << (op_size - 1)) + "ULL) == ((" + left + " + " + right + ") & " +
1251  STR(1ULL << (op_size - 1)) +
1252  "ULL))) ? "
1253  "(" +
1254  left + " + " + right +
1255  ") "
1256  ": ((" +
1257  left + " & " + STR(1ULL << (op_size - 1)) + "ULL) ? " +
1258  STR(static_cast<long long>(-1ULL << (res_size - 1))) + " : " + STR((1LL << (res_size - 1)) - 1) +
1259  "))";
1260  }
1261  else
1262  {
1263  res += "( (" + left + " + " + right + ") < " + right + " ? " + STR((1ULL << res_size) - 1) +
1264  (res_size > 32 ? "ULL" : "") + " : " + left + " + " + right + ")";
1265  }
1266  break;
1267  }
1268  case sat_minus_expr_K:
1269  {
1270  const auto be = GetPointerS<const binary_expr>(node);
1271  std::string left, right;
1272  left = ("(" + PrintNode(be->op0, v, vppf) + ")");
1273  right = ("(" + PrintNode(be->op1, v, vppf) + ")");
1274  if(tree_helper::IsSignedIntegerType(be->type))
1275  {
1276  const auto res_size = tree_helper::Size(be->type);
1277  const auto op_size = tree_helper::Size(be->op0);
1278  res += "((((" + left + " & " + STR(1ULL << (op_size - 1)) + "ULL) ^ (~" + right + " & " +
1279  STR(1ULL << (op_size - 1)) +
1280  "ULL)) | "
1281  "((" +
1282  left + " & " + STR(1ULL << (op_size - 1)) + "ULL) == ((" + left + " - " + right + ") & " +
1283  STR(1ULL << (op_size - 1)) +
1284  "ULL))) ? "
1285  "(" +
1286  left + " - " + right +
1287  ") "
1288  ": ((" +
1289  left + " & " + STR(1ULL << (op_size - 1)) + "ULL) ? " +
1290  STR(static_cast<long long>(-1ULL << (res_size - 1))) + " : " + STR((1LL << (res_size - 1)) - 1) +
1291  "))";
1292  }
1293  else
1294  {
1295  res += "( " + left + " > " + right + " ? " + left + " - " + right + " : 0)";
1296  }
1297  break;
1298  }
1299  case frem_expr_K:
1300  {
1301  const auto be = GetPointerS<const binary_expr>(node);
1302  std::string left, right;
1303  THROW_ASSERT(GetPointer<const real_type>(GET_CONST_NODE(be->type)), "unexpected case");
1304  left = ("(" + PrintNode(be->op0, v, vppf) + ")");
1305  right = ("(" + PrintNode(be->op1, v, vppf) + ")");
1306 
1307  const auto rt = GetPointerS<const real_type>(GET_CONST_NODE(be->type));
1308  if(rt->prec == 80)
1309  {
1310  res += "fmodl(" + left + "," + right + ")";
1311  }
1312  else if(rt->prec == 64)
1313  {
1314  res += "fmod(" + left + "," + right + ")";
1315  }
1316  else if(rt->prec == 32)
1317  {
1318  res += "fmodf(" + left + "," + right + ")";
1319  }
1320  else
1321  {
1322  THROW_ERROR("fmod on a real number with not supported precision");
1323  }
1324  break;
1325  }
1326  case plus_expr_K:
1327  {
1328  const auto be = GetPointerS<const binary_expr>(node);
1329  const auto op = tree_helper::op_symbol(node);
1330  const auto left_op_type = tree_helper::CGetType(be->op0);
1331  const auto right_op_type = tree_helper::CGetType(be->op1);
1332  const auto vector =
1333  tree_helper::IsVectorType(be->type) &&
1334  ((tree_helper::IsVectorType(left_op_type) && left_op_type->index != GET_INDEX_NODE(be->type)) ||
1335  (tree_helper::IsVectorType(right_op_type) && right_op_type->index != GET_INDEX_NODE(be->type)));
1336  if(vector)
1337  {
1338  const auto element_type = tree_helper::CGetElements(be->type);
1339  const auto element_size = tree_helper::Size(element_type);
1340  const auto size = tree_helper::Size(be->type);
1341  const auto vector_size = size / element_size;
1342  res += "(" + tree_helper::PrintType(TM, be->type) + ") ";
1343  res += "{";
1344  for(unsigned int ind = 0; ind < vector_size; ++ind)
1345  {
1346  res += "(" + PrintNode(be->op0, v, vppf) + ")[" + STR(ind) + "] + (" + PrintNode(be->op1, v, vppf) +
1347  ")[" + STR(ind) + "]";
1348  if(ind != vector_size - 1)
1349  {
1350  res += ", ";
1351  }
1352  }
1353  res += "}";
1354  }
1355  else
1356  {
1357  const auto type = tree_helper::CGetType(_node);
1358  unsigned int prec = 0;
1359  unsigned int algn = 0;
1360  if(type && GET_CONST_NODE(type)->get_kind() == integer_type_K)
1361  {
1362  prec = GetPointerS<const integer_type>(GET_CONST_NODE(type))->prec;
1363  algn = GetPointerS<const integer_type>(GET_CONST_NODE(type))->algn;
1364  }
1365  // bitfield type
1366  if(prec != algn && prec % algn)
1367  {
1368  res += "((";
1369  }
1370  res += "(" + tree_helper::PrintType(TM, be->type) + ")(";
1371 
1372  if(GetPointer<const decl_node>(GET_CONST_NODE(be->op0)) ||
1373  GetPointer<const ssa_name>(GET_CONST_NODE(be->op0)))
1374  {
1375  res += PrintNode(be->op0, v, vppf);
1376  }
1377  else
1378  {
1379  res += ("(" + PrintNode(be->op0, v, vppf) + ")");
1380  }
1381  res += std::string(" ") + op + " ";
1382 
1383  if(GetPointer<const decl_node>(GET_CONST_NODE(be->op1)) ||
1384  GetPointer<const ssa_name>(GET_CONST_NODE(be->op1)))
1385  {
1386  res += PrintNode(be->op1, v, vppf);
1387  }
1388  else
1389  {
1390  res += ("(" + PrintNode(be->op1, v, vppf) + ")");
1391  }
1392  res += ")";
1393  if(prec != algn && prec % algn)
1394  {
1395  res += ")%(1";
1396  if(prec > 32)
1397  {
1398  res += "LL";
1399  }
1400  if(GetPointerS<const integer_type>(GET_CONST_NODE(type))->unsigned_flag)
1401  {
1402  res += "U";
1403  }
1404  res += " << " + STR(prec) + "))";
1405  }
1406  }
1407  break;
1408  }
1409  case bit_ior_expr_K:
1410  case bit_xor_expr_K:
1411  case bit_and_expr_K:
1412  {
1413  const auto be = GetPointerS<const binary_expr>(node);
1414  const auto left_op_type = tree_helper::CGetType(be->op0);
1415  const auto right_op_type = tree_helper::CGetType(be->op1);
1416  const auto op = tree_helper::op_symbol(node);
1417  const auto vector =
1418  tree_helper::IsVectorType(be->type) &&
1419  ((tree_helper::IsVectorType(left_op_type) && left_op_type->index != GET_INDEX_NODE(be->type)) ||
1420  (tree_helper::IsVectorType(right_op_type) && right_op_type->index != GET_INDEX_NODE(be->type)));
1421  if(vector)
1422  {
1423  const auto element_type = tree_helper::CGetElements(be->type);
1424  const auto element_size = tree_helper::Size(element_type);
1425  const auto size = tree_helper::Size(be->type);
1426  const auto vector_size = size / element_size;
1427  res += "(" + tree_helper::PrintType(TM, be->type) + ") ";
1428  res += "{";
1429  for(unsigned int ind = 0; ind < vector_size; ++ind)
1430  {
1431  res += "(" + PrintNode(be->op0, v, vppf) + ")[" + STR(ind) + "] " + op + " (" +
1432  PrintNode(be->op1, v, vppf) + ")[" + STR(ind) + "]";
1433  if(ind != vector_size - 1)
1434  {
1435  res += ", ";
1436  }
1437  }
1438  res += "}";
1439  }
1440  else
1441  {
1442  const auto type = tree_helper::CGetType(node);
1443  bool bit_expression = type && GET_CONST_NODE(type)->get_kind() == pointer_type_K;
1444  unsigned int prec = 0;
1445  unsigned int algn = 0;
1446  if(type && GET_CONST_NODE(type)->get_kind() == integer_type_K)
1447  {
1448  prec = GetPointerS<const integer_type>(GET_CONST_NODE(type))->prec;
1449  algn = GetPointerS<const integer_type>(GET_CONST_NODE(type))->algn;
1450  }
1451  // bitfield type
1452  if(prec != algn && prec % algn)
1453  {
1454  res += "((";
1455  }
1456  if(bit_expression)
1457  {
1458  res += "((" + tree_helper::PrintType(TM, tree_helper::CGetType(_node)) + ")(((unsigned)(";
1459  }
1460 
1461  if(GetPointer<const decl_node>(GET_CONST_NODE(be->op0)) ||
1462  GetPointer<const ssa_name>(GET_CONST_NODE(be->op0)))
1463  {
1464  res += PrintNode(be->op0, v, vppf);
1465  }
1466  else
1467  {
1468  res += ("(" + PrintNode(be->op0, v, vppf) + ")");
1469  }
1470  if(bit_expression)
1471  {
1472  res += "))";
1473  }
1474  res += std::string(" ") + op + " ";
1475  if(bit_expression)
1476  {
1477  res += "((unsigned)(";
1478  }
1479 
1480  if(GetPointer<const decl_node>(GET_CONST_NODE(be->op1)) ||
1481  GetPointer<const ssa_name>(GET_CONST_NODE(be->op1)))
1482  {
1483  res += PrintNode(be->op1, v, vppf);
1484  }
1485  else
1486  {
1487  res += ("(" + PrintNode(be->op1, v, vppf) + ")");
1488  }
1489  if(bit_expression)
1490  {
1491  res += "))))";
1492  }
1493  if(prec != algn && prec % algn)
1494  {
1495  res += ")%(1";
1496  if(prec > 32)
1497  {
1498  res += "LL";
1499  }
1500  if(GetPointerS<const integer_type>(GET_CONST_NODE(type))->unsigned_flag)
1501  {
1502  res += "U";
1503  }
1504  res += " << " + STR(prec) + "))";
1505  }
1506  }
1507  break;
1508  }
1509  case vec_rshift_expr_K:
1510  {
1511  const auto vre = GetPointerS<const vec_rshift_expr>(node);
1512  const auto element_type = tree_helper::CGetElements(vre->type);
1513  const auto element_size = tree_helper::Size(element_type);
1514  const auto size = tree_helper::Size(vre->type);
1515  const auto vector_size = size / element_size;
1516  res += "/*" + vre->get_kind_text() + "*/";
1517  res += "(" + tree_helper::PrintType(TM, vre->type) + ") ";
1518  res += "{";
1519  for(unsigned int ind = 0; ind < vector_size; ++ind)
1520  {
1521  for(unsigned int k = ind; k < vector_size; ++k)
1522  {
1523  res += "((" + PrintNode(vre->op1, v, vppf) + " >= " + STR(element_size * (k - ind)) + "&&" +
1524  PrintNode(vre->op1, v, vppf) + " < " + STR(element_size * (k - ind + 1)) + ") ? ((" +
1525  PrintNode(vre->op0, v, vppf) + ")[" + STR(k) + "]) >> (" + PrintNode(vre->op1, v, vppf) + "-" +
1526  STR(element_size * (k - ind)) + "): 0)";
1527  if(k != vector_size - 1)
1528  {
1529  res += "|";
1530  }
1531  }
1532 
1533  for(unsigned int k = ind + 1; k < vector_size; ++k)
1534  {
1535  res += "| ((" + PrintNode(vre->op1, v, vppf) + " > " + STR(element_size * (k - 1 - ind)) + "&&" +
1536  PrintNode(vre->op1, v, vppf) + " < " + STR(element_size * (k - ind)) + ") ? ((" +
1537  PrintNode(vre->op0, v, vppf) + ")[" + STR(k) + "]) << (" + STR(element_size * (k - ind)) + "-" +
1538  PrintNode(vre->op1, v, vppf) + "): 0)";
1539  }
1540  if(ind != vector_size - 1)
1541  {
1542  res += ", ";
1543  }
1544  }
1545  res += "}";
1546  break;
1547  }
1548  case vec_lshift_expr_K:
1549  {
1550  const auto vle = GetPointerS<const vec_lshift_expr>(node);
1551  const auto element_type = tree_helper::CGetElements(vle->type);
1552  const auto element_size = tree_helper::Size(element_type);
1553  const auto size = tree_helper::Size(vle->type);
1554  const auto vector_size = size / element_size;
1555  res += "/*" + vle->get_kind_text() + "*/";
1556  res += "(" + tree_helper::PrintType(TM, vle->type) + ") ";
1557  res += "{";
1558  for(unsigned int ind = 0; ind < vector_size; ++ind)
1559  {
1560  for(unsigned int k = 0; k <= ind; ++k)
1561  {
1562  res += "((" + PrintNode(vle->op1, v, vppf) + " >= " + STR(element_size * (k)) + "&&" +
1563  PrintNode(vle->op1, v, vppf) + " < " + STR(element_size * (k + 1)) + ") ? ((" +
1564  PrintNode(vle->op0, v, vppf) + ")[" + STR(ind - k) + "]) << (" + PrintNode(vle->op1, v, vppf) +
1565  "-" + STR(element_size * k) + "): 0)";
1566  if(k != ind)
1567  {
1568  res += "|";
1569  }
1570  }
1571  for(unsigned int k = 0; k < ind; ++k)
1572  {
1573  res += "| ((" + PrintNode(vle->op1, v, vppf) + " > " + STR(element_size * (k)) + "&&" +
1574  PrintNode(vle->op1, v, vppf) + " < " + STR(element_size * (k + 1)) + ") ? ((" +
1575  PrintNode(vle->op0, v, vppf) + ")[" + STR(ind - k - 1) + "]) >> (" + STR(element_size * (k + 1)) +
1576  "-" + PrintNode(vle->op1, v, vppf) + "): 0)";
1577  }
1578  if(ind != vector_size - 1)
1579  {
1580  res += ", ";
1581  }
1582  }
1583  res += "}";
1584  break;
1585  }
1586  case mult_highpart_expr_K:
1587  {
1588  THROW_UNREACHABLE("Not implemented");
1589  break;
1590  }
1591  case mult_expr_K:
1592  case minus_expr_K:
1593  case trunc_div_expr_K:
1594  case ceil_div_expr_K:
1595  case floor_div_expr_K:
1596  case round_div_expr_K:
1597  case trunc_mod_expr_K:
1598  case ceil_mod_expr_K:
1599  case floor_mod_expr_K:
1600  case round_mod_expr_K:
1601  case rdiv_expr_K:
1602  case exact_div_expr_K:
1603  case lshift_expr_K:
1604  case rshift_expr_K:
1605  case truth_andif_expr_K:
1606  case truth_orif_expr_K:
1607  case truth_and_expr_K:
1608  case truth_or_expr_K:
1609  case truth_xor_expr_K:
1610  {
1611  const auto op = tree_helper::op_symbol(node);
1612  const auto be = GetPointerS<const binary_expr>(node);
1613  const auto left_op_type = tree_helper::CGetType(be->op0);
1614  const auto right_op_type = tree_helper::CGetType(be->op1);
1615  const auto vector =
1616  tree_helper::IsVectorType(be->type) &&
1617  ((tree_helper::IsVectorType(left_op_type) && left_op_type->index != GET_INDEX_NODE(be->type)) ||
1618  (tree_helper::IsVectorType(right_op_type) && right_op_type->index != GET_INDEX_NODE(be->type)));
1619  if(vector)
1620  {
1621  const auto element_type = tree_helper::CGetElements(be->type);
1622  const auto element_size = tree_helper::Size(element_type);
1623  const auto size = tree_helper::Size(be->type);
1624  const auto vector_size = size / element_size;
1625  res += "(" + tree_helper::PrintType(TM, be->type) + ") ";
1626  res += "{";
1627  for(unsigned int ind = 0; ind < vector_size; ++ind)
1628  {
1629  res += "(" + PrintNode(be->op0, v, vppf) + ")[" + STR(ind) + "] " + op + " (" +
1630  PrintNode(be->op1, v, vppf) + ")";
1631  if(GET_CONST_NODE(be->op1)->get_kind() != integer_cst_K)
1632  {
1633  res += "[" + STR(ind) + "]";
1634  }
1635  if(ind != vector_size - 1)
1636  {
1637  res += ", ";
1638  }
1639  }
1640  res += "}";
1641  }
1642  else
1643  {
1644  const auto type = tree_helper::CGetType(node);
1645  unsigned int prec = 0;
1646  unsigned int algn = 0;
1647  if(type && GET_CONST_NODE(type)->get_kind() == integer_type_K)
1648  {
1649  prec = GetPointerS<const integer_type>(GET_CONST_NODE(type))->prec;
1650  algn = GetPointerS<const integer_type>(GET_CONST_NODE(type))->algn;
1651  }
1652  // bitfield type
1653  if(prec != algn && prec % algn)
1654  {
1655  res += "((";
1656  }
1657  if((node->get_kind() == lshift_expr_K || node->get_kind() == rshift_expr_K) &&
1658  left_op_type->index != GET_INDEX_NODE(be->type))
1659  {
1660  res += "(" + tree_helper::PrintType(TM, be->type) + ")(";
1661  }
1662  if(GetPointer<const decl_node>(GET_CONST_NODE(be->op0)) ||
1663  GetPointer<const ssa_name>(GET_CONST_NODE(be->op0)))
1664  {
1665  res += PrintNode(be->op0, v, vppf);
1666  }
1667  else
1668  {
1669  res += ("(" + PrintNode(be->op0, v, vppf) + ")");
1670  }
1671  if((node->get_kind() == lshift_expr_K || node->get_kind() == rshift_expr_K) &&
1672  left_op_type->index != GET_INDEX_NODE(be->type))
1673  {
1674  res += ")";
1675  }
1676  res += std::string(" ") + op + " ";
1677  if(GetPointer<const decl_node>(GET_CONST_NODE(be->op1)) ||
1678  GetPointer<const ssa_name>(GET_CONST_NODE(be->op1)))
1679  {
1680  res += PrintNode(be->op1, v, vppf);
1681  }
1682  else
1683  {
1684  res += ("(" + PrintNode(be->op1, v, vppf) + ")");
1685  }
1686  if(prec != algn && prec % algn)
1687  {
1688  res += ")%(1";
1689  if(prec > 32)
1690  {
1691  res += "LL";
1692  }
1693  if(GetPointerS<const integer_type>(GET_CONST_NODE(type))->unsigned_flag)
1694  {
1695  res += "U";
1696  }
1697  res += " << " + STR(prec) + "))";
1698  }
1699  }
1700  break;
1701  }
1702  case widen_sum_expr_K:
1703  case widen_mult_expr_K:
1704  {
1705  const auto op = tree_helper::op_symbol(node);
1706  const auto be = GetPointerS<const binary_expr>(node);
1707  const auto return_type = tree_helper::CGetType(node);
1708 
1709  res += "((" + tree_helper::PrintType(TM, return_type) + ")(" + PrintNode(be->op0, v, vppf) + "))";
1710  res += std::string(" ") + op + " ";
1711  res += "((" + tree_helper::PrintType(TM, return_type) + ")(" + PrintNode(be->op1, v, vppf) + "))";
1712  break;
1713  }
1714  case extract_bit_expr_K:
1715  {
1716  const auto be = GetPointerS<const binary_expr>(node);
1717  res += "(_Bool)(((unsigned long long int)(" + PrintNode(be->op0, v, vppf);
1718  res += std::string(") >> ");
1719  res += PrintNode(be->op1, v, vppf) + ") & 1)";
1720  break;
1721  }
1722  case extractvalue_expr_K:
1723  {
1724  const auto be = GetPointerS<const extractvalue_expr>(node);
1725  const auto return_type = tree_helper::CGetType(node);
1726  res += "(" + tree_helper::PrintType(TM, return_type) + ")(" + PrintNode(be->op0, v, vppf) + " >> " +
1727  PrintNode(be->op1, v, vppf) + ");";
1728  break;
1729  }
1730  case insertvalue_expr_K:
1731  {
1732  const auto te = GetPointerS<const insertvalue_expr>(node);
1733  unsigned long long op2_size;
1734  op2_size = tree_helper::Size(te->op2);
1735  const auto return_type = tree_helper::CGetType(node);
1736  res += "(" + tree_helper::PrintType(TM, return_type) + ")";
1737  res +=
1738  "(((" + PrintNode(te->op0, v, vppf) + " >> (" + STR(op2_size) + " + " + PrintNode(te->op2, v, vppf) + "))";
1739  res += " << (" + STR(op2_size) + " + " + PrintNode(te->op2, v, vppf) + ")) | (( " +
1740  PrintNode(te->op1, v, vppf) + " << ";
1741  res += PrintNode(te->op2, v, vppf) + ") | ((" + PrintNode(te->op0, v, vppf) + " << " +
1742  PrintNode(te->op2, v, vppf);
1743  res += ") >> " + PrintNode(te->op2, v, vppf) + ")))";
1744  break;
1745  }
1746  case extractelement_expr_K:
1747  {
1748  const auto be = GetPointerS<const extractvalue_expr>(node);
1749  const auto return_type = tree_helper::CGetType(node);
1750  res += "((" + tree_helper::PrintType(TM, return_type) + ")(" + PrintNode(be->op0, v, vppf) + "[" +
1751  PrintNode(be->op1, v, vppf) + "]))";
1752  break;
1753  }
1754  case insertelement_expr_K:
1755  {
1756  const auto iee = GetPointerS<const insertelement_expr>(node);
1757  const auto element_type = tree_helper::CGetElements(iee->type);
1758  const auto element_size = tree_helper::Size(element_type);
1759  const auto size = tree_helper::Size(iee->type);
1760  const auto vector_size = size / element_size;
1761 
1762  res += "/*" + iee->get_kind_text() + "*/";
1763  res += "(" + tree_helper::PrintType(TM, iee->type) + ") ";
1764  res += "{";
1765  for(unsigned int ind = 0; ind < vector_size; ++ind)
1766  {
1767  res += "(" + PrintNode(iee->op2, v, vppf) + " == " + STR(ind) + " ? " + PrintNode(iee->op1, v, vppf) +
1768  " : " + PrintNode(iee->op0, v, vppf) + "[" + STR(ind) + "])";
1769  if(ind != vector_size - 1)
1770  {
1771  res += ", ";
1772  }
1773  }
1774  res += "}";
1775  break;
1776  }
1777  case pointer_plus_expr_K:
1778  {
1779  const auto ppe = GetPointerS<const pointer_plus_expr>(node);
1780  const auto op = tree_helper::op_symbol(node);
1781  const auto binary_op_cast = tree_helper::IsPointerType(_node);
1782  const auto type_node = tree_helper::CGetType(ppe->op0);
1783  const auto left_op_cast = tree_helper::IsPointerType(ppe->op0);
1785 #ifndef NDEBUG
1786  if(left_op_cast)
1787  {
1788  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Left part is a pointer");
1789  }
1790 #endif
1791  bool do_reverse_pointer_arithmetic = false;
1792  auto right_op_node = GET_CONST_NODE(ppe->op1);
1794  "Starting right op node is " + STR(GET_INDEX_NODE(ppe->op1)) + " - " +
1795  right_op_node->get_kind_text());
1796  const auto right_cost = right_op_node->get_kind() == integer_cst_K;
1797  THROW_ASSERT(!tree_helper::IsPointerType(ppe->op1), "expected a right operand different from a pointer");
1799  "expected a pointer type: " + GET_NODE(ppe->type)->get_kind_text() + " - " + STR(ppe->type));
1800 
1802  unsigned long long deltabit;
1803  const auto pointed_type = tree_helper::CGetPointedType(tree_helper::CGetType(ppe->op0));
1805  "Pointed type (" + STR(pointed_type) + ") is " + GET_CONST_NODE(pointed_type)->get_kind_text());
1806  if(tree_helper::IsVoidType(pointed_type))
1807  {
1808  const auto vt = GetPointerS<const void_type>(GET_CONST_NODE(pointed_type));
1809  deltabit = vt->algn;
1810  }
1811  else
1812  {
1813  deltabit = tree_helper::Size(pointed_type);
1814  }
1815  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "deltabit is " + STR(deltabit));
1816  integer_cst_t pointer_offset = 0;
1817  std::string right_offset_var;
1818  if(right_cost)
1819  {
1820  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Offset is constant");
1821  pointer_offset = tree_helper::GetConstValue(right_op_node, tree_helper::IsSignedIntegerType(right_op_node));
1822  if(deltabit / 8 == 0)
1823  {
1824  do_reverse_pointer_arithmetic = false;
1825  }
1826  else if(GET_CONST_NODE(pointed_type)->get_kind() != array_type_K && deltabit && pointer_offset > deltabit &&
1827  ((pointer_offset % (deltabit / 8)) == 0))
1828  {
1829  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Arithmetic pointer pattern matched");
1830  const auto ic = GetPointerS<const integer_cst>(right_op_node);
1831  const auto it = GetPointer<const integer_type>(GET_CONST_NODE(ic->type));
1832  if(it && (it->prec == 32))
1833  {
1834  pointer_offset = static_cast<unsigned int>(pointer_offset / (deltabit / 8));
1835  }
1836  else
1837  {
1838  pointer_offset = pointer_offset / (deltabit / 8);
1839  }
1840  do_reverse_pointer_arithmetic = true;
1841  }
1842  else
1843  {
1845  "Arithmetic pointer pattern not matched " + STR(pointer_offset) + " vs " +
1846  STR(deltabit / 8));
1847  }
1848  }
1849  else
1850  {
1851  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Offset is not constant");
1852  bool exit = GET_CONST_NODE(pointed_type)->get_kind() == array_type_K;
1853  while(!do_reverse_pointer_arithmetic && !exit)
1854  {
1855  switch(right_op_node->get_kind())
1856  {
1857  case ssa_name_K:
1858  {
1859  if(GetPointerS<const ssa_name>(right_op_node)->CGetDefStmts().empty())
1860  {
1861  exit = true;
1862  break;
1863  }
1864  const auto rssa = GetPointerS<const ssa_name>(right_op_node);
1865  const auto defstmt = GET_CONST_NODE(rssa->CGetDefStmt());
1866  if(defstmt->get_kind() != gimple_assign_K)
1867  {
1868  exit = true;
1869  break;
1870  }
1871  right_op_node = GET_NODE(GetPointerS<const gimple_assign>(defstmt)->op1);
1873  "New op node is " + STR(right_op_node->index) + " - " +
1874  right_op_node->get_kind_text());
1875  break;
1876  }
1877  case mult_highpart_expr_K:
1878  {
1879  THROW_UNREACHABLE("");
1880  break;
1881  }
1882  case mult_expr_K:
1883  {
1884  const auto mult = GetPointerS<const mult_expr>(right_op_node);
1885  if(GET_NODE(mult->op1)->get_kind() == integer_cst_K)
1886  {
1888  "-->Right part of multiply is an integer constant " +
1889  STR(GET_INDEX_NODE(mult->op1)));
1890  const auto size_of_pointer = tree_helper::GetConstValue(mult->op1);
1892  "---Size of pointer is " + STR(size_of_pointer));
1893  if(size_of_pointer == (deltabit / 8))
1894  {
1895  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Constant is the size of the pointed");
1896  right_offset_var += PrintNode(mult->op0, v, vppf);
1897  do_reverse_pointer_arithmetic = true;
1898  }
1899  else
1900  {
1902  "-->Constant is not the size of the pointed: " + STR(size_of_pointer) +
1903  " vs " + STR(deltabit / 8));
1904  const auto temp1 = tree_helper::CGetType(mult->op1);
1905  THROW_ASSERT(GetPointer<const integer_type>(GET_CONST_NODE(temp1)),
1906  "Type of integer cast " + STR(GET_INDEX_NODE(mult->op1)) +
1907  " is not an integer type");
1908  const auto it = GetPointerS<const integer_type>(GET_CONST_NODE(temp1));
1909  const auto max_int = tree_helper::GetConstValue(it->max);
1910  const auto new_size_of_pointer = max_int + 1 - size_of_pointer;
1911  if(new_size_of_pointer == (deltabit / 8))
1912  {
1914  "---Constant is minus the size of the pointed");
1915  right_offset_var += "-(" + PrintNode(mult->op0, v, vppf) + ")";
1916  do_reverse_pointer_arithmetic = true;
1917  }
1918  else if(deltabit && (deltabit / 8) && (size_of_pointer % ((deltabit / 8)) == 0))
1919  {
1921  "---Constant is a multiple of the size of the pointed");
1922  right_offset_var += PrintNode(mult->op0, v, vppf);
1923  right_offset_var += " * ";
1924  right_offset_var += STR(size_of_pointer / ((deltabit / 8)));
1925  do_reverse_pointer_arithmetic = true;
1926  }
1927  }
1930  "<--Right offset variable is " + right_offset_var);
1931  }
1932  else if(GET_NODE(mult->op0)->get_kind() == integer_cst_K)
1933  {
1934  const auto size_of_pointer = tree_helper::GetConstValue(mult->op0);
1935  if(size_of_pointer == (deltabit / 8))
1936  {
1937  right_offset_var += PrintNode(mult->op1, v, vppf);
1938  do_reverse_pointer_arithmetic = true;
1939  }
1940  else
1941  {
1942  const auto temp1 = tree_helper::CGetType(mult->op0);
1943  THROW_ASSERT(GetPointer<const integer_type>(GET_CONST_NODE(temp1)),
1944  "Type of integer cast " + STR(GET_INDEX_NODE(mult->op0)) +
1945  " is not an integer type");
1946  const auto it = GetPointerS<const integer_type>(GET_CONST_NODE(temp1));
1947  const auto max_int = tree_helper::GetConstValue(it->max);
1948  const auto new_size_of_pointer = max_int + 1 - size_of_pointer;
1949  if(new_size_of_pointer == (deltabit / 8))
1950  {
1951  right_offset_var += "-" + PrintNode(mult->op1, v, vppf);
1952  do_reverse_pointer_arithmetic = true;
1953  }
1954  else if((deltabit / 8) && (size_of_pointer % ((deltabit / 8)) == 0))
1955  {
1956  right_offset_var += PrintNode(mult->op1, v, vppf);
1957  right_offset_var += " * ";
1958  right_offset_var += STR(size_of_pointer / ((deltabit / 8)));
1959  do_reverse_pointer_arithmetic = true;
1960  }
1961  }
1962  }
1963  exit = true;
1964  break;
1965  }
1966  case negate_expr_K:
1967  {
1968  const auto ne = GetPointerS<const negate_expr>(right_op_node);
1969  right_offset_var += "-";
1970  right_op_node = GET_NODE(ne->op);
1972  "New op node is " + STR(GET_INDEX_NODE(ne->op)) + " - " +
1973  right_op_node->get_kind_text());
1974  break;
1975  }
1976  case paren_expr_K:
1977  case nop_expr_K:
1978  {
1979  const auto ne = GetPointerS<const nop_expr>(right_op_node);
1980  right_op_node = GET_CONST_NODE(ne->op);
1982  "New op node is " + STR(GET_INDEX_NODE(ne->op)) + " - " +
1983  right_op_node->get_kind_text());
1984  break;
1985  }
1986  case binfo_K:
1987  case block_K:
1988  case call_expr_K:
1989  case aggr_init_expr_K:
1990  case case_label_expr_K:
1991  case constructor_K:
1992  case identifier_node_K:
1993  case statement_list_K:
1994  case target_expr_K:
1995  case target_mem_ref_K:
1996  case target_mem_ref461_K:
1997  case tree_list_K:
1998  case tree_vec_K:
1999  case addr_expr_K:
2000  case alignof_expr_K:
2001  case arrow_expr_K:
2002  case bit_not_expr_K:
2003  case buffer_ref_K:
2004  case card_expr_K:
2005  case cleanup_point_expr_K:
2006  case conj_expr_K:
2007  case convert_expr_K:
2008  case exit_expr_K:
2009  case fix_ceil_expr_K:
2010  case fix_floor_expr_K:
2011  case fix_round_expr_K:
2012  case fix_trunc_expr_K:
2013  case float_expr_K:
2014  case imagpart_expr_K:
2015  case indirect_ref_K:
2016  case misaligned_indirect_ref_K:
2017  case loop_expr_K:
2018  case non_lvalue_expr_K:
2019  case realpart_expr_K:
2020  case reference_expr_K:
2021  case reinterpret_cast_expr_K:
2022  case sizeof_expr_K:
2023  case static_cast_expr_K:
2024  case throw_expr_K:
2025  case truth_not_expr_K:
2026  case unsave_expr_K:
2027  case va_arg_expr_K:
2028  case view_convert_expr_K:
2029  case reduc_max_expr_K:
2030  case reduc_min_expr_K:
2031  case reduc_plus_expr_K:
2032  case vec_unpack_hi_expr_K:
2033  case vec_unpack_lo_expr_K:
2034  case vec_unpack_float_hi_expr_K:
2035  case vec_unpack_float_lo_expr_K:
2036  case abs_expr_K:
2037  case assert_expr_K:
2038  case bit_and_expr_K:
2039  case bit_ior_expr_K:
2040  case bit_xor_expr_K:
2041  case catch_expr_K:
2042  case ceil_div_expr_K:
2043  case ceil_mod_expr_K:
2044  case complex_expr_K:
2045  case compound_expr_K:
2046  case eh_filter_expr_K:
2047  case eq_expr_K:
2048  case exact_div_expr_K:
2049  case fdesc_expr_K:
2050  case floor_div_expr_K:
2051  case floor_mod_expr_K:
2052  case ge_expr_K:
2053  case gt_expr_K:
2054  case goto_subroutine_K:
2055  case in_expr_K:
2056  case init_expr_K:
2057  case le_expr_K:
2058  case lrotate_expr_K:
2059  case lshift_expr_K:
2060  case lt_expr_K:
2061  case lut_expr_K:
2062  case max_expr_K:
2063  case mem_ref_K:
2064  case min_expr_K:
2065  case minus_expr_K:
2066  case modify_expr_K:
2067  case ne_expr_K:
2068  case ordered_expr_K:
2069  case plus_expr_K:
2070  case pointer_plus_expr_K:
2071  case postdecrement_expr_K:
2072  case postincrement_expr_K:
2073  case predecrement_expr_K:
2074  case preincrement_expr_K:
2075  case range_expr_K:
2076  case rdiv_expr_K:
2077  case round_div_expr_K:
2078  case round_mod_expr_K:
2079  case rrotate_expr_K:
2080  case rshift_expr_K:
2081  case set_le_expr_K:
2082  case trunc_div_expr_K:
2083  case trunc_mod_expr_K:
2084  case truth_and_expr_K:
2085  case truth_andif_expr_K:
2086  case truth_or_expr_K:
2087  case truth_orif_expr_K:
2088  case truth_xor_expr_K:
2089  case try_catch_expr_K:
2090  case try_finally_K:
2091  case uneq_expr_K:
2092  case ltgt_expr_K:
2093  case unge_expr_K:
2094  case ungt_expr_K:
2095  case unle_expr_K:
2096  case unlt_expr_K:
2097  case unordered_expr_K:
2098  case widen_sum_expr_K:
2099  case widen_mult_expr_K:
2100  case with_size_expr_K:
2101  case vec_lshift_expr_K:
2102  case vec_rshift_expr_K:
2103  case widen_mult_hi_expr_K:
2104  case widen_mult_lo_expr_K:
2105  case vec_pack_trunc_expr_K:
2106  case vec_pack_sat_expr_K:
2107  case vec_pack_fix_trunc_expr_K:
2108  case vec_extracteven_expr_K:
2109  case vec_extractodd_expr_K:
2110  case vec_interleavehigh_expr_K:
2111  case vec_interleavelow_expr_K:
2112  case error_mark_K:
2113  case extract_bit_expr_K:
2114  case sat_plus_expr_K:
2115  case sat_minus_expr_K:
2116  case extractvalue_expr_K:
2117  case extractelement_expr_K:
2118  case frem_expr_K:
2119  case CASE_CPP_NODES:
2120  case CASE_CST_NODES:
2121  case CASE_DECL_NODES:
2122  case CASE_FAKE_NODES:
2123  case CASE_GIMPLE_NODES:
2124  case CASE_PRAGMA_NODES:
2127  case CASE_TYPE_NODES:
2128  default:
2129  {
2130  exit = true;
2131  break;
2132  }
2133  }
2134  }
2135  if(deltabit == 8)
2136  {
2137  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "Reversing pointer arithmetic sucessful");
2138  do_reverse_pointer_arithmetic = true;
2139  right_offset_var = PrintNode(ppe->op1, v, vppf);
2140  }
2141  }
2142  bool char_pointer = false;
2143  if(!do_reverse_pointer_arithmetic &&
2144  tree_helper::Size(GetPointerS<const pointer_type>(GET_CONST_NODE(type_node))->ptd) == 8)
2145  {
2147  "Reversing pointer arithmetic sucessful because of char pointer");
2148  do_reverse_pointer_arithmetic = true;
2149  char_pointer = true;
2150  }
2151  if(binary_op_cast && !do_reverse_pointer_arithmetic)
2152  {
2153  res += "(" + tree_helper::PrintType(TM, ppe->type) + ")(";
2154  }
2155  if((left_op_cast && tree_helper::IsVoidType(pointed_type)) || !do_reverse_pointer_arithmetic)
2156  {
2157  res += "((unsigned char*)";
2158  }
2159  res += PrintNode(ppe->op0, v, vppf);
2160  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "After printing of left part " + res);
2161  if((left_op_cast && tree_helper::IsVoidType(pointed_type)) || !do_reverse_pointer_arithmetic)
2162  {
2163  res += ")";
2164  }
2165  res += std::string(" ") + op + " ";
2166  /*
2167  if (!do_reverse_pointer_arithmetic)
2168  {
2169  TM->increment_unremoved_pointer_plus();
2170  }
2171  else
2172  {
2173  TM->increment_removable_pointer_plus();
2174  }
2175  */
2176  if(do_reverse_pointer_arithmetic && !char_pointer)
2177  {
2178  if(right_offset_var != "")
2179  {
2180  res += right_offset_var;
2181  }
2182  else
2183  {
2184  res += STR(pointer_offset);
2185  const auto type = GET_NODE(GetPointerS<const integer_cst>(right_op_node)->type);
2186  const auto it = GetPointer<const integer_type>(type);
2187  bool unsigned_flag = (it && it->unsigned_flag) || type->get_kind() == pointer_type_K ||
2188  type->get_kind() == boolean_type_K || type->get_kind() == enumeral_type_K;
2189  if(unsigned_flag)
2190  {
2191  res += "u";
2192  }
2193  }
2194  }
2195  else
2196  {
2197  if(right_op_node->get_kind() == integer_cst_K)
2198  {
2199  res += STR(tree_helper::GetConstValue(right_op_node));
2200  }
2201  else
2202  {
2203  res += PrintNode(ppe->op1, v, vppf);
2204  }
2205  }
2206  if(binary_op_cast && !do_reverse_pointer_arithmetic)
2207  {
2208  res += ")";
2209  }
2211  break;
2212  }
2213  /* Binary relational expressions. */
2214  case lt_expr_K:
2215  case le_expr_K:
2216  case gt_expr_K:
2217  case ge_expr_K:
2218  case eq_expr_K:
2219  case ne_expr_K:
2220  {
2221  const auto binary_op_cast = tree_helper::IsPointerType(_node);
2222  if(binary_op_cast)
2223  {
2224  res += "((" + tree_helper::PrintType(TM, tree_helper::CGetType(_node)) + ")(";
2225  }
2226  const auto op = tree_helper::op_symbol(node);
2227  const auto be = GetPointerS<const binary_expr>(node);
2228  const auto& left_op = be->op0;
2229  const auto& right_op = be->op1;
2230  const auto left_op_type = tree_helper::CGetType(be->op0);
2231  const auto right_op_type = tree_helper::CGetType(be->op1);
2232 
2233  bool vector = tree_helper::IsVectorType(be->type) && tree_helper::IsVectorType(right_op_type) &&
2234  right_op_type->index != GET_INDEX_NODE(be->type);
2235  if(vector)
2236  {
2237  const auto element_type = tree_helper::CGetElements(be->type);
2238  const auto element_size = tree_helper::Size(element_type);
2239  const auto size = tree_helper::Size(be->type);
2240  const auto vector_size = size / element_size;
2241  res += "(" + tree_helper::PrintType(TM, be->type) + ") ";
2242  res += "{";
2243  for(unsigned int ind = 0; ind < vector_size; ++ind)
2244  {
2245  res += "(" + PrintNode(left_op, v, vppf) + ")[" + STR(ind) + "] " + op + " (" +
2246  PrintNode(right_op, v, vppf) + ")[" + STR(ind) + "]";
2247  if(ind != vector_size - 1)
2248  {
2249  res += ", ";
2250  }
2251  }
2252  res += "}";
2253  break;
2254  }
2255  else
2256  {
2257  const auto left_op_cast = tree_helper::IsPointerType(left_op) && tree_helper::IsPointerType(right_op) &&
2258  (tree_helper::Size(left_op) != tree_helper::Size(right_op));
2259  const auto right_op_cast = tree_helper::IsPointerType(right_op) && tree_helper::IsPointerType(left_op) &&
2260  (tree_helper::Size(left_op) != tree_helper::Size(right_op));
2261  const auto left_op_bracket =
2262  !(GetPointer<decl_node>(GET_NODE(be->op0)) || GetPointer<ssa_name>(GET_NODE(be->op0)));
2263  const auto right_op_bracket =
2264  !(GetPointer<decl_node>(GET_NODE(be->op1)) || GetPointer<ssa_name>(GET_NODE(be->op1)));
2265 
2266  if(left_op_bracket)
2267  {
2268  res += "(";
2269  }
2270  if(left_op_cast)
2271  {
2272  res += "((unsigned long int)";
2273  }
2274 
2275  if(tree_helper::IsVectorType(be->type) && tree_helper::IsVectorType(left_op_type) &&
2276  left_op_type->index != GET_INDEX_NODE(be->type))
2277  {
2278  res += "(" + tree_helper::PrintType(TM, be->type) + ")(";
2279  }
2280 
2281  res += PrintNode(left_op, v, vppf);
2282 
2283  if(tree_helper::IsVectorType(be->type) && tree_helper::IsVectorType(left_op_type) &&
2284  left_op_type->index != GET_INDEX_NODE(be->type))
2285  {
2286  res += ")";
2287  }
2288 
2289  if(left_op_cast)
2290  {
2291  res += ")";
2292  }
2293  if(left_op_bracket)
2294  {
2295  res += ")";
2296  }
2297  res += std::string(" ") + op + " ";
2298  if(right_op_bracket)
2299  {
2300  res += "(";
2301  }
2302  if(right_op_cast)
2303  {
2304  res += "((unsigned long int)";
2305  }
2306 
2307  res += PrintNode(right_op, v, vppf);
2308 
2309  if(right_op_cast)
2310  {
2311  res += ")";
2312  }
2313  if(right_op_bracket)
2314  {
2315  res += ")";
2316  }
2317  if(binary_op_cast)
2318  {
2319  res += "))";
2320  }
2321  }
2322  break;
2323  }
2324  case rrotate_expr_K:
2325  case lrotate_expr_K:
2326  {
2327  const auto binary_op_cast = tree_helper::IsPointerType(node);
2328  const auto type = tree_helper::CGetType(node);
2329  if(binary_op_cast)
2330  {
2331  res += "((" + tree_helper::PrintType(TM, type) + ")(";
2332  }
2333  const auto be = GetPointerS<const binary_expr>(node);
2334  const auto& left_op = be->op0;
2335  const auto& right_op = be->op1;
2336  bool left_op_cast = tree_helper::IsPointerType(left_op);
2337  bool right_op_cast = tree_helper::IsPointerType(right_op);
2338  if(left_op_cast)
2339  {
2340  res += "((unsigned long int)";
2341  }
2342  res += PrintNode(left_op, v, vppf);
2343  if(left_op_cast)
2344  {
2345  res += ")";
2346  }
2347  if(node->get_kind() == rrotate_expr_K)
2348  {
2349  res += " >> ";
2350  }
2351  else
2352  {
2353  res += " << ";
2354  }
2355  if(right_op_cast)
2356  {
2357  res += "((unsigned long int)";
2358  }
2359  res += PrintNode(right_op, v, vppf);
2360  if(right_op_cast)
2361  {
2362  res += ")";
2363  }
2364  res += " | ";
2365  if(left_op_cast)
2366  {
2367  res += "((unsigned long int)";
2368  }
2369  res += PrintNode(left_op, v, vppf);
2370  if(left_op_cast)
2371  {
2372  res += ")";
2373  }
2374  if(node->get_kind() == rrotate_expr_K)
2375  {
2376  res += " << ";
2377  }
2378  else
2379  {
2380  res += " >> ";
2381  }
2382  res += "(" + STR(GetPointerS<const integer_type>(GET_CONST_NODE(type))->prec) + "-";
2383  if(right_op_cast)
2384  {
2385  res += "((unsigned long int)";
2386  }
2387  res += PrintNode(right_op, v, vppf);
2388  if(right_op_cast)
2389  {
2390  res += ")";
2391  }
2392  res += ")";
2393  if(binary_op_cast)
2394  {
2395  res += "))";
2396  }
2397  break;
2398  }
2399  case lut_expr_K:
2400  {
2401  const auto le = GetPointerS<const lut_expr>(node);
2402  std::string concat_shift_string;
2403  if(le->op8)
2404  {
2405  THROW_ERROR("not supported");
2406  }
2407  if(le->op7)
2408  {
2409  THROW_ERROR("not supported");
2410  }
2411  if(le->op6)
2412  {
2413  concat_shift_string = concat_shift_string + "((" + PrintNode(le->op6, v, vppf) + ")<<5) | ";
2414  }
2415  if(le->op5)
2416  {
2417  concat_shift_string = concat_shift_string + "((" + PrintNode(le->op5, v, vppf) + ")<<4) | ";
2418  }
2419  if(le->op4)
2420  {
2421  concat_shift_string = concat_shift_string + "((" + PrintNode(le->op4, v, vppf) + ")<<3) | ";
2422  }
2423  if(le->op3)
2424  {
2425  concat_shift_string = concat_shift_string + "((" + PrintNode(le->op3, v, vppf) + ")<<2) | ";
2426  }
2427  if(le->op2)
2428  {
2429  concat_shift_string = concat_shift_string + "((" + PrintNode(le->op2, v, vppf) + ")<<1) | ";
2430  }
2431  concat_shift_string = concat_shift_string + "(" + PrintNode(le->op1, v, vppf) + ")";
2432  res = res + "(" + PrintNode(le->op0->index, v, vppf) + ">>(" + concat_shift_string + "))&1";
2433  break;
2434  }
2435  case negate_expr_K:
2436  case bit_not_expr_K:
2437  case reference_expr_K:
2438  case predecrement_expr_K:
2439  case preincrement_expr_K:
2440  {
2441  const auto ue = GetPointerS<const unary_expr>(node);
2442  const auto op = tree_helper::op_symbol(node);
2443  res = res + " " + op + "(" + PrintNode(ue->op, v, vppf) + ")";
2444  break;
2445  }
2446  case truth_not_expr_K:
2447  {
2448  const auto te = GetPointerS<const truth_not_expr>(node);
2449  if(tree_helper::IsVectorType(te->type))
2450  {
2451  const auto element_type = tree_helper::CGetElements(te->type);
2452  const auto element_size = tree_helper::Size(element_type);
2453  const auto size = tree_helper::Size(te->type);
2454  const auto vector_size = size / element_size;
2455  res += "(" + tree_helper::PrintType(TM, te->type) + ") ";
2456  res += "{";
2457  for(unsigned int ind = 0; ind < vector_size; ++ind)
2458  {
2459  res += " !(" + PrintNode(te->op, v, vppf) + ")[" + STR(ind) + "]";
2460  if(ind != vector_size - 1)
2461  {
2462  res += ", ";
2463  }
2464  }
2465  res += "}";
2466  }
2467  else
2468  {
2469  const auto op = tree_helper::op_symbol(node);
2470  res = res + " " + op + "(" + PrintNode(te->op, v, vppf) + ")";
2471  break;
2472  }
2473  break;
2474  }
2475  case realpart_expr_K:
2476  case imagpart_expr_K:
2477  {
2478  const auto op = tree_helper::op_symbol(node);
2479  const auto ue = GetPointerS<const unary_expr>(node);
2480  res = res + " " + op + PrintNode(ue->op, v, vppf);
2481  const auto sa = GetPointer<const ssa_name>(GET_CONST_NODE(ue->op));
2482  if(sa && (sa->volatile_flag || (GET_NODE(sa->CGetDefStmt())->get_kind() == gimple_nop_K)) &&
2483  (sa->var && GetPointer<const var_decl>(GET_CONST_NODE(sa->var))))
2484  {
2485  res += " = 0";
2486  }
2487  break;
2488  }
2489  case addr_expr_K:
2490  {
2491  const auto ue = GetPointerS<const addr_expr>(node);
2492  if(GetPointer<const component_ref>(GET_CONST_NODE(ue->op)) &&
2493  has_bit_field(GET_INDEX_CONST_NODE(GetPointerS<const component_ref>(GET_CONST_NODE(ue->op))->op1)))
2494  {
2495  THROW_ERROR_CODE(BITFIELD_EC, "Trying to get the address of a bitfield");
2496  }
2497  if(GET_CONST_NODE(ue->op)->get_kind() == array_ref_K)
2498  {
2499  const auto ar = GetPointerS<const array_ref>(GET_CONST_NODE(ue->op));
2501  if(GET_NODE(ar->op0)->get_kind() == string_cst_K && GET_CONST_NODE(ar->op1)->get_kind() == integer_cst_K &&
2502  tree_helper::GetConstValue(ar->op1) == 0)
2503  {
2504  res += PrintNode(ar->op0, v, vppf);
2505  break;
2506  }
2507  }
2509  if(GET_NODE(ue->op)->get_kind() == var_decl_K &&
2510  (GET_CONST_NODE(tree_helper::CGetType(ue->op))->get_kind() == array_type_K))
2511  {
2512  res += PrintNode(ue->op, v, vppf);
2513  break;
2514  }
2515  if(GET_CONST_NODE(ue->op)->get_kind() == label_decl_K)
2516  {
2517  res += "&&" + PrintNode(ue->op, v, vppf);
2518  break;
2519  }
2520  res += "(" + tree_helper::op_symbol(node) + "(" + PrintNode(ue->op, v, vppf) + "))";
2521  break;
2522  }
2523  case function_decl_K:
2524  {
2525  const auto fd = GetPointerS<const function_decl>(node);
2527  break;
2528  }
2529  case fix_trunc_expr_K:
2530  case fix_ceil_expr_K:
2531  case fix_floor_expr_K:
2532  case fix_round_expr_K:
2533  case float_expr_K:
2534  case convert_expr_K:
2535  case nop_expr_K:
2536  {
2537  const auto ue = GetPointerS<const unary_expr>(node);
2538  const auto type = tree_helper::CGetType(node);
2539  unsigned int prec = 0;
2540  unsigned int algn = 0;
2541  if(type && GET_CONST_NODE(type)->get_kind() == integer_type_K)
2542  {
2543  prec = GetPointerS<const integer_type>(GET_CONST_NODE(type))->prec;
2544  algn = GetPointerS<const integer_type>(GET_CONST_NODE(type))->algn;
2545  }
2546 
2547  const auto operand_type = tree_helper::CGetType(ue->op);
2548  unsigned int operand_prec = 0;
2549  unsigned int operand_algn = 0;
2550  if(operand_type && GET_CONST_NODE(operand_type)->get_kind() == integer_type_K)
2551  {
2552  operand_prec = GetPointerS<const integer_type>(GET_CONST_NODE(operand_type))->prec;
2553  operand_algn = GetPointerS<const integer_type>(GET_CONST_NODE(operand_type))->algn;
2554  }
2555 
2556  std::string operand_res = PrintNode(ue->op, v, vppf);
2557  if(operand_prec != operand_algn && operand_prec % operand_algn &&
2558  tree_helper::IsSignedIntegerType(operand_type))
2559  {
2560  operand_res = "((union {" + tree_helper::PrintType(TM, operand_type) + " orig; " +
2561  tree_helper::PrintType(TM, operand_type) + " bitfield : " + STR(operand_prec) + ";}){" +
2562  operand_res + "}).bitfield";
2563  }
2564  if(type && (type->get_kind() == boolean_type_K))
2565  {
2566  res += "(";
2567  res += operand_res;
2568  res += ")&1";
2569  }
2570  // bitfield type
2571  else if(prec != algn && prec % algn)
2572  {
2575  if(ui)
2576  {
2577  res += "((" + tree_helper::PrintType(TM, type) + ")(";
2578  }
2579  res += "(";
2580  res += operand_res;
2581  res += ")%(1";
2582  if(prec > 32)
2583  {
2584  res += "LL";
2585  }
2586  if(GetPointerS<const integer_type>(GET_CONST_NODE(type))->unsigned_flag)
2587  {
2588  res += "U";
2589  }
2590  res += " << " + STR(prec) + ")";
2591  if(ui)
2592  {
2593  res += std::string(" << ") + STR(algn - prec) + ")) >> " + STR(algn - prec);
2594  }
2595  }
2596  else
2597  {
2598  res = res + "(" + tree_helper::PrintType(TM, ue->type) + ") (";
2599  res += operand_res;
2600  res += ")";
2601  }
2602  break;
2603  }
2604  case view_convert_expr_K:
2605  {
2606  const auto vce = GetPointerS<const view_convert_expr>(node);
2607  if(GetPointer<const integer_cst>(GET_CONST_NODE(vce->op)))
2608  {
2609  res = res + "__panda_union.dest;}";
2610  }
2611  else
2612  {
2613  if(tree_helper::IsPointerType(vce->type))
2614  {
2615  res = res + "((" + tree_helper::PrintType(TM, vce->type) + ") (" + PrintNode(vce->op, v, vppf) + "))";
2616  }
2617  else
2618  {
2619  res =
2620  res + "*((" + tree_helper::PrintType(TM, vce->type) + " * ) &(" + PrintNode(vce->op, v, vppf) + "))";
2621  }
2622  }
2623  break;
2624  }
2625  case component_ref_K:
2626  {
2627  const auto cr = GetPointerS<const component_ref>(node);
2628  res = "(" + PrintNode(cr->op0, v, vppf) + ")." + PrintNode(cr->op1, v, vppf);
2629  break;
2630  }
2631  case indirect_ref_K:
2632  {
2633  const auto ir = GetPointerS<const indirect_ref>(node);
2634  res = "*(";
2635  if(GetPointer<const integer_cst>(GET_NODE(ir->op)))
2636  {
2637  res += "(" + tree_helper::PrintType(TM, tree_helper::CGetType(ir->op)) + ")";
2638  }
2639  res += PrintNode(ir->op, v, vppf);
2640  res += ")";
2641  break;
2642  }
2643  case misaligned_indirect_ref_K:
2644  {
2645  const auto mir = GetPointerS<const misaligned_indirect_ref>(node);
2646  res = "*(" + PrintNode(mir->op, v, vppf) + ")";
2647  break;
2648  }
2649  case mem_ref_K:
2650  {
2651  const auto mr = GetPointerS<const mem_ref>(node);
2652  const auto offset = tree_helper::GetConstValue(mr->op1);
2653  const tree_manipulationRef tm(new tree_manipulation(AppM->get_tree_manager(), Param, AppM));
2654  const auto pointer_type = tm->GetPointerType(mr->type, 8);
2655  const std::string type_string = tree_helper::PrintType(TM, pointer_type);
2656  if(offset == 0)
2657  {
2658  res = "(*((" + type_string + ")(" + PrintNode(mr->op0, v, vppf) + ")))";
2659  }
2660  else
2661  {
2662  res = "(*((" + type_string + ")(((unsigned char*)" + PrintNode(mr->op0, v, vppf) + ") + " + STR(offset) +
2663  ")))";
2664  }
2665  break;
2666  }
2667  case target_mem_ref_K:
2668  {
2669  const auto tmr = GetPointerS<const target_mem_ref>(node);
2670  bool need_plus = false;
2671  res = "(*((" + tree_helper::PrintType(TM, tmr->type) + "*)(";
2672  if(tmr->symbol)
2673  {
2674  res += "((unsigned char*)" +
2675  (tree_helper::IsStructType(tmr->symbol) || tree_helper::IsUnionType(tmr->symbol) ? std::string("&") :
2676  std::string("")) +
2677  PrintNode(tmr->symbol, v, vppf) + ")";
2678  need_plus = true;
2679  }
2680  if(tmr->base)
2681  {
2682  if(need_plus)
2683  {
2684  res += "+";
2685  }
2686  else
2687  {
2688  need_plus = true;
2689  }
2690  if(tmr->symbol)
2691  {
2692  res += "(" + PrintNode(tmr->base, v, vppf) + ")";
2693  }
2694  else
2695  {
2696  res += "((unsigned char*)" + PrintNode(tmr->base, v, vppf) + ")";
2697  }
2698  }
2699  if(tmr->step)
2700  {
2701  if(need_plus)
2702  {
2703  res += "+";
2704  }
2705  need_plus = false;
2706  res += PrintNode(tmr->step, v, vppf) + "*";
2707  THROW_ASSERT(tmr->idx, "idx expected!");
2708  }
2709  if(tmr->idx)
2710  {
2711  if(need_plus)
2712  {
2713  res += "+";
2714  }
2715  else
2716  {
2717  need_plus = true;
2718  }
2719  res += PrintNode(tmr->idx, v, vppf);
2720  }
2721  if(tmr->offset)
2722  {
2723  if(need_plus)
2724  {
2725  res += "+";
2726  }
2727  res += PrintNode(tmr->offset, v, vppf);
2728  }
2729  res += ")))";
2730  break;
2731  }
2732  case target_mem_ref461_K:
2733  {
2734  const auto tmr = GetPointerS<const target_mem_ref461>(node);
2735  bool need_plus = false;
2736  bool isFunctionPointer = tree_helper::IsFunctionPointerType(tmr->type);
2737  res = isFunctionPointer ? "(" : "(*((";
2738  res += tree_helper::PrintType(TM, tmr->type);
2739  res += isFunctionPointer ? ")(" : "*)(";
2740  if(tmr->base)
2741  {
2742  need_plus = true;
2743  res += "((unsigned char*)" +
2744  (tree_helper::IsStructType(tmr->base) || tree_helper::IsUnionType(tmr->base) ? std::string("&") :
2745  std::string("")) +
2746  PrintNode(tmr->base, v, vppf) + ")";
2747  }
2748  if(tmr->step)
2749  {
2750  if(need_plus)
2751  {
2752  res += "+";
2753  }
2754  need_plus = false;
2755  res += PrintNode(tmr->step, v, vppf) + "*";
2756  THROW_ASSERT(tmr->idx, "idx expected!");
2757  }
2758  if(tmr->idx)
2759  {
2760  if(need_plus)
2761  {
2762  res += "+";
2763  }
2764  else
2765  {
2766  need_plus = true;
2767  }
2768  res += PrintNode(tmr->idx, v, vppf);
2769  }
2770  if(tmr->idx2)
2771  {
2772  if(need_plus)
2773  {
2774  res += "+";
2775  }
2776  else
2777  {
2778  need_plus = true;
2779  }
2780  res += PrintNode(tmr->idx2, v, vppf);
2781  }
2782  if(tmr->offset)
2783  {
2784  if(need_plus)
2785  {
2786  res += "+";
2787  }
2788  res += PrintNode(tmr->offset, v, vppf);
2789  }
2790  res += isFunctionPointer ? ")" : ")))";
2791  break;
2792  }
2793  case array_ref_K:
2794  {
2795  const auto ar = GetPointerS<const array_ref>(node);
2796  const auto base = GET_NODE(ar->op0);
2797  // tree_nodeRef offset = GET_NODE(ar->op1);
2798  if(base->get_kind() == mem_ref_K)
2799  {
2800  const auto mr = GetPointerS<const mem_ref>(base);
2801  const auto offset = tree_helper::GetConstValue(mr->op1);
2802  std::string type_string = tree_helper::PrintType(TM, mr->type);
2803  if(GET_CONST_NODE(mr->type)->get_kind() == array_type_K)
2804  {
2805  size_t found_square_bracket = type_string.find('[');
2806  if(found_square_bracket != std::string::npos)
2807  {
2808  type_string.insert(found_square_bracket, "(*)");
2809  }
2810  else
2811  {
2812  type_string = type_string + "*";
2813  }
2814  }
2815  else
2816  {
2817  type_string = type_string + "*";
2818  }
2819  if(offset == 0)
2820  {
2821  res = "(*((" + type_string + ")(" + PrintNode(mr->op0, v, vppf) + ")))";
2822  }
2823  else
2824  {
2825  res = "(*((" + type_string + ")(((unsigned char*)" + PrintNode(mr->op0, v, vppf) + ") + " + STR(offset) +
2826  ")))";
2827  }
2828  }
2829  else
2830  {
2831  res = "(" + PrintNode(ar->op0, v, vppf) + ")";
2832  }
2833  res += "[" + PrintNode(ar->op1, v, vppf) + "]";
2834  break;
2835  }
2836  case bit_field_ref_K:
2837  {
2838  const auto bf = GetPointerS<const bit_field_ref>(node);
2839  const auto bpos = tree_helper::GetConstValue(bf->op2);
2840  res += "*((" + tree_helper::PrintType(TM, bf->type) + "* ) (((unsigned long int) &(" +
2841  PrintNode(bf->op0, v, vppf) + ")) + (unsigned long int)" + STR(bpos / 8) + "))";
2842  if(bpos % 8)
2843  {
2844  res += " >> " + STR(bpos % 8);
2845  }
2846  break;
2847  }
2848  /* post/pre increment and decrement operator should be treated as unary even if they are binary_expr*/
2849  case postdecrement_expr_K:
2850  case postincrement_expr_K:
2851  {
2852  const auto op = tree_helper::op_symbol(node);
2853  const auto be = GetPointerS<const binary_expr>(node);
2854  res += PrintNode(be->op0, v, vppf) + op + PrintNode(be->op1, v, vppf);
2855  break;
2856  }
2857  case min_expr_K:
2858  {
2859  const auto me = GetPointerS<const min_expr>(node);
2860  if(tree_helper::IsVectorType(me->type))
2861  {
2862  const auto element_type = tree_helper::CGetElements(me->type);
2863  const auto element_size = tree_helper::Size(element_type);
2864  const auto size = tree_helper::Size(me->type);
2865  const auto vector_size = size / element_size;
2866  res += "/*" + me->get_kind_text() + "*/";
2867  res += "(" + tree_helper::PrintType(TM, me->type) + ") ";
2868  res += "{";
2869  for(unsigned int ind = 0; ind < vector_size; ++ind)
2870  {
2871  res += "(" + PrintNode(me->op0, v, vppf) + ")[" + STR(ind) + "] < (" + PrintNode(me->op1, v, vppf) +
2872  ")[" + STR(ind) + "] ? " + "(" + PrintNode(me->op0, v, vppf) + ")[" + STR(ind) + "]" + " : " +
2873  "(" + PrintNode(me->op1, v, vppf) + ")[" + STR(ind) + "]";
2874  if(ind != vector_size - 1)
2875  {
2876  res += ", ";
2877  }
2878  }
2879  res += "}";
2880  }
2881  else
2882  {
2883  std::string op_0 = PrintNode(me->op0, v, vppf), op_1 = PrintNode(me->op1, v, vppf);
2884  res += op_0 + " < " + op_1 + " ? " + op_0 + " : " + op_1;
2885  }
2886  break;
2887  }
2888  case max_expr_K:
2889  {
2890  const auto me = GetPointerS<const max_expr>(node);
2891  if(tree_helper::IsVectorType(me->type))
2892  {
2893  const auto element_type = tree_helper::CGetElements(me->type);
2894  const auto element_size = tree_helper::Size(element_type);
2895  const auto size = tree_helper::Size(me->type);
2896  const auto vector_size = size / element_size;
2897  res += "/*" + me->get_kind_text() + "*/";
2898  res += "(" + tree_helper::PrintType(TM, me->type) + ") ";
2899  res += "{";
2900  for(unsigned int ind = 0; ind < vector_size; ++ind)
2901  {
2902  res += "(" + PrintNode(me->op0, v, vppf) + ")[" + STR(ind) + "] > (" + PrintNode(me->op1, v, vppf) +
2903  ")[" + STR(ind) + "] ? " + "(" + PrintNode(me->op0, v, vppf) + ")[" + STR(ind) + "]" + " : " +
2904  "(" + PrintNode(me->op1, v, vppf) + ")[" + STR(ind) + "]";
2905  if(ind != vector_size - 1)
2906  {
2907  res += ", ";
2908  }
2909  }
2910  res += "}";
2911  }
2912  else
2913  {
2914  std::string op_0 = PrintNode(me->op0, v, vppf), op_1 = PrintNode(me->op1, v, vppf);
2915  res += op_0 + " > " + op_1 + " ? " + op_0 + " : " + op_1;
2916  }
2917  break;
2918  }
2919  case unordered_expr_K:
2920  {
2921  const auto be = GetPointerS<const binary_expr>(node);
2922  std::string op_0 = PrintNode(be->op0, v, vppf), op_1 = PrintNode(be->op1, v, vppf);
2923  res += "__builtin_isunordered(" + op_0 + "," + op_1 + ")";
2924  break;
2925  }
2926  case ordered_expr_K:
2927  {
2928  const auto be = GetPointerS<const binary_expr>(node);
2929  std::string op_0 = PrintNode(be->op0, v, vppf), op_1 = PrintNode(be->op1, v, vppf);
2930  res += "!__builtin_isunordered(" + op_0 + "," + op_1 + ")";
2931  break;
2932  }
2933  case unlt_expr_K:
2934  {
2935  const auto be = GetPointerS<const binary_expr>(node);
2936  std::string op_0 = PrintNode(be->op0, v, vppf), op_1 = PrintNode(be->op1, v, vppf);
2937  res += "!__builtin_isgreaterequal(" + op_0 + "," + op_1 + ")";
2938  break;
2939  }
2940  case unle_expr_K:
2941  {
2942  const auto be = GetPointerS<const binary_expr>(node);
2943  std::string op_0 = PrintNode(be->op0, v, vppf), op_1 = PrintNode(be->op1, v, vppf);
2944  res += "!__builtin_isgreater(" + op_0 + "," + op_1 + ")";
2945  break;
2946  }
2947  case ungt_expr_K:
2948  {
2949  const auto be = GetPointerS<const binary_expr>(node);
2950  std::string op_0 = PrintNode(be->op0, v, vppf), op_1 = PrintNode(be->op1, v, vppf);
2951  res += "!__builtin_islessequal(" + op_0 + "," + op_1 + ")";
2952  break;
2953  }
2954  case unge_expr_K:
2955  {
2956  const auto be = GetPointerS<const binary_expr>(node);
2957  std::string op_0 = PrintNode(be->op0, v, vppf), op_1 = PrintNode(be->op1, v, vppf);
2958  res += "!__builtin_isless(" + op_0 + "," + op_1 + ")";
2959  break;
2960  }
2961  case uneq_expr_K:
2962  {
2963  const auto be = GetPointerS<const binary_expr>(node);
2964  std::string op_0 = PrintNode(be->op0, v, vppf), op_1 = PrintNode(be->op1, v, vppf);
2965  res += "!__builtin_islessgreater(" + op_0 + "," + op_1 + ")";
2966  break;
2967  }
2968  case ltgt_expr_K:
2969  {
2970  const auto be = GetPointerS<const binary_expr>(node);
2971  std::string op_0 = PrintNode(be->op0, v, vppf), op_1 = PrintNode(be->op1, v, vppf);
2972  res += "__builtin_islessgreater(" + op_0 + "," + op_1 + ")";
2973  break;
2974  }
2975  case abs_expr_K:
2976  {
2977  const auto ae = GetPointerS<const abs_expr>(node);
2978  std::string op_0 = PrintNode(ae->op, v, vppf);
2979  if(GetPointer<const real_type>(GET_CONST_NODE(ae->type)))
2980  {
2981  const auto rt = GetPointerS<const real_type>(GET_CONST_NODE(ae->type));
2982  if(rt->prec == 80)
2983  {
2984  res += "__builtin_fabsl(" + op_0 + ")";
2985  }
2986  else if(rt->prec == 64)
2987  {
2988  res += "__builtin_fabs(" + op_0 + ")";
2989  }
2990  else if(rt->prec == 32)
2991  {
2992  res += "__builtin_fabsf(" + op_0 + ")";
2993  }
2994  else
2995  {
2996  THROW_ERROR("Abs on a real number with not supported precision");
2997  }
2998  }
2999  else
3000  {
3001  res += "(" + op_0 + ") >= 0 ? (" + op_0 + ") : -(" + op_0 + ")";
3002  }
3003  // res += "__builtin_llabs(" + op_0 + ")";
3004  break;
3005  }
3006  case complex_expr_K:
3007  {
3008  const auto ce = GetPointerS<const complex_expr>(node);
3009  std::string op_0 = PrintNode(ce->op0, v, vppf), op_1 = PrintNode(ce->op1, v, vppf);
3010  res += op_0 + "+ 1i*" + op_1;
3011  break;
3012  }
3013  case cond_expr_K:
3014  {
3015  const auto ce = GetPointerS<const cond_expr>(node);
3016  res = PrintNode(ce->op0, v, vppf) + " ? " + PrintNode(ce->op1, v, vppf) + " : " + PrintNode(ce->op2, v, vppf);
3017  break;
3018  }
3019  case ternary_plus_expr_K:
3020  {
3021  const auto te = GetPointerS<const ternary_expr>(node);
3022  res = PrintNode(te->op0, v, vppf) + " + " + PrintNode(te->op1, v, vppf) + " + " + PrintNode(te->op2, v, vppf);
3023  break;
3024  }
3025  case ternary_pm_expr_K:
3026  {
3027  const auto te = GetPointerS<const ternary_expr>(node);
3028  res = PrintNode(te->op0, v, vppf) + " + " + PrintNode(te->op1, v, vppf) + " - " + PrintNode(te->op2, v, vppf);
3029  break;
3030  }
3031  case ternary_mp_expr_K:
3032  {
3033  const auto te = GetPointerS<const ternary_expr>(node);
3034  res = PrintNode(te->op0, v, vppf) + " - " + PrintNode(te->op1, v, vppf) + " + " + PrintNode(te->op2, v, vppf);
3035  break;
3036  }
3037  case ternary_mm_expr_K:
3038  {
3039  const auto te = GetPointerS<const ternary_expr>(node);
3040  res = PrintNode(te->op0, v, vppf) + " - " + PrintNode(te->op1, v, vppf) + " - " + PrintNode(te->op2, v, vppf);
3041  break;
3042  }
3043  case fshl_expr_K:
3044  case fshr_expr_K:
3045  {
3046  const auto te = GetPointerS<const ternary_expr>(node);
3047  const auto type_size = tree_helper::Size(te->type);
3048  const auto left_op_cast = tree_helper::IsPointerType(te->op0);
3049  const auto right_op_cast = tree_helper::IsPointerType(te->op1);
3050  res += "(";
3051  if(left_op_cast)
3052  {
3053  res += "((unsigned long int)";
3054  }
3055  res += PrintNode(te->op0, v, vppf);
3056  if(left_op_cast)
3057  {
3058  res += ")";
3059  }
3060  res += " << (";
3061  if(node->get_kind() == fshl_expr_K)
3062  {
3063  res += PrintNode(te->op2, v, vppf);
3064  res += " % ";
3065  res += STR(type_size);
3066  }
3067  else
3068  {
3069  res += STR(type_size);
3070  res += " - (";
3071  res += PrintNode(te->op2, v, vppf);
3072  res += " % ";
3073  res += STR(type_size);
3074  res += ")";
3075  }
3076  res += ")) | (";
3077 
3078  if(right_op_cast)
3079  {
3080  res += "((unsigned long int)";
3081  }
3082  res += PrintNode(te->op1, v, vppf);
3083  if(right_op_cast)
3084  {
3085  res += ")";
3086  }
3087  res += " >> (";
3088  if(node->get_kind() == fshr_expr_K)
3089  {
3090  res += PrintNode(te->op2, v, vppf);
3091  res += " % ";
3092  res += STR(type_size);
3093  }
3094  else
3095  {
3096  res += STR(type_size);
3097  res += " - (";
3098  res += PrintNode(te->op2, v, vppf);
3099  res += " % ";
3100  res += STR(type_size);
3101  res += ")";
3102  }
3103  res += "))";
3104  break;
3105  }
3106  case bit_ior_concat_expr_K:
3107  {
3108  const auto te = GetPointerS<const ternary_expr>(node);
3109  res = PrintNode(te->op0, v, vppf) + " | (" + PrintNode(te->op1, v, vppf) + " & ((1ULL<<" +
3110  PrintNode(te->op2, v, vppf) + ")-1))";
3111  break;
3112  }
3113  case vec_cond_expr_K:
3114  {
3115  auto vce = GetPointerS<const vec_cond_expr>(node);
3116  const auto element_type = tree_helper::CGetElements(vce->type);
3117  const auto element_size = tree_helper::Size(element_type);
3118  const auto size = tree_helper::Size(vce->type);
3119  const auto vector_size = size / element_size;
3120  res += "/*" + vce->get_kind_text() + "*/";
3121  res += "(" + tree_helper::PrintType(TM, vce->type) + ") ";
3122  res += "{";
3123  for(unsigned int ind = 0; ind < vector_size; ++ind)
3124  {
3125  res += "(" + PrintNode(vce->op0, v, vppf) + ")" +
3126  (tree_helper::IsVectorType(vce->op0) ? "[" + STR(ind) + "]" : "") + " ? " + "(" +
3127  PrintNode(vce->op1, v, vppf) + ")[" + STR(ind) + "]" + " : " + "(" + PrintNode(vce->op2, v, vppf) +
3128  ")[" + STR(ind) + "]";
3129  if(ind != vector_size - 1)
3130  {
3131  res += ", ";
3132  }
3133  }
3134  res += "}";
3135  break;
3136  }
3137  case vec_perm_expr_K:
3138  {
3139  const auto vpe = GetPointerS<const vec_perm_expr>(node);
3140  const auto element_type = tree_helper::CGetElements(vpe->type);
3141  const auto element_size = tree_helper::Size(element_type);
3142  const auto size = tree_helper::Size(vpe->op0);
3143  const auto vector_size = size / element_size;
3144  res += "/*" + vpe->get_kind_text() + "*/";
3145  res += "(" + tree_helper::PrintType(TM, vpe->type) + ") ";
3146  res += "{";
3147  for(unsigned int ind = 0; ind < vector_size; ++ind)
3148  {
3149  res += "((((" + PrintNode(vpe->op2, v, vppf) + ")[" + STR(ind) + "])%" + STR(2 * vector_size) + ") < " +
3150  STR(vector_size) + ") ? (" + PrintNode(vpe->op0, v, vppf) + ")[(((" + PrintNode(vpe->op2, v, vppf) +
3151  ")[" + STR(ind) + "])%" + STR(2 * vector_size) + ")] : (" + PrintNode(vpe->op1, v, vppf) + ")[(((" +
3152  PrintNode(vpe->op2, v, vppf) + ")[" + STR(ind) + "])%" + STR(2 * vector_size) + ")-" +
3153  STR(vector_size) + "]";
3154  if(ind != vector_size - 1)
3155  {
3156  res += ", ";
3157  }
3158  }
3159  res += "}";
3160  break;
3161  }
3162  case gimple_cond_K:
3163  {
3164  const auto gc = GetPointerS<const gimple_cond>(node);
3165  for(const auto& pragma : gc->pragmas)
3166  {
3167  res += PrintNode(pragma, v, vppf) + "\n";
3168  }
3169  res = "if (" + PrintNode(gc->op0, v, vppf) + ")";
3170  break;
3171  }
3172  case gimple_multi_way_if_K:
3173  {
3174  const auto gmwi = GetPointerS<const gimple_multi_way_if>(node);
3175  res = "if (";
3176  bool first = true;
3177  for(const auto& cond : gmwi->list_of_cond)
3178  {
3179  if(first)
3180  {
3181  THROW_ASSERT(cond.first, "First condition of multi way if " + STR(node->index) + " is empty");
3182  res += PrintNode(cond.first, v, vppf);
3183  first = false;
3184  }
3185  else if(cond.first)
3186  {
3187  res += " /* else if(" + PrintNode(cond.first, v, vppf) + ")*/";
3188  }
3189  }
3190  res += ")";
3191  break;
3192  }
3193  case gimple_while_K:
3194  {
3195  const auto we = GetPointerS<const gimple_while>(node);
3196  res = "while (" + PrintNode(we->op0, v, vppf) + ")";
3197  break;
3198  }
3199  case gimple_for_K:
3200  {
3201  const auto fe = GetPointerS<const gimple_for>(node);
3202 #if !RELEASE
3203  if(fe->omp_for)
3204  {
3205  res = "//#pragma omp " + PrintNode(fe->omp_for, v, vppf) + "\n";
3206  }
3207 #endif
3208  res += "for (" + PrintNode(fe->op1, v, vppf) + "; ";
3209  res += PrintNode(fe->op0, v, vppf) + "; ";
3210  res += PrintNode(fe->op2, v, vppf);
3211  res += ")";
3212  break;
3213  }
3214  case gimple_switch_K:
3215  {
3216  const auto se = GetPointerS<const gimple_switch>(node);
3217  res += "switch(" + PrintNode(se->op0, v, vppf) + ")";
3218  break;
3219  }
3220  case gimple_assign_K:
3221  {
3222  const auto ms = GetPointerS<const gimple_assign>(node);
3223  if(!ms->init_assignment && !ms->clobber)
3224  {
3225  for(const auto& pragma : ms->pragmas)
3226  {
3227  res += PrintNode(pragma, v, vppf) + "\n";
3228  }
3229  res = "";
3230  if(tree_helper::IsArrayType(ms->op0))
3231  {
3232  const auto size = tree_helper::Size(ms->op0);
3233  res += "__builtin_memcpy(";
3234  if(GetPointer<const mem_ref>(GET_CONST_NODE(ms->op0)))
3235  {
3236  res += "&";
3237  }
3238  res += PrintNode(ms->op0, v, vppf) + ", ";
3239  if(GET_CONST_NODE(ms->op1)->get_kind() == view_convert_expr_K)
3240  {
3241  const auto vce = GetPointerS<const view_convert_expr>(GET_CONST_NODE(ms->op1));
3242  res += "&" + PrintNode(vce->op, v, vppf) + ", ";
3243  }
3244  else
3245  {
3246  if(GetPointer<const mem_ref>(GET_CONST_NODE(ms->op1)))
3247  {
3248  res += "&";
3249  }
3250  res += PrintNode(ms->op1, v, vppf) + ", ";
3251  }
3252  res += STR(size / 8) + ")";
3253  break;
3254  }
3255  if((!Param->getOption<bool>(OPT_without_transformation)) &&
3256  ((tree_helper::IsStructType(ms->op0) || tree_helper::IsUnionType(ms->op0)) &&
3257  (tree_helper::IsStructType(ms->op1) || tree_helper::IsUnionType(ms->op1)) &&
3260  {
3262  C_EC,
3263  "Implicit struct type definition not supported in gimple assignment " + STR(node->index) + " - " +
3266  }
3267  res += PrintNode(ms->op0, v, vppf) + " = ";
3268  const auto right = GET_CONST_NODE(ms->op1);
3270  switch(right->get_kind())
3271  {
3272  case constructor_K:
3273  {
3274  res += "(" + tree_helper::PrintType(TM, tree_helper::CGetType(ms->op0)) + ") ";
3275  res += PrintNode(ms->op1, v, vppf);
3276  break;
3277  }
3278  case vector_cst_K:
3279  {
3280  const auto vc = GetPointerS<const vector_cst>(right);
3281  const auto type = tree_helper::CGetType(ms->op0);
3282  if(type->index != GET_INDEX_NODE(vc->type))
3283  {
3284  res += "(" + tree_helper::PrintType(TM, type) + ") ";
3285  }
3286  res += PrintNode(ms->op1, v, vppf);
3287  break;
3288  }
3289  case binfo_K:
3290  case block_K:
3291  case call_expr_K:
3292  case aggr_init_expr_K:
3293  case case_label_expr_K:
3294  case identifier_node_K:
3295  case ssa_name_K:
3296  case statement_list_K:
3297  case target_expr_K:
3298  case target_mem_ref_K:
3299  case target_mem_ref461_K:
3300  case tree_list_K:
3301  case tree_vec_K:
3302  case complex_cst_K:
3303  case integer_cst_K:
3304  case real_cst_K:
3305  case string_cst_K:
3306  case error_mark_K:
3307  case lut_expr_K:
3309  case CASE_CPP_NODES:
3310  case CASE_DECL_NODES:
3311  case CASE_FAKE_NODES:
3312  case CASE_GIMPLE_NODES:
3313  case CASE_PRAGMA_NODES:
3316  case CASE_TYPE_NODES:
3317  case CASE_UNARY_EXPRESSION:
3318  {
3319  const auto left_type = tree_helper::CGetType(ms->op0);
3320  const auto right_type = tree_helper::CGetType(ms->op1);
3321  if(tree_helper::IsVectorType(left_type) && left_type->index != right_type->index)
3322  {
3323  res += "(" + tree_helper::PrintType(TM, left_type) + ") ";
3324  }
3325  if((right->get_kind() == rshift_expr_K || right->get_kind() == lshift_expr_K) &&
3326  tree_helper::IsPointerType(GetPointerS<const binary_expr>(right)->op0))
3327  {
3328  res += "(unsigned int)";
3329  }
3330  res += PrintNode(ms->op1, v, vppf);
3331  break;
3332  }
3333  case void_cst_K:
3334  default:
3335  {
3336  THROW_UNREACHABLE("");
3337  }
3338  }
3339  const auto vce = GetPointer<const view_convert_expr>(right);
3340  if(vce && GET_CONST_NODE(vce->op)->get_kind() == integer_cst_K)
3341  {
3342  const auto dest_type = tree_helper::CGetType(ms->op1);
3343  const auto source_type = tree_helper::CGetType(vce->op);
3344  res = "{union {" + tree_helper::PrintType(TM, dest_type) + " dest; " +
3345  tree_helper::PrintType(TM, source_type) +
3346  " source;} __panda_union; __panda_union.source = " + PrintNode(vce->op, v, vppf) + "; " + res;
3347  }
3348  }
3349  if(ms->predicate)
3350  {
3351  res = "if(" + PrintNode(ms->predicate, v, vppf) + ") " + res;
3352  }
3353  if(GET_CONST_NODE(ms->op1)->get_kind() == trunc_div_expr_K ||
3354  GET_CONST_NODE(ms->op1)->get_kind() == trunc_mod_expr_K)
3355  {
3356  const auto tde = GetPointerS<const binary_expr>(GET_CONST_NODE(ms->op1));
3357  res = "if(" + PrintNode(tde->op1, v, vppf) + " != 0) " + res;
3358  }
3359  break;
3360  }
3361  case gimple_nop_K:
3362  {
3363  res += "/*gimple_nop*/";
3364  break;
3365  }
3366  case init_expr_K:
3367  {
3368  const auto be = GetPointerS<const binary_expr>(node);
3369  res = PrintNode(be->op0, v, vppf) + " = ";
3370  const auto right = GET_CONST_NODE(be->op1);
3372  switch(right->get_kind())
3373  {
3374  case fix_trunc_expr_K:
3375  case fix_ceil_expr_K:
3376  case fix_floor_expr_K:
3377  case fix_round_expr_K:
3378  case float_expr_K:
3379  case convert_expr_K:
3380  case view_convert_expr_K:
3381  case nop_expr_K:
3382  case paren_expr_K:
3383  {
3384  const auto ue = GetPointerS<const unary_expr>(right);
3385  res = res + "(" + tree_helper::PrintType(TM, tree_helper::CGetType(be->op0)) + ") ";
3386  res += PrintNode(ue->op, v, vppf);
3387  break;
3388  }
3389  case binfo_K:
3390  case block_K:
3391  case call_expr_K:
3392  case aggr_init_expr_K:
3393  case case_label_expr_K:
3394  case constructor_K:
3395  case identifier_node_K:
3396  case ssa_name_K:
3397  case statement_list_K:
3398  case target_expr_K:
3399  case target_mem_ref_K:
3400  case target_mem_ref461_K:
3401  case tree_list_K:
3402  case tree_vec_K:
3403  case abs_expr_K:
3404  case addr_expr_K:
3405  case alignof_expr_K:
3406  case arrow_expr_K:
3407  case bit_not_expr_K:
3408  case buffer_ref_K:
3409  case card_expr_K:
3410  case cleanup_point_expr_K:
3411  case conj_expr_K:
3412  case exit_expr_K:
3413  case imagpart_expr_K:
3414  case indirect_ref_K:
3415  case misaligned_indirect_ref_K:
3416  case loop_expr_K:
3417  case negate_expr_K:
3418  case non_lvalue_expr_K:
3419  case realpart_expr_K:
3420  case reference_expr_K:
3421  case reinterpret_cast_expr_K:
3422  case sizeof_expr_K:
3423  case static_cast_expr_K:
3424  case throw_expr_K:
3425  case truth_not_expr_K:
3426  case unsave_expr_K:
3427  case va_arg_expr_K:
3428  case reduc_max_expr_K:
3429  case reduc_min_expr_K:
3430  case reduc_plus_expr_K:
3431  case vec_unpack_hi_expr_K:
3432  case vec_unpack_lo_expr_K:
3433  case vec_unpack_float_hi_expr_K:
3434  case vec_unpack_float_lo_expr_K:
3435  case error_mark_K:
3436  case lut_expr_K:
3438  case CASE_CPP_NODES:
3439  case CASE_CST_NODES:
3440  case CASE_DECL_NODES:
3441  case CASE_FAKE_NODES:
3442  case CASE_GIMPLE_NODES:
3443  case CASE_PRAGMA_NODES:
3446  case CASE_TYPE_NODES:
3447  default:
3448  res += PrintNode(be->op1, v, vppf);
3449  }
3450  break;
3451  }
3452  case gimple_return_K:
3453  {
3454  const auto re = GetPointerS<const gimple_return>(node);
3455  for(const auto& pragma : re->pragmas)
3456  {
3457  res += PrintNode(pragma, v, vppf) + "\n";
3458  }
3459  res += "return ";
3460  if(re->op != nullptr)
3461  {
3462  const auto return_node = GET_CONST_NODE(re->op);
3464  switch(return_node->get_kind())
3465  {
3466  case fix_trunc_expr_K:
3467  case fix_ceil_expr_K:
3468  case fix_floor_expr_K:
3469  case fix_round_expr_K:
3470  case float_expr_K:
3471  case convert_expr_K:
3472  case nop_expr_K:
3473  {
3474  const auto ue = GetPointerS<const unary_expr>(return_node);
3475  res += "(" + tree_helper::PrintType(TM, tree_helper::CGetType(re->op)) + ") (";
3476  res += PrintNode(ue->op, v, vppf);
3477  res += ")";
3478  break;
3479  }
3480  case constructor_K:
3481  {
3482  res += "(" + tree_helper::PrintType(TM, tree_helper::CGetType(re->op)) + ") ";
3483  res += PrintNode(re->op, v, vppf);
3484  break;
3485  }
3486  case binfo_K:
3487  case block_K:
3488  case call_expr_K:
3489  case aggr_init_expr_K:
3490  case case_label_expr_K:
3491  case identifier_node_K:
3492  case ssa_name_K:
3493  case statement_list_K:
3494  case target_expr_K:
3495  case target_mem_ref_K:
3496  case target_mem_ref461_K:
3497  case tree_list_K:
3498  case tree_vec_K:
3499  case abs_expr_K:
3500  case addr_expr_K:
3501  case alignof_expr_K:
3502  case arrow_expr_K:
3503  case bit_not_expr_K:
3504  case buffer_ref_K:
3505  case card_expr_K:
3506  case cleanup_point_expr_K:
3507  case conj_expr_K:
3508  case exit_expr_K:
3509  case imagpart_expr_K:
3510  case indirect_ref_K:
3511  case misaligned_indirect_ref_K:
3512  case loop_expr_K:
3513  case negate_expr_K:
3514  case non_lvalue_expr_K:
3515  case realpart_expr_K:
3516  case reference_expr_K:
3517  case reinterpret_cast_expr_K:
3518  case sizeof_expr_K:
3519  case static_cast_expr_K:
3520  case throw_expr_K:
3521  case truth_not_expr_K:
3522  case unsave_expr_K:
3523  case va_arg_expr_K:
3524  case reduc_max_expr_K:
3525  case reduc_min_expr_K:
3526  case reduc_plus_expr_K:
3527  case vec_unpack_hi_expr_K:
3528  case vec_unpack_lo_expr_K:
3529  case vec_unpack_float_hi_expr_K:
3530  case vec_unpack_float_lo_expr_K:
3531  case view_convert_expr_K:
3532  case error_mark_K:
3533  case paren_expr_K:
3534  case lut_expr_K:
3536  case CASE_CPP_NODES:
3537  case CASE_CST_NODES:
3538  case CASE_DECL_NODES:
3539  case CASE_FAKE_NODES:
3540  case CASE_GIMPLE_NODES:
3541  case CASE_PRAGMA_NODES:
3544  case CASE_TYPE_NODES:
3545  default:
3546  {
3547  res += PrintNode(re->op, v, vppf);
3548  break;
3549  }
3550  }
3551  }
3552  res += ";";
3553  break;
3554  }
3555  case call_expr_K:
3556  case aggr_init_expr_K:
3557  {
3558  const auto ce = GetPointerS<const call_expr>(node);
3559  const function_decl* fd = nullptr;
3560  const auto op0 = GET_CONST_NODE(ce->fn);
3561  bool is_va_start_end = false;
3562 
3563  // sizeof workaround
3564  bool is_sizeof = false;
3565  auto op0_kind = op0->get_kind();
3566 
3567  switch(op0_kind)
3568  {
3569  case addr_expr_K:
3570  {
3571  const auto ue = GetPointerS<const unary_expr>(op0);
3572  const auto fn = GET_CONST_NODE(ue->op);
3573  THROW_ASSERT(fn->get_kind() == function_decl_K,
3574  "tree node not currently supported " + fn->get_kind_text());
3575  fd = GetPointerS<const function_decl>(fn);
3577  std::string fname = tree_helper::print_function_name(TM, fd);
3578  if(fname == "__builtin_va_start" || fname == "__builtin_va_end" || fname == "__builtin_va_copy")
3579  {
3580  is_va_start_end = true;
3581  }
3582  if(fname == "__builtin_constant_p")
3583  {
3584  THROW_ERROR_CODE(C_EC, "Not supported function " + fname);
3585  }
3586  if(fname == STR_CST_string_sizeof)
3587  {
3588  is_sizeof = true;
3589  res += "sizeof";
3590  }
3591  else
3592  {
3593  res += fname;
3594  }
3595  break;
3596  }
3597  case ssa_name_K:
3598  {
3599  res += "(*" + PrintNode(ce->fn, v, vppf) + ")";
3600  break;
3601  }
3602  case binfo_K:
3603  case block_K:
3604  case call_expr_K:
3605  case aggr_init_expr_K:
3606  case case_label_expr_K:
3607  case constructor_K:
3608  case identifier_node_K:
3609  case statement_list_K:
3610  case target_mem_ref_K:
3611  case target_mem_ref461_K:
3612  case tree_list_K:
3613  case tree_vec_K:
3615  {
3616  if(op0_kind == obj_type_ref_K)
3617  {
3618  const auto fn = tree_helper::find_obj_type_ref_function(ce->fn);
3619  THROW_ASSERT(GET_CONST_NODE(fn)->get_kind(),
3620  "tree node not currently supported " + GET_CONST_NODE(fn)->get_kind_text());
3621  const auto local_fd = GetPointerS<const function_decl>(GET_CONST_NODE(fn));
3623  {
3624  res += PrintNode(fn, v, vppf) + " = ";
3625  }
3626  res += tree_helper::print_function_name(TM, local_fd);
3627  }
3628  else
3629  {
3630  THROW_ERROR(std::string("tree node not currently supported ") + op0->get_kind_text());
3631  }
3632  break;
3633  }
3634  case target_expr_K:
3635  case error_mark_K:
3636  case paren_expr_K:
3637  case lut_expr_K:
3639  case CASE_CPP_NODES:
3640  case CASE_CST_NODES:
3641  case CASE_DECL_NODES:
3642  case CASE_FAKE_NODES:
3643  case CASE_GIMPLE_NODES:
3645  case CASE_PRAGMA_NODES:
3647  case CASE_TYPE_NODES:
3648  default:
3649  {
3650  THROW_ERROR(std::string("tree node not currently supported ") + op0->get_kind_text());
3651  }
3652  }
3654  res += "(";
3655  if(is_va_start_end)
3656  {
3657  THROW_ASSERT(ce->args.size(), "va_start or va_end have to have arguments");
3658  const auto par1 = GET_CONST_NODE(ce->args[0]);
3659  // print the first removing the address
3660  if(GetPointer<const addr_expr>(par1))
3661  {
3662  res += PrintNode(GetPointerS<const addr_expr>(par1)->op, v, vppf);
3663  }
3664  else if(GetPointer<const var_decl>(par1) || GetPointer<const ssa_name>(par1))
3665  {
3666  res += "*(" + PrintNode(par1, v, vppf) + ")";
3667  }
3668  else
3669  {
3670  THROW_ERROR("expected an address or a variable " + STR(par1->index));
3671  }
3672  for(size_t arg_index = 1; arg_index < ce->args.size(); arg_index++)
3673  {
3674  res += ", ";
3675  res += PrintNode(ce->args[arg_index], v, vppf);
3676  }
3677  }
3678  else if(is_sizeof)
3679  {
3680  THROW_ASSERT(ce->args.size() == 1, "Wrong number of arguments: " + STR(ce->args.size()));
3681  std::string argument = PrintNode(ce->args[0], v, vppf);
3682  const auto arg1 = GET_CONST_NODE(ce->args[0]);
3683  THROW_ASSERT(GetPointer<const addr_expr>(arg1),
3684  "Argument is not an addr_expr but a " + std::string(arg1->get_kind_text()));
3685  const auto ae = GetPointer<const addr_expr>(arg1);
3687  if(GetPointer<const array_ref>(GET_CONST_NODE(ae->op)))
3688  {
3689  THROW_ASSERT(GetPointer<const array_ref>(GET_CONST_NODE(ae->op)),
3690  "Argument is not an array ref but a " +
3691  std::string(GET_CONST_NODE(ae->op)->get_kind_text()));
3692 #if HAVE_ASSERTS
3693  const auto ar = GetPointerS<const array_ref>(GET_CONST_NODE(ae->op));
3694 #endif
3695  THROW_ASSERT(GetPointer<const string_cst>(GET_CONST_NODE(ar->op0)),
3696  "Argument is not a string cast but a " +
3697  std::string(GET_CONST_NODE(ar->op0)->get_kind_text()));
3698  std::string unquoted_argument = argument.substr(1, argument.size() - 2);
3699  res += unquoted_argument;
3700  }
3701  else
3703  {
3704  THROW_ASSERT(GetPointer<const string_cst>(GET_CONST_NODE(ae->op)),
3705  "Argument is not a string cast but a " +
3706  std::string(GET_CONST_NODE(ae->op)->get_kind_text()));
3707  std::string unquoted_argument = argument.substr(3, argument.size() - 6);
3708  res += unquoted_argument;
3709  }
3710  }
3711  else
3712  {
3713  if(ce->args.size())
3714  {
3715  const auto& actual_args = ce->args;
3716  std::vector<tree_nodeRef> formal_args;
3717  if(fd)
3718  {
3719  formal_args = fd->list_of_args;
3720  }
3721  std::vector<tree_nodeRef>::const_iterator actual_arg, actual_arg_end = actual_args.end();
3722  std::vector<tree_nodeRef>::const_iterator formal_arg, formal_arg_end = formal_args.end();
3723  for(actual_arg = actual_args.begin(), formal_arg = formal_args.begin(); actual_arg != actual_arg_end;
3724  ++actual_arg)
3725  {
3726  if(formal_arg != formal_arg_end &&
3727  (tree_helper::IsStructType(*actual_arg) || tree_helper::IsUnionType(*actual_arg)) &&
3728  (tree_helper::IsStructType(*formal_arg) || tree_helper::IsUnionType(*formal_arg)) &&
3731  {
3732  THROW_ERROR_CODE(C_EC, "Implicit struct type definition not supported in gimple assignment " +
3733  STR(node->index));
3734  }
3735  if(actual_arg != actual_args.begin())
3736  {
3737  res += ", ";
3738  }
3739  res += PrintNode(*actual_arg, v, vppf);
3740  if(formal_arg != formal_arg_end)
3741  {
3742  ++formal_arg;
3743  }
3744  }
3745  }
3746  }
3747  res += ")";
3748  break;
3749  }
3750  case gimple_call_K:
3751  {
3752  const auto ce = GetPointerS<const gimple_call>(node);
3753  const function_decl* fd = nullptr;
3754  for(const auto& pragma : ce->pragmas)
3755  {
3756  res += PrintNode(pragma, v, vppf) + "\n";
3757  }
3758  const auto op0 = GET_CONST_NODE(ce->fn);
3759  bool is_va_start_end = false;
3760 
3761  // sizeof workaround
3762  bool is_sizeof = false;
3763  auto op0_kind = op0->get_kind();
3764 
3765  switch(op0_kind)
3766  {
3767  case addr_expr_K:
3768  {
3769  const auto ue = GetPointerS<const unary_expr>(op0);
3770  const auto fn = GET_CONST_NODE(ue->op);
3771  THROW_ASSERT(fn->get_kind() == function_decl_K,
3772  "tree node not currently supported " + fn->get_kind_text());
3773  fd = GetPointerS<const function_decl>(fn);
3775  std::string fname = tree_helper::print_function_name(TM, fd);
3776  if(fname == "__builtin_va_start" || fname == "__builtin_va_end" || fname == "__builtin_va_copy")
3777  {
3778  is_va_start_end = true;
3779  }
3780  if(fname == "__builtin_constant_p")
3781  {
3782  THROW_ERROR_CODE(C_EC, "Not supported function " + fname);
3783  }
3784  if(fname == STR_CST_string_sizeof)
3785  {
3786  is_sizeof = true;
3787  res += "sizeof";
3788  }
3789  else
3790  {
3791  res += fname;
3792  }
3793  break;
3794  }
3795  case ssa_name_K:
3796  {
3797  res += "(*" + PrintNode(ce->fn, v, vppf) + ")";
3798  break;
3799  }
3800  case binfo_K:
3801  case block_K:
3802  case call_expr_K:
3803  case aggr_init_expr_K:
3804  case case_label_expr_K:
3805  case constructor_K:
3806  case identifier_node_K:
3807  case statement_list_K:
3808  case target_mem_ref_K:
3809  case target_mem_ref461_K:
3810  case tree_list_K:
3811  case tree_vec_K:
3813  {
3814  if(op0_kind == obj_type_ref_K)
3815  {
3816  const auto fn = tree_helper::find_obj_type_ref_function(ce->fn);
3817  THROW_ASSERT(GET_CONST_NODE(fn)->get_kind() == function_decl_K,
3818  "tree node not currently supported " + fn->get_kind_text());
3819  const auto local_fd = GetPointerS<const function_decl>(GET_CONST_NODE(fn));
3821  {
3822  res += PrintNode(fn, v, vppf) + " = ";
3823  }
3824  res += tree_helper::print_function_name(TM, local_fd);
3825  }
3826  else
3827  {
3828  THROW_ERROR(std::string("tree node not currently supported ") + op0->get_kind_text());
3829  }
3830  break;
3831  }
3832  case target_expr_K:
3833  case error_mark_K:
3834  case paren_expr_K:
3835  case lut_expr_K:
3837  case CASE_CPP_NODES:
3838  case CASE_CST_NODES:
3839  case CASE_DECL_NODES:
3840  case CASE_FAKE_NODES:
3841  case CASE_GIMPLE_NODES:
3843  case CASE_PRAGMA_NODES:
3845  case CASE_TYPE_NODES:
3846  default:
3847  {
3848  THROW_ERROR(std::string("tree node not currently supported ") + op0->get_kind_text());
3849  }
3850  }
3852  res += "(";
3853  if(is_va_start_end)
3854  {
3855  THROW_ASSERT(ce->args.size(), "va_start or va_end have to have arguments");
3856  const auto par1 = GET_CONST_NODE(ce->args[0]);
3857  // print the first removing the address
3858  if(GetPointer<const addr_expr>(par1))
3859  {
3860  res += PrintNode(GetPointerS<const addr_expr>(par1)->op, v, vppf);
3861  }
3862  else if(GetPointer<const var_decl>(par1) || GetPointer<const ssa_name>(par1))
3863  {
3864  res += "*(" + PrintNode(par1, v, vppf) + ")";
3865  }
3866  else
3867  {
3868  THROW_ERROR("expected an address or a variable " + STR(par1));
3869  }
3870  for(size_t arg_index = 1; arg_index < ce->args.size(); arg_index++)
3871  {
3872  res += ", ";
3873  res += PrintNode(ce->args[arg_index], v, vppf);
3874  }
3875  }
3876  else if(is_sizeof)
3877  {
3878  THROW_ASSERT(ce->args.size() == 1, "Wrong number of arguments: " + STR(ce->args.size()));
3879  const auto arg1 = GET_CONST_NODE(ce->args[0]);
3880 #ifndef NDEBUG
3881  THROW_ASSERT(GetPointer<const addr_expr>(arg1),
3882  "Argument is not an addr_expr but a " + std::string(arg1->get_kind_text()));
3883  const auto ae = GetPointerS<const addr_expr>(arg1);
3884  if(GetPointer<const array_ref>(GET_CONST_NODE(ae->op)))
3885  {
3886  THROW_ASSERT(GetPointer<const array_ref>(GET_CONST_NODE(ae->op)),
3887  "Argument is not an array ref but a " +
3888  std::string(GET_CONST_NODE(ae->op)->get_kind_text()));
3889  const auto ar = GetPointer<const array_ref>(GET_CONST_NODE(ae->op));
3890  THROW_ASSERT(GetPointer<const string_cst>(GET_CONST_NODE(ar->op0)),
3891  "Argument is not a string cast but a " +
3892  std::string(GET_CONST_NODE(ar->op0)->get_kind_text()));
3893  }
3894  else
3895  {
3896  THROW_ASSERT(GetPointer<const string_cst>(GET_CONST_NODE(ae->op)),
3897  "Argument is not a string cast but a " +
3898  std::string(GET_CONST_NODE(ae->op)->get_kind_text()));
3899  }
3900 #endif
3901  const auto argument = PrintNode(ce->args[0], v, vppf);
3902  const auto unquoted_argument = argument.substr(1, argument.size() - 2);
3903  res += unquoted_argument;
3904  }
3905  else
3906  {
3907  if(ce->args.size())
3908  {
3909  const auto& actual_args = ce->args;
3910  std::vector<tree_nodeRef> formal_args;
3911  if(fd)
3912  {
3913  formal_args = fd->list_of_args;
3914  }
3915  std::vector<tree_nodeRef>::const_iterator actual_arg, actual_arg_end = actual_args.end();
3916  std::vector<tree_nodeRef>::const_iterator formal_arg, formal_arg_end = formal_args.end();
3917  for(actual_arg = actual_args.begin(), formal_arg = formal_args.begin(); actual_arg != actual_arg_end;
3918  ++actual_arg)
3919  {
3920  if(formal_arg != formal_arg_end &&
3921  (tree_helper::IsStructType(*actual_arg) || tree_helper::IsUnionType(*actual_arg)) &&
3922  (tree_helper::IsStructType(*formal_arg) || tree_helper::IsUnionType(*formal_arg)) &&
3925  {
3926  THROW_ERROR_CODE(C_EC, "Implicit struct type definition not supported in gimple assignment " +
3927  STR(node->index));
3928  }
3929  if(actual_arg != actual_args.begin())
3930  {
3931  res += ", ";
3932  }
3933  res += PrintNode(*actual_arg, v, vppf);
3934  if(formal_arg != formal_arg_end)
3935  {
3936  ++formal_arg;
3937  }
3938  }
3939  }
3940  }
3941  res += ")";
3942  break;
3943  }
3944  case gimple_resx_K:
3945  {
3946  res += "__gimple_resx()";
3947  break;
3948  }
3949  case gimple_asm_K:
3950  {
3951  const auto ae = GetPointerS<const gimple_asm>(node);
3952  for(const auto& pragma : ae->pragmas)
3953  {
3954  res += PrintNode(pragma, v, vppf);
3955  }
3956  res += "asm";
3957  if(ae->volatile_flag)
3958  {
3959  res += " __volatile__ ";
3960  }
3961  res += "(\"" + ae->str + "\"";
3962  if(ae->out)
3963  {
3964  res += ":";
3965  auto tl = GetPointerS<const tree_list>(GET_CONST_NODE(ae->out));
3966  std::string out_string;
3967  do
3968  {
3969  auto tl_purp = GetPointerS<const tree_list>(GET_CONST_NODE(tl->purp));
3970  out_string = "";
3971  do
3972  {
3973  out_string += PrintConstant(tl_purp->valu, vppf);
3974  if(tl_purp->chan)
3975  {
3976  tl_purp = GetPointer<const tree_list>(GET_CONST_NODE(tl_purp->chan));
3977  }
3978  else
3979  {
3980  tl_purp = nullptr;
3981  }
3982  } while(tl_purp);
3983  if(out_string == "\"=\"")
3984  {
3985  out_string = "\"=r\"";
3986  }
3987  res += out_string;
3988  res += "(" + PrintNode(tl->valu, v, vppf) + ")";
3989  if(tl->chan)
3990  {
3991  res += ",";
3992  tl = GetPointer<const tree_list>(GET_CONST_NODE(tl->chan));
3993  }
3994  else
3995  {
3996  tl = nullptr;
3997  }
3998  } while(tl);
3999  }
4000  else if(ae->in || ae->clob)
4001  {
4002  res += ":";
4003  }
4004  if(ae->in)
4005  {
4006  res += ":";
4007  auto tl = GetPointerS<const tree_list>(GET_CONST_NODE(ae->in));
4008  std::string in_string;
4009  do
4010  {
4011  auto tl_purp = GetPointer<const tree_list>(GET_CONST_NODE(tl->purp));
4012  in_string = "";
4013  do
4014  {
4015  in_string += PrintConstant(tl_purp->valu, vppf);
4016  if(tl_purp->chan)
4017  {
4018  tl_purp = GetPointer<const tree_list>(GET_CONST_NODE(tl_purp->chan));
4019  }
4020  else
4021  {
4022  tl_purp = nullptr;
4023  }
4024  } while(tl_purp);
4025  if(in_string == "\"\"")
4026  {
4027  in_string = "\"r\"";
4028  }
4029  res += in_string;
4030  res += "(" + PrintNode(tl->valu, v, vppf) + ")";
4031  if(tl->chan)
4032  {
4033  res += ",";
4034  tl = GetPointer<const tree_list>(GET_CONST_NODE(tl->chan));
4035  }
4036  else
4037  {
4038  tl = nullptr;
4039  }
4040  } while(tl);
4041  }
4042  else if(ae->clob)
4043  {
4044  res += ":";
4045  }
4046  if(ae->clob)
4047  {
4048  res += ":";
4049  auto tl = GetPointerS<const tree_list>(GET_CONST_NODE(ae->clob));
4050  do
4051  {
4052  res += PrintNode(tl->valu, v, vppf);
4053  if(tl->chan)
4054  {
4055  res += " ";
4056  tl = GetPointer<const tree_list>(GET_CONST_NODE(tl->chan));
4057  }
4058  else
4059  {
4060  tl = nullptr;
4061  }
4062  } while(tl);
4063  }
4064  res += ")";
4065  break;
4066  }
4067  case gimple_phi_K:
4068  {
4069  const auto pn = GetPointerS<const gimple_phi>(node);
4070  res += "/* " + PrintNode(pn->res, v, vppf) + " = gimple_phi(";
4071  for(const auto& def_edge : pn->CGetDefEdgesList())
4072  {
4073  if(def_edge != pn->CGetDefEdgesList().front())
4074  {
4075  res += ", ";
4076  }
4077  res += "<" + PrintNode(def_edge.first, v, vppf) + ", BB" + STR(def_edge.second) + ">";
4078  }
4079  res += ") */";
4080  break;
4081  }
4082  case ssa_name_K:
4083  {
4084  res += (*vppf)(node->index);
4085  // res += PrintNode(sn->var, v, vppf);
4086  /*if (!sn->volatile_flag || GET_CONST_NODE(sn->CGetDefStmt())->get_kind() == gimple_nop_K)
4087  res += "_" + STR(sn->vers);*/
4088  break;
4089  }
4090  case integer_cst_K:
4091  case real_cst_K:
4092  case string_cst_K:
4093  case vector_cst_K:
4094  case void_cst_K:
4095  case complex_cst_K:
4096  {
4097  res = PrintConstant(node, vppf);
4098  break;
4099  }
4100  case var_decl_K:
4101  case result_decl_K:
4102  case parm_decl_K:
4103  {
4104  res = (*vppf)(node->index);
4105  break;
4106  }
4107  case field_decl_K:
4108  {
4109  res = PrintVariable(node->index);
4110  break;
4111  }
4112  case label_decl_K:
4113  {
4114  const auto ld = GetPointerS<const label_decl>(node);
4115  if(ld->name)
4116  {
4117  const auto id = GetPointerS<const identifier_node>(GET_CONST_NODE(ld->name));
4118  res = id->strg;
4119  }
4120  else
4121  {
4122  res = "_unnamed_label_" + STR(node->index);
4123  }
4124  break;
4125  }
4126  case gimple_label_K:
4127  {
4128  const auto le = GetPointerS<const gimple_label>(node);
4129  if(!GetPointerS<const label_decl>(GET_CONST_NODE(le->op))->artificial_flag)
4130  {
4131  res += PrintNode(le->op, v, vppf);
4132  res += ":";
4133  }
4134  break;
4135  }
4136  case gimple_goto_K:
4137  {
4138  const auto ge = GetPointerS<const gimple_goto>(node);
4139  const auto is_a_label = GetPointer<const label_decl>(GET_CONST_NODE(ge->op)) != nullptr;
4140  res += (is_a_label ? "goto " : "goto *") + PrintNode(ge->op, v, vppf);
4141  break;
4142  }
4143  case constructor_K:
4144  {
4145  res += PrintInit(node, vppf);
4146  break;
4147  }
4148  case with_size_expr_K:
4149  {
4150  const auto wse = GetPointerS<const with_size_expr>(node);
4151  res += PrintNode(wse->op0, v, vppf);
4152  break;
4153  }
4154  case gimple_predict_K:
4155  case null_node_K:
4156  {
4157  break;
4158  }
4159  case gimple_pragma_K:
4160  {
4161  const auto pn = GetPointerS<const gimple_pragma>(node);
4162 #if 0
4163  if(pn->directive && (GetPointer<const omp_for_pragma>(GET_CONST_NODE(pn->directive)) || GetPointer<const omp_simd_pragma>(GET_CONST_NODE(pn->directive))))
4164  {
4165  break;
4166  }
4167 #endif
4168  if(pn->is_block && !pn->is_opening)
4169  {
4170  res += "\n}";
4171  }
4172  else
4173  {
4174  res += "#pragma ";
4175  if(!pn->scope)
4176  {
4177  res += pn->line;
4178  }
4179  else
4180  {
4181  res += PrintNode(pn->scope, v, vppf);
4182  res += " ";
4183  res += PrintNode(pn->directive, v, vppf);
4184  if(pn->is_block)
4185  {
4186  res += "\n{";
4187  }
4188  }
4189  }
4190  break;
4191  }
4192  case omp_pragma_K:
4193  {
4194  res += "omp";
4195  break;
4196  }
4197  case omp_atomic_pragma_K:
4198  {
4199  res += " atomic";
4200  break;
4201  }
4202  case omp_for_pragma_K:
4203  {
4204  const auto fp = GetPointerS<const omp_for_pragma>(node);
4205  res += "for ";
4207  for(const auto& clause : fp->clauses)
4208  {
4209  res += " " + clause.first + "(" + clause.second + ")";
4210  }
4211  break;
4212  }
4213  case omp_parallel_pragma_K:
4214  {
4215  const auto pn = GetPointerS<const omp_parallel_pragma>(node);
4216  if(!pn->is_shortcut)
4217  {
4218  res += "parallel";
4219  }
4221  for(const auto& clause : pn->clauses)
4222  {
4223  res += " " + clause.first + "(" + clause.second + ")";
4224  }
4225  break;
4226  }
4227  case omp_sections_pragma_K:
4228  {
4229  const auto pn = GetPointerS<const omp_sections_pragma>(node);
4230  if(!pn->is_shortcut)
4231  {
4232  res += "sections";
4233  }
4234  break;
4235  }
4236  case omp_parallel_sections_pragma_K:
4237  {
4238  const auto pn = GetPointerS<const omp_parallel_sections_pragma>(node);
4239  res += "parallel sections";
4240  res += PrintNode(pn->op0, v, vppf);
4241  res += " ";
4242  res += PrintNode(pn->op1, v, vppf);
4243  break;
4244  }
4245  case omp_section_pragma_K:
4246  {
4247  res += "section";
4248  break;
4249  }
4250  case omp_declare_simd_pragma_K:
4251  {
4252  const auto fp = GetPointerS<const omp_declare_simd_pragma>(node);
4253  res += "declare simd ";
4255  for(const auto& clause : fp->clauses)
4256  {
4257  res += " " + clause.first + "(" + clause.second + ")";
4258  }
4259  break;
4260  }
4261  case omp_simd_pragma_K:
4262  {
4263  const auto fp = GetPointerS<const omp_simd_pragma>(node);
4264  res += "simd ";
4266  for(const auto& clause : fp->clauses)
4267  {
4268  res += " " + clause.first + "(" + clause.second + ")";
4269  }
4270  break;
4271  }
4272  case omp_critical_pragma_K:
4273  {
4274  res += "critical";
4275  const auto ocp = GetPointerS<const omp_critical_pragma>(node);
4276  for(const auto& clause : ocp->clauses)
4277  {
4278  res += " " + clause.first + "(" + clause.second + ")";
4279  }
4280  break;
4281  }
4282  case omp_target_pragma_K:
4283  {
4284  res += "target";
4285  const auto otp = GetPointerS<const omp_target_pragma>(node);
4286  for(const auto& clause : otp->clauses)
4287  {
4288  res += " " + clause.first + "(" + clause.second + ")";
4289  }
4290  break;
4291  }
4292  case omp_task_pragma_K:
4293  {
4294  res += "task";
4295  const auto otp = GetPointerS<const omp_task_pragma>(node);
4296  for(const auto& clause : otp->clauses)
4297  {
4298  res += " " + clause.first + "(" + clause.second + ")";
4299  }
4300  break;
4301  }
4302 #if HAVE_FROM_PRAGMA_BUILT
4303  case map_pragma_K:
4304  {
4306  break;
4307  }
4308  case call_hw_pragma_K:
4309  {
4310  res += STR_CST_pragma_keyword_call_hw " ";
4311  const auto ch = GetPointerS<const call_hw_pragma>(node);
4312  res += ch->HW_component;
4313  if(ch->ID_implementation.size())
4314  {
4315  res += " " + STR(ch->ID_implementation);
4316  }
4317  break;
4318  }
4319  case call_point_hw_pragma_K:
4320  {
4322  const auto ch = GetPointerS<const call_point_hw_pragma>(node);
4323  res += ch->HW_component;
4324  if(ch->ID_implementation.size())
4325  {
4326  res += " " + STR(ch->ID_implementation);
4327  }
4328  if(ch->recursive)
4329  {
4330  res += " " + std::string(STR_CST_pragma_keyword_recursive);
4331  }
4332  break;
4333  }
4334 #else
4335  case map_pragma_K:
4336  case call_hw_pragma_K:
4337  case call_point_hw_pragma_K:
4338  {
4339  THROW_UNREACHABLE("Mapping pragmas can not be printed in this version");
4340  break;
4341  }
4342 #endif
4343  case issue_pragma_K:
4344  {
4345  res = "issue";
4346  break;
4347  }
4348  case profiling_pragma_K:
4349  {
4350  res = "profiling";
4351  break;
4352  }
4353  case blackbox_pragma_K:
4354  {
4355  res = "blackbox";
4356  break;
4357  }
4358  case statistical_profiling_K:
4359  {
4360  res = "profiling";
4361  break;
4362  }
4363  case assert_expr_K:
4364  {
4365  const auto ae = GetPointerS<const assert_expr>(node);
4366  res += PrintNode(ae->op0, v, vppf) + "/* " + PrintNode(ae->op1, v, vppf) + "*/";
4367  break;
4368  }
4369  case reduc_max_expr_K:
4370  {
4371  const auto rme = GetPointerS<const reduc_max_expr>(node);
4372  res += "/*reduc_max_expr*/" + PrintNode(rme->op, v, vppf);
4373  break;
4374  }
4375  case reduc_min_expr_K:
4376  {
4377  const auto rme = GetPointerS<const reduc_min_expr>(node);
4378  res += "/*reduc_min_expr*/" + PrintNode(rme->op, v, vppf);
4379  break;
4380  }
4381  case reduc_plus_expr_K:
4382  {
4383  const auto rpe = GetPointerS<const reduc_plus_expr>(node);
4384  res += "/*reduc_plus_expr*/";
4385  res += "(" + tree_helper::PrintType(TM, rpe->type) + ") ";
4386  res += "{";
4387  const auto size = tree_helper::Size(rpe->type);
4388  const auto element_type = tree_helper::CGetElements(rpe->type);
4389  const auto element_size = tree_helper::Size(element_type);
4390  const auto vector_size = size / element_size;
4391  res += PrintNode(rpe->op, v, vppf) + "[0]";
4392  for(unsigned int ind = 1; ind < vector_size; ++ind)
4393  {
4394  res += "+" + PrintNode(rpe->op, v, vppf) + "[" + STR(ind) + "]";
4395  }
4396  for(unsigned int ind = 1; ind < vector_size; ++ind)
4397  {
4398  res += ", 0";
4399  }
4400  res += "}";
4401  break;
4402  }
4403  case vec_unpack_hi_expr_K:
4404  {
4405  const auto vuh = GetPointerS<const vec_unpack_hi_expr>(node);
4406  const auto op = GET_CONST_NODE(vuh->op);
4407  const auto element_type = tree_helper::CGetElements(vuh->type);
4408  const auto element_size = tree_helper::Size(element_type);
4409  const auto size = tree_helper::Size(vuh->type);
4410  const auto vector_size = size / element_size;
4411  res += "/*" + vuh->get_kind_text() + "*/";
4412  res += "(" + tree_helper::PrintType(TM, vuh->type) + ") ";
4413  res += "{";
4414  if(op->get_kind() == vector_cst_K)
4415  {
4416  const auto vc = GetPointerS<const vector_cst>(op);
4417  for(auto i = static_cast<unsigned int>(vc->list_of_valu.size() / 2); i < vc->list_of_valu.size();
4418  i++) // vector elements
4419  {
4420  res += "((" + tree_helper::PrintType(TM, element_type) + ") (";
4421  res += PrintConstant(vc->list_of_valu[i], vppf);
4422  res += "))";
4423  if(i != (vc->list_of_valu).size() - 1)
4424  { // not the last element element
4425  res += ", ";
4426  }
4427  }
4428  }
4429  else
4430  {
4431  for(auto ind = vector_size; ind < 2 * vector_size; ++ind)
4432  {
4433  res += "((" + tree_helper::PrintType(TM, element_type) + ") (" + PrintNode(vuh->op, v, vppf) + "[" +
4434  STR(ind) + "]))";
4435  if(ind != 2 * vector_size - 1)
4436  {
4437  res += ", ";
4438  }
4439  }
4440  }
4441  res += "}";
4442  break;
4443  }
4444  case vec_unpack_lo_expr_K:
4445  {
4446  const auto vul = GetPointerS<const vec_unpack_lo_expr>(node);
4447  const auto op = GET_CONST_NODE(vul->op);
4448  const auto element_type = tree_helper::CGetElements(vul->type);
4449  const auto element_size = tree_helper::Size(element_type);
4450  const auto size = tree_helper::Size(vul->type);
4451  const auto vector_size = size / element_size;
4452  res += "/*" + vul->get_kind_text() + "*/";
4453  res += "(" + tree_helper::PrintType(TM, vul->type) + ") ";
4454  res += "{";
4455  if(op->get_kind() == vector_cst_K)
4456  {
4457  const auto vc = GetPointerS<const vector_cst>(op);
4458  for(unsigned int i = 0; i < vc->list_of_valu.size() / 2; i++) // vector elements
4459  {
4460  res += "((" + tree_helper::PrintType(TM, element_type) + ") (";
4461  res += PrintConstant(vc->list_of_valu[i], vppf);
4462  res += "))";
4463  if(i != (vc->list_of_valu).size() / 2 - 1)
4464  { // not the last element element
4465  res += ", ";
4466  }
4467  }
4468  }
4469  else
4470  {
4471  for(unsigned int ind = 0; ind < vector_size; ++ind)
4472  {
4473  res += "((" + tree_helper::PrintType(TM, element_type) + ") (" + PrintNode(vul->op, v, vppf) + "[" +
4474  STR(ind) + "]))";
4475  if(ind != vector_size - 1)
4476  {
4477  res += ", ";
4478  }
4479  }
4480  }
4481  res += "}";
4482  break;
4483  }
4484  case vec_unpack_float_hi_expr_K:
4485  case vec_unpack_float_lo_expr_K:
4486  {
4487  const auto vie = GetPointerS<const unary_expr>(node);
4488  res += "/*" + vie->get_kind_text() + "*/" + PrintNode(vie->op, v, vppf);
4489  break;
4490  }
4491  case paren_expr_K:
4492  {
4493  const auto vie = GetPointerS<const unary_expr>(node);
4494  res += "(" + PrintNode(vie->op, v, vppf) + ")";
4495  break;
4496  }
4497 
4498  case vec_pack_trunc_expr_K:
4499  {
4500  const auto vpt = GetPointerS<const vec_pack_trunc_expr>(node);
4501  const auto op0 = GET_CONST_NODE(vpt->op0);
4502  const auto op1 = GET_CONST_NODE(vpt->op1);
4503  const auto element_type = tree_helper::CGetElements(vpt->type);
4504  const auto element_size = tree_helper::Size(element_type);
4505  const auto size = tree_helper::Size(vpt->type);
4506  const auto vector_size = size / element_size;
4507  res += "/*" + vpt->get_kind_text() + "*/";
4508  res += "(" + tree_helper::PrintType(TM, vpt->type) + ") ";
4509  res += "{";
4510  if(op0->get_kind() == vector_cst_K)
4511  {
4512  const auto vc = GetPointerS<const vector_cst>(op0);
4513  for(const auto& i : vc->list_of_valu) // vector elements
4514  {
4515  res += "((" + tree_helper::PrintType(TM, element_type) + ") (";
4516  res += PrintConstant(i, vppf);
4517  res += ")), ";
4518  }
4519  }
4520  else
4521  {
4522  res += "((" + tree_helper::PrintType(TM, element_type) + ") (" + PrintNode(vpt->op0, v, vppf) + "[0])), ";
4523  for(unsigned int ind = 1; ind < vector_size / 2; ++ind)
4524  {
4525  res += "((" + tree_helper::PrintType(TM, element_type) + ") (" + PrintNode(vpt->op0, v, vppf) + "[" +
4526  STR(ind) + "])), ";
4527  }
4528  }
4529 
4530  if(op1->get_kind() == vector_cst_K)
4531  {
4532  const auto vc = GetPointerS<const vector_cst>(op1);
4533  for(unsigned int i = 0; i < (vc->list_of_valu).size(); i++) // vector elements
4534  {
4535  res += "((" + tree_helper::PrintType(TM, element_type) + ") (";
4536  res += PrintConstant(vc->list_of_valu[i], vppf);
4537  res += "))";
4538  if(i != (vc->list_of_valu).size() - 1)
4539  { // not the last element element
4540  res += ", ";
4541  }
4542  }
4543  }
4544  else
4545  {
4546  res += "((" + tree_helper::PrintType(TM, element_type) + ") (" + PrintNode(vpt->op1, v, vppf) + "[0]))";
4547  for(unsigned int ind = 1; ind < vector_size / 2; ++ind)
4548  {
4549  res += ", ((" + tree_helper::PrintType(TM, element_type) + ") (" + PrintNode(vpt->op1, v, vppf) + "[" +
4550  STR(ind) + "]))";
4551  }
4552  }
4553  res += "}";
4554  break;
4555  }
4556  case dot_prod_expr_K:
4557  {
4558  const auto dpe = GetPointerS<const ternary_expr>(node);
4559  const auto two_op_type = tree_helper::CGetType(dpe->op2);
4560  const auto element_type = tree_helper::CGetElements(two_op_type);
4561  const auto element_size = tree_helper::Size(element_type);
4562  const auto size = tree_helper::Size(two_op_type);
4563  const auto vector_size = size / element_size;
4564 
4565  res += "/*" + dpe->get_kind_text() + "*/";
4566  if(tree_helper::IsVectorType(dpe->type) && tree_helper::IsVectorType(two_op_type) &&
4567  two_op_type->index != GET_INDEX_CONST_NODE(dpe->type))
4568  {
4569  res += "(" + tree_helper::PrintType(TM, dpe->type) + ")(";
4570  }
4571  res += "(" + tree_helper::PrintType(TM, two_op_type) + ")";
4572  res += "{";
4573  for(unsigned int ind = 0; ind < vector_size; ++ind)
4574  {
4575  res += "(" + PrintNode(dpe->op0, v, vppf) + "[" + STR(2 * ind) + "]" + " * " +
4576  PrintNode(dpe->op1, v, vppf) + "[" + STR(2 * ind) + "]" + ")";
4577  res += "+(" + PrintNode(dpe->op0, v, vppf) + "[" + STR(2 * ind + 1) + "]" + " * " +
4578  PrintNode(dpe->op1, v, vppf) + "[" + STR(2 * ind + 1) + "]" + ")";
4579  if(ind != (vector_size - 1))
4580  {
4581  res += ", ";
4582  }
4583  }
4584  res += "}";
4585  res += " + " + PrintNode(dpe->op2, v, vppf);
4586  if(tree_helper::IsVectorType(dpe->type) && tree_helper::IsVectorType(two_op_type) &&
4587  two_op_type->index != GET_INDEX_CONST_NODE(dpe->type))
4588  {
4589  res += ")";
4590  }
4591  break;
4592  }
4593  case widen_mult_hi_expr_K:
4594  {
4595  const auto wmhe = GetPointerS<const widen_mult_hi_expr>(node);
4596  const auto element_type = tree_helper::CGetElements(wmhe->type);
4597  const auto element_size = tree_helper::Size(element_type);
4598  const auto size = tree_helper::Size(wmhe->type);
4599  const auto vector_size = size / element_size;
4600 
4601  res += "/*" + wmhe->get_kind_text() + "*/";
4602  res += "(" + tree_helper::PrintType(TM, wmhe->type) + ") ";
4603  res += "{";
4604  for(auto ind = vector_size; ind < vector_size * 2; ++ind)
4605  {
4606  res += PrintNode(wmhe->op0, v, vppf) + "[" + STR(ind) + "]";
4607  res += " * ";
4608  res += PrintNode(wmhe->op1, v, vppf) + "[" + STR(ind) + "]";
4609  if(ind != (vector_size * 2 - 1))
4610  {
4611  res += ", ";
4612  }
4613  }
4614  res += "}";
4615  break;
4616  }
4617  case widen_mult_lo_expr_K:
4618  {
4619  const auto wmle = GetPointerS<const widen_mult_lo_expr>(node);
4620  const auto element_type = tree_helper::CGetElements(wmle->type);
4621  const auto element_size = tree_helper::Size(element_type);
4622  const auto size = tree_helper::Size(wmle->type);
4623  const auto vector_size = size / element_size;
4624 
4625  res += "/*" + wmle->get_kind_text() + "*/";
4626  res += "(" + tree_helper::PrintType(TM, wmle->type) + ") ";
4627  res += "{";
4628  for(unsigned int ind = 0; ind < vector_size; ++ind)
4629  {
4630  res += PrintNode(wmle->op0, v, vppf) + "[" + STR(ind) + "]";
4631  res += " * ";
4632  res += PrintNode(wmle->op1, v, vppf) + "[" + STR(ind) + "]";
4633  if(ind != (vector_size - 1))
4634  {
4635  res += ", ";
4636  }
4637  }
4638  res += "}";
4639  break;
4640  }
4641  case vec_pack_sat_expr_K:
4642  case vec_pack_fix_trunc_expr_K:
4643  {
4644  const auto vie = GetPointerS<const binary_expr>(node);
4645  res += "/*" + vie->get_kind_text() + "*/" + PrintNode(vie->op0, v, vppf) + " /**/ " +
4646  PrintNode(vie->op1, v, vppf);
4647  break;
4648  }
4649  case vec_extracteven_expr_K:
4650  {
4651  const auto vee = GetPointerS<const vec_extracteven_expr>(node);
4652  const auto element_type = tree_helper::CGetElements(vee->type);
4653  const auto element_size = tree_helper::Size(element_type);
4654  const auto size = tree_helper::Size(vee->type);
4655  const auto vector_size = size / element_size;
4656 
4657  res += "/*" + vee->get_kind_text() + "*/";
4658  res += "(" + tree_helper::PrintType(TM, vee->type) + ") ";
4659  res += "{";
4660  for(unsigned int ind = 0; ind < vector_size; ind += 2)
4661  {
4662  res += PrintNode(vee->op0, v, vppf) + "[" + STR(ind) + "]";
4663  res += ", ";
4664  }
4665  for(unsigned int ind = 0; ind < vector_size; ind += 2)
4666  {
4667  res += PrintNode(vee->op1, v, vppf) + "[" + STR(ind) + "]";
4668  if(ind != vector_size - 2)
4669  {
4670  res += ", ";
4671  }
4672  }
4673  res += "}";
4674  break;
4675  }
4676  case vec_extractodd_expr_K:
4677  {
4678  const auto vee = GetPointerS<const vec_extractodd_expr>(node);
4679  const auto element_type = tree_helper::CGetElements(vee->type);
4680  const auto element_size = tree_helper::Size(element_type);
4681  const auto size = tree_helper::Size(vee->type);
4682  const auto vector_size = size / element_size;
4683 
4684  res += "/*" + vee->get_kind_text() + "*/";
4685  res += "(" + tree_helper::PrintType(TM, vee->type) + ") ";
4686  res += "{";
4687  for(unsigned int ind = 1; ind < vector_size; ind += 2)
4688  {
4689  res += PrintNode(vee->op0, v, vppf) + "[" + STR(ind) + "]";
4690  res += ", ";
4691  }
4692  for(unsigned int ind = 1; ind < vector_size; ind += 2)
4693  {
4694  res += PrintNode(vee->op1, v, vppf) + "[" + STR(ind) + "]";
4695  if(ind != vector_size - 1)
4696  {
4697  res += ", ";
4698  }
4699  }
4700  res += "}";
4701  break;
4702  }
4703  case vec_interleavehigh_expr_K:
4704  {
4705  const auto vie = GetPointerS<const vec_interleavehigh_expr>(node);
4706  const auto element_type = tree_helper::CGetElements(vie->type);
4707  const auto element_size = tree_helper::Size(element_type);
4708  const auto size = tree_helper::Size(vie->type);
4709  const auto vector_size = size / element_size;
4710 
4711  res += "/*" + vie->get_kind_text() + "*/";
4712  res += "(" + tree_helper::PrintType(TM, vie->type) + ") ";
4713  res += "{";
4714  for(auto ind = vector_size / 2; ind < vector_size; ++ind)
4715  {
4716  res += PrintNode(vie->op0, v, vppf) + "[" + STR(ind) + "]";
4717  res += ", ";
4718  res += PrintNode(vie->op1, v, vppf) + "[" + STR(ind) + "]";
4719  if(ind != vector_size - 1)
4720  {
4721  res += ", ";
4722  }
4723  }
4724  res += "}";
4725  break;
4726  }
4727  case vec_interleavelow_expr_K:
4728  {
4729  const auto vie = GetPointerS<const vec_interleavelow_expr>(node);
4730  const auto element_type = tree_helper::CGetElements(vie->type);
4731  const auto element_size = tree_helper::Size(element_type);
4732  const auto size = tree_helper::Size(vie->type);
4733  const auto vector_size = size / element_size;
4734 
4735  res += "/*" + vie->get_kind_text() + "*/";
4736  res += "(" + tree_helper::PrintType(TM, vie->type) + ") ";
4737  res += "{";
4738  for(unsigned int ind = 0; ind < vector_size / 2; ++ind)
4739  {
4740  res += PrintNode(vie->op0, v, vppf) + "[" + STR(ind) + "]";
4741  res += ", ";
4742  res += PrintNode(vie->op1, v, vppf) + "[" + STR(ind) + "]";
4743  if(ind != (vector_size / 2) - 1)
4744  {
4745  res += ", ";
4746  }
4747  }
4748  res += "}";
4749  break;
4750  }
4751  case case_label_expr_K:
4752  {
4753  res = PrintConstant(node, vppf);
4754  break;
4755  }
4756  case array_range_ref_K:
4757  case catch_expr_K:
4758  case compound_expr_K:
4759  case eh_filter_expr_K:
4760  case fdesc_expr_K:
4761  case goto_subroutine_K:
4762  case in_expr_K:
4763  case modify_expr_K:
4764  case range_expr_K:
4765  case set_le_expr_K:
4766  case try_catch_expr_K:
4767  case try_finally_K:
4768  case const_decl_K:
4769  case namespace_decl_K:
4770  case translation_unit_decl_K:
4771  case template_decl_K:
4772  case using_decl_K:
4773  case type_decl_K:
4774  case gimple_bind_K:
4775  case binfo_K:
4776  case block_K:
4777  case identifier_node_K:
4778  case statement_list_K:
4779  case tree_list_K:
4780  case tree_vec_K:
4781  case target_expr_K:
4782  case obj_type_ref_K:
4783  case save_expr_K:
4784  case vtable_ref_K:
4785  case with_cleanup_expr_K:
4786  case alignof_expr_K:
4787  case arrow_expr_K:
4788  case buffer_ref_K:
4789  case card_expr_K:
4790  case cleanup_point_expr_K:
4791  case conj_expr_K:
4792  case exit_expr_K:
4793  case loop_expr_K:
4794  case non_lvalue_expr_K:
4795  case reinterpret_cast_expr_K:
4796  case sizeof_expr_K:
4797  case static_cast_expr_K:
4798  case throw_expr_K:
4799  case unsave_expr_K:
4800  case va_arg_expr_K:
4801  case error_mark_K:
4802  case CASE_CPP_NODES:
4803  case CASE_FAKE_NODES:
4804  case CASE_TYPE_NODES:
4805  THROW_ERROR(std::string("tree node not currently supported ") + node->get_kind_text());
4806  break;
4807  default:
4808  THROW_UNREACHABLE("");
4809  }
4811  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Printed node " + STR(node->index) + " res = " + res);
4812 
4813  return res;
4814 }
4815 
4816 std::string BehavioralHelper::print_type_declaration(unsigned int type) const
4817 {
4818  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Printing type declaration " + STR(type));
4819  std::string res;
4820  const auto node_type = TM->CGetTreeNode(type);
4821  switch(node_type->get_kind())
4822  {
4823  case record_type_K:
4824  {
4825  const auto rt = GetPointerS<const record_type>(node_type);
4826  THROW_ASSERT(tree_helper::GetRealType(TM, type) == type, "Printing declaration of fake type " + STR(type));
4827  if(rt->unql)
4828  {
4829  res += "typedef ";
4830  }
4831  res += tree_helper::return_C_qualifiers(rt->qual, false);
4832  if(!rt->unql)
4833  {
4834  res += tree_helper::PrintType(TM, node_type) + " ";
4835  }
4836  else
4837  {
4838  res += "struct ";
4839  }
4840  if(!rt->unql || (!GetPointerS<const record_type>(GET_NODE(rt->unql))->name &&
4841  !Param->getOption<bool>(OPT_without_transformation)))
4842  {
4844  res += "\n{\n";
4845  null_deleter null_del;
4846  const var_pp_functorConstRef std_vpf(new std_var_pp_functor(BehavioralHelperConstRef(this, null_del)));
4847  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Printing content of the structure");
4848  for(auto& list_of_fld : rt->list_of_flds)
4849  {
4850  auto field = GET_INDEX_NODE(list_of_fld);
4851  const auto fld_node = TM->CGetTreeReindex(field);
4852  if(GET_CONST_NODE(fld_node)->get_kind() == type_decl_K)
4853  {
4854  continue;
4855  }
4856  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Printing field " + STR(field));
4857  const auto fd = GetPointerS<const field_decl>(GET_CONST_NODE(fld_node));
4858  const auto field_type = tree_helper::CGetType(fld_node);
4859  if(has_bit_field(field))
4860  {
4862  res += tree_helper::PrintType(TM, field_type) + " ";
4863  res += (*std_vpf)(field);
4864  res += " : ";
4865  res += PrintConstant(fd->size);
4866  }
4867  else
4868  {
4869  res += tree_helper::PrintType(TM, field_type, false, false, false, fld_node, std_vpf);
4870  }
4871  if(fd && fd->packed_flag)
4872  {
4873  res += " __attribute__((packed))";
4874  }
4875  res += ";\n";
4877  }
4879  res += '}';
4880  if(rt->packed_flag)
4881  {
4882  res += " __attribute__((packed))";
4883  }
4884  res += " ";
4885  }
4886  if(rt->unql)
4887  {
4888  if(rt->name || Param->getOption<bool>(OPT_without_transformation))
4889  {
4890  const auto rt_unqal = GetPointerS<const record_type>(GET_NODE(rt->unql));
4891  if(rt_unqal->name)
4892  {
4893  res += tree_helper::PrintType(TM, rt_unqal->name) + " ";
4894  }
4895  else if(Param->getOption<bool>(OPT_without_transformation))
4896  {
4897  res += "Internal_" + STR(GET_INDEX_NODE(rt->unql)) + " ";
4898  }
4899  res += tree_helper::PrintType(TM, rt->name);
4900  }
4901  if(rt->algn != GetPointerS<const record_type>(GET_NODE(rt->unql))->algn)
4902  {
4903  res += " __attribute__ ((aligned (" + STR(rt->algn / 8) + ")))";
4904  }
4905  }
4906  break;
4907  }
4908  case union_type_K:
4909  {
4910  const auto ut = GetPointerS<const union_type>(node_type);
4911  THROW_ASSERT(tree_helper::GetRealType(TM, type) == type,
4912  "Printing declaration of fake type " + STR(node_type));
4913  if(ut->unql)
4914  {
4915  res += "typedef ";
4916  }
4917  res += tree_helper::return_C_qualifiers(ut->qual, false);
4918  if(!ut->unql)
4919  {
4920  res += tree_helper::PrintType(TM, node_type) + " ";
4921  }
4922  else
4923  {
4924  res += "union ";
4925  }
4926  if(!ut->unql || (!GetPointerS<const union_type>(GET_NODE(ut->unql))->name &&
4927  !Param->getOption<bool>(OPT_without_transformation)))
4928  {
4930  res += "\n{\n";
4931  null_deleter null_del;
4932  const var_pp_functorConstRef std_vpf(new std_var_pp_functor(BehavioralHelperConstRef(this, null_del)));
4933  for(const auto& list_of_fld : ut->list_of_flds)
4934  {
4935  res += tree_helper::PrintType(TM, tree_helper::CGetType(list_of_fld), false, false, false, list_of_fld,
4936  std_vpf);
4937  res += ";\n";
4938  }
4939  res += '}';
4940  if(ut->packed_flag)
4941  {
4942  res += " __attribute__((packed))";
4943  }
4944  res += " ";
4945  }
4946  if(ut->unql)
4947  {
4948  if(ut->name || Param->getOption<bool>(OPT_without_transformation))
4949  {
4950  const auto uut = GetPointerS<const union_type>(GET_NODE(ut->unql));
4951  if(uut->name)
4952  {
4953  res += tree_helper::PrintType(TM, uut->name) + " ";
4954  }
4955  else if(Param->getOption<bool>(OPT_without_transformation))
4956  {
4957  res += "Internal_" + STR(GET_INDEX_NODE(ut->unql)) + " ";
4958  }
4959  else
4960  {
4961  THROW_UNREACHABLE("");
4962  }
4963  res += tree_helper::PrintType(TM, ut->name);
4964  }
4965  if(ut->algn != GetPointerS<const union_type>(GET_NODE(ut->unql))->algn)
4966  {
4967  res += " __attribute__ ((aligned (" + STR(ut->algn / 8) + "))) ";
4968  }
4969  }
4970  break;
4971  }
4972  case enumeral_type_K:
4973  {
4974  const auto et = GetPointerS<const enumeral_type>(node_type);
4975  if(et->unql)
4976  {
4977  res += "typedef ";
4978  }
4979  res += tree_helper::return_C_qualifiers(et->qual, false);
4980  res += "enum ";
4981  if(!et->unql)
4982  {
4983  if(et->packed_flag)
4984  {
4985  res += " __attribute__((packed)) ";
4986  }
4987  if(et->name)
4988  {
4989  res += tree_helper::PrintType(TM, et->name) + " ";
4990  }
4991  else
4992  {
4993  res += "Internal_" + STR(type) + " ";
4994  }
4995  }
4996  if(!et->unql || !GetPointerS<const enumeral_type>(GET_NODE(et->unql))->name)
4997  {
4998  res += "{";
4999  auto tl = GetPointer<tree_list>(GET_NODE(et->csts));
5000  while(tl)
5001  {
5002  res += tree_helper::PrintType(TM, tl->purp);
5003  if(tl->valu)
5004  {
5005  res += " = " + PrintConstant(tl->valu);
5006  }
5007  if(tl->chan)
5008  {
5009  res += ",";
5010  tl = GetPointer<tree_list>(GET_NODE(tl->chan));
5011  }
5012  else
5013  {
5014  tl = nullptr;
5015  }
5016  }
5017  res += "}";
5018  }
5019  if(et->unql && et->name)
5020  {
5021  const auto et_unql = GetPointerS<const enumeral_type>(GET_NODE(et->unql));
5022  if(et_unql->name)
5023  {
5024  res += tree_helper::PrintType(TM, et_unql->name) + " ";
5025  }
5026  res += tree_helper::PrintType(TM, et->name);
5027  }
5028  break;
5029  }
5030  case array_type_K:
5031  {
5032  const auto at = GetPointerS<const array_type>(node_type);
5034  if(!at->size)
5035  {
5036  THROW_ERROR_CODE(C_EC, "Declaration of array type without size");
5037  }
5038  const auto array_length = GET_NODE(at->size);
5039  const auto array_t = GET_NODE(at->elts);
5040  if(array_length->get_kind() != integer_cst_K)
5041  {
5042  THROW_ERROR_CODE(C_EC, "Declaration of array type without fixed size");
5043  }
5044  const auto tn = GetPointerS<const type_node>(array_t);
5045 
5046  res += "typedef ";
5047  res += tree_helper::PrintType(TM, at->elts);
5048  res += " ";
5049  THROW_ASSERT(at->name, "Trying to declare array without name " + STR(type));
5050  res += tree_helper::PrintType(TM, at->name);
5051  res += "[";
5052  res += STR(tree_helper::GetConstValue(at->size) / tree_helper::GetConstValue(tn->size));
5053  res += "]";
5054  break;
5055  }
5057  case pointer_type_K:
5058  {
5059  const auto pt = GetPointerS<const pointer_type>(node_type);
5060  if(pt->unql && GET_NODE(pt->ptd)->get_kind() == function_type_K)
5061  {
5062  const auto ft = GetPointerS<const function_type>(GET_NODE(pt->ptd));
5063  res += "typedef ";
5064  res += tree_helper::PrintType(TM, ft->retn);
5065  res += " (* ";
5066  res += tree_helper::return_C_qualifiers(GetPointerS<const type_node>(node_type)->qual, false);
5067  if(GetPointerS<const type_node>(node_type)->name)
5068  {
5069  res += tree_helper::PrintType(TM, GetPointerS<const type_node>(node_type)->name);
5070  }
5071  else
5072  {
5073  res += "Internal_" + STR(type);
5074  }
5075  res += ") (";
5076  if(ft->prms)
5077  {
5078  res += tree_helper::PrintType(TM, ft->prms);
5079  }
5080  res += ")";
5081  return res;
5082  }
5083  // in this point break has not been forgotten. Pointer to not function type could be treated normally
5084 #if(__GNUC__ >= 7)
5085  [[gnu::fallthrough]];
5086 #endif
5087  }
5088  case boolean_type_K:
5089  case CharType_K:
5090  case nullptr_type_K:
5091  case type_pack_expansion_K:
5092  case complex_type_K:
5093  case function_type_K:
5094  case integer_type_K:
5095  case lang_type_K:
5096  case method_type_K:
5097  case offset_type_K:
5098  case qual_union_type_K:
5099  case real_type_K:
5100  case reference_type_K:
5101  case set_type_K:
5102  case template_type_parm_K:
5103  case typename_type_K:
5104  case type_argument_pack_K:
5105  case vector_type_K:
5106  case void_type_K:
5107  {
5108  const auto nt = GetPointerS<const type_node>(node_type);
5109  if(nt->unql)
5110  {
5111  res += "typedef ";
5112  res += tree_helper::return_C_qualifiers(nt->qual, false);
5113  res += tree_helper::PrintType(TM, nt->unql);
5114  res += " ";
5115  /* if(nt->algn != 8)
5116  res += "__attribute__ ((aligned (" + STR(nt->algn/8) + "))) ";*/
5117  if(nt->name)
5118  {
5119  res += tree_helper::PrintType(TM, nt->name);
5120  }
5121  else
5122  {
5123  res += "Internal_" + STR(type);
5124  }
5125  }
5126  else
5127  {
5128  THROW_ASSERT(node_type->get_kind() == integer_cst_K,
5129  "Expected an integer, got a " + node_type->get_kind_text());
5130  THROW_ASSERT(nt->name, "Expected a typedef declaration with a name " + STR(type));
5131  /* #ifndef NDEBUG
5132  identifier_node * id = GetPointerS<const identifier_node>(GET_NODE(bt->name));
5133  THROW_ASSERT(id && id->strg == "bit_size_type", "Expected bit_size_type " + STR(type));
5134  #endif */
5135  res += "typedef long long int bit_size_type";
5136  }
5137  break;
5138  }
5139  case binfo_K:
5140  case block_K:
5141  case call_expr_K:
5142  case aggr_init_expr_K:
5143  case case_label_expr_K:
5144  case constructor_K:
5145  case identifier_node_K:
5146  case ssa_name_K:
5147  case statement_list_K:
5148  case target_expr_K:
5149  case target_mem_ref_K:
5150  case target_mem_ref461_K:
5151  case tree_list_K:
5152  case tree_vec_K:
5153  case error_mark_K:
5154  case lut_expr_K:
5156  case CASE_CPP_NODES:
5157  case CASE_CST_NODES:
5158  case CASE_DECL_NODES:
5159  case CASE_FAKE_NODES:
5160  case CASE_GIMPLE_NODES:
5161  case CASE_PRAGMA_NODES:
5164  case CASE_UNARY_EXPRESSION:
5165  default:
5166  {
5167  THROW_UNREACHABLE("Unexpected type " + node_type->get_kind_text());
5168  }
5169  }
5170  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Printed type declaration " + STR(type));
5171  return res;
5172 }
5173 
5174 bool BehavioralHelper::is_bool(unsigned int index) const
5175 {
5176  return tree_helper::is_bool(TM, get_type(index));
5177 }
5178 
5179 bool BehavioralHelper::is_natural(unsigned int index) const
5180 {
5181  return tree_helper::is_natural(TM, index);
5182 }
5183 
5184 bool BehavioralHelper::is_int(unsigned int index) const
5185 {
5186  return tree_helper::is_int(TM, get_type(index));
5187 }
5188 
5189 bool BehavioralHelper::is_an_enum(unsigned int index) const
5190 {
5191  return tree_helper::is_an_enum(TM, get_type(index));
5192 }
5193 bool BehavioralHelper::is_unsigned(unsigned int index) const
5194 {
5195  return tree_helper::is_unsigned(TM, get_type(index));
5196 }
5197 
5198 bool BehavioralHelper::is_real(unsigned int index) const
5199 {
5200  return tree_helper::is_real(TM, get_type(index));
5201 }
5202 
5203 bool BehavioralHelper::is_a_complex(unsigned int index) const
5204 {
5205  return tree_helper::is_a_complex(TM, get_type(index));
5206 }
5207 
5208 bool BehavioralHelper::is_a_struct(unsigned int variable) const
5209 {
5210  return tree_helper::is_a_struct(TM, get_type(variable));
5211 }
5212 
5213 bool BehavioralHelper::is_an_union(unsigned int variable) const
5214 {
5215  return tree_helper::is_an_union(TM, get_type(variable));
5216 }
5217 
5218 bool BehavioralHelper::is_an_array(unsigned int variable) const
5219 {
5220  return tree_helper::is_an_array(TM, get_type(variable));
5221 }
5222 
5223 bool BehavioralHelper::is_a_vector(unsigned int variable) const
5224 {
5225  return tree_helper::is_a_vector(TM, get_type(variable));
5226 }
5227 
5228 bool BehavioralHelper::is_a_pointer(unsigned int variable) const
5229 {
5230  return tree_helper::is_a_pointer(TM, variable);
5231 }
5232 
5233 bool BehavioralHelper::is_an_indirect_ref(unsigned int variable) const
5234 {
5235  const auto temp = TM->CGetTreeNode(variable);
5236  if(temp->get_kind() == indirect_ref_K || temp->get_kind() == misaligned_indirect_ref_K)
5237  {
5238  return true;
5239  }
5240  else
5241  {
5242  return false;
5243  }
5244 }
5245 
5246 bool BehavioralHelper::is_an_array_ref(unsigned int variable) const
5247 {
5248  const auto temp = TM->CGetTreeNode(variable);
5249  if(temp->get_kind() == array_ref_K)
5250  {
5251  return true;
5252  }
5253  else
5254  {
5255  return false;
5256  }
5257 }
5258 
5259 bool BehavioralHelper::is_a_component_ref(unsigned int variable) const
5260 {
5261  const auto temp = TM->CGetTreeNode(variable);
5262  if(temp->get_kind() == component_ref_K)
5263  {
5264  return true;
5265  }
5266  else
5267  {
5268  return false;
5269  }
5270 }
5271 
5272 bool BehavioralHelper::is_an_addr_expr(unsigned int variable) const
5273 {
5274  const auto temp = TM->CGetTreeNode(variable);
5275  if(temp->get_kind() == addr_expr_K)
5276  {
5277  return true;
5278  }
5279  else
5280  {
5281  return false;
5282  }
5283 }
5284 
5285 bool BehavioralHelper::is_a_mem_ref(unsigned int variable) const
5286 {
5287  const auto temp = TM->CGetTreeNode(variable);
5288  if(temp->get_kind() == mem_ref_K)
5289  {
5290  return true;
5291  }
5292  else
5293  {
5294  return false;
5295  }
5296 }
5297 
5298 bool BehavioralHelper::is_static(unsigned int decl) const
5299 {
5300  return tree_helper::is_static(TM, decl);
5301 }
5302 
5303 bool BehavioralHelper::is_extern(unsigned int decl) const
5304 {
5305  return tree_helper::is_extern(TM, decl);
5306 }
5307 
5308 bool BehavioralHelper::is_a_constant(unsigned int obj) const
5309 {
5310  const auto node = TM->CGetTreeNode(obj);
5311  switch(node->get_kind())
5312  {
5313  case addr_expr_K:
5314  return true;
5315  case paren_expr_K:
5316  case nop_expr_K:
5317  {
5318  const auto ue = GetPointerS<const unary_expr>(node);
5319  return is_a_constant(GET_INDEX_NODE(ue->op));
5320  }
5321  case integer_cst_K:
5322  case real_cst_K:
5323  case string_cst_K:
5324  case vector_cst_K:
5325  case void_cst_K:
5326  case complex_cst_K:
5327  case case_label_expr_K:
5328  case label_decl_K:
5329  return true;
5330  case binfo_K:
5331  case block_K:
5332  case call_expr_K:
5333  case aggr_init_expr_K:
5334  case constructor_K:
5335  case identifier_node_K:
5336  case ssa_name_K:
5337  case statement_list_K:
5338  case target_mem_ref_K:
5339  case target_mem_ref461_K:
5340  case tree_list_K:
5341  case tree_vec_K:
5342  case const_decl_K:
5343  case field_decl_K:
5344  case function_decl_K:
5345  case namespace_decl_K:
5346  case parm_decl_K:
5347  case result_decl_K:
5348  case translation_unit_decl_K:
5349  case template_decl_K:
5350  case using_decl_K:
5351  case type_decl_K:
5352  case var_decl_K:
5353  case abs_expr_K:
5354  case alignof_expr_K:
5355  case arrow_expr_K:
5356  case bit_not_expr_K:
5357  case buffer_ref_K:
5358  case card_expr_K:
5359  case cleanup_point_expr_K:
5360  case conj_expr_K:
5361  case convert_expr_K:
5362  case exit_expr_K:
5363  case fix_ceil_expr_K:
5364  case fix_floor_expr_K:
5365  case fix_round_expr_K:
5366  case fix_trunc_expr_K:
5367  case float_expr_K:
5368  case imagpart_expr_K:
5369  case indirect_ref_K:
5370  case misaligned_indirect_ref_K:
5371  case loop_expr_K:
5372  case negate_expr_K:
5373  case non_lvalue_expr_K:
5374  case realpart_expr_K:
5375  case reference_expr_K:
5376  case reinterpret_cast_expr_K:
5377  case sizeof_expr_K:
5378  case static_cast_expr_K:
5379  case throw_expr_K:
5380  case truth_not_expr_K:
5381  case unsave_expr_K:
5382  case va_arg_expr_K:
5383  case view_convert_expr_K:
5384  case reduc_max_expr_K:
5385  case reduc_min_expr_K:
5386  case reduc_plus_expr_K:
5387  case vec_unpack_hi_expr_K:
5388  case vec_unpack_lo_expr_K:
5389  case vec_unpack_float_hi_expr_K:
5390  case vec_unpack_float_lo_expr_K:
5391  case target_expr_K:
5392  case error_mark_K:
5393  case lut_expr_K:
5395  case CASE_CPP_NODES:
5396  case CASE_FAKE_NODES:
5397  case CASE_GIMPLE_NODES:
5398  case CASE_PRAGMA_NODES:
5401  case CASE_TYPE_NODES:
5402  default:
5403  return false;
5404  }
5405 }
5406 
5407 bool BehavioralHelper::is_a_result_decl(unsigned int obj) const
5408 {
5409  const tree_nodeRef node = TM->get_tree_node_const(obj);
5410  if(node->get_kind() == result_decl_K)
5411  {
5412  return true;
5413  }
5414  else
5415  {
5416  return false;
5417  }
5418 }
5419 
5420 bool BehavioralHelper::is_a_realpart_expr(unsigned int obj) const
5421 {
5422  const tree_nodeRef temp = TM->get_tree_node_const(obj);
5423  if(temp->get_kind() == realpart_expr_K)
5424  {
5425  return true;
5426  }
5427  else
5428  {
5429  return false;
5430  }
5431 }
5432 
5433 bool BehavioralHelper::is_a_imagpart_expr(unsigned int obj) const
5434 {
5435  const tree_nodeRef temp = TM->get_tree_node_const(obj);
5436  if(temp->get_kind() == imagpart_expr_K)
5437  {
5438  return true;
5439  }
5440  else
5441  {
5442  return false;
5443  }
5444 }
5445 
5446 bool BehavioralHelper::is_operating_system_function(const unsigned int obj) const
5447 {
5448  const tree_nodeRef curr_tn = TM->get_tree_node_const(obj);
5449  const function_decl* fd = GetPointer<function_decl>(curr_tn);
5450  if(!fd)
5451  {
5452  return false;
5453  }
5454  return fd->operating_system_flag;
5455 }
5456 
5457 unsigned int BehavioralHelper::get_indirect_ref_var(unsigned int obj) const
5458 {
5459  THROW_ASSERT(is_an_indirect_ref(obj), "obj assumed to be an inderect_ref object");
5460  const tree_nodeRef temp = TM->get_tree_node_const(obj);
5461  auto ir = GetPointer<indirect_ref>(temp);
5462  if(ir)
5463  {
5464  return GET_INDEX_NODE(ir->op);
5465  }
5466  auto mir = GetPointer<misaligned_indirect_ref>(temp);
5467  return GET_INDEX_NODE(mir->op);
5468 }
5469 
5470 unsigned int BehavioralHelper::get_array_ref_array(unsigned int obj) const
5471 {
5472  THROW_ASSERT(is_an_array_ref(obj), "obj assumed to be an array_ref object");
5473  const tree_nodeRef temp = TM->get_tree_node_const(obj);
5474  auto ar = GetPointer<array_ref>(temp);
5475  return GET_INDEX_NODE(ar->op0);
5476 }
5477 
5478 unsigned int BehavioralHelper::get_array_ref_index(unsigned int obj) const
5479 {
5480  THROW_ASSERT(is_an_array_ref(obj), "obj assumed to be an array_ref object");
5481  const tree_nodeRef temp = TM->get_tree_node_const(obj);
5482  auto ar = GetPointer<array_ref>(temp);
5483  return GET_INDEX_NODE(ar->op1);
5484 }
5485 
5486 unsigned int BehavioralHelper::get_component_ref_record(unsigned int obj) const
5487 {
5488  THROW_ASSERT(is_a_component_ref(obj), "obj assumed to be a component_ref object");
5489  const tree_nodeRef temp = TM->get_tree_node_const(obj);
5490  auto cr = GetPointer<component_ref>(temp);
5491  return GET_INDEX_NODE(cr->op0);
5492 }
5493 
5494 unsigned int BehavioralHelper::get_component_ref_field(unsigned int obj) const
5495 {
5496  THROW_ASSERT(is_a_component_ref(obj), "obj assumed to be a component_ref object");
5497  const tree_nodeRef temp = TM->get_tree_node_const(obj);
5498  auto cr = GetPointer<component_ref>(temp);
5499  return GET_INDEX_NODE(cr->op1);
5500 }
5501 
5502 unsigned int BehavioralHelper::get_mem_ref_base(unsigned int obj) const
5503 {
5504  THROW_ASSERT(is_a_mem_ref(obj), "obj assumed to be a mem_ref object");
5505  const tree_nodeRef temp = TM->get_tree_node_const(obj);
5506  auto mr = GetPointer<mem_ref>(temp);
5507  return GET_INDEX_NODE(mr->op0);
5508 }
5509 
5510 unsigned int BehavioralHelper::get_mem_ref_offset(unsigned int obj) const
5511 {
5512  THROW_ASSERT(is_a_mem_ref(obj), "obj assumed to be a mem_ref object");
5513  const tree_nodeRef temp = TM->get_tree_node_const(obj);
5514  auto mr = GetPointer<mem_ref>(temp);
5515  return GET_INDEX_NODE(mr->op1);
5516 }
5517 
5518 unsigned int BehavioralHelper::get_operand_from_unary_expr(unsigned int obj) const
5519 {
5521  "obj assumed to be an addr_expr, a realpart_expr or an imagpart_expr object. obj is " + STR(obj));
5522  const tree_nodeRef temp = TM->get_tree_node_const(obj);
5523  auto ue = GetPointer<unary_expr>(temp);
5524  return GET_INDEX_NODE(ue->op);
5525 }
5526 
5527 unsigned int BehavioralHelper::GetVarFromSsa(unsigned int index) const
5528 {
5529  const tree_nodeRef temp = TM->get_tree_node_const(index);
5530  auto sn = GetPointer<ssa_name>(temp);
5531  if(sn)
5532  {
5533  return GET_INDEX_NODE(sn->var);
5534  }
5535  else
5536  {
5537  return index;
5538  }
5539 }
5540 
5541 unsigned int BehavioralHelper::get_intermediate_var(unsigned int obj) const
5542 {
5543  const tree_nodeRef node = TM->get_tree_node_const(obj);
5544  switch(node->get_kind())
5545  {
5546  case modify_expr_K:
5547  case init_expr_K:
5548  {
5549  auto be = GetPointer<binary_expr>(node);
5550  const tree_nodeRef right = GET_NODE(be->op1);
5552  switch(right->get_kind())
5553  {
5554  // case fix_trunc_expr_K:
5555  case fix_ceil_expr_K:
5556  case fix_floor_expr_K:
5557  case fix_round_expr_K:
5558  case float_expr_K:
5559  case convert_expr_K:
5560  case view_convert_expr_K:
5561  case nop_expr_K:
5562  case realpart_expr_K:
5563  case imagpart_expr_K:
5564  case paren_expr_K:
5565  {
5566  auto ue = GetPointer<unary_expr>(right);
5567  return GET_INDEX_NODE(ue->op);
5568  }
5569  case binfo_K:
5570  case block_K:
5571  case call_expr_K:
5572  case aggr_init_expr_K:
5573  case case_label_expr_K:
5574  case constructor_K:
5575  case fix_trunc_expr_K:
5576  case identifier_node_K:
5577  case ssa_name_K:
5578  case statement_list_K:
5579  case target_mem_ref_K:
5580  case target_mem_ref461_K:
5581  case tree_list_K:
5582  case tree_vec_K:
5583  case abs_expr_K:
5584  case addr_expr_K:
5585  case alignof_expr_K:
5586  case arrow_expr_K:
5587  case bit_not_expr_K:
5588  case buffer_ref_K:
5589  case card_expr_K:
5590  case cleanup_point_expr_K:
5591  case conj_expr_K:
5592  case exit_expr_K:
5593  case indirect_ref_K:
5594  case misaligned_indirect_ref_K:
5595  case loop_expr_K:
5596  case negate_expr_K:
5597  case non_lvalue_expr_K:
5598  case reference_expr_K:
5599  case reinterpret_cast_expr_K:
5600  case sizeof_expr_K:
5601  case static_cast_expr_K:
5602  case throw_expr_K:
5603  case truth_not_expr_K:
5604  case unsave_expr_K:
5605  case va_arg_expr_K:
5606  case reduc_max_expr_K:
5607  case reduc_min_expr_K:
5608  case reduc_plus_expr_K:
5609  case vec_unpack_hi_expr_K:
5610  case vec_unpack_lo_expr_K:
5611  case vec_unpack_float_hi_expr_K:
5612  case vec_unpack_float_lo_expr_K:
5613  case target_expr_K:
5614  case error_mark_K:
5615  case lut_expr_K:
5617  case CASE_CPP_NODES:
5618  case CASE_CST_NODES:
5619  case CASE_DECL_NODES:
5620  case CASE_FAKE_NODES:
5621  case CASE_GIMPLE_NODES:
5622  case CASE_PRAGMA_NODES:
5625  case CASE_TYPE_NODES:
5626  default:
5627  return GET_INDEX_NODE(be->op1);
5628  }
5629  }
5630  case binfo_K:
5631  case block_K:
5632  case call_expr_K:
5633  case aggr_init_expr_K:
5634  case case_label_expr_K:
5635  case constructor_K:
5636  case identifier_node_K:
5637  case ssa_name_K:
5638  case statement_list_K:
5639  case target_mem_ref_K:
5640  case target_mem_ref461_K:
5641  case tree_list_K:
5642  case tree_vec_K:
5643  case assert_expr_K:
5644  case bit_and_expr_K:
5645  case bit_ior_expr_K:
5646  case bit_xor_expr_K:
5647  case catch_expr_K:
5648  case ceil_div_expr_K:
5649  case ceil_mod_expr_K:
5650  case complex_expr_K:
5651  case compound_expr_K:
5652  case eh_filter_expr_K:
5653  case eq_expr_K:
5654  case exact_div_expr_K:
5655  case fdesc_expr_K:
5656  case floor_div_expr_K:
5657  case floor_mod_expr_K:
5658  case ge_expr_K:
5659  case gt_expr_K:
5660  case goto_subroutine_K:
5661  case in_expr_K:
5662  case le_expr_K:
5663  case lrotate_expr_K:
5664  case lshift_expr_K:
5665  case lt_expr_K:
5666  case max_expr_K:
5667  case mem_ref_K:
5668  case min_expr_K:
5669  case minus_expr_K:
5670  case mult_expr_K:
5671  case mult_highpart_expr_K:
5672  case ne_expr_K:
5673  case ordered_expr_K:
5674  case plus_expr_K:
5675  case pointer_plus_expr_K:
5676  case postdecrement_expr_K:
5677  case postincrement_expr_K:
5678  case predecrement_expr_K:
5679  case preincrement_expr_K:
5680  case range_expr_K:
5681  case rdiv_expr_K:
5682  case round_div_expr_K:
5683  case round_mod_expr_K:
5684  case rrotate_expr_K:
5685  case rshift_expr_K:
5686  case set_le_expr_K:
5687  case trunc_div_expr_K:
5688  case trunc_mod_expr_K:
5689  case truth_and_expr_K:
5690  case truth_andif_expr_K:
5691  case truth_or_expr_K:
5692  case truth_orif_expr_K:
5693  case truth_xor_expr_K:
5694  case try_catch_expr_K:
5695  case try_finally_K:
5696  case uneq_expr_K:
5697  case ltgt_expr_K:
5698  case lut_expr_K:
5699  case unge_expr_K:
5700  case ungt_expr_K:
5701  case unle_expr_K:
5702  case unlt_expr_K:
5703  case unordered_expr_K:
5704  case widen_sum_expr_K:
5705  case widen_mult_expr_K:
5706  case with_size_expr_K:
5707  case vec_lshift_expr_K:
5708  case vec_rshift_expr_K:
5709  case widen_mult_hi_expr_K:
5710  case widen_mult_lo_expr_K:
5711  case vec_pack_trunc_expr_K:
5712  case vec_pack_sat_expr_K:
5713  case vec_pack_fix_trunc_expr_K:
5714  case vec_extracteven_expr_K:
5715  case vec_extractodd_expr_K:
5716  case vec_interleavehigh_expr_K:
5717  case vec_interleavelow_expr_K:
5718  case target_expr_K:
5719  case error_mark_K:
5720  case extract_bit_expr_K:
5721  case sat_plus_expr_K:
5722  case sat_minus_expr_K:
5723  case extractvalue_expr_K:
5724  case extractelement_expr_K:
5725  case frem_expr_K:
5726  case CASE_CPP_NODES:
5727  case CASE_CST_NODES:
5728  case CASE_DECL_NODES:
5729  case CASE_FAKE_NODES:
5730  case CASE_GIMPLE_NODES:
5731  case CASE_PRAGMA_NODES:
5734  case CASE_TYPE_NODES:
5735  case CASE_UNARY_EXPRESSION:
5736  default:
5737  return 0;
5738  }
5739 }
5740 
5742 {
5743  TreeNodeConstSet ret;
5744  const auto node = TM->CGetTreeNode(function_index);
5745  const auto fd = GetPointer<const function_decl>(node);
5746  if(!fd)
5747  {
5748  return ret;
5749  }
5750  for(const auto& arg : fd->list_of_args)
5751  {
5752  const auto pd = GetPointerS<const parm_decl>(GET_CONST_NODE(arg));
5753  ret.insert(pd->type);
5754  }
5755  const auto ft = GetPointerS<const function_type>(GET_CONST_NODE(fd->type));
5756  if(!ft || !ft->prms)
5757  {
5758  return ret;
5759  }
5760  auto tl = GetPointer<const tree_list>(GET_CONST_NODE(ft->prms));
5761  while(tl)
5762  {
5763  ret.insert(tl->valu);
5764  if(tl->chan)
5765  {
5766  tl = GetPointerS<const tree_list>(GET_CONST_NODE(tl->chan));
5767  }
5768  else
5769  {
5770  break;
5771  }
5772  }
5773  return ret;
5774 }
5775 
5776 unsigned int BehavioralHelper::is_named_pointer(const unsigned int index) const
5777 {
5778  THROW_ASSERT(index, "this index does not exist: " + STR(index));
5779  const auto type = TM->CGetTreeReindex(index);
5780  THROW_ASSERT(type, "this index does not exist: " + STR(type));
5781  const auto Type_node = tree_helper::CGetType(type);
5782  THROW_ASSERT(Type_node, "this index does not exist: " + STR(type));
5783  if(GET_CONST_NODE(Type_node)->get_kind() == pointer_type_K)
5784  {
5785  const auto pt = GetPointerS<const pointer_type>(GET_CONST_NODE(Type_node));
5786  if(pt->name)
5787  {
5788  return GET_INDEX_CONST_NODE(type);
5789  }
5790  else
5791  {
5792  return is_named_pointer(GET_INDEX_NODE(pt->ptd));
5793  }
5794  }
5795  else
5796  {
5797  return 0;
5798  }
5799 }
5800 
5801 bool BehavioralHelper::is_va_start_call(unsigned int stm) const
5802 {
5803  if(is_var_args())
5804  {
5805  const tree_nodeRef node = TM->get_tree_node_const(stm);
5806  if(node->get_kind() == gimple_call_K)
5807  {
5808  auto ce = GetPointer<gimple_call>(node);
5809  tree_nodeRef cefn = GET_NODE(ce->fn);
5810  if(cefn->get_kind() == addr_expr_K)
5811  {
5812  auto ue = GetPointer<unary_expr>(cefn);
5813  auto fd = GetPointer<function_decl>(GET_NODE(ue->op));
5814  if(fd && tree_helper::print_function_name(TM, fd) == "__builtin_va_start")
5815  {
5816  return true;
5817  }
5818  else
5819  {
5820  return false;
5821  }
5822  }
5823  else
5824  {
5825  return false;
5826  }
5827  }
5828  else
5829  {
5830  return false;
5831  }
5832  }
5833  else
5834  {
5835  return false;
5836  }
5837 }
5838 
5839 bool BehavioralHelper::has_bit_field(unsigned int variable) const
5840 {
5841  const tree_nodeRef node = TM->get_tree_node_const(variable);
5842  if(node->get_kind() == field_decl_K)
5843  {
5844  auto fd = GetPointer<field_decl>(node);
5845  if((fd->list_attr.find(TreeVocabularyTokenTypes_TokenEnum::TOK_BITFIELD)) != fd->list_attr.end())
5846  {
5847  return true;
5848  }
5849  else
5850  {
5851  return false;
5852  }
5853  }
5854  else
5855  {
5856  return false;
5857  }
5858 }
5859 
5860 unsigned int BehavioralHelper::get_attributes(unsigned int var) const
5861 {
5862  const tree_nodeRef node = TM->get_tree_node_const(var);
5863  switch(node->get_kind())
5864  {
5865  case parm_decl_K:
5866  case ssa_name_K:
5867  {
5868  /*ssa_name * sn = GetPointer<ssa_name>(node);
5869  return get_attributes(GET_INDEX_NODE(sn->var));*/
5870  return 0;
5871  }
5872  case function_decl_K:
5873  case result_decl_K:
5874  case var_decl_K:
5875  {
5876  THROW_ASSERT(GetPointer<decl_node>(node), "get_attributes is only for decl_node: " + STR(var));
5877  return GetPointer<decl_node>(node)->attributes ? GET_INDEX_NODE(GetPointer<decl_node>(node)->attributes) : 0;
5878  }
5879  case binfo_K:
5880  case block_K:
5881  case call_expr_K:
5882  case aggr_init_expr_K:
5883  case case_label_expr_K:
5884  case constructor_K:
5885  case identifier_node_K:
5886  case statement_list_K:
5887  case target_expr_K:
5888  case target_mem_ref_K:
5889  case target_mem_ref461_K:
5890  case tree_list_K:
5891  case tree_vec_K:
5892  case const_decl_K:
5893  case field_decl_K:
5894  case label_decl_K:
5895  case namespace_decl_K:
5896  case translation_unit_decl_K:
5897  case using_decl_K:
5898  case type_decl_K:
5899  case template_decl_K:
5900  case error_mark_K:
5901  case lut_expr_K:
5903  case CASE_CPP_NODES:
5904  case CASE_CST_NODES:
5905  case CASE_FAKE_NODES:
5906  case CASE_GIMPLE_NODES:
5907  case CASE_PRAGMA_NODES:
5910  case CASE_TYPE_NODES:
5911  case CASE_UNARY_EXPRESSION:
5912  default:
5913  THROW_ERROR("Not supported: " + std::string(node->get_kind_text()));
5914  }
5915  return 0;
5916 }
5917 
5918 unsigned int BehavioralHelper::GetInit(unsigned int var, CustomUnorderedSet<unsigned int>& list_of_variables) const
5919 {
5920  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Get init of " + PrintVariable(var));
5921  if(initializations.find(var) != initializations.end())
5922  {
5923  unsigned int init = var;
5924  while(initializations.find(init) != initializations.end())
5925  {
5926  init = initializations.find(init)->second;
5927  }
5928  if(TM->get_tree_node_const(init)->get_kind() == var_decl_K)
5929  {
5930  list_of_variables.insert(init);
5931  const auto init_of_init = GetInit(init, list_of_variables);
5932  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Init is " + STR(init_of_init));
5933  return init_of_init;
5934  }
5935  else
5936  {
5937  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Init is " + STR(init));
5938  return init;
5939  }
5940  }
5941  const tree_nodeRef node = TM->get_tree_node_const(var);
5942  switch(node->get_kind())
5943  {
5944  case ssa_name_K:
5945  {
5946  auto sn = GetPointer<ssa_name>(node);
5947  if(!sn->var)
5948  {
5949  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Without init");
5950  return 0;
5951  }
5952  const unsigned ssa_init = GetInit(GET_INDEX_NODE(sn->var), list_of_variables);
5953  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Init is " + STR(ssa_init));
5954  return ssa_init;
5955  }
5956  case var_decl_K:
5957  {
5958  auto vd = GetPointer<var_decl>(node);
5959  if(vd->init)
5960  {
5961  tree_helper::get_used_variables(true, vd->init, list_of_variables);
5962  const unsigned var_init = GET_INDEX_NODE(vd->init);
5963  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Init is " + STR(var_init));
5964  return var_init;
5965  }
5966  else
5967  {
5968  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Without init");
5969  return 0;
5970  }
5971  }
5972  case constructor_K:
5973  {
5974  auto co = GetPointerS<const constructor>(TM->get_tree_node_const(var));
5975  auto vend = co->list_of_idx_valu.end();
5976  for(auto i = co->list_of_idx_valu.begin(); i != vend; ++i)
5977  {
5978  tree_helper::get_used_variables(true, i->second, list_of_variables);
5979  }
5980  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Init is " + STR(var));
5981  return var;
5982  }
5983  case binfo_K:
5984  case block_K:
5985  case call_expr_K:
5986  case aggr_init_expr_K:
5987  case case_label_expr_K:
5988  case identifier_node_K:
5989  case statement_list_K:
5990  case target_expr_K:
5991  case target_mem_ref_K:
5992  case target_mem_ref461_K:
5993  case tree_list_K:
5994  case tree_vec_K:
5995  case const_decl_K:
5996  case field_decl_K:
5997  case function_decl_K:
5998  case label_decl_K:
5999  case namespace_decl_K:
6000  case parm_decl_K:
6001  case result_decl_K:
6002  case translation_unit_decl_K:
6003  case template_decl_K:
6004  case using_decl_K:
6005  case type_decl_K:
6006  case error_mark_K:
6007  case lut_expr_K:
6009  case CASE_CPP_NODES:
6010  case CASE_CST_NODES:
6011  case CASE_FAKE_NODES:
6012  case CASE_GIMPLE_NODES:
6013  case CASE_PRAGMA_NODES:
6016  case CASE_TYPE_NODES:
6017  case CASE_UNARY_EXPRESSION:
6018  {
6019  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Without init");
6020  return 0;
6021  }
6022  default:
6023  THROW_UNREACHABLE("get_init: Tree node not yet supported " + STR(var) + " " + node->get_kind_text());
6024  }
6025  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Without init");
6026  return 0;
6027 }
6028 
6029 std::string BehavioralHelper::print_phinode_res(unsigned int phi_node_id, vertex v,
6030  const var_pp_functorConstRef vppf) const
6031 {
6032  const auto node = TM->CGetTreeNode(phi_node_id);
6033  const auto phi = GetPointer<const gimple_phi>(node);
6034  THROW_ASSERT(phi, "NodeId is not related to a gimple_phi");
6035  return PrintNode(phi->res, v, vppf);
6036 }
6037 
6038 unsigned int BehavioralHelper::start_with_a_label(const blocRef& block) const
6039 {
6040  if(block->CGetStmtList().empty())
6041  {
6042  return 0;
6043  }
6044  const auto& first_stmt = block->CGetStmtList().front();
6045  const auto le = GetPointer<const gimple_label>(GET_CONST_NODE(first_stmt));
6046  if(le && le->op && GET_NODE(le->op)->get_kind() == label_decl_K)
6047  {
6048  const auto ld = GetPointerS<const label_decl>(GET_CONST_NODE(le->op));
6049  if(ld->name)
6050  {
6051  return GET_INDEX_NODE(first_stmt);
6052  }
6053  else
6054  {
6055  return 0;
6056  }
6057  }
6058  else
6059  {
6060  return 0;
6061  }
6062 }
6063 
6064 const std::string BehavioralHelper::get_label_name(unsigned int label_expr_nid) const
6065 {
6066  tree_nodeRef tn = TM->get_tree_node_const(label_expr_nid);
6067  auto le = GetPointer<gimple_label>(tn);
6068  THROW_ASSERT(le->op && GET_NODE(le->op)->get_kind() == label_decl_K, "label decl expected");
6069  auto ld = GetPointer<label_decl>(GET_NODE(le->op));
6070  THROW_ASSERT(ld->name && GET_NODE(ld->name)->get_kind() == identifier_node_K, "identifier_node expected");
6071  auto id = GetPointer<identifier_node>(GET_NODE(ld->name));
6072  return id->strg;
6073 }
6074 
6075 unsigned int BehavioralHelper::end_with_a_cond_or_goto(const blocRef& block) const
6076 {
6077  if(block->CGetStmtList().empty())
6078  {
6079  return 0;
6080  }
6081  tree_nodeRef last = block->CGetStmtList().back();
6082  auto gc = GetPointer<gimple_cond>(GET_NODE(last));
6083  if(gc)
6084  {
6085  return GET_INDEX_NODE(last);
6086  }
6087  auto se = GetPointer<gimple_switch>(GET_NODE(last));
6088  if(se)
6089  {
6090  return GET_INDEX_NODE(last);
6091  }
6092  auto ge = GetPointer<gimple_goto>(GET_NODE(last));
6093  if(ge)
6094  {
6095  return GET_INDEX_NODE(last);
6096  }
6097  auto gmwi = GetPointer<gimple_multi_way_if>(GET_NODE(last));
6098  if(gmwi)
6099  {
6100  return GET_INDEX_NODE(last);
6101  }
6102  return 0;
6103 }
6104 
6105 std::string BehavioralHelper::print_forward_declaration(unsigned int type) const
6106 {
6107  std::string res;
6108  const auto node_type = TM->CGetTreeNode(type);
6109  switch(node_type->get_kind())
6110  {
6111  case record_type_K:
6112  {
6113  const auto rt = GetPointerS<const record_type>(node_type);
6114  if(rt->name)
6115  {
6116  res += "struct " + tree_helper::PrintType(TM, rt->name);
6117  }
6118  else
6119  {
6120  res += "struct Internal_" + STR(type);
6121  }
6122  break;
6123  }
6124  case union_type_K:
6125  {
6126  const auto rt = GetPointerS<const union_type>(node_type);
6127  if(rt->name)
6128  {
6129  res += "union " + tree_helper::PrintType(TM, rt->name);
6130  }
6131  else
6132  {
6133  res += "union Internal_" + STR(type);
6134  }
6135  break;
6136  }
6137  case enumeral_type_K:
6138  {
6139  const auto rt = GetPointerS<const enumeral_type>(node_type);
6140  if(rt->name)
6141  {
6142  res += "enum " + tree_helper::PrintType(TM, rt->name);
6143  }
6144  else
6145  {
6146  res += "enum Internal_" + STR(type);
6147  }
6148  break;
6149  }
6150  case array_type_K:
6151  case binfo_K:
6152  case block_K:
6153  case boolean_type_K:
6154  case call_expr_K:
6155  case aggr_init_expr_K:
6156  case case_label_expr_K:
6157  case CharType_K:
6158  case nullptr_type_K:
6159  case type_pack_expansion_K:
6160  case complex_type_K:
6161  case constructor_K:
6162  case function_type_K:
6163  case identifier_node_K:
6164  case integer_type_K:
6165  case lang_type_K:
6166  case method_type_K:
6167  case offset_type_K:
6168  case pointer_type_K:
6169  case qual_union_type_K:
6170  case real_type_K:
6171  case reference_type_K:
6172  case set_type_K:
6173  case ssa_name_K:
6174  case statement_list_K:
6175  case target_expr_K:
6176  case target_mem_ref_K:
6177  case target_mem_ref461_K:
6178  case template_type_parm_K:
6179  case type_argument_pack_K:
6180  case tree_list_K:
6181  case tree_vec_K:
6182  case typename_type_K:
6183  case vector_type_K:
6184  case void_type_K:
6185  case error_mark_K:
6186  case lut_expr_K:
6188  case CASE_CPP_NODES:
6189  case CASE_CST_NODES:
6190  case CASE_DECL_NODES:
6191  case CASE_FAKE_NODES:
6192  case CASE_GIMPLE_NODES:
6193  case CASE_PRAGMA_NODES:
6196  case CASE_UNARY_EXPRESSION:
6197  default:
6198  {
6199  THROW_ERROR("Not yet supported " + std::string(node_type->get_kind_text()));
6200  }
6201  }
6202  return res;
6203 }
6204 
6206 {
6207  const auto retNode = TM->CGetTreeNode(index);
6208  const auto re = GetPointer<const gimple_return>(retNode);
6209  THROW_ASSERT(re, "Expected a return statement");
6210  return !re->op;
6211 }
6212 
6213 unsigned int BehavioralHelper::GetUnqualified(const unsigned int index) const
6214 {
6215  return tree_helper::GetUnqualified(TM, index);
6216 }
6217 
6218 std::string BehavioralHelper::print_type(unsigned int type, bool global, bool print_qualifiers, bool print_storage,
6219  unsigned int var, const var_pp_functorConstRef vppf, const std::string& prefix,
6220  const std::string& tail) const
6221 {
6222  return tree_helper::PrintType(TM, TM->CGetTreeReindex(type), global, print_qualifiers, print_storage,
6223  var ? TM->CGetTreeReindex(var) : nullptr, vppf, prefix, tail);
6224 }
6225 
6226 void BehavioralHelper::rename_a_variable(unsigned int var, const std::string& new_name)
6227 {
6228  vars_renaming_table[var] = new_name;
6229 }
6230 
6232 {
6233  vars_renaming_table.clear();
6234 }
6235 
6237 {
6238  type_casting Visitor(types);
6239  tn->visit(&Visitor);
6240 }
6241 
6242 bool BehavioralHelper::IsDefaultSsaName(const unsigned int ssa_name_index) const
6243 {
6244  const auto sn = GetPointer<const ssa_name>(TM->get_tree_node_const(ssa_name_index));
6245  return sn && sn->default_flag;
6246 }
6247 
6248 #if HAVE_FROM_PRAGMA_BUILT
6249 size_t BehavioralHelper::GetOmpForDegree() const
6250 {
6251  const auto fd = GetPointerS<const function_decl>(TM->get_tree_node_const(function_index));
6252  return fd->omp_for_wrapper;
6253 }
6254 
6255 bool BehavioralHelper::IsOmpFunctionAtomic() const
6256 {
6257  const auto fd = GetPointerS<const function_decl>(TM->get_tree_node_const(function_index));
6258  return fd->omp_atomic;
6259 }
6260 
6261 bool BehavioralHelper::IsOmpBodyLoop() const
6262 {
6263  const auto fd = GetPointerS<const function_decl>(TM->get_tree_node_const(function_index));
6264  return fd->omp_body_loop;
6265 }
6266 #endif
6267 
6268 #if HAVE_FROM_PRAGMA_BUILT
6269 bool BehavioralHelper::IsOmpAtomic() const
6270 {
6271  const auto fd = GetPointerS<const function_decl>(TM->get_tree_node_const(function_index));
6272  return fd->omp_atomic;
6273 }
6274 #endif
6275 
6277 {
6278  if(function_name == "__builtin_cond_expr32")
6279  {
6280  return false;
6281  }
6282  if(tree_helper::IsInLibbambu(TM, f_id))
6283  {
6284  return true;
6285  }
6286  return !tree_helper::is_system(TM, f_id);
6287 }
6288 
6289 std::string BehavioralHelper::get_asm_string(const unsigned int node_index) const
6290 {
6291  return tree_helper::get_asm_string(TM, node_index);
6292 }
6293 
6294 bool BehavioralHelper::CanBeSpeculated(const unsigned int node_index) const
6295 {
6296  if(node_index == ENTRY_ID || node_index == EXIT_ID)
6297  {
6298  return false;
6299  }
6300  const auto tn = TM->CGetTreeNode(node_index);
6301  const auto ga = GetPointer<const gimple_assign>(tn);
6303  if(ga && ga->predicate && GET_NODE(ga->predicate)->get_kind() != integer_cst_K)
6304  {
6305  return true;
6306  }
6307  if(IsStore(node_index))
6308  {
6309  return false;
6310  }
6312  if(IsLoad(node_index))
6313  {
6314  return false;
6315  }
6316  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "-->Checking if " + STR(tn) + " can be speculated");
6317  switch(tn->get_kind())
6318  {
6319  case gimple_nop_K:
6320  case gimple_phi_K:
6321  {
6322  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--Yes because is a " + tn->get_kind_text());
6323  return true;
6324  }
6325  case(gimple_assign_K):
6326  {
6327  THROW_ASSERT(ga && ga->op1, "unexpected condition"); // to silence the clang static analyzer
6328  switch(GET_NODE(ga->op1)->get_kind())
6329  {
6330  case call_expr_K:
6331  case aggr_init_expr_K:
6332  {
6334  "<--No because of " + GET_NODE(ga->op1)->get_kind_text() +
6335  " in right part of gimple_assign");
6336  return false;
6337  }
6338  case CASE_CST_NODES:
6339  case CASE_DECL_NODES:
6342  case CASE_UNARY_EXPRESSION:
6343  case ssa_name_K:
6344  case assert_expr_K:
6345  case bit_and_expr_K:
6346  case bit_ior_expr_K:
6347  case bit_xor_expr_K:
6348  case catch_expr_K:
6349  case complex_expr_K:
6350  case compound_expr_K:
6351  case constructor_K:
6352  case eh_filter_expr_K:
6353  case eq_expr_K:
6354  case fdesc_expr_K:
6355  case ge_expr_K:
6356  case gt_expr_K:
6357  case goto_subroutine_K:
6358  case in_expr_K:
6359  case init_expr_K:
6360  case le_expr_K:
6361  case lrotate_expr_K:
6362  case lshift_expr_K:
6363  case lt_expr_K:
6364  case lut_expr_K:
6365  case max_expr_K:
6366  case mem_ref_K:
6367  case min_expr_K:
6368  case minus_expr_K:
6369  case modify_expr_K:
6370  case mult_expr_K:
6371  case mult_highpart_expr_K:
6372  case ne_expr_K:
6373  case ordered_expr_K:
6374  case plus_expr_K:
6375  case pointer_plus_expr_K:
6376  case postdecrement_expr_K:
6377  case postincrement_expr_K:
6378  case predecrement_expr_K:
6379  case preincrement_expr_K:
6380  case range_expr_K:
6381  case rrotate_expr_K:
6382  case rshift_expr_K:
6383  case set_le_expr_K:
6384  case trunc_div_expr_K:
6385  case truth_and_expr_K:
6386  case truth_andif_expr_K:
6387  case truth_or_expr_K:
6388  case truth_orif_expr_K:
6389  case truth_xor_expr_K:
6390  case try_catch_expr_K:
6391  case try_finally_K:
6392  case uneq_expr_K:
6393  case ltgt_expr_K:
6394  case unge_expr_K:
6395  case ungt_expr_K:
6396  case unle_expr_K:
6397  case unlt_expr_K:
6398  case unordered_expr_K:
6399  case widen_sum_expr_K:
6400  case widen_mult_expr_K:
6401  case with_size_expr_K:
6402  case vec_lshift_expr_K:
6403  case vec_rshift_expr_K:
6404  case widen_mult_hi_expr_K:
6405  case widen_mult_lo_expr_K:
6406  case vec_pack_trunc_expr_K:
6407  case vec_pack_sat_expr_K:
6408  case vec_pack_fix_trunc_expr_K:
6409  case vec_extracteven_expr_K:
6410  case vec_extractodd_expr_K:
6411  case vec_interleavehigh_expr_K:
6412  case vec_interleavelow_expr_K:
6413  case ceil_div_expr_K:
6414  case ceil_mod_expr_K:
6415  case exact_div_expr_K:
6416  case floor_div_expr_K:
6417  case floor_mod_expr_K:
6418  case rdiv_expr_K:
6419  case round_div_expr_K:
6420  case round_mod_expr_K:
6421  case trunc_mod_expr_K:
6422  case target_expr_K:
6423  case extract_bit_expr_K:
6424  case sat_plus_expr_K:
6425  case sat_minus_expr_K:
6426  case extractvalue_expr_K:
6427  case extractelement_expr_K:
6428  case frem_expr_K:
6429  {
6431  "<--Yes because it is a gimple_assign with " + GET_NODE(ga->op1)->get_kind_text() +
6432  " in right part of assignment");
6433  return true;
6434  }
6435  case binfo_K:
6436  case block_K:
6437  case CASE_GIMPLE_NODES:
6438  case case_label_expr_K:
6439  case identifier_node_K:
6440  case statement_list_K:
6441  case target_mem_ref_K:
6442  case target_mem_ref461_K:
6443  case tree_list_K:
6444  case tree_vec_K:
6445  case error_mark_K:
6446  case CASE_CPP_NODES:
6447  case CASE_FAKE_NODES:
6448  case CASE_PRAGMA_NODES:
6449  case CASE_TYPE_NODES:
6450  {
6451  THROW_UNREACHABLE(GET_NODE(ga->op1)->get_kind_text() + " - " + STR(tn));
6452  break;
6453  }
6454  default:
6455  THROW_UNREACHABLE("");
6456  }
6457  return true;
6458  }
6459  case gimple_asm_K:
6462  case gimple_call_K:
6463  case gimple_cond_K:
6464  case gimple_goto_K:
6465  case gimple_label_K:
6466  case gimple_multi_way_if_K:
6467  case gimple_pragma_K:
6468  case gimple_return_K:
6469  case gimple_switch_K:
6470  {
6471  INDENT_DBG_MEX(DEBUG_LEVEL_PARANOIC, debug_level, "<--No because is a " + tn->get_kind_text());
6472  return false;
6473  }
6474  case binfo_K:
6475  case block_K:
6476  case call_expr_K:
6477  case aggr_init_expr_K:
6478  case case_label_expr_K:
6479  case constructor_K:
6480  case gimple_bind_K:
6481  case gimple_for_K:
6482  case gimple_predict_K:
6483  case gimple_resx_K:
6484  case gimple_while_K:
6485  case identifier_node_K:
6486  case ssa_name_K:
6487  case statement_list_K:
6488  case target_expr_K:
6489  case target_mem_ref_K:
6490  case target_mem_ref461_K:
6491  case tree_list_K:
6492  case tree_vec_K:
6493  case error_mark_K:
6494  case lut_expr_K:
6496  case CASE_CPP_NODES:
6497  case CASE_CST_NODES:
6498  case CASE_DECL_NODES:
6499  case CASE_FAKE_NODES:
6500  case CASE_PRAGMA_NODES:
6503  case CASE_TYPE_NODES:
6504  case CASE_UNARY_EXPRESSION:
6505  {
6506  THROW_UNREACHABLE(tn->get_kind_text());
6507  break;
6508  }
6509  default:
6510  THROW_UNREACHABLE("");
6511  }
6512  THROW_UNREACHABLE("");
6513  return false;
6514 }
6515 
6516 bool BehavioralHelper::CanBeMoved(const unsigned int node_index) const
6517 {
6518  // entry and exit nodes can never be moved
6519  if(node_index == ENTRY_ID || node_index == EXIT_ID)
6520  {
6521  return false;
6522  }
6523  THROW_ASSERT(node_index, "unexpected condition");
6524  const auto tn = TM->CGetTreeNode(node_index);
6525  const auto gn = GetPointer<const gimple_node>(tn);
6526  THROW_ASSERT(gn, "unexpected condition: node " + STR(tn) + " is not a gimple_node");
6527  /*
6528  * artificial gimple_node can never be moved because they are created to
6529  * handle specific situations, like for example handling functions returnin
6530  * structs by value or accepting structs passed by value as parameters
6531  */
6532  if(gn->artificial)
6533  {
6534  return false;
6535  }
6536  const auto gc = GetPointer<const gimple_call>(tn);
6537  if(gc && GET_NODE(gc->fn)->get_kind() == addr_expr_K)
6538  {
6539  // the node is a gimple_call to a function (no function pointers
6540  const auto addr_node = GET_NODE(gc->fn);
6541  const auto ae = GetPointerS<const addr_expr>(addr_node);
6542  THROW_ASSERT(GET_NODE(ae->op)->get_kind() == function_decl_K,
6543  "node " + STR(GET_NODE(ae->op)) + " is not function_decl but " + GET_NODE(ae->op)->get_kind_text());
6544  auto called_id = GET_INDEX_NODE(ae->op);
6545  const std::string fu_name = tree_helper::name_function(TM, called_id);
6546  /*
6547  * __builtin_bambu_time_start() and __builtin_bambu_time_stop() can never
6548  * be moved, even if they have not the artificial flag.
6549  * the reason is that they must stay exactly where they are placed in
6550  * order to work properly to compute the number of simulation cycles
6551  */
6552  if(fu_name == "__builtin_bambu_time_start" || fu_name == "__builtin_bambu_time_stop")
6553  {
6554  return false;
6555  }
6556  }
6557  return true;
6558 }
6559 
6560 bool BehavioralHelper::IsStore(const unsigned int statement_index) const
6561 {
6562  const auto& fun_mem_data = AppM->CGetFunctionBehavior(function_index)->get_function_mem();
6563  return tree_helper::IsStore(TM->CGetTreeReindex(statement_index), fun_mem_data);
6564 }
6565 
6566 bool BehavioralHelper::IsLoad(const unsigned int statement_index) const
6567 {
6568  const auto& fun_mem_data = AppM->CGetFunctionBehavior(function_index)->get_function_mem();
6569  return tree_helper::IsLoad(TM->CGetTreeReindex(statement_index), fun_mem_data);
6570 }
6571 
6572 bool BehavioralHelper::IsLut(const unsigned int statement_index) const
6573 {
6574  return tree_helper::IsLut(TM->CGetTreeReindex(statement_index));
6575 }
6576 
6578 {
6579  if(vars_symbol_table.find(index) != vars_symbol_table.end())
6580  {
6581  vars_symbol_table.erase(vars_symbol_table.find(index));
6582  }
6583 }
#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 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.
virtual unsigned long long get_size(unsigned int var) const
Return the size in bit of a C object.
std::string PrintVarDeclaration(unsigned int var, const var_pp_functorConstRef vppf, bool init_has_to_be_printed) const
This function prints the declaration of a variable without the closing ";".
bool CanBeMoved(const unsigned int node_index) const
Return if an operation can be moved.
bool CanBeSpeculated(const unsigned int node_index) const
Return true if an operation can be speculated.
virtual bool is_a_complex(unsigned int index) const
Return true if index is a variable or a type of type complex.
static bool IsUnionType(const tree_nodeConstRef &type)
Return if treenode is an union.
bool operating_system_flag
operating system flag: it&#39;s true when this is a variable of operating system library ...
Definition: tree_node.hpp:924
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
static std::string name_function(const tree_managerConstRef &tm, const unsigned int index)
Return the name of the function.
virtual std::string PrintNode(const tree_nodeConstRef &node, vertex v, const var_pp_functorConstRef vppf) const
Print the operations corresponding to the node.
virtual std::string print_attributes(unsigned int var, const var_pp_functorConstRef vppf, bool first=true) const
Print the attributes associated to a variable.
virtual unsigned int get_intermediate_var(unsigned int obj) const
Return the intermediate variable of an operation.
File containing functions and utilities to support the printing of debug messagges.
virtual bool is_an_array_ref(unsigned int variable) const
Return true if the index is an array ref.
static void clear_renaming_table()
remove all the entries from the renaming table
This class collects some utility functions used to extract information from tree-based data structure...
Definition: tree_helper.hpp:78
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 GetMangledFunctionName() const
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
Definition: tree_node.hpp:463
virtual bool is_a_mem_ref(unsigned int variable) const
Return true if the index is a mem_ref.
bool get_opaque() const
Return the opaque flag.
const tree_nodeRef CGetTreeReindex(const unsigned int i) const
Return a tree_reindex wrapping the i-th tree_node.
#define MAX_ROW_LENGTH
Max length of a row (at the moment checked only during constructor printing)
virtual unsigned int get_component_ref_record(unsigned int obj) const
Return the record variable of a component ref.
std::string get_function_name() const
Return the name of the function.
void add_initialization(unsigned int var, unsigned int init)
Add the initialization of a variables.
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
virtual unsigned int end_with_a_cond_or_goto(const blocRef &block) const
Return the nodeID of the last statement of a basic block in case that statement is a cond or a goto e...
static bool is_unsigned(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of unsigned integer type.
Definition of the class representing a generic C application.
#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
BehavioralHelper(const application_managerRef AppM, unsigned int index, bool body, const ParameterConstRef parameters)
Constructor.
bool is_a_vector(unsigned int variable) const
Return true if index is a variable or a type of type vector.
static bool is_real(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of real type.
bool IsLoad(const unsigned int statement_index) const
Return if an operation is a load.
#define CASE_NON_ADDR_UNARY_EXPRESSION
This macro collects all case labels for unary_expr objects.
Definition: tree_node.hpp:419
struct definition of the function_decl tree node.
Definition: tree_node.hpp:2759
virtual std::string PrintInit(const tree_nodeConstRef &var, const var_pp_functorConstRef vppf) const
Print the initialization part.
static std::string return_C_qualifiers(const TreeVocabularyTokenTypes_TokenEnum quals, bool real_const)
return the qualifiers in C format
std::vector< tree_nodeRef > GetParameters() const
Return the list of index of original parameters of the function.
static bool is_static(const tree_managerConstRef &TM, const unsigned int index)
FIXME: to be remove after substitution with IsStaticDeclaration.
static tree_nodeConstRef CGetElements(const tree_nodeConstRef &type)
Given an array or a vector return the element type.
virtual std::string print_phinode_res(unsigned int phi_node_id, vertex v, const var_pp_functorConstRef vppf) const
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.
virtual bool is_var_args() const
Returns true if this function is of var args type.
static std::map< unsigned int, std::string > vars_renaming_table
Variable renaming table.
#define STR_CST_string_sizeof
The string used to replace sizeof keyword in the original source code (second step) ...
exceptions managed by PandA
std::string function_name
Name of the function.
unsigned int get_function_index() const
Return the index of the function.
virtual bool is_empty_return(unsigned int index) const
return true in case index is a return expr with an empty operand.
virtual unsigned int get_mem_ref_offset(unsigned int obj) const
Return the offset of a mem ref.
void set_opaque()
Set opaque flag to true.
virtual void visit(tree_node_visitor *const v) const
virtual function used to traverse the tree_node data structure.
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.
virtual std::string print_type(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="") const
Print a type and its variable in case var is not zero.
const application_managerRef AppM
The application manager.
virtual unsigned int get_operand_from_unary_expr(unsigned int obj) const
Return the index of the operand if index is addr_expr, a realpart_expr or a imagpart_expr.
tree node visitor collecting the types used in type casting
#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
bitfield not supported
Definition: exceptions.hpp:336
virtual bool is_a_result_decl(unsigned int obj) const
Return true if index is a result_decl.
static std::string print_function_name(const tree_managerConstRef &TM, const function_decl *fd)
Return the name of the function in a string.
virtual bool is_an_array(unsigned int variable) const
Return true if index is a variable or a type of type array.
Data structure describing a basic block at tree level.
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.
std::map< unsigned int, unsigned int > initializations
Structure which stores initializations.
virtual bool is_unsigned(unsigned int index) const
Return true if index is a variable or a type of type unsigned int.
redefinition of map to manage ordered/unordered structures
static bool is_an_enum(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is an enumeral type.
constant strings used in pragma identification
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.
bool IsDefaultSsaName(const unsigned int ssa_name_index) const
Return true if node is the default ssa_name.
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.
bool has_implementation() const
Return true if function has implementation.
virtual bool is_a_realpart_expr(unsigned int obj) const
Return true if index is a realpart_expr.
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.
const tree_managerConstRef TM
The tree manager.
A set of const tree node.
Definition: tree_node.hpp:267
#define STR(s)
Macro which performs a lexical_cast to a string.
virtual std::tuple< std::string, unsigned int, unsigned int > get_definition(unsigned int index, bool &is_system) const
Returns where the type index is defined.
Auxiliary methods for manipulating string.
virtual std::string PrintConstant(const tree_nodeConstRef &var, const var_pp_functorConstRef vppf=var_pp_functorConstRef()) const
Print the constant associated with var.
virtual bool is_a_pointer(unsigned int variable) const
Return true if index is a variable or a type of type pointer.
C pattern not supported.
Definition: exceptions.hpp:337
virtual bool is_operating_system_function(const unsigned int obj) const
Return true if function is an operating system function.
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.
const OpNodeInfoConstRef CGetOpNodeInfo(const vertex node) const
Returns the info associated with a node.
Definition: op_graph.hpp:843
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 body
Flag to check if behavioral_graph_manager contains the function implementation.
Standard functor that returns the name of a variable.
virtual std::string print_forward_declaration(unsigned int type) const
Print the declaration of a non built-in type.
virtual unsigned int get_array_ref_array(unsigned int obj) const
Return the array variable of an array ref.
const std::list< unsigned int > get_parameters() const
Return the list of index of original parameters of the function.
static unsigned long long Size(const tree_nodeConstRef &tn)
Return the size of a tree object.
#define EXIT_ID
constant used to represent tree node index of exit operation
Definition: op_graph.hpp:81
static unsigned int GetUnqualified(const tree_managerConstRef &TM, unsigned int type)
Return the unqualified version of a type.
tree_nodeRef GetPointerType(const tree_nodeConstRef &ptd, unsigned long long algn=0) const
Function that creates a pointer type if it is not already present, otherwise it returns the one that ...
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
void InvaildateVariableName(const unsigned int index)
Invalidate cached variable name.
const ParameterConstRef Param
The set of input parameters.
virtual bool is_an_enum(unsigned int index) const
Return true if index is a variable or a type of type enum.
#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 const uint32_t k[]
Definition: sha-256.c:22
virtual unsigned int GetInit(unsigned int var, CustomUnorderedSet< unsigned int > &list_of_variables) const
return the initialization object associated with the variable.
bool has_bit_field(unsigned int variable) const
Return true if the variable is a field_decl and it has a bitfield.
#define STR_CST_pragma_keyword_call_point_hw
The call_point_hw pragma keyword.
#define STR_CST_pragma_keyword_call_hw
The call_point_hw pragma keyword.
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.
unsigned int GetFunctionReturnType(unsigned int function) const
Return the index associated with the type of the return of the function.
#define default_COND
constant used to represent label "default" of a switch construct
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
#define index(x, y)
Definition: Keccak.c:74
virtual bool is_va_start_call(unsigned int stm) const
return true in case stm is a va_start call_expr
virtual unsigned int is_named_pointer(const unsigned int index) const
return the nodeid of the named pointer (pointer_type with a name different
virtual bool is_extern(unsigned int decl) const
check if a given index is a extern declaration
virtual int unsigned start_with_a_label(const blocRef &block) const
Return the nodeID of the first statement of a basic block in case that statement is a label expressio...
static void rename_a_variable(unsigned int var, const std::string &new_name)
rename a variable
virtual bool is_int(unsigned int index) const
Return true if index is a variable or a type of type int.
virtual unsigned int get_mem_ref_base(unsigned int obj) const
Return the base of a mem ref.
boost::graph_traits< graph >::vertex_descriptor vertex
vertex definition.
Definition: graph.hpp:1303
static bool IsVectorType(const tree_nodeConstRef &type)
Return true if the treenode is a vector.
unsigned offset[NUM_VERTICES+1]
Definition: graph.h:3
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
virtual bool is_bool(unsigned int index) const
Return true if index is a variable or a type of type bool.
static std::string NormalizeTypename(const std::string &id)
Return normalized name of types and variables.
bool function_has_to_be_printed(unsigned int f_id) const
returns true if the function body has to be printed by the C backend
unsigned int GetUnqualified(const unsigned int index) const
Return the unqualified version of a type.
virtual bool is_static(unsigned int decl) const
check if a given index is a static declaration
virtual bool is_a_constant(unsigned int obj) const
Return true if the index is a constant object.
Class defining some useful functions to create tree nodes and to manipulate the tree manager...
#define DEBUG_LEVEL_NONE
no debugging print is performed.
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
std::string PrintVariable(unsigned int var) const
Print the name of the variable associated to the index.
struct definition of the pointer_type tree node.
Definition: tree_node.hpp:3896
virtual bool is_an_addr_expr(unsigned int variable) const
Return true if the index is an addr_expr.
This struct specifies the block node.
Definition: tree_node.hpp:1820
void set_not_opaque()
Set opaque flag to false.
#define STR_CST_pragma_keyword_map
The keyword &#39;map&#39; which identifies mapping pragmas.
#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.
virtual bool is_natural(unsigned int index) const
Return true if index is a variable grater than or equal to zero.
virtual bool is_a_struct(unsigned int variable) const
Return true if index is a variable or a type of type struct.
virtual ~BehavioralHelper()
Destructor.
virtual void GetTypecast(const tree_nodeConstRef &tn, TreeNodeConstSet &types) const
return the types used in type casting by tn
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.
Definition: APInt.hpp:53
null deleter
Definition: refcount.hpp:51
static std::string op_symbol(const tree_nodeConstRef &op)
Function return the symbol related with the operator op passed as parameter.
void init(int bucket[BUCKETSIZE])
Definition: sort.c:42
Data structures used to represent an edge in operation and basic block graphs.
std::string print_vertex(const OpGraphConstRef g, const vertex v, const var_pp_functorConstRef vppf, const bool dot=false) const
Print the operations corrisponding to the vertex.
#define STR_CST_pragma_keyword_recursive
The keyword &#39;omp&#39; which identifies openmp recursive.
virtual bool is_real(unsigned int index) const
Return true if index is a variable or a type of type real.
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
Definition: tree_node.hpp:689
bool IsStore(const unsigned int statement_index) const
Return if an operation is a store.
unsigned int GetElements(const unsigned int type) const
Given an array or a vector return the element type.
struct definition of the type node structures.
Definition: tree_node.hpp:1318
Class specification of the tree_reindex support class.
#define ENTRY_ID
constant used to represent tree node index of entry operation
Definition: op_graph.hpp:79
#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.
virtual unsigned int GetVarFromSsa(unsigned int index) const
Return the index of the variable base of a ssa var.
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.
virtual bool is_a_imagpart_expr(unsigned int obj) const
Return true if index is a imagpart_expr.
static bool is_a_complex(const tree_managerConstRef &TM, const unsigned int index)
Return if treenode index is a complex.
Data structures used in operations graph.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
static tree_nodeConstRef CGetType(const tree_nodeConstRef &node)
Return the treenode of the type of node.
static bool IsStructType(const tree_nodeConstRef &type)
Return true if treenode is a record.
virtual bool is_an_union(unsigned int variable) const
Return true if index is a variable of a type of type union.
#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 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.
this class is used to manage the command-line or XML options.
virtual unsigned int get_indirect_ref_var(unsigned int obj) const
Return the variable of an indirect ref.
virtual unsigned int get_type(const unsigned int var) const
Return the type of the variable.
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
Definition: tree_node.hpp:644
static bool is_bool(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode is of bool type.
#define INTERNAL
static bool IsLut(const tree_nodeConstRef &tn)
Return true in case the right operation is a lut_expr.
refcount< tree_node > tree_nodeRef
RefCount type definition of the tree_node class structure.
Definition: tree_node.hpp:212
bool opaque
Flag to check if a call to this function has to be treated as a TYPE_OPAQUE nodeID.
unsigned int function_index
Index of the function.
virtual unsigned int get_component_ref_field(unsigned int obj) const
Return the field index of a component ref.
virtual TreeNodeConstSet GetParameterTypes() const
Returns the types of the parameters.
static bool is_a_vector(const tree_managerConstRef &TM, const unsigned int index)
Return true if the treenode index is a vector.
virtual bool is_a_component_ref(unsigned int variable) const
Return true if the index is a component ref.
virtual bool is_an_indirect_ref(unsigned int variable) const
Return true if the index is an indirect ref.
static std::map< std::string, unsigned int > used_name
Set of variables name already used.
static integer_cst_t GetConstValue(const tree_nodeConstRef &tn, bool is_signed=true)
Get value from integer constant.
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
Definition: tree_node.hpp:700
virtual std::string print_type_declaration(unsigned int type) const
Print the declaration of a non built-in type.
int fun(float *A, float *invA, float *b, float *x, float *I)
virtual const std::string get_label_name(unsigned int label_expr_nid) const
return the label name associated with the label expression
#define GET_INDEX_CONST_NODE(t)
Definition: tree_node.hpp:363
static std::map< unsigned int, std::string > vars_symbol_table
The var symbol table.
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.
bool IsLut(const unsigned int statement_index) const
Return if an operation is a lut_expr.
static tree_nodeConstRef GetFunctionReturnType(const tree_nodeConstRef &function, bool void_as_null=true)
Return the return type of a function.
virtual unsigned int get_array_ref_index(unsigned int obj) const
Return the index variable of an array ref.
std::string get_asm_string(const unsigned int node_index) const
return the string associated with the gimple_asm
#define NULL_VERTEX
null vertex definition
Definition: graph.hpp:1305
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...
This class creates a layer to add nodes and to manipulate the tree_nodes manager. ...
int debug_level
the debug level
struct definition of the declaration node structures.
Definition: tree_node.hpp:877
#define CASE_TERNARY_EXPRESSION
This macro collects all case labels for ternary_expr objects.
Definition: tree_node.hpp:550
Class specification of the manager of the tree structures extracted from the raw file.
virtual unsigned int get_pointed_type(const unsigned int type) const
Return the pointed type of a pointer.
A brief description of the C++ Header File.
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.
refcount< const BehavioralHelper > BehavioralHelperConstRef
virtual unsigned int get_attributes(unsigned int var) const
return the attributes associated with the variable.
#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