stage3/case_elements_check.cc
author mjsousa
Sat, 07 May 2016 21:17:49 +0100
changeset 1010 242907849850
parent 1000 556b74055518
child 1041 56ebe2a31b5b
permissions -rw-r--r--
Correctly identify errors when parsing erroneous code (make sure flex goes back to INITIAL state when code contains errors that do not allow determining whether ST or IL is being parsed)
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++)
556b74055518 Add check for repeated elements in a CASE statement. Emit warnings (and not errors) if found.
mjsousa
parents:
diff changeset
   245
    case_elements_list.push_back(symbol->elements[i]);
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