stage4/generate_c/generate_c_vardecl.cc
changeset 592 99a284cec1f2
parent 587 1ecf916cc397
child 594 c8092e909886
equal deleted inserted replaced
591:76bad7199896 592:99a284cec1f2
    20  *
    20  *
    21  * This code is made available on the understanding that it will not be
    21  * This code is made available on the understanding that it will not be
    22  * used in safety-critical situations without a full and competent review.
    22  * used in safety-critical situations without a full and competent review.
    23  */
    23  */
    24 
    24 
       
    25 #include <limits>  // required for std::numeric_limits<XXX>
       
    26 
    25 class initialization_analyzer_c: public null_visitor_c {
    27 class initialization_analyzer_c: public null_visitor_c {
    26   public:
    28   public:
    27 	typedef enum {
    29 	typedef enum {
    28 	  simple_it,
    30 	  simple_it,
    29 	  array_it,
    31 	  array_it,
    72     symbol_c* array_default_value;
    74     symbol_c* array_default_value;
    73     symbol_c* array_default_initialization;
    75     symbol_c* array_default_initialization;
    74 
    76 
    75   private:
    77   private:
    76     int current_dimension;
    78     int current_dimension;
    77     int array_size;
    79     unsigned long long int array_size;
    78     int defined_values_count;
    80     unsigned long long int defined_values_count;
    79     int current_initialization_count;
    81     unsigned long long int current_initialization_count;
    80 
    82 
    81   public:
    83   public:
    82     generate_c_array_initialization_c(stage4out_c *s4o_ptr): generate_c_typedecl_c(s4o_ptr) {}
    84     generate_c_array_initialization_c(stage4out_c *s4o_ptr): generate_c_typedecl_c(s4o_ptr) {}
    83     ~generate_c_array_initialization_c(void) {}
    85     ~generate_c_array_initialization_c(void) {}
    84 
    86 
   122       array_initialization->accept(*this);
   124       array_initialization->accept(*this);
   123 
   125 
   124       if (array_default_initialization != NULL && defined_values_count < array_size)
   126       if (array_default_initialization != NULL && defined_values_count < array_size)
   125         array_default_initialization->accept(*this);
   127         array_default_initialization->accept(*this);
   126       if (defined_values_count < array_size) {
   128       if (defined_values_count < array_size) {
   127         for (int i = defined_values_count; i < array_size; i++) {
   129         for (unsigned long long int i = defined_values_count; i < array_size; i++) {
   128           if (defined_values_count > 0)
   130           if (defined_values_count > 0)
   129             s4o.print(",");
   131             s4o.print(",");
   130           array_default_value->accept(*this);
   132           array_default_value->accept(*this);
   131           defined_values_count++;
   133           defined_values_count++;
   132         }
   134         }
   209     }
   211     }
   210     
   212     
   211     /*  signed_integer DOTDOT signed_integer */
   213     /*  signed_integer DOTDOT signed_integer */
   212     //SYM_REF2(subrange_c, lower_limit, upper_limit)
   214     //SYM_REF2(subrange_c, lower_limit, upper_limit)
   213     void *visit(subrange_c *symbol) {
   215     void *visit(subrange_c *symbol) {
   214       int dimension = extract_int64_value(symbol->upper_limit) - extract_int64_value(symbol->lower_limit) + 1;
       
   215       switch (current_mode) {
   216       switch (current_mode) {
   216         case arraysize_am:
   217         case arraysize_am:
   217           array_size *= dimension;
   218           /* res = a * b; --->  Check for overflow by pre-condition: If (UINT_MAX / a) < b => overflow! */
       
   219           if ((std::numeric_limits< unsigned long long int >::max() / array_size) < symbol->dimension)
       
   220             STAGE4_ERROR(symbol, symbol, "The array containing this subrange has a total number of elements larger than the maximum currently supported (%llu).", 
       
   221                          std::numeric_limits< unsigned long long int >::max());
       
   222           array_size *= symbol->dimension;
   218           break;
   223           break;
   219         case typedecl_am:
   224         case typedecl_am:
   220           s4o.print("_");
   225           s4o.print("_");
   221           s4o.print_integer(dimension);
   226           s4o.print_integer(symbol->dimension);
   222           break;
   227           break;
   223         default:
   228         default:
   224           break;
   229           break;
   225       }
   230       }
   226       return NULL;
   231       return NULL;
   258     }
   263     }
   259     
   264     
   260     /* integer '(' [array_initial_element] ')' */
   265     /* integer '(' [array_initial_element] ')' */
   261     /* array_initial_element may be NULL ! */
   266     /* array_initial_element may be NULL ! */
   262     void *visit(array_initial_elements_c *symbol) {
   267     void *visit(array_initial_elements_c *symbol) {
   263       int initial_element_number;
   268       unsigned long long int initial_element_number;
   264       
   269       
   265       switch (current_mode) {
   270       switch (current_mode) {
   266         case initializationvalue_am:
   271         case initializationvalue_am:
   267           initial_element_number = extract_int64_value(symbol->integer);
   272           initial_element_number = extract_int64_value(symbol->integer);
   268           if (current_initialization_count < defined_values_count) {
   273           if (current_initialization_count < defined_values_count) {
   269             int temp_element_number = 0;
   274             unsigned long long int temp_element_number = 0;
   270             int diff = defined_values_count - current_initialization_count;
   275             unsigned long long int diff = defined_values_count - current_initialization_count;
   271             if (diff <= initial_element_number)
   276             if (diff <= initial_element_number)
   272               temp_element_number = initial_element_number - diff;
   277               temp_element_number = initial_element_number - diff;
   273             current_initialization_count += initial_element_number - 1;
   278             current_initialization_count += initial_element_number - 1;
   274             initial_element_number = temp_element_number;
   279             initial_element_number = temp_element_number;
   275             if (initial_element_number > 0) {
   280             if (initial_element_number > 0) {
   279           }
   284           }
   280           else
   285           else
   281             current_initialization_count += initial_element_number - 1;
   286             current_initialization_count += initial_element_number - 1;
   282           if (defined_values_count + initial_element_number > array_size)
   287           if (defined_values_count + initial_element_number > array_size)
   283             ERROR;
   288             ERROR;
   284           for (int i = 0; i < initial_element_number; i++) {
   289           for (unsigned long long int i = 0; i < initial_element_number; i++) {
   285             if (i > 0)
   290             if (i > 0)
   286               s4o.print(",");
   291               s4o.print(",");
   287             if (symbol->array_initial_element != NULL) {
   292             if (symbol->array_initial_element != NULL) {
   288               symbol->array_initial_element->accept(*this);
   293               symbol->array_initial_element->accept(*this);
   289             }
   294             }
  1405 }
  1410 }
  1406 
  1411 
  1407 /*  signed_integer DOTDOT signed_integer */
  1412 /*  signed_integer DOTDOT signed_integer */
  1408 //SYM_REF2(subrange_c, lower_limit, upper_limit)
  1413 //SYM_REF2(subrange_c, lower_limit, upper_limit)
  1409 void *visit(subrange_c *symbol) {
  1414 void *visit(subrange_c *symbol) {
  1410   long long dimension = extract_int64_value(symbol->upper_limit) - extract_int64_value(symbol->lower_limit) + 1;
       
  1411   s4o.print("_");
  1415   s4o.print("_");
  1412   print_integer(dimension);
  1416   print_integer(symbol->dimension);
  1413   return NULL;
  1417   return NULL;
  1414 }
  1418 }
  1415 
  1419 
  1416 /*  var1_list ':' initialized_structure */
  1420 /*  var1_list ':' initialized_structure */
  1417 // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure)
  1421 // SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure)