PandA-2024.02
check_system_type.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
44 #include "config_LIBBAMBU_SRCDIR.hpp"
46 #include "config_PANDA_DATA_INSTALLDIR.hpp"
47 
49 #include "check_system_type.hpp"
50 
52 #include "application_manager.hpp"
53 #include "behavioral_helper.hpp"
54 #include "function_behavior.hpp"
55 
57 #include "Parameter.hpp"
58 
60 #include <fstream>
61 
63 #include "ext_tree_node.hpp"
64 #include "tree_basic_block.hpp"
65 #include "tree_helper.hpp"
66 #include "tree_manager.hpp"
67 #include "tree_reindex.hpp"
68 
70 #include <filesystem>
71 
73 #include "compiler_wrapper.hpp"
74 #include "string_manipulation.hpp" // for GET_CLASS
75 
76 #define FILENAME_NORM(name) (std::filesystem::path(name).lexically_normal().string())
77 
78 std::vector<std::string> CheckSystemType::systemIncPath;
79 
81  {FILENAME_NORM("i386-linux-gnu/bits/ipc.h"), FILENAME_NORM("sys/ipc.h")},
82  {FILENAME_NORM("i386-linux-gnu/bits/sem.h"), FILENAME_NORM("sys/sem.h")},
83  {FILENAME_NORM("i386-linux-gnu/bits/mathcalls.h"), FILENAME_NORM("math.h")},
84  {FILENAME_NORM("i386-linux-gnu/bits/math-finite.h"), FILENAME_NORM("math.h")},
85  {FILENAME_NORM("i386-linux-gnu/bits/types.h"), FILENAME_NORM("sys/types.h")},
86  {FILENAME_NORM("i386-linux-gnu/bits/stat.h"), FILENAME_NORM("sys/stat.h")},
87  {FILENAME_NORM("i386-linux-gnu/bits/mman.h"), FILENAME_NORM("sys/mman.h")},
88  {FILENAME_NORM("i386-linux-gnu/bits/in.h"), FILENAME_NORM("netinet/in.h")},
89  {FILENAME_NORM("i386-linux-gnu/bits/errno.h"), FILENAME_NORM("errno.h")},
90  {FILENAME_NORM("i386-linux-gnu/bits/fcntl.h"), FILENAME_NORM("fcntl.h")},
91  {FILENAME_NORM("i386-linux-gnu/bits/link.h"), FILENAME_NORM("link.h")},
92  {FILENAME_NORM("i386-linux-gnu/bits/shm.h"), FILENAME_NORM("sys/shm.h")},
93  {FILENAME_NORM("i386-linux-gnu/bits/stdio.h"), FILENAME_NORM("stdio.h")},
94  {FILENAME_NORM("i386-linux-gnu/bits/resource.h"), FILENAME_NORM("sys/resource.h")},
95  {FILENAME_NORM("i386-linux-gnu/bits/sigthread.h"), FILENAME_NORM("pthread.h")},
96  {FILENAME_NORM("i386-linux-gnu/bits/string2.h"), FILENAME_NORM("string.h")},
97  {FILENAME_NORM("i386-linux-gnu/bits/time.h"), FILENAME_NORM("sys/time.h")},
98  {FILENAME_NORM("i386-linux-gnu/bits/pthreadtypes.h"), FILENAME_NORM("pthread.h")},
99  {FILENAME_NORM("i386-linux-gnu/bits/sched.h"), FILENAME_NORM("sched.h")},
100  {FILENAME_NORM("i386-linux-gnu/bits/stdio2.h"), FILENAME_NORM("stdio.h")},
101  {FILENAME_NORM("bits/ipc.h"), FILENAME_NORM("sys/ipc.h")},
102  {FILENAME_NORM("bits/sem.h"), FILENAME_NORM("sys/sem.h")},
103  {FILENAME_NORM("bits/mathcalls.h"), FILENAME_NORM("math.h")},
104  {FILENAME_NORM("bits/math-finite."), FILENAME_NORM("math.h")},
105  {FILENAME_NORM("bits/types.h"), FILENAME_NORM("sys/types.h")},
106  {FILENAME_NORM("bits/stat.h"), FILENAME_NORM("sys/stat.h")},
107  {FILENAME_NORM("bits/mman.h"), FILENAME_NORM("sys/mman.h")},
108  {FILENAME_NORM("bits/in.h"), FILENAME_NORM("netinet/in.h")},
109  {FILENAME_NORM("bits/errno.h"), FILENAME_NORM("errno.h")},
110  {FILENAME_NORM("bits/fcntl.h"), FILENAME_NORM("fcntl.h")},
111  {FILENAME_NORM("bits/link.h"), FILENAME_NORM("link.h")},
112  {FILENAME_NORM("bits/shm.h"), FILENAME_NORM("sys/shm.h")},
113  {FILENAME_NORM("bits/stdio.h"), FILENAME_NORM("stdio.h")},
114  {FILENAME_NORM("bits/resource.h"), FILENAME_NORM("sys/resource.h")},
115  {FILENAME_NORM("bits/sigthread.h"), FILENAME_NORM("pthread.h")},
116  {FILENAME_NORM("bits/string2.h"), FILENAME_NORM("string.h")},
117  {FILENAME_NORM("bits/time.h"), FILENAME_NORM("sys/time.h")},
118  {FILENAME_NORM("bits/pthreadtypes.h"), FILENAME_NORM("pthread.h")},
119  {FILENAME_NORM("bits/sched.h"), FILENAME_NORM("sched.h")},
120  {FILENAME_NORM("bits/stdio2.h"), FILENAME_NORM("stdio.h")},
121  {FILENAME_NORM("libio.h"), FILENAME_NORM("stdio.h")},
122  {FILENAME_NORM("libm/math_private_kernels.h"), FILENAME_NORM("math.h")},
123  {FILENAME_NORM("libm/math_private.h"), FILENAME_NORM("math.h")},
124  {FILENAME_NORM("libm/math_privatef.h"), FILENAME_NORM("math.h")}};
125 
127  {"_IO_getc", "getc"}};
128 
130  {"__suseconds_t", "long int"}};
131 
133  {"__errno_location", "exit", "abort"},
134 };
135 
137 
139  {"atof", "stdlib.h"}, {"atoi", "stdlib.h"}, {"srand48", "stdlib.h"},
140  {"va_start", "stdarg.h"}, {"va_end", "stdarg.h"}, {"lgamma", "math.h"},
141  {"lgammaf", "math.h"}, {"lgamma_r", "math.h"}, {"lgammaf_r", "math.h"}};
142 
144  unsigned int _function_id, const DesignFlowManagerConstRef _design_flow_manager)
145  : FunctionFrontendFlowStep(_AppM, _function_id, CHECK_SYSTEM_TYPE, _design_flow_manager, _parameters),
146  behavioral_helper(AppM->CGetFunctionBehavior(function_id)->CGetBehavioralHelper()),
147  TM(AppM->get_tree_manager()),
148  already_executed(false)
149 {
150  debug_level = parameters->get_class_debug_level(GET_CLASS(*this), DEBUG_LEVEL_NONE);
151  if(systemIncPath.size() == 0)
152  {
154  }
155 }
156 
158 
161 {
163  switch(relationship_type)
164  {
166  {
167  relationships.insert(std::make_pair(IR_LOWERING, SAME_FUNCTION));
168  break;
169  }
171  {
172  relationships.insert(std::make_pair(UN_COMPARISON_LOWERING, SAME_FUNCTION));
173  break;
174  }
176  {
177  break;
178  }
179  default:
180  {
181  THROW_UNREACHABLE("");
182  }
183  }
184  return relationships;
185 }
186 
188 {
189  return !already_executed;
190 }
191 
193 {
194  const auto curr_tn = TM->GetTreeNode(function_id);
195  const auto fd = GetPointerS<function_decl>(curr_tn);
196  const auto sl = GetPointerS<statement_list>(GET_NODE(fd->body));
197 
198  CustomUnorderedSet<unsigned int> already_visited;
199  recursive_examinate(curr_tn, function_id, already_visited);
200 
201  for(const auto f : AppM->get_functions_without_body())
202  {
203  recursive_examinate(TM->CGetTreeReindex(f), already_visited);
204  }
205 
206  for(const auto& bbi_bb : sl->list_of_bloc)
207  {
208  const auto& bb = bbi_bb.second;
209  if(bb)
210  {
211  for(const auto& stmt : bb->CGetStmtList())
212  {
213  recursive_examinate(stmt, already_visited);
214  }
215  }
216  }
217 
218  already_executed = true;
220 }
221 
223  CustomUnorderedSet<unsigned int>& already_visited) const
224 {
225  THROW_ASSERT(tn->get_kind() == tree_reindex_K, "Not Passed a tree_reindex");
226  recursive_examinate(GET_NODE(tn), GET_INDEX_NODE(tn), already_visited);
227 }
228 
229 void CheckSystemType::recursive_examinate(const tree_nodeRef& curr_tn, const unsigned int index,
230  CustomUnorderedSet<unsigned int>& already_visited) const
231 {
232  THROW_ASSERT(curr_tn, "Empty current tree node");
233  if(already_visited.count(index))
234  {
235  return;
236  }
237  already_visited.insert(index);
238  THROW_ASSERT(curr_tn->get_kind() != tree_reindex_K, "Passed tree_reindex instead of real node");
239  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "-->Checking @" + STR(index));
240  switch(curr_tn->get_kind())
241  {
242  case call_expr_K:
243  case aggr_init_expr_K:
244  {
245  const auto ce = GetPointerS<call_expr>(curr_tn);
246  recursive_examinate(ce->fn, already_visited);
247  for(const auto& arg : ce->args)
248  {
249  recursive_examinate(arg, already_visited);
250  }
251  break;
252  }
253  case gimple_call_K:
254  {
255  const auto ce = GetPointerS<gimple_call>(curr_tn);
256  recursive_examinate(ce->fn, already_visited);
257  for(const auto& arg : ce->args)
258  {
259  recursive_examinate(arg, already_visited);
260  }
261  break;
262  }
263  case gimple_assign_K:
264  {
265  const auto gm = GetPointerS<gimple_assign>(curr_tn);
266  recursive_examinate(gm->op0, already_visited);
267  recursive_examinate(gm->op1, already_visited);
268  if(gm->predicate)
269  {
270  recursive_examinate(gm->predicate, already_visited);
271  }
272  break;
273  }
274  case gimple_nop_K:
275  {
276  break;
277  }
278  case CASE_DECL_NODES:
279  {
280  const auto dn = GetPointerS<decl_node>(curr_tn);
281  auto fd = GetPointer<function_decl>(curr_tn);
282  bool is_system;
283  const auto include = std::get<0>(behavioral_helper->get_definition(index, is_system));
285  {
286  dn->library_system_flag = true;
287  }
288  else if(!dn->operating_system_flag && !dn->library_system_flag && (is_system || is_system_include(include)))
289  {
290  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "System declaration");
291  const auto sr = GetPointer<srcp>(curr_tn);
292  if(!is_system && sr && sr->include_name != "")
293  {
294  sr->include_name = getRealInclName(include);
295  }
296  fd = GetPointer<function_decl>(curr_tn);
297  if(fd)
298  {
299  if(sr)
300  {
301  if(library_system_includes.count(sr->include_name))
302  {
303  dn->library_system_flag = true;
304  }
305  else
306  {
307  dn->operating_system_flag = true;
308  }
309  }
310  else
311  {
312  dn->operating_system_flag = true;
313  }
314  }
315  else
316  {
317  dn->operating_system_flag = true;
318  }
319  }
321  {
322  dn->library_system_flag = true;
323  const auto sr = GetPointer<srcp>(curr_tn);
325  }
326  // Checking for implicit declaration
327  if(curr_tn->get_kind() == function_decl_K)
328  {
329  fd = GetPointerS<function_decl>(curr_tn);
330  const auto sr = GetPointer<srcp>(curr_tn);
331  if(fd->type && fd->undefined_flag && !fd->operating_system_flag && !fd->library_system_flag &&
332  sr->include_name != "<built-in>")
333  {
334  const auto ft = GetPointerS<function_type>(GET_NODE(fd->type));
335  if(!ft->prms && ft->retn && GetPointer<integer_type>(GET_NODE(ft->retn)))
336  {
337  const auto it = GetPointerS<integer_type>(GET_NODE(ft->retn));
338  if(it->name && GetPointer<type_decl>(GET_NODE(it->name)))
339  {
340  const auto td = GetPointerS<type_decl>(GET_NODE(it->name));
341  if(td->name && GetPointer<identifier_node>(GET_NODE(td->name)))
342  {
343  const auto in = GetPointerS<identifier_node>(GET_NODE(td->name));
344  if(in->strg == "int")
345  {
346  fd->include_name = "<built-in>";
347  }
348  }
349  }
350  }
351  }
352  if(fd->name && GET_NODE(fd->name)->get_kind() == identifier_node_K)
353  {
354  const auto in = GetPointerS<identifier_node>(GET_NODE(fd->name));
355  if(rename_function.count(in->strg))
356  {
357  in->strg = rename_function.at(in->strg);
358  }
359  }
360  }
361  // Checking for type
362  if(curr_tn->get_kind() == type_decl_K)
363  {
364  const auto td = GetPointerS<type_decl>(curr_tn);
365  if(td->name && GET_NODE(td->name)->get_kind() == identifier_node_K)
366  {
367  const auto in = GetPointerS<identifier_node>(GET_NODE(td->name));
368  if(rename_types.count(in->strg))
369  {
370  in->strg = rename_types.at(in->strg);
371  }
372  }
373  }
374  if(curr_tn->get_kind() == var_decl_K && dn->artificial_flag &&
375  (behavioral_helper->PrintVariable(dn->index) == "__FUNCTION__" or
376  behavioral_helper->PrintVariable(dn->index) == "__PRETTY_FUNCTION__"))
377  {
378  dn->library_system_flag = true;
379  }
380  if(include.find("etc/libbambu") != std::string::npos)
381  {
383  dn->libbambu_flag = true;
384  }
385  else if(dn->libbambu_flag)
386  {
388  }
389  recursive_examinate(dn->type, already_visited);
390  break;
391  }
392  case ssa_name_K:
393  {
394  const auto sn = GetPointerS<ssa_name>(curr_tn);
395  if(sn->type)
396  {
397  recursive_examinate(sn->type, already_visited);
398  }
399  else
400  {
401  recursive_examinate(sn->var, already_visited);
402  }
403  break;
404  }
405  case tree_list_K:
406  {
407  tree_nodeRef current = curr_tn;
408  while(current)
409  {
410  if(GetPointerS<tree_list>(current)->purp)
411  {
412  recursive_examinate(GetPointerS<tree_list>(current)->purp, already_visited);
413  }
414  recursive_examinate(GetPointerS<tree_list>(current)->valu, already_visited);
415  current = GetPointerS<tree_list>(current)->chan;
416  if(current)
417  {
418  current = GET_NODE(current);
419  }
420  }
421  break;
422  }
424  {
425  const auto ue = GetPointerS<unary_expr>(curr_tn);
426  if(ue->type)
427  {
428  recursive_examinate(ue->type, already_visited);
429  }
430  recursive_examinate(ue->op, already_visited);
431  break;
432  }
434  {
435  const auto be = GetPointerS<binary_expr>(curr_tn);
436  if(be->type)
437  {
438  recursive_examinate(be->type, already_visited);
439  }
440  recursive_examinate(be->op0, already_visited);
441  recursive_examinate(be->op1, already_visited);
442  break;
443  }
445  {
446  const auto te = GetPointerS<ternary_expr>(curr_tn);
447  if(te->type)
448  {
449  recursive_examinate(te->type, already_visited);
450  }
451  recursive_examinate(te->op0, already_visited);
452  if(te->op1)
453  {
454  recursive_examinate(te->op1, already_visited);
455  }
456  if(te->op2)
457  {
458  recursive_examinate(te->op2, already_visited);
459  }
460  break;
461  }
463  {
464  const auto qe = GetPointerS<quaternary_expr>(curr_tn);
465  if(qe->type)
466  {
467  recursive_examinate(qe->type, already_visited);
468  }
469  recursive_examinate(qe->op0, already_visited);
470  if(qe->op1)
471  {
472  recursive_examinate(qe->op1, already_visited);
473  }
474  if(qe->op2)
475  {
476  recursive_examinate(qe->op2, already_visited);
477  }
478  if(qe->op3)
479  {
480  recursive_examinate(qe->op3, already_visited);
481  }
482  break;
483  }
484  case lut_expr_K:
485  {
486  const auto le = GetPointerS<lut_expr>(curr_tn);
487  recursive_examinate(le->op0, already_visited);
488  recursive_examinate(le->op1, already_visited);
489  if(le->op2)
490  {
491  recursive_examinate(le->op2, already_visited);
492  }
493  if(le->op3)
494  {
495  recursive_examinate(le->op3, already_visited);
496  }
497  if(le->op4)
498  {
499  recursive_examinate(le->op4, already_visited);
500  }
501  if(le->op5)
502  {
503  recursive_examinate(le->op5, already_visited);
504  }
505  if(le->op6)
506  {
507  recursive_examinate(le->op6, already_visited);
508  }
509  if(le->op7)
510  {
511  recursive_examinate(le->op7, already_visited);
512  }
513  if(le->op8)
514  {
515  recursive_examinate(le->op8, already_visited);
516  }
517  break;
518  }
519  case constructor_K:
520  {
521  const auto co = GetPointerS<constructor>(curr_tn);
522  if(co->type)
523  {
524  recursive_examinate(co->type, already_visited);
525  }
526  else
527  {
528  for(const auto& it : co->list_of_idx_valu)
529  {
530  recursive_examinate(it.second, already_visited);
531  }
532  }
533  break;
534  }
535  case gimple_cond_K:
536  {
537  const auto gc = GetPointerS<gimple_cond>(curr_tn);
538  recursive_examinate(gc->op0, already_visited);
539  break;
540  }
541  case gimple_switch_K:
542  {
543  const auto se = GetPointerS<gimple_switch>(curr_tn);
544  recursive_examinate(se->op0, already_visited);
545  break;
546  }
547  case gimple_multi_way_if_K:
548  {
549  const auto gmwi = GetPointerS<gimple_multi_way_if>(curr_tn);
550  for(const auto& cond : gmwi->list_of_cond)
551  {
552  if(cond.first)
553  {
554  recursive_examinate(cond.first, already_visited);
555  }
556  }
557  break;
558  }
559  case gimple_return_K:
560  {
561  const auto re = GetPointerS<gimple_return>(curr_tn);
562  if(re->op)
563  {
564  recursive_examinate(re->op, already_visited);
565  }
566  break;
567  }
568  case gimple_for_K:
569  {
570  const auto fe = GetPointerS<gimple_for>(curr_tn);
571  recursive_examinate(fe->op0, already_visited);
572  recursive_examinate(fe->op1, already_visited);
573  recursive_examinate(fe->op2, already_visited);
574  break;
575  }
576  case gimple_while_K:
577  {
578  const auto we = GetPointerS<gimple_while>(curr_tn);
579  recursive_examinate(we->op0, already_visited);
580  break;
581  }
582  case gimple_goto_K:
583  {
584  const auto ge = GetPointerS<gimple_goto>(curr_tn);
585  recursive_examinate(ge->op, already_visited);
586  break;
587  }
588  case CASE_TYPE_NODES:
589  {
590  const auto ty = GetPointerS<type_node>(curr_tn);
591  THROW_ASSERT(ty, "expected a name");
592  if(ty->name)
593  {
594  recursive_examinate(ty->name, already_visited);
595  }
596  switch(curr_tn->get_kind())
597  {
598  case boolean_type_K:
599  {
600  //_Bool is C99: we replace it for MAGIC compatibility
601  const auto bt = GetPointerS<boolean_type>(curr_tn);
602  if(bt->name && GetPointer<type_decl>(GET_NODE(bt->name)))
603  {
604  const auto td = GetPointerS<type_decl>(GET_NODE(bt->name));
605  if(td->name && GetPointer<identifier_node>(GET_NODE(td->name)))
606  {
607  const auto in = GetPointerS<identifier_node>(GET_NODE(td->name));
608  if(parameters->isOption(OPT_gcc_standard) &&
609  parameters->getOption<std::string>(OPT_gcc_standard) == "c99" && in->strg == "_Bool")
610  {
611  const std::string INT = "int";
612  in->strg = INT;
613  }
614  }
615  }
616  break;
617  }
618  case vector_type_K:
619  {
620  const auto vt = GetPointerS<vector_type>(curr_tn);
621  recursive_examinate(vt->elts, already_visited);
622  break;
623  }
624  case array_type_K:
625  {
626  const auto at = GetPointerS<array_type>(curr_tn);
627  recursive_examinate(at->elts, already_visited);
628  break;
629  }
630  case record_type_K:
631  {
632  const auto rt = GetPointerS<record_type>(curr_tn);
633  for(const auto& it : rt->list_of_flds)
634  {
635  recursive_examinate(it, already_visited);
636  if(!rt->libbambu_flag && tree_helper::IsInLibbambu(TM, it->index))
637  {
638  rt->libbambu_flag = true;
639  }
640  }
641  for(const auto& it : rt->list_of_fncs)
642  {
643  recursive_examinate(it, already_visited);
644  }
645  break;
646  }
647  case union_type_K:
648  {
649  const auto ut = GetPointerS<union_type>(curr_tn);
650  for(const auto& it : ut->list_of_flds)
651  {
652  recursive_examinate(it, already_visited);
653  if(!ut->libbambu_flag && tree_helper::IsInLibbambu(TM, it->index))
654  {
655  ut->libbambu_flag = true;
656  }
657  }
658  for(const auto& it : ut->list_of_fncs)
659  {
660  recursive_examinate(it, already_visited);
661  }
662  break;
663  }
664  case pointer_type_K:
665  {
666  const auto pt = GetPointerS<pointer_type>(curr_tn);
667  recursive_examinate(pt->ptd, already_visited);
668  break;
669  }
670  case reference_type_K:
671  {
672  const auto rt = GetPointerS<reference_type>(curr_tn);
673  if(rt->refd)
674  {
675  recursive_examinate(rt->refd, already_visited);
676  }
677  break;
678  }
679  case function_type_K:
680  {
681  const auto ft = GetPointerS<function_type>(curr_tn);
682  if(ft->retn)
683  {
684  recursive_examinate(ft->retn, already_visited);
685  }
686  if(ft->prms)
687  {
688  recursive_examinate(ft->prms, already_visited);
689  }
690  break;
691  }
692  case method_type_K:
693  {
694  const auto mt = GetPointerS<method_type>(curr_tn);
695  if(mt->retn)
696  {
697  recursive_examinate(mt->retn, already_visited);
698  }
699  if(mt->prms)
700  {
701  recursive_examinate(mt->prms, already_visited);
702  }
703  if(mt->clas)
704  {
705  recursive_examinate(mt->clas, already_visited);
706  }
707  break;
708  }
709  case integer_type_K:
710  {
711  const auto it = GetPointerS<integer_type>(curr_tn);
712  if(it->name && GetPointer<identifier_node>(GET_NODE(it->name)))
713  {
714  const auto in = GetPointerS<identifier_node>(GET_NODE(it->name));
715  if(in->strg == "sizetype")
716  {
717  const std::string INT = "unsigned long";
718  in->strg = INT;
719  }
720  if(in->strg == "ssizetype")
721  {
722  const std::string INT = "long";
723  in->strg = INT;
724  }
725  else if(in->strg == "bitsizetype")
726  {
727  const std::string INT = "unsigned long long int";
728  in->strg = INT;
729  }
730  else if(in->strg == "bit_size_type")
731  {
732  const std::string INT = "unsigned long long int";
733  in->strg = INT;
734  }
735  }
736  break;
737  }
738  case template_type_parm_K:
739  {
740  const auto ttp = GetPointerS<template_type_parm>(curr_tn);
741  recursive_examinate(ttp->name, already_visited);
742  break;
743  }
744  case typename_type_K:
745  {
746  const auto tt = GetPointerS<typename_type>(curr_tn);
747  recursive_examinate(tt->name, already_visited);
748  break;
749  }
750 
751  case enumeral_type_K:
752  case CharType_K:
753  case nullptr_type_K:
754  case type_pack_expansion_K:
755  case type_argument_pack_K:
756  case complex_type_K:
757  case real_type_K:
758  case void_type_K:
759  break;
760  case binfo_K:
761  case block_K:
762  case constructor_K:
763  case call_expr_K:
764  case aggr_init_expr_K:
765  case case_label_expr_K:
766  case identifier_node_K:
767  case lang_type_K:
768  case offset_type_K:
769  case qual_union_type_K:
770  case set_type_K:
771  case ssa_name_K:
772  case statement_list_K:
773  case target_expr_K:
774  case target_mem_ref_K:
775  case target_mem_ref461_K:
776  case tree_list_K:
777  case tree_vec_K:
778  case error_mark_K:
779  case lut_expr_K:
780  case CASE_CPP_NODES:
782  case CASE_CST_NODES:
783  case CASE_DECL_NODES:
784  case CASE_FAKE_NODES:
785  case CASE_GIMPLE_NODES:
786  case CASE_PRAGMA_NODES:
790  default:
791  THROW_ERROR_CODE(NODE_NOT_YET_SUPPORTED_EC, "Not supported node: " + curr_tn->get_kind_text());
792  }
793  bool is_system;
794  const auto include = std::get<0>(behavioral_helper->get_definition(index, is_system));
795  if((include.find("etc/libbambu") != std::string::npos) ||
796  (include.find(PANDA_DATA_INSTALLDIR "/panda/ac_types/include") != std::string::npos) ||
797  (include.find(PANDA_DATA_INSTALLDIR "/panda/ac_math/include") != std::string::npos) ||
798  (ty->name && GetPointer<const type_decl>(GET_CONST_NODE(ty->name)) &&
799  GetPointerS<const type_decl>(GET_CONST_NODE(ty->name))->libbambu_flag))
800  {
801  ty->libbambu_flag = true;
802  }
803  if(!ty->system_flag && (is_system || is_system_include(include)))
804  {
806  ty->system_flag = true;
807  const auto sr = GetPointer<srcp>(curr_tn);
808  if(!is_system && sr && sr->include_name != "")
809  {
810  sr->include_name = getRealInclName(include);
811  }
812  }
813  break;
814  }
815  case target_mem_ref_K:
816  {
817  const auto tmr = GetPointerS<target_mem_ref>(curr_tn);
818  if(tmr->symbol)
819  {
820  recursive_examinate(tmr->symbol, already_visited);
821  }
822  if(tmr->base)
823  {
824  recursive_examinate(tmr->base, already_visited);
825  }
826  if(tmr->idx)
827  {
828  recursive_examinate(tmr->idx, already_visited);
829  }
830  break;
831  }
832  case target_mem_ref461_K:
833  {
834  const auto tmr = GetPointerS<target_mem_ref461>(curr_tn);
835  if(tmr->base)
836  {
837  recursive_examinate(tmr->base, already_visited);
838  }
839  if(tmr->idx)
840  {
841  recursive_examinate(tmr->idx, already_visited);
842  }
843  if(tmr->idx2)
844  {
845  recursive_examinate(tmr->idx2, already_visited);
846  }
847  break;
848  }
849  case real_cst_K:
850  case complex_cst_K:
851  case string_cst_K:
852  case integer_cst_K:
853  case vector_cst_K:
854  case void_cst_K:
855  case tree_vec_K:
856  case case_label_expr_K:
857  case gimple_label_K:
858  case gimple_asm_K:
859  case gimple_pragma_K:
860  case gimple_predict_K:
861  case identifier_node_K:
862  case CASE_PRAGMA_NODES:
863  break;
864  case cast_expr_K:
865  {
866  const auto ce = GetPointerS<cast_expr>(curr_tn);
867  if(ce->op)
868  {
869  recursive_examinate(ce->op, already_visited);
870  }
871  break;
872  }
873  case binfo_K:
874  case block_K:
875  case baselink_K:
876  case ctor_initializer_K:
877  case do_stmt_K:
878  case expr_stmt_K:
879  case if_stmt_K:
880  case for_stmt_K:
881  case handler_K:
882  case modop_expr_K:
883  case new_expr_K:
884  case overload_K:
885  case return_stmt_K:
886  case scope_ref_K:
887  case template_id_expr_K:
888  case template_parm_index_K:
889  case trait_expr_K:
890  case try_block_K:
891  case vec_new_expr_K:
892  case while_stmt_K:
893  case nontype_argument_pack_K:
894  case expr_pack_expansion_K:
895  case CASE_FAKE_NODES:
896  case gimple_bind_K:
897  case gimple_phi_K:
898  case gimple_resx_K:
899  case statement_list_K:
900  case target_expr_K:
901  case error_mark_K:
902  {
903  THROW_ERROR_CODE(NODE_NOT_YET_SUPPORTED_EC, "Not supported node: " + curr_tn->get_kind_text());
904  break;
905  }
906  default:
907  {
908  THROW_UNREACHABLE("");
909  }
910  }
911  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "<--Checked @" + STR(index));
912  return;
913 }
914 
915 bool CheckSystemType::is_system_include(std::string include) const
916 {
917  if(include == "<built-in>")
918  {
919  return true;
920  }
921  std::string include_p(FILENAME_NORM(include));
922  for(const auto& i : systemIncPath)
923  {
924  if(include_p.compare(0, i.size() + 1, i + "/") == 0)
925  {
926  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Include is " + include + ": system include");
927  return true;
928  }
929  }
930  INDENT_DBG_MEX(DEBUG_LEVEL_VERY_PEDANTIC, debug_level, "---Include is " + include + ": non-system include");
931  return false;
932 }
933 
935 {
936  const CompilerWrapperConstRef compiler_wrapper(new CompilerWrapper(
938  std::vector<std::string> Splitted;
939  compiler_wrapper->GetSystemIncludes(Splitted);
940 
941  for(const auto& tok_iter : Splitted)
942  {
943  if(tok_iter != "")
944  {
945  std::string temp;
946  std::error_code ec;
947  if(getenv("MINGW_INST_DIR"))
948  {
949  std::string mingw_prefix = getenv("MINGW_INST_DIR");
950  temp = tok_iter;
951  if(starts_with(temp, "z:/mingw"))
952  {
953  temp =
954  temp.replace(0, 8, FILENAME_NORM(mingw_prefix));
955  }
956  temp = FILENAME_NORM(temp);
957  }
958  else if(getenv("APPDIR"))
959  {
960  const std::string app_prefix = getenv("APPDIR");
961  temp = FILENAME_NORM(tok_iter);
962  const auto canon_temp = std::filesystem::weakly_canonical(temp, ec);
963  if(!ec)
964  {
965  systemIncPath.push_back(canon_temp.string());
966  if(temp.find(app_prefix) != 0)
967  {
968  temp = app_prefix + "/" + FILENAME_NORM(tok_iter);
969  }
970  else
971  {
972  temp = temp.substr(app_prefix.size());
973  }
974  }
975  }
976  else
977  {
978  temp = FILENAME_NORM(tok_iter);
979  }
980  const auto canon_temp = std::filesystem::weakly_canonical(temp, ec);
981  if(!ec)
982  {
983  systemIncPath.push_back(canon_temp.string());
984  }
985  }
986  }
987  systemIncPath.push_back("/usr/local/share/hframework/include");
988  if(!parameters->isOption(OPT_pretty_print))
989  {
990  systemIncPath.push_back(LIBBAMBU_SRCDIR);
991  }
992 }
993 
994 std::string CheckSystemType::getRealInclName(const std::string& include)
995 {
996  // Now I have to see if one of the elements in systemIncPath is the start of the include:
997  // in case I eliminate it && look the remaining part of the string in the map
998  std::string include_p(FILENAME_NORM(include));
999  for(const auto& i : systemIncPath)
1000  {
1001  if(include_p.compare(0, i.size() + 1, i + "/") == 0)
1002  {
1003  const auto trimmed = include_p.substr(i.size() + 1);
1004  if(inclNameToPath.find(trimmed) != inclNameToPath.end())
1005  {
1006  return inclNameToPath.find(trimmed)->second;
1007  }
1008  else if(LIBBAMBU_SRCDIR == i && starts_with(trimmed, "libm/"))
1009  {
1010  return FILENAME_NORM("math.h");
1011  }
1012  else
1013  {
1014  return trimmed;
1015  }
1016  }
1017  }
1018 
1019  // If, finally, the include is not a system one I simply print it back as it is
1020  return include;
1021 }
#define GET_NODE(t)
Macro used to hide implementation details when accessing a tree_node from another tree_node...
Definition: tree_node.hpp:343
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
static const CustomUnorderedMap< std::string, std::string > rename_function
Associates a function to its original name.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
#define CASE_BINARY_EXPRESSION
This macro collects all case labels for binary_expr objects.
Definition: tree_node.hpp:463
#define GET_CLASS(obj)
Macro returning the actual type of an object.
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
RelationshipType
The relationship type.
Source must be executed to satisfy target.
void recursive_examinate(const tree_nodeRef &tn, CustomUnorderedSet< unsigned int > &already_visited) const
Examinate recursively the tree to detect system types and system variables.
static const CustomUnorderedMap< std::string, std::string > undefined_library_function_include
Map undefined library function to corresponding header.
#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
static std::string print_function_name(const tree_managerConstRef &TM, const function_decl *fd)
Return the name of the function in a string.
Node not yet supported.
Definition: exceptions.hpp:323
Data structure describing a basic block at tree level.
static const CustomUnorderedMap< std::string, std::string > inclNameToPath
Associates to each system header file its full path.
static bool IsInLibbambu(const tree_managerConstRef &TM, const unsigned int index)
Return true if the decl node or type is in libbambu.
virtual enum kind get_kind() const =0
Virtual function returning the type of the actual class.
#define STR(s)
Macro which performs a lexical_cast to a string.
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.
CheckSystemType(const ParameterConstRef _parameters, const application_managerRef AppM, unsigned int function_id, const DesignFlowManagerConstRef design_flow_manager)
Constructor.
#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 starts_with(const std::string &str, const std::string &pattern)
static std::vector< std::string > systemIncPath
Contains the list of the folders containing the system header files.
absl::flat_hash_map< T, U, Hash, Eq, Alloc > CustomUnorderedMap
Definition: custom_map.hpp:148
#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 CustomUnorderedMap< std::string, std::string > rename_types
Associates a type to its original name.
bool already_executed
Already executed.
DesignFlowStep_Status InternalExec() override
Adds the system_flag to the tree_node&#39;s of variables and types when necessary.
#define index(x, y)
Definition: Keccak.c:74
const CustomUnorderedSet< std::pair< FrontendFlowStepType, FunctionRelationship > > ComputeFrontendRelationships(const DesignFlowStep::RelationshipType relationship_type) const override
Return the set of analyses in relationship with this design step.
~CheckSystemType() override
Destructor.
#define GET_CONST_NODE(t)
Definition: tree_node.hpp:347
const ParameterConstRef parameters
Set of input parameters.
DesignFlowStep_Status
The status of a step.
bool is_system_include(std::string include) const
Check if an header is a system header.
#define DEBUG_LEVEL_NONE
no debugging print is performed.
analyse srcp of variables and types to detect system ones; the identified one are flagged ...
std::string PrintVariable(unsigned int var) const
Print the name of the variable associated to the index.
#define CASE_TYPE_NODES
This macro collects all case labels for type objects.
Definition: tree_node.hpp:581
This file collects some utility functions.
bool HasToBeExecuted() const override
Check if this step has actually to be executed.
static void build_include_structures(ParameterConstRef parameters)
Build the include map, the function rename map and library system sets.
const unsigned int function_id
The index of the function to be analyzed.
#define CASE_CST_NODES
This macro collects all case labels for cast nodes.
Definition: tree_node.hpp:689
const application_managerRef AppM
The application manager.
Class specification of the tree_reindex support class.
#define CASE_FAKE_NODES
This macro collects all case labels for fake or empty nodes.
Definition: tree_node.hpp:635
static std::string getRealInclName(const std::string &include)
Given the string stored in a srcp of the raw return the correct include name.
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
#define THROW_ERROR_CODE(code, str_expr)
helper function used to throw an error with a code error
Definition: exceptions.hpp:266
static const CustomUnorderedSet< std::string > library_system_includes
The set of headers which contains function which have to be considered library_system.
static const CustomUnorderedSet< std::string > library_system_functions
The set of functions which have to be considered library_system.
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.
#define CASE_CPP_NODES
This macro collects all case labels for cpp nodes.
Definition: tree_node.hpp:644
Main class for wrapping the frontend compiler.
#define CASE_GIMPLE_NODES
This macro collects all cases labels for gimple nodes.
Definition: tree_node.hpp:700
int debug_level
The debug level.
const tree_managerRef TM
The tree manager.
#define FILENAME_NORM(name)
Autoheader include.
#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.
A brief description of the C++ Header File.
int sl
Definition: adpcm.c:105
const BehavioralHelperConstRef behavioral_helper
The helper associated with the current function.
#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
Implementation of the wrapper to Gcc for C sources.

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