stage3/case_elements_check.cc
author Mario de Sousa <msousa@fe.up.pt>
Wed, 26 Dec 2018 11:56:14 +0000
changeset 1082 903e2782e405
parent 1041 56ebe2a31b5b
permissions -rw-r--r--
fix bug introduced in previous commit (force literals to unsigned log long)
1000
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
     1
/*
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
     2
 *  matiec - a compiler for the programming languages defined in IEC 61131-3
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
     3
 *
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
     4
 *  Copyright (C) 2015  Mario de Sousa (msousa@fe.up.pt)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
     5
 *
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
     6
 *
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
     7
 *  This program is free software: you can redistribute it and/or modify
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
     8
 *  it under the terms of the GNU General Public License as published by
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
     9
 *  the Free Software Foundation, either version 3 of the License, or
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    10
 *  (at your option) any later version.
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    11
 *
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    12
 *  This program is distributed in the hope that it will be useful,
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    15
 *  GNU General Public License for more details.
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    16
 *
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    17
 *  You should have received a copy of the GNU General Public License
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    18
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    19
 *
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    20
 *
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    21
 * This code is made available on the understanding that it will not be
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    22
 * used in safety-critical situations without a full and competent review.
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    23
 */
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    24
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    25
/*
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    26
 * An IEC 61131-3 compiler.
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    27
 *
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    28
 * Based on the
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    29
 * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    30
 *
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    31
 */
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    32
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    33
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    34
/*
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    35
 * Case Options Checking:
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    36
 *   - Check whether the options in a case statement are repeated, either directly, or in a range.
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    37
 *       For example:
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    38
 *         case var of
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    39
 *           1: ...   <- OK
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    40
 *           2: ...   <- OK
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    41
 *           1: ...   <- OK (not an error), but produce a warning due to repeated '1'!
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    42
 *           0..8: ...<- OK (not an error), but produce a warning cue to repeated '1' and '2'!
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    43
 */
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    44
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    45
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    46
#include "case_elements_check.hh"
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    47
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    48
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    49
#define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    50
#define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    51
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    52
#define STAGE3_ERROR(error_level, symbol1, symbol2, ...) {                                                                  \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    53
  if (current_display_error_level >= error_level) {                                                                         \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    54
    fprintf(stderr, "%s:%d-%d..%d-%d: error: ",                                                                             \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    55
            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    56
                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    57
    fprintf(stderr, __VA_ARGS__);                                                                                           \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    58
    fprintf(stderr, "\n");                                                                                                  \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    59
    error_count++;                                                                                                     \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    60
  }                                                                                                                         \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    61
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    62
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    63
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    64
#define STAGE3_WARNING(symbol1, symbol2, ...) {                                                                             \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    65
    fprintf(stderr, "%s:%d-%d..%d-%d: warning: ",                                                                           \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    66
            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    67
                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    68
    fprintf(stderr, __VA_ARGS__);                                                                                           \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    69
    fprintf(stderr, "\n");                                                                                                  \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    70
    warning_found = true;                                                                                                   \
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    71
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    72
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    73
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    74
#define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.get())
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    75
#define VALID_CVALUE(dtype, symbol)           ((symbol)->const_value._##dtype.is_valid())
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    76
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    77
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    78
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    79
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    80
case_elements_check_c::case_elements_check_c(symbol_c *ignore) {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    81
  warning_found = false;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    82
  error_count = 0;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    83
  current_display_error_level = 0;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    84
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    85
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    86
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    87
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    88
case_elements_check_c::~case_elements_check_c(void) {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    89
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    90
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    91
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    92
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    93
int case_elements_check_c::get_error_count() {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    94
  return error_count;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    95
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    96
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    97
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    98
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
    99
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   100
/* compare two integer constants, and determins if s1 < s2 */
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   101
static bool less_than(symbol_c *s1, symbol_c *s2) {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   102
  if (   (VALID_CVALUE( int64, s1))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   103
      && (VALID_CVALUE( int64, s2))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   104
      && (  GET_CVALUE( int64, s1) < GET_CVALUE( int64, s2)))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   105
    return true;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   106
  
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   107
  if (   (VALID_CVALUE(uint64, s1))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   108
      && (VALID_CVALUE(uint64, s2))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   109
      && (  GET_CVALUE(uint64, s1) < GET_CVALUE(uint64, s2)))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   110
    return true;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   111
  
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   112
  if (   (VALID_CVALUE( int64, s1))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   113
      && (VALID_CVALUE(uint64, s2))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   114
      && (  GET_CVALUE( int64, s1) < 0))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   115
    return true;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   116
  
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   117
  return false;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   118
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   119
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   120
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   121
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   122
void case_elements_check_c::check_subr_subr(symbol_c *s1, symbol_c *s2) {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   123
  subrange_c *sub1 = dynamic_cast<subrange_c *>(s1);
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   124
  subrange_c *sub2 = dynamic_cast<subrange_c *>(s2);
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   125
  
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   126
  if ((NULL == sub1) || (NULL == sub2)) return;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   127
  symbol_c *l1 = sub1->lower_limit;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   128
  symbol_c *u1 = sub1->upper_limit;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   129
  symbol_c *l2 = sub2->lower_limit;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   130
  symbol_c *u2 = sub2->upper_limit;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   131
  
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   132
  if (less_than(u1, l2))  return; // no overlap!
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   133
  if (less_than(u2, l1))  return; // no overlap!
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   134
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   135
  if (   (VALID_CVALUE( int64, l1) || (VALID_CVALUE(uint64, l1)))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   136
      && (VALID_CVALUE( int64, l2) || (VALID_CVALUE(uint64, l2)))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   137
      && (VALID_CVALUE( int64, u1) || (VALID_CVALUE(uint64, u1)))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   138
      && (VALID_CVALUE( int64, u2) || (VALID_CVALUE(uint64, u2))))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   139
    STAGE3_WARNING(s1, s2, "Elements in CASE options have overlapping ranges.");
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   140
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   141
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   142
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   143
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   144
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   145
void case_elements_check_c::check_subr_symb(symbol_c *s1, symbol_c *s2) {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   146
  subrange_c *subr = NULL;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   147
  symbol_c   *symb = NULL;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   148
  if ((subr = dynamic_cast<subrange_c *>(s1)) != NULL) {symb = s2;}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   149
  if ((subr = dynamic_cast<subrange_c *>(s2)) != NULL) {symb = s1;}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   150
  
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   151
  if ((NULL == subr) || (NULL == symb)) return;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   152
  symbol_c   *lowl = subr->lower_limit;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   153
  symbol_c   *uppl = subr->upper_limit;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   154
  
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   155
  if (   (VALID_CVALUE(int64, symb))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   156
      && (VALID_CVALUE(int64, lowl))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   157
      && (VALID_CVALUE(int64, uppl))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   158
      && (  GET_CVALUE(int64, symb) >= GET_CVALUE(int64, lowl))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   159
      && (  GET_CVALUE(int64, symb) <= GET_CVALUE(int64, uppl)))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   160
    {STAGE3_WARNING(s1, s2, "Element in CASE option falls within range of another element."); return;}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   161
    
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   162
  if (   (VALID_CVALUE(uint64, symb))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   163
      && (VALID_CVALUE( int64, lowl))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   164
      && (VALID_CVALUE(uint64, uppl))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   165
      && (  GET_CVALUE( int64, lowl) < 0)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   166
      && (  GET_CVALUE(uint64, symb) <= GET_CVALUE(uint64, uppl)))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   167
    {STAGE3_WARNING(s1, s2, "Element in CASE option falls within range of another element."); return;}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   168
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   169
  if (   (VALID_CVALUE(uint64, symb))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   170
      && (VALID_CVALUE(uint64, lowl))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   171
      && (VALID_CVALUE(uint64, uppl))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   172
      && (  GET_CVALUE(uint64, symb) >= GET_CVALUE(uint64, lowl))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   173
      && (  GET_CVALUE(uint64, symb) <= GET_CVALUE(uint64, uppl)))
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   174
    {STAGE3_WARNING(s1, s2, "Element in CASE option falls within range of another element."); return;}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   175
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   176
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   177
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   178
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   179
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   180
#include <typeinfo>
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   181
void case_elements_check_c::check_symb_symb(symbol_c *s1, symbol_c *s2) {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   182
  if (   (dynamic_cast<subrange_c *>(s1) != NULL)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   183
      || (dynamic_cast<subrange_c *>(s2) != NULL)) 
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   184
    return; // only run this test if neither s1 nor s2 are subranges!
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   185
  
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   186
  if (   (s1->const_value.is_const() && s2->const_value.is_const() && (s1->const_value == s2->const_value))  // if const, then compare const values (using overloaded '==' operator!)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   187
      || (compare_identifiers(s1, s2) == 0))  // if token_c, compare tokens! (compare_identifiers() returns 0 when equal tokens!, -1 when either is not token_c)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   188
    STAGE3_WARNING(s1, s2, "Duplicate element found in CASE options.");
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   189
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   190
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   191
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   192
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   193
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   194
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   195
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   196
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   197
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   198
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   199
/***************************************/
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   200
/* B.3 - Language ST (Structured Text) */
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   201
/***************************************/
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   202
/********************/
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   203
/* B 3.2 Statements */
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   204
/********************/
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   205
/********************************/
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   206
/* B 3.2.3 Selection Statements */
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   207
/********************************/
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   208
/* CASE expression OF case_element_list ELSE statement_list END_CASE */
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   209
// SYM_REF3(case_statement_c, expression, case_element_list, statement_list)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   210
void *case_elements_check_c::visit(case_statement_c *symbol) {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   211
  std::vector<symbol_c *> case_elements_list_local = case_elements_list; // Required when source code contains CASE inside another CASE !
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   212
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   213
  case_elements_list.clear();
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   214
  symbol->case_element_list->accept(*this); // will fill up the case_elements_list with all the elements in the case!
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   215
  
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   216
  // OK, now check whether we have any overlappings...
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   217
  std::vector<symbol_c *>::iterator s1 = case_elements_list.begin();
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   218
  for (  ; s1 != case_elements_list.end(); s1++) {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   219
    std::vector<symbol_c *>::iterator s2 = s1;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   220
    s2++; // do not compare the value with itself!
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   221
    for (; s2 != case_elements_list.end(); s2++) {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   222
      // Check for overlapping elements
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   223
      check_subr_subr(*s1, *s2);
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   224
      check_subr_symb(*s1, *s2);
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   225
      check_symb_symb(*s2, *s1);
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   226
    }
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   227
  }
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   228
  
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   229
  case_elements_list = case_elements_list_local;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   230
  return NULL;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   231
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   232
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   233
/* helper symbol for case_statement */
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   234
// SYM_LIST(case_element_list_c)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   235
// void *case_elements_check_c::visit(case_element_list_c *symbol) // not needed! We inherit from iterator_visitor_c
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   236
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   237
/*  case_list ':' statement_list */
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   238
// SYM_REF2(case_element_c, case_list, statement_list)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   239
// void *case_elements_check_c::visit(case_element_c *symbol) // not needed! We inherit from iterator_visitor_c
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   240
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   241
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   242
// SYM_LIST(case_list_c)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   243
void *case_elements_check_c::visit(case_list_c *symbol) {
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   244
  for (int i = 0; i < symbol->n; i++)
1041
56ebe2a31b5b Access elements[] in list_c through a new get_element() method.
Mario de Sousa <msousa@fe.up.pt>
parents: 1000
diff changeset
   245
    case_elements_list.push_back(symbol->get_element(i));
1000
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   246
  return NULL;
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   247
}
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   248
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   249