Merge
authorMario de Sousa <msousa@fe.up.pt>
Thu, 04 Oct 2012 15:10:45 +0100
changeset 667 bd1360f29f15
parent 666 8ba9ec4bae50 (diff)
parent 633 73b56dc69e61 (current diff)
child 668 90b6eb7f1775
Merge
absyntax_utils/search_base_type.cc
configure
stage1_2/iec_bison.yy
stage3/array_range_check.cc
stage3/constant_folding.cc
stage3/constant_folding.hh
stage4/generate_c/generate_c.cc
stage4/generate_c/generate_c_il.cc
stage4/generate_c/generate_c_inlinefcall.cc
stage4/generate_c/generate_c_st.cc
stage4/generate_c/generate_var_list.cc
--- a/Makefile.in	Thu Sep 13 16:35:10 2012 +0200
+++ b/Makefile.in	Thu Oct 04 15:10:45 2012 +0100
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -91,9 +91,11 @@
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
 am__remove_distdir = \
-  { test ! -d "$(distdir)" \
-    || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
-         && rm -fr "$(distdir)"; }; }
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
 am__relativize = \
   dir0=`pwd`; \
   sed_first='s,^\([^/]*\)/.*$$,\1,'; \
@@ -122,6 +124,8 @@
 DIST_ARCHIVES = $(distdir).tar.gz
 GZIP_ENV = --best
 distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
 distcleancheck_listfiles = find . -type f -print
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
@@ -243,7 +247,7 @@
 
 .SUFFIXES:
 .SUFFIXES: .cc .o .obj
-am--refresh:
+am--refresh: Makefile
 	@:
 $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am $(srcdir)/common.mk $(am__configure_deps)
 	@for dep in $?; do \
@@ -268,6 +272,7 @@
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
 	esac;
+$(srcdir)/common.mk:
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	$(SHELL) ./config.status --recheck
@@ -279,10 +284,8 @@
 $(am__aclocal_m4_deps):
 
 config/config.h: config/stamp-h1
-	@if test ! -f $@; then \
-	  rm -f config/stamp-h1; \
-	  $(MAKE) $(AM_MAKEFLAGS) config/stamp-h1; \
-	else :; fi
+	@if test ! -f $@; then rm -f config/stamp-h1; else :; fi
+	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) config/stamp-h1; else :; fi
 
 config/stamp-h1: $(top_srcdir)/config/config.h.in $(top_builddir)/config.status
 	@rm -f config/stamp-h1
@@ -331,10 +334,10 @@
 
 clean-binPROGRAMS:
 	-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-iec2c$(EXEEXT): $(iec2c_OBJECTS) $(iec2c_DEPENDENCIES) 
+iec2c$(EXEEXT): $(iec2c_OBJECTS) $(iec2c_DEPENDENCIES) $(EXTRA_iec2c_DEPENDENCIES) 
 	@rm -f iec2c$(EXEEXT)
 	$(CXXLINK) $(iec2c_OBJECTS) $(iec2c_LDADD) $(LIBS)
-iec2iec$(EXEEXT): $(iec2iec_OBJECTS) $(iec2iec_DEPENDENCIES) 
+iec2iec$(EXEEXT): $(iec2iec_OBJECTS) $(iec2iec_DEPENDENCIES) $(EXTRA_iec2iec_DEPENDENCIES) 
 	@rm -f iec2iec$(EXEEXT)
 	$(CXXLINK) $(iec2iec_OBJECTS) $(iec2iec_LDADD) $(LIBS)
 
@@ -567,7 +570,11 @@
 	$(am__remove_distdir)
 
 dist-bzip2: distdir
-	tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+	tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+	$(am__remove_distdir)
+
+dist-lzip: distdir
+	tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
 	$(am__remove_distdir)
 
 dist-lzma: distdir
@@ -575,7 +582,7 @@
 	$(am__remove_distdir)
 
 dist-xz: distdir
-	tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
 	$(am__remove_distdir)
 
 dist-tarZ: distdir
@@ -606,6 +613,8 @@
 	  bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
 	*.tar.lzma*) \
 	  lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
+	*.tar.lz*) \
+	  lzip -dc $(distdir).tar.lz | $(am__untar) ;;\
 	*.tar.xz*) \
 	  xz -dc $(distdir).tar.xz | $(am__untar) ;;\
 	*.tar.Z*) \
@@ -625,6 +634,7 @@
 	  && am__cwd=`pwd` \
 	  && $(am__cd) $(distdir)/_build \
 	  && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+	    $(AM_DISTCHECK_CONFIGURE_FLAGS) \
 	    $(DISTCHECK_CONFIGURE_FLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) \
 	  && $(MAKE) $(AM_MAKEFLAGS) dvi \
@@ -653,8 +663,16 @@
 	  list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
 	  sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
 distuninstallcheck:
-	@$(am__cd) '$(distuninstallcheck_dir)' \
-	&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+	@test -n '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: trying to run $@ with an empty' \
+	       '$$(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	$(am__cd) '$(distuninstallcheck_dir)' || { \
+	  echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+	  exit 1; \
+	}; \
+	test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
 	   || { echo "ERROR: files left after uninstall:" ; \
 	        if test -n "$(DESTDIR)"; then \
 	          echo "  (check DESTDIR support)"; \
@@ -688,10 +706,15 @@
 
 installcheck: installcheck-recursive
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
@@ -781,11 +804,11 @@
 .PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
 	all all-am am--refresh check check-am clean clean-binPROGRAMS \
 	clean-generic ctags ctags-recursive dist dist-all dist-bzip2 \
-	dist-gzip dist-lzma dist-shar dist-tarZ dist-xz dist-zip \
-	distcheck distclean distclean-compile distclean-generic \
-	distclean-hdr distclean-tags distcleancheck distdir \
-	distuninstallcheck dvi dvi-am html html-am info info-am \
-	install install-am install-binPROGRAMS install-data \
+	dist-gzip dist-lzip dist-lzma dist-shar dist-tarZ dist-xz \
+	dist-zip distcheck distclean distclean-compile \
+	distclean-generic distclean-hdr distclean-tags distcleancheck \
+	distdir distuninstallcheck dvi dvi-am html html-am info \
+	info-am install install-am install-binPROGRAMS install-data \
 	install-data-am install-dvi install-dvi-am install-exec \
 	install-exec-am install-html install-html-am install-info \
 	install-info-am install-man install-pdf install-pdf-am \
--- a/absyntax/Makefile.in	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax/Makefile.in	Thu Oct 04 15:10:45 2012 +0100
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -64,6 +64,12 @@
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LIBRARIES = $(lib_LIBRARIES)
 AR = ar
@@ -214,6 +220,7 @@
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
+$(srcdir)/../common.mk:
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -249,13 +256,11 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(libdir)' && rm -f "$$files" )"; \
-	cd "$(DESTDIR)$(libdir)" && rm -f $$files
+	dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir)
 
 clean-libLIBRARIES:
 	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
-libabsyntax.a: $(libabsyntax_a_OBJECTS) $(libabsyntax_a_DEPENDENCIES) 
+libabsyntax.a: $(libabsyntax_a_OBJECTS) $(libabsyntax_a_DEPENDENCIES) $(EXTRA_libabsyntax_a_DEPENDENCIES) 
 	-rm -f libabsyntax.a
 	$(libabsyntax_a_AR) libabsyntax.a $(libabsyntax_a_OBJECTS) $(libabsyntax_a_LIBADD)
 	$(RANLIB) libabsyntax.a
@@ -382,10 +387,15 @@
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
--- a/absyntax/absyntax.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax/absyntax.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -76,36 +76,39 @@
 
 
 
-
+# define LIST_CAP_INIT 8
+# define LIST_CAP_INCR 8
 
 list_c::list_c(
                int fl, int fc, const char *ffile, long int forder,
                int ll, int lc, const char *lfile, long int lorder)
-  :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder) {
+  :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder),c(LIST_CAP_INIT) {
   n = 0;
-  elements = NULL;
-}
+  elements = (symbol_c**)malloc(LIST_CAP_INIT*sizeof(symbol_c*));
+  if (NULL == elements) ERROR_MSG("out of memory");
+}
+
 
 list_c::list_c(symbol_c *elem, 
                int fl, int fc, const char *ffile, long int forder,
                int ll, int lc, const char *lfile, long int lorder)
-  :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder) {
+  :symbol_c(fl, fc, ffile, forder, ll, lc, lfile, lorder),c(LIST_CAP_INIT) { 
   n = 0;
-  elements = NULL;
-  add_element(elem);
-}
+  elements = (symbol_c**)malloc(LIST_CAP_INIT*sizeof(symbol_c*));
+  if (NULL == elements) ERROR_MSG("out of memory");
+  add_element(elem); 
+}
+
 
 /* append a new element to the end of the list */
 void list_c::add_element(symbol_c *elem) {
-//printf("list_c::add_element()\n");
-  n++;
-  elements = (symbol_c **)realloc(elements, n * sizeof(symbol_c *));
-  if (elements == NULL)
-    ERROR_MSG("Out of memory");
-  elements[n - 1] = elem;
+  // printf("list_c::add_element()\n");
+  if (c <= n)
+    if (!(elements=(symbol_c**)realloc(elements,(c+=LIST_CAP_INCR)*sizeof(symbol_c *))))
+      ERROR_MSG("out of memory");
+  elements[n++] = elem;
  
-  if (elem == NULL)
-    return;
+  if (NULL == elem) return;
 
   /* adjust the location parameters, taking into account the new element. */
   if ((first_line == elem->first_line) &&
@@ -130,26 +133,28 @@
 /* To insert into the begining of list, call with pos=0  */
 /* To insert into the end of list, call with pos=list->n */
 void list_c::insert_element(symbol_c *elem, int pos) {
-  if (pos > n) ERROR;
+  if((pos<0) || (n<pos)) ERROR;
   
   /* add new element to end of list. Basically alocate required memory... */
   /* will also increment n by 1 ! */
   add_element(elem);
   /* if not inserting into end position, shift all elements up one position, to open up a slot in pos for new element */
-  if (pos < (n-1)) for (int i = n-2; i >= pos; i--) elements[i+1] = elements[i];
-  elements[pos] = elem;
+  if(pos < (n-1)){ 
+    for(int i=n-2 ; i>=pos ; --i) elements[i+1] = elements[i];
+    elements[pos] = elem;
+  }
 }
 
 
 /* remove element at position pos. */
 void list_c::remove_element(int pos) {
-  if (pos > n) ERROR;
+  if((pos<0) || (n<=pos)) ERROR;
   
   /* Shift all elements down one position, starting at the entry to delete. */
   for (int i = pos; i < n-1; i++) elements[i] = elements[i+1];
-  /* corrent the new size, and free unused memory */
+  /* corrent the new size */
   n--;
-  elements = (symbol_c **)realloc(elements, n * sizeof(symbol_c *));
+  /* elements = (symbol_c **)realloc(elements, n * sizeof(symbol_c *)); */
 }
 
 #define SYM_LIST(class_name_c, ...)								\
--- a/absyntax/absyntax.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax/absyntax.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -80,6 +80,9 @@
 class symbol_c {
 
   public:
+    /* WARNING: only use this method for debugging purposes!! */
+    virtual const char *absyntax_cname(void) {return "symbol_c";};
+
     /*
      * Line number for the purposes of error checking.
      * Annotated (inserted) by stage1_2
@@ -152,6 +155,9 @@
 
 class token_c: public symbol_c {
   public:
+    /* WARNING: only use this method for debugging purposes!! */
+    virtual const char *absyntax_cname(void) {return "token_c";};
+
     /* the value of the symbol. */
     const char *value;
 
@@ -166,7 +172,10 @@
  /* a list of symbols... */
 class list_c: public symbol_c {
   public:
-    int n;
+    /* WARNING: only use this method for debugging purposes!! */
+    virtual const char *absyntax_cname(void) {return "list_c";};
+
+    int c,n; /* c: current capacity of list (malloc'd memory);  n: current number of elements in list */
     symbol_c **elements;
 
   public:
@@ -203,6 +212,8 @@
                  int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0,			\
                  int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0);			\
     virtual void *accept(visitor_c &visitor);										\
+    /* WARNING: only use this method for debugging purposes!! */							\
+    virtual const char *absyntax_cname(void) {return #class_name_c;};							\
 };
 
 
@@ -215,6 +226,8 @@
                  int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0,			\
                  int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0);			\
     virtual void *accept(visitor_c &visitor);										\
+    /* WARNING: only use this method for debugging purposes!! */							\
+    virtual const char *absyntax_cname(void) {return #class_name_c;};							\
 };
 
 
@@ -227,6 +240,8 @@
                  int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0,			\
                  int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0);			\
     virtual void *accept(visitor_c &visitor);										\
+    /* WARNING: only use this method for debugging purposes!! */							\
+    virtual const char *absyntax_cname(void) {return #class_name_c;};							\
 };
 
 
@@ -240,6 +255,8 @@
                  int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0,			\
                  int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0);			\
     virtual void *accept(visitor_c &visitor);										\
+    /* WARNING: only use this method for debugging purposes!! */							\
+    virtual const char *absyntax_cname(void) {return #class_name_c;};							\
 };
 
 
@@ -255,6 +272,8 @@
                  int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0,			\
                  int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0);			\
     virtual void *accept(visitor_c &visitor);										\
+    /* WARNING: only use this method for debugging purposes!! */							\
+    virtual const char *absyntax_cname(void) {return #class_name_c;};							\
 };
 
 
@@ -272,6 +291,8 @@
                  int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0,			\
                  int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0);			\
     virtual void *accept(visitor_c &visitor);										\
+    /* WARNING: only use this method for debugging purposes!! */							\
+    virtual const char *absyntax_cname(void) {return #class_name_c;};							\
 };
 
 
@@ -291,6 +312,8 @@
                  int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0,			\
                  int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0);			\
     virtual void *accept(visitor_c &visitor);										\
+    /* WARNING: only use this method for debugging purposes!! */							\
+    virtual const char *absyntax_cname(void) {return #class_name_c;};							\
 };
 
 
@@ -312,6 +335,8 @@
                  int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0,			\
                  int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0);			\
     virtual void *accept(visitor_c &visitor);										\
+    /* WARNING: only use this method for debugging purposes!! */							\
+    virtual const char *absyntax_cname(void) {return #class_name_c;};							\
 };
 
 
@@ -335,6 +360,8 @@
                  int fl = 0, int fc = 0, const char *ffile = NULL /* filename */, long int forder=0,			\
                  int ll = 0, int lc = 0, const char *lfile = NULL /* filename */, long int lorder=0);			\
     virtual void *accept(visitor_c &visitor);										\
+    /* WARNING: only use this method for debugging purposes!! */							\
+    virtual const char *absyntax_cname(void) {return #class_name_c;};							\
 };
 
 
--- a/absyntax_utils/Makefile.am	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax_utils/Makefile.am	Thu Oct 04 15:10:45 2012 +0100
@@ -26,8 +26,5 @@
 	search_varfb_instance_type.cc \
 	search_var_instance_decl.cc \
 	spec_init_separator.cc \
-	type_initial_value.cc 
-
-#search_il_operand_type.cc 
-#search_type_code.c
-
+	type_initial_value.cc \
+	get_datatype_info.cc
--- a/absyntax_utils/Makefile.in	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax_utils/Makefile.in	Thu Oct 04 15:10:45 2012 +0100
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -64,6 +64,12 @@
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LIBRARIES = $(lib_LIBRARIES)
 AR = ar
@@ -88,7 +94,9 @@
 	spec_init_separator.$(OBJEXT) type_initial_value.$(OBJEXT) \
 	search_varfb_instance_type.$(OBJEXT) \
 	search_var_instance_decl.$(OBJEXT) \
-	spec_init_separator.$(OBJEXT) type_initial_value.$(OBJEXT)
+	spec_init_separator.$(OBJEXT) type_initial_value.$(OBJEXT) \
+	get_datatype_info.$(OBJEXT)
+
 libabsyntax_utils_a_OBJECTS = $(am_libabsyntax_utils_a_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
@@ -227,7 +235,9 @@
 	search_varfb_instance_type.cc \
 	search_var_instance_decl.cc \
 	spec_init_separator.cc \
-	type_initial_value.cc 
+	type_initial_value.cc \
+	get_datatype_info.cc
+
 
 all: all-am
 
@@ -254,6 +264,7 @@
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
+$(srcdir)/../common.mk:
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -289,13 +300,11 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(libdir)' && rm -f "$$files" )"; \
-	cd "$(DESTDIR)$(libdir)" && rm -f $$files
+	dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir)
 
 clean-libLIBRARIES:
 	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
-libabsyntax_utils.a: $(libabsyntax_utils_a_OBJECTS) $(libabsyntax_utils_a_DEPENDENCIES) 
+libabsyntax_utils.a: $(libabsyntax_utils_a_OBJECTS) $(libabsyntax_utils_a_DEPENDENCIES) $(EXTRA_libabsyntax_utils_a_DEPENDENCIES) 
 	-rm -f libabsyntax_utils.a
 	$(libabsyntax_utils_a_AR) libabsyntax_utils.a $(libabsyntax_utils_a_OBJECTS) $(libabsyntax_utils_a_LIBADD)
 	$(RANLIB) libabsyntax_utils.a
@@ -314,6 +323,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/function_call_iterator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/function_call_param_iterator.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/function_param_iterator.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_datatype_info.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_sizeof_datatype.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/get_var_name.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/search_base_type.Po@am__quote@
@@ -440,10 +450,15 @@
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
@@ -540,9 +555,6 @@
 	uninstall-am uninstall-libLIBRARIES
 
 
-#search_il_operand_type.cc 
-#search_type_code.c
-
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
--- a/absyntax_utils/absyntax_utils.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax_utils/absyntax_utils.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -118,6 +118,7 @@
 #include "get_sizeof_datatype.hh"
 #include "search_il_label.hh"
 #include "get_var_name.hh"
+#include "get_datatype_info.hh"
 
 /***********************************************************************/
 /***********************************************************************/
--- a/absyntax_utils/case_element_iterator.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax_utils/case_element_iterator.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -55,7 +55,7 @@
      */
     typedef enum {
       element_single,
-      element_subrange,
+      element_subrange
     } case_element_t ;
 
 
--- a/absyntax_utils/function_param_iterator.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax_utils/function_param_iterator.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -442,7 +442,6 @@
 //SYM_REF2(array_var_init_decl_c, var1_list, array_spec_init)
 void *function_param_iterator_c::visit(array_var_init_decl_c *symbol) {
   TRACE("array_var_init_decl_c");
-
   current_param_default_value = spec_init_sperator_c::get_init(symbol->array_spec_init);
   current_param_type = spec_init_sperator_c::get_spec(symbol->array_spec_init);
 
@@ -460,6 +459,26 @@
   return symbol->var1_list->accept(*this);
 }
 
+
+
+
+/* fb_name_list ':' function_block_type_name ASSIGN structure_initialization */
+/* structure_initialization -> may be NULL ! */
+// SYM_REF3(fb_name_decl_c, fb_name_list, function_block_type_name, structure_initialization)
+void *function_param_iterator_c::visit(fb_name_decl_c *symbol) {
+  TRACE("structured_var_init_decl_c");
+  current_param_default_value = symbol->structure_initialization ; 
+  current_param_type          = symbol->function_block_type_name ;
+
+  return symbol->fb_name_list->accept(*this);
+}
+
+
+/* fb_name_list ',' fb_name */
+// SYM_LIST(fb_name_list_c)
+void *function_param_iterator_c::visit(fb_name_list_c *symbol) {TRACE("fb_name_list_c"); return handle_param_list(symbol);}
+
+
 void *function_param_iterator_c::visit(output_declarations_c *symbol) {
   TRACE("output_declarations_c");
   current_param_direction = direction_out;
@@ -496,22 +515,18 @@
 /*  var1_list ':' array_specification */
 //SYM_REF2(array_var_declaration_c, var1_list, array_specification)
 void *function_param_iterator_c::visit(array_var_declaration_c *symbol) {
-	TRACE("array_var_declaration_c");
-
-	current_param_default_value = NULL;
-	current_param_type = symbol->array_specification;
-
-	return symbol->var1_list->accept(*this);
+  TRACE("array_var_declaration_c");
+  current_param_default_value = NULL;
+  current_param_type = symbol->array_specification;
+  return symbol->var1_list->accept(*this);
 }
 
 /*  var1_list ':' structure_type_name */
 //SYM_REF2(structured_var_declaration_c, var1_list, structure_type_name)
 void *function_param_iterator_c::visit(structured_var_declaration_c *symbol) {
   TRACE("structured_var_declaration_c");
-
   current_param_default_value = NULL;
   current_param_type = symbol->structure_type_name;
-
   return symbol->var1_list->accept(*this);
 }
 
--- a/absyntax_utils/function_param_iterator.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax_utils/function_param_iterator.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -193,15 +193,15 @@
     //SYM_REF2(structured_var_init_decl_c, var1_list, initialized_structure)
     void *visit(structured_var_init_decl_c *symbol);
     
-#if 0
-/* name_list ':' function_block_type_name ASSIGN structure_initialization */
-/* structure_initialization -> may be NULL ! */
-SYM_REF4(fb_name_decl_c, fb_name_list, function_block_type_name, structure_initialization, unused)
-
-/* name_list ',' fb_name */
-SYM_LIST(fb_name_list_c)
-#endif
-
+    /* name_list ':' function_block_type_name ASSIGN structure_initialization */
+    /* structure_initialization -> may be NULL ! */
+    // SYM_REF4(fb_name_decl_c, fb_name_list, function_block_type_name, structure_initialization, unused)
+    void *visit(fb_name_decl_c *symbol);
+
+    /* name_list ',' fb_name */
+    // SYM_LIST(fb_name_list_c)
+    void *visit(fb_name_list_c *symbol);
+    
     void *visit(output_declarations_c *symbol);
     void *visit(eno_param_declaration_c *symbol);
     void *visit(input_output_declarations_c *symbol);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/absyntax_utils/get_datatype_info.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -0,0 +1,583 @@
+/*
+ *  matiec - a compiler for the programming languages defined in IEC 61131-3
+ *
+ *  Copyright (C) 2003-2012  Mario de Sousa (msousa@fe.up.pt)
+ *  Copyright (C) 2007-2011  Laurent Bessard and Edouard Tisserant
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+/*
+ * An IEC 61131-3 compiler.
+ *
+ * Based on the
+ * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
+ *
+ */
+
+/* Determine the characteristics of a specific data type
+ *  e.g., is it an enumeration, is it an array, is it ANY_INT, etc...
+ *
+ * The methods of this class may be passed either:
+ *  - a data type declaration symbol_c, 
+ *   OR
+ *  - the name of a data type (identifier_c)
+ *    In this case, we shall first serach for the basetype declaration using search_base_type_c, and then 
+ *    run the normal process.
+ */
+#include "absyntax_utils.hh"
+
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
+
+
+
+#include <typeinfo>  // required for typeid
+
+
+
+
+
+
+static search_base_type_c search_base_type;
+
+
+
+
+bool get_datatype_info_c::is_sfc_initstep(symbol_c *type_symbol) {
+  symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); 
+  if (typeid(*type_decl) == typeid(initial_step_c))                  {return true;}   /* INITIAL_STEP step_name ':' action_association_list END_STEP */  /* A pseudo data type! */
+  return false;
+}
+
+
+
+
+
+bool get_datatype_info_c::is_sfc_step(symbol_c *type_symbol) {
+  symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); 
+  if (typeid(*type_decl) == typeid(initial_step_c))                  {return true;}   /* INITIAL_STEP step_name ':' action_association_list END_STEP */  /* A pseudo data type! */
+  if (typeid(*type_decl) == typeid(        step_c))                  {return true;}   /*         STEP step_name ':' action_association_list END_STEP */  /* A pseudo data type! */
+  return false;
+}
+
+
+
+
+bool get_datatype_info_c::is_function_block(symbol_c *type_symbol) {
+  symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); 
+  if (typeid(*type_decl) == typeid(function_block_declaration_c))    {return true;}   /*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
+  return false;
+}
+
+
+
+
+
+bool get_datatype_info_c::is_subrange(symbol_c *type_symbol) {
+  symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol); /* NOTE: will work correctly once we update the way search_base_type_c works, by adding a new search_effective_type:c */
+  
+  if (typeid(*type_decl) == typeid(subrange_type_declaration_c))     {return true;}   /*  subrange_type_name ':' subrange_spec_init */
+  if (typeid(*type_decl) == typeid(subrange_spec_init_c))            {return true;}   /* subrange_specification ASSIGN signed_integer */
+  if (typeid(*type_decl) == typeid(subrange_specification_c))        {return true;}   /*  integer_type_name '(' subrange')' */
+    
+  if (typeid(*type_decl) == typeid(subrange_c))                      {ERROR;}         /*  signed_integer DOTDOT signed_integer */
+  return false;
+}
+
+
+
+
+
+bool get_datatype_info_c::is_enumerated(symbol_c *type_symbol) {
+  symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol);
+  
+  if (typeid(*type_decl) == typeid(enumerated_type_declaration_c))   {return true;}   /*  enumerated_type_name ':' enumerated_spec_init */
+  if (typeid(*type_decl) == typeid(enumerated_spec_init_c))          {return true;}   /* enumerated_specification ASSIGN enumerated_value */
+  if (typeid(*type_decl) == typeid(enumerated_value_list_c))         {return true;}   /* enumerated_value_list ',' enumerated_value */        /* once we change the way we handle enums, this will probably become an ERROR! */
+  
+  if (typeid(*type_decl) == typeid(enumerated_value_c))              {ERROR;}         /* enumerated_type_name '#' identifier */
+  return false;
+}
+
+
+
+
+
+bool get_datatype_info_c::is_array(symbol_c *type_symbol) {
+  symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol);
+  
+  if (typeid(*type_decl) == typeid(array_type_declaration_c))        {return true;}   /*  identifier ':' array_spec_init */
+  if (typeid(*type_decl) == typeid(array_spec_init_c))               {return true;}   /* array_specification [ASSIGN array_initialization} */
+  if (typeid(*type_decl) == typeid(array_specification_c))           {return true;}   /* ARRAY '[' array_subrange_list ']' OF non_generic_type_name */
+  
+  if (typeid(*type_decl) == typeid(array_subrange_list_c))           {ERROR;}         /* array_subrange_list ',' subrange */
+  if (typeid(*type_decl) == typeid(array_initial_elements_list_c))   {ERROR;}         /* array_initialization:  '[' array_initial_elements_list ']' */  /* array_initial_elements_list ',' array_initial_elements */
+  if (typeid(*type_decl) == typeid(array_initial_elements_c))        {ERROR;}         /* integer '(' [array_initial_element] ')' */
+  return false;
+}
+
+
+
+
+
+bool get_datatype_info_c::is_structure(symbol_c *type_symbol) {
+  symbol_c *type_decl = search_base_type.get_basetype_decl(type_symbol);
+  
+  if (typeid(*type_decl) == typeid(structure_type_declaration_c))              {return true;}   /*  structure_type_name ':' structure_specification */
+  if (typeid(*type_decl) == typeid(initialized_structure_c))                   {return true;}   /* structure_type_name ASSIGN structure_initialization */
+  if (typeid(*type_decl) == typeid(structure_element_declaration_list_c))      {return true;}   /* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */ /* structure_element_declaration_list structure_element_declaration ';' */
+  
+  if (typeid(*type_decl) == typeid(structure_element_declaration_c))           {ERROR;}         /*  structure_element_name ':' *_spec_init */
+  if (typeid(*type_decl) == typeid(structure_element_initialization_list_c))   {ERROR;}         /* structure_initialization: '(' structure_element_initialization_list ')' */  /* structure_element_initialization_list ',' structure_element_initialization */
+  if (typeid(*type_decl) == typeid(structure_element_initialization_c))        {ERROR;}         /*  structure_element_name ASSIGN value */
+  return false;
+}
+
+
+
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_ELEMENTARY(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_MAGNITUDE(type_symbol))                           {return true;}
+  if (is_ANY_BIT      (type_symbol))                           {return true;}
+  if (is_ANY_STRING   (type_symbol))                           {return true;}
+  if (is_ANY_DATE     (type_symbol))                           {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_SAFEELEMENTARY(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_SAFEMAGNITUDE(type_symbol))                       {return true;}
+  if (is_ANY_SAFEBIT      (type_symbol))                       {return true;}
+  if (is_ANY_SAFESTRING   (type_symbol))                       {return true;}
+  if (is_ANY_SAFEDATE     (type_symbol))                       {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_ELEMENTARY_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_ELEMENTARY    (type_symbol))                      {return true;}
+  if (is_ANY_SAFEELEMENTARY(type_symbol))                      {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_MAGNITUDE(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(time_type_name_c))        {return true;}
+  if (is_ANY_NUM(type_symbol))                                 {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_SAFEMAGNITUDE(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(safetime_type_name_c))    {return true;}
+  if (is_ANY_SAFENUM(type_symbol))                             {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_MAGNITUDE_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_MAGNITUDE    (type_symbol))                       {return true;}
+  if (is_ANY_SAFEMAGNITUDE(type_symbol))                       {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_signed_MAGNITUDE(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(time_type_name_c))        {return true;}
+  if (is_ANY_signed_NUM(type_symbol))                          {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_signed_SAFEMAGNITUDE(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(safetime_type_name_c))    {return true;}
+  return is_ANY_signed_SAFENUM(type_symbol);
+}
+
+
+bool get_datatype_info_c::is_ANY_signed_MAGNITUDE_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_signed_MAGNITUDE    (type_symbol))                {return true;}
+  if (is_ANY_signed_SAFEMAGNITUDE(type_symbol))                {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_NUM(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_REAL(type_symbol))                                {return true;}
+  if (is_ANY_INT (type_symbol))                                {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_SAFENUM(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_SAFEREAL(type_symbol))                            {return true;}
+  if (is_ANY_SAFEINT (type_symbol))                            {return true;}
+}
+
+
+bool get_datatype_info_c::is_ANY_NUM_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_NUM    (type_symbol))                             {return true;}
+  if (is_ANY_SAFENUM(type_symbol))                             {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_signed_NUM(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_REAL      (type_symbol))                          {return true;}
+  if (is_ANY_signed_INT(type_symbol))                          {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_signed_SAFENUM(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_SAFEREAL      (type_symbol))                      {return true;}
+  if (is_ANY_signed_SAFEINT(type_symbol))                      {return true;}
+}
+
+
+bool get_datatype_info_c::is_ANY_signed_NUM_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_signed_NUM    (type_symbol))                      {return true;}
+  if (is_ANY_signed_SAFENUM(type_symbol))                      {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_DATE(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(date_type_name_c))        {return true;}
+  if (typeid(*type_symbol) == typeid(tod_type_name_c))         {return true;}
+  if (typeid(*type_symbol) == typeid(dt_type_name_c))          {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_SAFEDATE(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(safedate_type_name_c))    {return true;}
+  if (typeid(*type_symbol) == typeid(safetod_type_name_c))     {return true;}
+  if (typeid(*type_symbol) == typeid(safedt_type_name_c))      {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_DATE_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_DATE    (type_symbol))                            {return true;}
+  if (is_ANY_SAFEDATE(type_symbol))                            {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_STRING(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(string_type_name_c))      {return true;}
+  if (typeid(*type_symbol) == typeid(wstring_type_name_c))     {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_SAFESTRING(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(safestring_type_name_c))  {return true;}
+  if (typeid(*type_symbol) == typeid(safewstring_type_name_c)) {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_STRING_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_STRING    (type_symbol))                          {return true;}
+  if (is_ANY_SAFESTRING(type_symbol))                          {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_INT(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_signed_INT  (type_symbol))                        {return true;}
+  if (is_ANY_unsigned_INT(type_symbol))                        {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_SAFEINT(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_signed_SAFEINT  (type_symbol))                    {return true;}
+  if (is_ANY_unsigned_SAFEINT(type_symbol))                    {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_INT_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_INT    (type_symbol))                             {return true;}
+  if (is_ANY_SAFEINT(type_symbol))                             {return true;}
+  return false;
+}
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_signed_INT(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(sint_type_name_c))        {return true;}
+  if (typeid(*type_symbol) == typeid(int_type_name_c))         {return true;}
+  if (typeid(*type_symbol) == typeid(dint_type_name_c))        {return true;}
+  if (typeid(*type_symbol) == typeid(lint_type_name_c))        {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_signed_SAFEINT(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(safesint_type_name_c))    {return true;}
+  if (typeid(*type_symbol) == typeid(safeint_type_name_c))     {return true;}
+  if (typeid(*type_symbol) == typeid(safedint_type_name_c))    {return true;}
+  if (typeid(*type_symbol) == typeid(safelint_type_name_c))    {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_signed_INT_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_signed_INT    (type_symbol))                      {return true;}
+  if (is_ANY_signed_SAFEINT(type_symbol))                      {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_unsigned_INT(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(usint_type_name_c))       {return true;}
+  if (typeid(*type_symbol) == typeid(uint_type_name_c))        {return true;}
+  if (typeid(*type_symbol) == typeid(udint_type_name_c))       {return true;}
+  if (typeid(*type_symbol) == typeid(ulint_type_name_c))       {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_unsigned_SAFEINT(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(safeusint_type_name_c))   {return true;}
+  if (typeid(*type_symbol) == typeid(safeuint_type_name_c))    {return true;}
+  if (typeid(*type_symbol) == typeid(safeudint_type_name_c))   {return true;}
+  if (typeid(*type_symbol) == typeid(safeulint_type_name_c))   {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_unsigned_INT_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_unsigned_INT    (type_symbol))                    {return true;}
+  if (is_ANY_unsigned_SAFEINT(type_symbol))                    {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_REAL(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(real_type_name_c))        {return true;}
+  if (typeid(*type_symbol) == typeid(lreal_type_name_c))       {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_SAFEREAL(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(safereal_type_name_c))    {return true;}
+  if (typeid(*type_symbol) == typeid(safelreal_type_name_c))   {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_REAL_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_REAL    (type_symbol))                            {return true;}
+  if (is_ANY_SAFEREAL(type_symbol))                            {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_nBIT(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(byte_type_name_c))        {return true;}
+  if (typeid(*type_symbol) == typeid(word_type_name_c))        {return true;}
+  if (typeid(*type_symbol) == typeid(dword_type_name_c))       {return true;}
+  if (typeid(*type_symbol) == typeid(lword_type_name_c))       {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_SAFEnBIT(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(safebyte_type_name_c))    {return true;}
+  if (typeid(*type_symbol) == typeid(safeword_type_name_c))    {return true;}
+  if (typeid(*type_symbol) == typeid(safedword_type_name_c))   {return true;}
+  if (typeid(*type_symbol) == typeid(safelword_type_name_c))   {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_nBIT_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_nBIT    (type_symbol))                            {return true;}
+  if (is_ANY_SAFEnBIT(type_symbol))                            {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_BOOL(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(bool_type_name_c))        {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_SAFEBOOL(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (typeid(*type_symbol) == typeid(safebool_type_name_c))    {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_BOOL_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_BOOL    (type_symbol))                                {return true;}
+  if (is_SAFEBOOL(type_symbol))                                {return true;}
+  return false;
+}
+
+
+
+
+
+
+
+
+
+bool get_datatype_info_c::is_ANY_BIT(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_BOOL    (type_symbol))                                {return true;}
+  if (is_ANY_nBIT(type_symbol))                                {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_SAFEBIT(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_SAFEBOOL    (type_symbol))                            {return true;}
+  if (is_ANY_SAFEnBIT(type_symbol))                            {return true;}
+  return false;
+}
+
+
+bool get_datatype_info_c::is_ANY_BIT_compatible(symbol_c *type_symbol) {
+  if (type_symbol == NULL)                                     {return false;}
+  if (is_ANY_BIT    (type_symbol))                             {return true;}
+  if (is_ANY_SAFEBIT(type_symbol))                             {return true;}
+  return false;
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/absyntax_utils/get_datatype_info.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -0,0 +1,126 @@
+/*
+ *  matiec - a compiler for the programming languages defined in IEC 61131-3
+ *
+ *  Copyright (C) 2003-2012  Mario de Sousa (msousa@fe.up.pt)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+/*
+ * An IEC 61131-3 compiler.
+ *
+ * Based on the
+ * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
+ *
+ */
+
+/* Determine the characteristics of a specific data type
+ *  e.g., is it an enumeration, is it an array, is it ANY_INT, etc...
+ *
+ * The methods of this class may be passed either:
+ *  - a data type declaration symbol_c, 
+ *   OR
+ *  - the name of a data type (identifier_c)
+ *    In this case, we shall first serach for the basetype declaration using search_base_type_c, and then 
+ *    run the normal process.
+ */
+#include "absyntax_utils.hh"
+
+#include "../main.hh" // required for ERROR() and ERROR_MSG() macros.
+
+
+
+
+
+
+class get_datatype_info_c { 
+
+
+  private: // this is a purely static class. No need for constructors!
+     get_datatype_info_c(void) {};
+    ~get_datatype_info_c(void) {};
+
+ 
+  public:
+    static bool is_sfc_initstep                    (symbol_c *type_symbol);
+    static bool is_sfc_step                        (symbol_c *type_symbol);
+    static bool is_function_block                  (symbol_c *type_symbol);
+    static bool is_subrange                        (symbol_c *type_symbol);
+    static bool is_enumerated                      (symbol_c *type_symbol);
+    static bool is_array                           (symbol_c *type_symbol);
+    static bool is_structure                       (symbol_c *type_symbol);
+
+  
+  
+    static bool is_ANY_ELEMENTARY                  (symbol_c *type_symbol);
+    static bool is_ANY_SAFEELEMENTARY              (symbol_c *type_symbol);
+    static bool is_ANY_ELEMENTARY_compatible       (symbol_c *type_symbol);
+
+    static bool is_ANY_MAGNITUDE                   (symbol_c *type_symbol);
+    static bool is_ANY_SAFEMAGNITUDE               (symbol_c *type_symbol);
+    static bool is_ANY_MAGNITUDE_compatible        (symbol_c *type_symbol);
+
+    static bool is_ANY_signed_MAGNITUDE            (symbol_c *type_symbol);
+    static bool is_ANY_signed_SAFEMAGNITUDE        (symbol_c *type_symbol);
+    static bool is_ANY_signed_MAGNITUDE_compatible (symbol_c *type_symbol);
+
+    static bool is_ANY_NUM                         (symbol_c *type_symbol);
+    static bool is_ANY_SAFENUM                     (symbol_c *type_symbol);
+    static bool is_ANY_NUM_compatible              (symbol_c *type_symbol);
+
+    static bool is_ANY_signed_NUM                  (symbol_c *type_symbol);
+    static bool is_ANY_signed_SAFENUM              (symbol_c *type_symbol);
+    static bool is_ANY_signed_NUM_compatible       (symbol_c *type_symbol);
+
+    static bool is_ANY_DATE                        (symbol_c *type_symbol);
+    static bool is_ANY_SAFEDATE                    (symbol_c *type_symbol);
+    static bool is_ANY_DATE_compatible             (symbol_c *type_symbol);
+
+    static bool is_ANY_STRING                      (symbol_c *type_symbol);
+    static bool is_ANY_SAFESTRING                  (symbol_c *type_symbol);
+    static bool is_ANY_STRING_compatible           (symbol_c *type_symbol);
+
+    static bool is_ANY_INT                         (symbol_c *type_symbol);
+    static bool is_ANY_SAFEINT                     (symbol_c *type_symbol);
+    static bool is_ANY_INT_compatible              (symbol_c *type_symbol);
+
+    static bool is_ANY_signed_INT                  (symbol_c *type_symbol);
+    static bool is_ANY_signed_SAFEINT              (symbol_c *type_symbol);
+    static bool is_ANY_signed_INT_compatible       (symbol_c *type_symbol);
+
+    static bool is_ANY_unsigned_INT                (symbol_c *type_symbol);
+    static bool is_ANY_unsigned_SAFEINT            (symbol_c *type_symbol);
+    static bool is_ANY_unsigned_INT_compatible     (symbol_c *type_symbol);
+
+    static bool is_ANY_REAL                        (symbol_c *type_symbol);
+    static bool is_ANY_SAFEREAL                    (symbol_c *type_symbol);
+    static bool is_ANY_REAL_compatible             (symbol_c *type_symbol);
+
+    static bool is_ANY_nBIT                        (symbol_c *type_symbol);
+    static bool is_ANY_SAFEnBIT                    (symbol_c *type_symbol);
+    static bool is_ANY_nBIT_compatible             (symbol_c *type_symbol);
+
+    static bool is_BOOL                            (symbol_c *type_symbol);
+    static bool is_SAFEBOOL                        (symbol_c *type_symbol);
+    static bool is_BOOL_compatible                 (symbol_c *type_symbol);
+
+    static bool is_ANY_BIT                         (symbol_c *type_symbol);
+    static bool is_ANY_SAFEBIT                     (symbol_c *type_symbol);
+    static bool is_ANY_BIT_compatible              (symbol_c *type_symbol);
+};
+
--- a/absyntax_utils/search_base_type.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax_utils/search_base_type.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -243,7 +243,10 @@
 
 /* helper symbol for enumerated_specification->enumerated_spec_init */
 /* enumerated_value_list ',' enumerated_value */
-void *search_base_type_c::visit(enumerated_value_list_c *symbol)                        {return (void *)symbol;}
+void *search_base_type_c::visit(enumerated_value_list_c *symbol) {
+  this->is_enumerated = true;
+  return (void *)symbol;
+}
 
 /* enumerated_type_name '#' identifier */
 // SYM_REF2(enumerated_value_c, type, value)
--- a/absyntax_utils/search_expression_type.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/absyntax_utils/search_expression_type.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -78,14 +78,6 @@
     symbol_c* common_type(symbol_c *first_type, symbol_c *second_type);
     symbol_c* default_literal_type(symbol_c *symbol);
 
-    /*
-    #include "search_type_code.c"
-    */
-    void *compute_standard_function_default(function_invocation_c *st_symbol, il_formal_funct_call_c *il_symbol);
-    void *compute_standard_function_il(il_function_call_c *symbol, symbol_c *param_data_type);
-
-
-
     /*static bool_type_name_c bool_type_name;*/
 
     /* A helper function... */
--- a/aclocal.m4	Thu Sep 13 16:35:10 2012 +0200
+++ b/aclocal.m4	Thu Oct 04 15:10:45 2012 +0100
@@ -1,7 +1,8 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.11.3 -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+# 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation,
+# Inc.
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -19,11 +20,14 @@
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically `autoreconf'.])])
 
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 2011 Free Software
+# Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
 
 # AM_AUTOMAKE_VERSION(VERSION)
 # ----------------------------
@@ -34,7 +38,7 @@
 [am__api_version='1.11'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.11.1], [],
+m4_if([$1], [1.11.3], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -50,18 +54,20 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
+[AM_AUTOMAKE_VERSION([1.11.3])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
 
 # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
 # $ac_aux_dir to `$srcdir/foo'.  In other projects, it is set to
@@ -144,14 +150,14 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 10
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009,
+# 2010, 2011 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 12
 
 # There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
 # written in clear, in which case automake, when reading aclocal.m4,
@@ -191,6 +197,7 @@
   # instance it was reported that on HP-UX the gcc test will end up
   # making a dummy file named `D' -- because `-MD' means `put the output
   # in D'.
+  rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
   # using a relative directory.
@@ -255,7 +262,7 @@
 	break
       fi
       ;;
-    msvisualcpp | msvcmsys)
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
       # This compiler won't grok `-c -o', but also, the minuso test has
       # not run yet.  These depmodes are late enough in the game, and
       # so weak that their functioning should not be impacted.
@@ -320,10 +327,13 @@
 if test "x$enable_dependency_tracking" != xno; then
   am_depcomp="$ac_aux_dir/depcomp"
   AMDEPBACKSLASH='\'
+  am__nodep='_no'
 fi
 AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
 AC_SUBST([AMDEPBACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
 ])
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
@@ -545,11 +555,14 @@
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001, 2003, 2005, 2008  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 2001, 2003, 2005, 2008, 2011 Free Software Foundation,
+# Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
 
 # AM_PROG_INSTALL_SH
 # ------------------
@@ -682,11 +695,14 @@
 fi
 ])
 
-# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 2003, 2004, 2005, 2006, 2011 Free Software Foundation,
+# Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
 
 # AM_PROG_MKDIR_P
 # ---------------
@@ -710,13 +726,14 @@
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001, 2002, 2003, 2005, 2008  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
+# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 Free Software
+# Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
 
 # _AM_MANGLE_OPTION(NAME)
 # -----------------------
@@ -724,13 +741,13 @@
 [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
 
 # _AM_SET_OPTION(NAME)
-# ------------------------------
+# --------------------
 # Set option NAME.  Presently that only means defining a flag for this option.
 AC_DEFUN([_AM_SET_OPTION],
 [m4_define(_AM_MANGLE_OPTION([$1]), 1)])
 
 # _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
+# ------------------------
 # OPTIONS is a space-separated list of Automake options.
 AC_DEFUN([_AM_SET_OPTIONS],
 [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
@@ -806,11 +823,13 @@
 fi
 AC_MSG_RESULT(yes)])
 
-# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
+# Copyright (C) 2001, 2003, 2005, 2011 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 1
 
 # AM_PROG_INSTALL_STRIP
 # ---------------------
@@ -834,13 +853,13 @@
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006, 2008  Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
+# Copyright (C) 2006, 2008, 2010 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 3
 
 # _AM_SUBST_NOTMAKE(VARIABLE)
 # ---------------------------
@@ -849,13 +868,13 @@
 AC_DEFUN([_AM_SUBST_NOTMAKE])
 
 # AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
+# --------------------------
 # Public sister of _AM_SUBST_NOTMAKE.
 AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -877,10 +896,11 @@
 # a tarball read from stdin.
 #     $(am__untar) < result.tar
 AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
+[# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AC_SUBST([AMTAR], ['$${TAR-tar}'])
 m4_if([$1], [v7],
-     [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'],
      [m4_case([$1], [ustar],, [pax],,
               [m4_fatal([Unknown tar format])])
 AC_MSG_CHECKING([how to create a $1 tar archive])
--- a/configure	Thu Sep 13 16:35:10 2012 +0200
+++ b/configure	Thu Oct 04 15:10:45 2012 +0100
@@ -622,6 +622,7 @@
 am__fastdepCC_FALSE
 am__fastdepCC_TRUE
 CCDEPMODE
+am__nodep
 AMDEPBACKSLASH
 AMDEP_FALSE
 AMDEP_TRUE
@@ -2861,11 +2862,11 @@
 
 # We need awk for the "check" target.  The system "awk" is bad on
 # some platforms.
-# Always define AMTAR for backward compatibility.
-
-AMTAR=${AMTAR-"${am_missing_run}tar"}
-
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+# Always define AMTAR for backward compatibility.  Yes, it's still used
+# in the wild :-(  We should find a proper way to deprecate it ...
+AMTAR='$${TAR-tar}'
+
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
 
 
 
@@ -2977,6 +2978,7 @@
 if test "x$enable_dependency_tracking" != xno; then
   am_depcomp="$ac_aux_dir/depcomp"
   AMDEPBACKSLASH='\'
+  am__nodep='_no'
 fi
  if test "x$enable_dependency_tracking" != xno; then
   AMDEP_TRUE=
@@ -3790,6 +3792,7 @@
   # instance it was reported that on HP-UX the gcc test will end up
   # making a dummy file named `D' -- because `-MD' means `put the output
   # in D'.
+  rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
   # using a relative directory.
@@ -3849,7 +3852,7 @@
 	break
       fi
       ;;
-    msvisualcpp | msvcmsys)
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
       # This compiler won't grok `-c -o', but also, the minuso test has
       # not run yet.  These depmodes are late enough in the game, and
       # so weak that their functioning should not be impacted.
@@ -4333,6 +4336,7 @@
   # instance it was reported that on HP-UX the gcc test will end up
   # making a dummy file named `D' -- because `-MD' means `put the output
   # in D'.
+  rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
   # using a relative directory.
@@ -4392,7 +4396,7 @@
 	break
       fi
       ;;
-    msvisualcpp | msvcmsys)
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
       # This compiler won't grok `-c -o', but also, the minuso test has
       # not run yet.  These depmodes are late enough in the game, and
       # so weak that their functioning should not be impacted.
@@ -4626,7 +4630,8 @@
 
 
 # Check bison version, we need a version great or equal than 2.4 to build matiec.
-[[ $(bison --version) =~ ([0-9][.][0-9]*) ]] && version_bison="${BASH_REMATCH[1]}"
+version_bison="$(bison --version | sed q | cut -d' ' -f4)"
+version_bison=${version_bison:0:3}
 
 if awk -v ver="$version_bison" 'BEGIN { if (ver < 2.4) exit 1; }'; then :
   have_bison_correct=yes
--- a/configure.ac	Thu Sep 13 16:35:10 2012 +0200
+++ b/configure.ac	Thu Oct 04 15:10:45 2012 +0100
@@ -28,7 +28,8 @@
 AC_PROG_AWK
 
 # Check bison version, we need a version great or equal than 2.4 to build matiec.
-[[[ $(bison --version) =~ ([0-9][.][0-9]*) ]]] && version_bison="${BASH_REMATCH[[1]]}"
+version_bison="$(bison --version | sed q | cut -d' ' -f4)"
+version_bison=${version_bison:0:3}
 
 AS_IF([awk -v ver="$version_bison" 'BEGIN { if (ver < 2.4) exit 1; }'],
 	[have_bison_correct=yes], [have_bison_correct=no])
--- a/main.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/main.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -40,16 +40,13 @@
 #include <stddef.h>  /* required for NULL */
  
 #define ERROR               error_exit(__FILE__,__LINE__)
-#define ERROR_MSG(msg, ...) error_exit(__FILE__,__LINE__, msg)
-// #define ERROR_MSG(msg, ...) error_exit(__FILE__,__LINE__, msg, __VA_ARGS__)
+#define ERROR_MSG(msg, ...) error_exit(__FILE__,__LINE__, msg, ## __VA_ARGS__)
 
 extern void error_exit(const char *file_name, int line_no, const char *errmsg = NULL, ...);
 
 
 
 
-
-
  /* Get the definition of INT16_MAX, INT16_MIN, UINT64_MAX, INT64_MAX, INT64_MIN, ... */
 
 #define __STDC_LIMIT_MACROS /* required to have UINTxx_MAX defined when including stdint.h from C++ source code. */
@@ -122,6 +119,13 @@
 
 
 
+/* get the printf format macros for printing variables of fixed data size
+ * e.g.  int64_t v; printf("value=%"PRId64" !!\n", v);
+ * e.g. uint64_t v; printf("value=%"PRIu64" !!\n", v);
+ * e.g. uint64_t v; printf("value=%"PRIx64" !!\n", v);  // hexadecimal format
+ */
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
 
 
-#endif // #ifndef _MAIN_HH
\ No newline at end of file
+#endif // #ifndef _MAIN_HH
--- a/stage1_2/Makefile.in	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage1_2/Makefile.in	Thu Oct 04 15:10:45 2012 +0100
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -64,6 +64,12 @@
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LIBRARIES = $(lib_LIBRARIES)
 AR = ar
@@ -83,9 +89,9 @@
 CXXLD = $(CXX)
 CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
 	-o $@
-LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS)
+LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS)
 YLWRAP = $(top_srcdir)/config/ylwrap
-YACCCOMPILE = $(YACC) $(YFLAGS) $(AM_YFLAGS)
+YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS)
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
 CCLD = $(CC)
@@ -237,6 +243,7 @@
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
+$(srcdir)/../common.mk:
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -272,18 +279,14 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(libdir)' && rm -f "$$files" )"; \
-	cd "$(DESTDIR)$(libdir)" && rm -f $$files
+	dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir)
 
 clean-libLIBRARIES:
 	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
 iec_bison.h: iec_bison.cc
-	@if test ! -f $@; then \
-	  rm -f iec_bison.cc; \
-	  $(MAKE) $(AM_MAKEFLAGS) iec_bison.cc; \
-	else :; fi
-libstage1_2.a: $(libstage1_2_a_OBJECTS) $(libstage1_2_a_DEPENDENCIES) 
+	@if test ! -f $@; then rm -f iec_bison.cc; else :; fi
+	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) iec_bison.cc; else :; fi
+libstage1_2.a: $(libstage1_2_a_OBJECTS) $(libstage1_2_a_DEPENDENCIES) $(EXTRA_libstage1_2_a_DEPENDENCIES) 
 	-rm -f libstage1_2.a
 	$(libstage1_2_a_AR) libstage1_2.a $(libstage1_2_a_OBJECTS) $(libstage1_2_a_LIBADD)
 	$(RANLIB) libstage1_2.a
@@ -461,10 +464,15 @@
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
--- a/stage1_2/iec_bison.yy	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage1_2/iec_bison.yy	Thu Oct 04 15:10:45 2012 +0100
@@ -433,7 +433,7 @@
 /* B 1.2 - Constants */
 /*********************/
 %type <leaf>	constant
-%type <leaf>	non_negative_constant
+%type <leaf>	non_int_or_real_constant
 
 /******************************/
 /* B 1.2.1 - Numeric Literals */
@@ -1299,7 +1299,7 @@
 %type  <leaf>	unary_expression
 // %type  <leaf>	unary_operator
 %type  <leaf>	primary_expression
-%type  <leaf>	non_negative_primary_expression
+%type  <leaf>	non_int_or_real_primary_expression
 /* intermediate helper symbol for primary_expression */
 %type  <leaf>	function_invocation
 
@@ -1730,91 +1730,64 @@
 /* B 1.2 - Constants */
 /*********************/
 constant:
-  numeric_literal
-| character_string
+  character_string
 | time_literal
 | bit_string_literal
 | boolean_literal
+| numeric_literal  
+/* NOTE: Our definition of numeric_literal is diferent than the one in the standard.
+ *       We will now add what is missing in our definition of numeric literal, so our
+ *       definition of constant matches what the definition of constant in the standard.
+ */
 /* NOTE: in order to remove reduce/reduce conflicts,
  * [between -9.5 being parsed as 
  *     (i)   a signed real, 
  *     (ii)  or as a real preceded by the '-' operator
  *  ]
  *  we need to define a variant of the constant construct
- *  where any constant is never preceded by the '-' character.
- * In order to do this, we have borugh the signed_real 
- * directly into the definition of the constant construct
- * (so we can define another non_negative_constant
- * construct that does not include it!)
- */
-| signed_real
-/* NOTE: in order to remove reduce/reduce conflicts,
- * unsigned_integer, signed_integer, binary_integer, octal_integer
- * and hex_integer have been integrated directly into
- * the constants construct, instead of belonging to
- * both the bit_string_literal or integer_literal
- * construct.
- */
+ *  where any real or integer constant is always preceded by 
+ *  a sign (i.e. the '-' or '+' characters).
+ *  (For more info, see comment in the construct non_int_or_real_primary_expression)
+ *
+ * For the above reason, our definition of the numeric_literal construct
+ * is missing the integer and real constrcuts (when not preceded by a sign)
+ * so we add then here explicitly!
+ */
+| real
+| integer
 /* NOTE: unsigned_integer, although used in some
  * rules, is not defined in the spec!
  * We therefore replaced unsigned_integer as integer
  */
-/*| integer {} */  /* i.e. an unsigned_integer */ /* NOTE: already included as a signed integer! */
-| signed_integer
-| binary_integer
-| octal_integer
-| hex_integer
-;
-
-
+;
+
+
+
+
+non_int_or_real_constant:
+  character_string
+| time_literal
+| bit_string_literal
+| boolean_literal
+| numeric_literal  
+/* NOTE: Our definition of numeric_literal is diferent than the one in the standard.
+ *       It is missing the integer and real when not prefixed by a sign 
+ *       (i.e. -54, +42 is included in numerical_literal,
+ *        but   54,  42 is not parsed as a numeric_literal!!)
+ */
 /* NOTE: in order to remove reduce/reduce conflicts,
  * [between -9.5 being parsed as 
  *     (i)   a signed real, 
  *     (ii)  or as a real preceded by the '-' operator
  *  ]
+ * [and a similar situation for integers!]
  *  we need to define a variant of the constant construct
- *  where any constant is never preceded by the '-' character.
- * In order to do this, we have borugh the signed_real 
- * directly into the definition of the constant construct
- * (so we can define another non_negative_constant
- * construct that does not include it!)
- */
-non_negative_constant:
-  numeric_literal
-| character_string
-| time_literal
-| bit_string_literal
-| boolean_literal
-/* NOTE: in order to remove reduce/reduce conflicts,
- * [between -9.5 being parsed as 
- *     (i)   a signed real, 
- *     (ii)  or as a real preceded by the '-' operator
- *  ]
- *  we need to define a variant of the constant construct
- *  where any constant is never preceded by the '-' character.
- * In order to do this, we have borugh the signed_real 
- * directly into the definition of the constant construct
- * (so we can define another non_negative_constant
- * construct that does not include it!)
- */
-/* | signed_real */
-| real /* an unsigned real */
-/* NOTE: in order to remove reduce/reduce conflicts,
- * unsigned_integer, signed_integer, binary_integer, octal_integer
- * and hex_integer have been integrated directly into
- * the constants construct, instead of belonging to
- * both the bit_string_literal or integer_literal
- * construct.
- */
-/* NOTE: unsigned_integer, although used in some
- * rules, is not defined in the spec!
- * We therefore replaced unsigned_integer as integer
- */
-| integer  /* i.e. an unsigned_integer */
-/* | signed_integer */
-| binary_integer
-| octal_integer
-| hex_integer
+ *  where any real or integer constant is always preceded by 
+ *  a sign (i.e. the '-' or '+' characters).
+ *
+ * For the above reason, our definition of the numeric_literal construct
+ * is missing the integer and real constrcuts (when not preceded by a sign)
+ */
 ;
 
 
@@ -1916,10 +1889,13 @@
 	{$$ = new integer_literal_c($1, $3, locloc(@$));}
 | integer_type_name '#' hex_integer
 	{$$ = new integer_literal_c($1, $3, locloc(@$));}
-/* NOTE: see note in the definition of constant for reason
- * why signed_integer, binary_integer, octal_integer
- * and hex_integer are missing here!
- */
+| binary_integer
+| octal_integer
+| hex_integer
+//|signed_integer  /* We expand the construct signed_integer here, so we can remove one of its constituents */
+//|  integer       /* REMOVED! see note in the definition of constant for reason why integer is missing here! */
+| '+' integer   {$$ = $2;}
+| '-' integer	{$$ = new neg_integer_c($2, locloc(@$));}
 /* ERROR_CHECK_BEGIN */
 | integer_type_name signed_integer
 	{$$ = NULL; print_err_msg(locl(@1), locf(@2), "'#' missing between integer type name and value in integer literal."); yynerrs++;}
@@ -1938,6 +1914,13 @@
 /* ERROR_CHECK_END */
 ;
 
+/* NOTE: this construct is used in the definition of integer_literal. However, in order to remove
+ *       a reduce/reduce conflict (see NOTE in definition of constant for reason why)
+ *       it is not used directly, but rather its expansion is copied there.
+ *
+ *       If for some reason you need to change the definition of signed_integer, don't forget
+ *       to change its expansion in integer_literal too!
+*/
 signed_integer:
   integer
 | '+' integer   {$$ = $2;}
@@ -1946,11 +1929,11 @@
 
 
 real_literal:
-/* NOTE: see note in the definition of constant for reason
- * why signed_real is missing here!
- */
-/*  signed_real */
-  real_type_name '#' signed_real
+// signed_real /* We expand the construct signed_integer here, so we can remove one of its constituents */
+// real        /* REMOVED! see note in the definition of constant for reason why real is missing here! */
+  '+' real	{$$ = $2;}
+| '-' real	{$$ = new neg_real_c($2, locloc(@2));}
+| real_type_name '#' signed_real
 	{$$ = new real_literal_c($1, $3, locloc(@$));}
 /* ERROR_CHECK_BEGIN */
 | real_type_name signed_real
@@ -1964,7 +1947,13 @@
 /* ERROR_CHECK_END */
 ;
 
-
+/* NOTE: this construct is used in the definition of real_literal. However, in order to remove
+ *       a reduce/reduce conflict (see NOTE in definition of constant for reason why)
+ *       it is not used directly, but rather its expansion is copied there.
+ *
+ *       If for some reason you need to change the definition of signed_real, don't forget
+ *       to change its expansion in real_literal too!
+*/
 signed_real:
   real
 | '+' real	{$$ = $2;}
@@ -1972,7 +1961,6 @@
 ;
 
 
-
 bit_string_literal:
   bit_string_type_name '#' integer  /* i.e. unsigned_integer */
 	{$$ = new bit_string_literal_c($1, $3, locloc(@$));}
@@ -7201,8 +7189,8 @@
 
 
 unary_expression:
-  non_negative_primary_expression
-| '-' non_negative_primary_expression
+  primary_expression
+| '-' non_int_or_real_primary_expression
 	{$$ = new neg_expression_c($2, locloc(@$));}
 | NOT primary_expression
 	{$$ = new not_expression_c($2, locloc(@$));}
@@ -7238,8 +7226,34 @@
  *       (i.e. the constant 9, preceded by a unary negation)
  *
  *       To remove the conflict, we only allow constants without
- *       a preceding '-' to be used in primary_expression
+ *       integer or reals that are not preceded by a sign 
+ *       (i.e. a '-' or '+' character) to be used in primary_expression
  *       (i.e. as a parameter to the unary negation operator)
+ *
+ *       e.g.  '-42', '+54', '42', '54' are all allowed in primary expression
+ *       according to the standard. However, we will allow only '-42' and '+54'
+ *       to be used as an argument to the negation operator ('-').
+ */
+/* NOTE: Notice that the standard considers the following syntax correct:
+ *         VAR intv: INT; END_VAR
+ *         intv :=      42;         <----- OK
+ *         intv :=     -42;         <----- OK
+ *         intv :=     +42;         <----- OK
+ *         intv :=    --42;         <----- OK!!
+ *         intv :=    -+42;         <----- OK!!
+ *         intv :=  -(--42);        <----- OK!!
+ *         intv :=  -(-+42);        <----- OK!!
+ *         intv :=-(-(--42));       <----- OK!!
+ *         intv :=-(-(-+42));       <----- OK!!
+ *     but does NOT allow the following syntax:
+ *         VAR intv: INT; END_VAR
+ *         intv :=   ---42;       <----- ERROR!!
+ *         intv :=   --+42;       <----- ERROR!!
+ *         intv :=  ----42;       <----- ERROR!!
+ *         intv :=  ---+42;       <----- ERROR!!
+ *
+ *    Although strange, we follow the standard to the letter, and do exactly
+ *    as stated above!!
  */
 /* NOTE: We use enumerated_value_without_identifier instead of enumerated_value
  *       in order to remove a reduce/reduce conflict between reducing an
@@ -7251,8 +7265,8 @@
  *       for a variable and an enumerated value, then the variable shall be
  *       considered.
  */
-non_negative_primary_expression:
-  non_negative_constant
+non_int_or_real_primary_expression:
+  non_int_or_real_constant
 //| enumerated_value_without_identifier
 | enumerated_value
 | variable
--- a/stage3/Makefile.am	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/Makefile.am	Thu Oct 04 15:10:45 2012 +0100
@@ -11,5 +11,6 @@
 	datatype_functions.cc \
 	lvalue_check.cc \
 	array_range_check.cc \
-        constant_folding.cc
+        constant_folding.cc \
+        declaration_check.cc
 
--- a/stage3/Makefile.in	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/Makefile.in	Thu Oct 04 15:10:45 2012 +0100
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -64,6 +64,12 @@
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LIBRARIES = $(lib_LIBRARIES)
 AR = ar
@@ -76,7 +82,7 @@
 	narrow_candidate_datatypes.$(OBJEXT) \
 	print_datatypes_error.$(OBJEXT) datatype_functions.$(OBJEXT) \
 	lvalue_check.$(OBJEXT) array_range_check.$(OBJEXT) \
-	constant_folding.$(OBJEXT)
+	constant_folding.$(OBJEXT) declaration_check.$(OBJEXT)
 libstage3_a_OBJECTS = $(am_libstage3_a_OBJECTS)
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
 depcomp = $(SHELL) $(top_srcdir)/config/depcomp
@@ -200,7 +206,8 @@
 	datatype_functions.cc \
 	lvalue_check.cc \
 	array_range_check.cc \
-        constant_folding.cc
+        constant_folding.cc \
+        declaration_check.cc
 
 all: all-am
 
@@ -227,6 +234,7 @@
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
+$(srcdir)/../common.mk:
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -262,13 +270,11 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(libdir)' && rm -f "$$files" )"; \
-	cd "$(DESTDIR)$(libdir)" && rm -f $$files
+	dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir)
 
 clean-libLIBRARIES:
 	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
-libstage3.a: $(libstage3_a_OBJECTS) $(libstage3_a_DEPENDENCIES) 
+libstage3.a: $(libstage3_a_OBJECTS) $(libstage3_a_DEPENDENCIES) $(EXTRA_libstage3_a_DEPENDENCIES) 
 	-rm -f libstage3.a
 	$(libstage3_a_AR) libstage3.a $(libstage3_a_OBJECTS) $(libstage3_a_LIBADD)
 	$(RANLIB) libstage3.a
@@ -282,6 +288,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/array_range_check.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/constant_folding.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/datatype_functions.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/declaration_check.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fill_candidate_datatypes.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flow_control_analysis.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lvalue_check.Po@am__quote@
@@ -402,10 +409,15 @@
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
--- a/stage3/array_range_check.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/array_range_check.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -89,6 +89,7 @@
 array_range_check_c::array_range_check_c(symbol_c *ignore) {
 	error_count = 0;
 	current_display_error_level = 0;
+	search_varfb_instance_type = NULL;
 }
 
 
@@ -133,36 +134,36 @@
     /* Check lower limit */
     if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE( int64, dimension->lower_limit))
       if ( GET_CVALUE( int64, l->elements[i]) < GET_CVALUE( int64, dimension->lower_limit) )
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds."); continue;}
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (should be >= %"PRId64").", GET_CVALUE( int64, dimension->lower_limit)); continue;}
 
     if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE(uint64, dimension->lower_limit))
       if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->lower_limit), GET_CVALUE( int64, l->elements[i])) > 0 )
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds."); continue;}
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (should be >= %"PRIu64").", GET_CVALUE(uint64, dimension->lower_limit)); continue;}
 
     if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE(uint64, dimension->lower_limit))
       if ( GET_CVALUE(uint64, l->elements[i])   <  GET_CVALUE(uint64, dimension->lower_limit))
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds."); continue;}
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (should be >= %"PRIu64").", GET_CVALUE(uint64, dimension->lower_limit)); continue;}
 
     if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE( int64, dimension->lower_limit))
       if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->lower_limit)) < 0 )
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds."); continue;}
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (should be >= %"PRId64").", GET_CVALUE( int64, dimension->lower_limit)); continue;}
 
     /* Repeat the same check, now for upper limit */
     if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE( int64, dimension->upper_limit))
       if ( GET_CVALUE( int64, l->elements[i])   >  GET_CVALUE( int64, dimension->upper_limit))
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds."); continue;}
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (should be <= %"PRId64").", GET_CVALUE( int64, dimension->upper_limit)); continue;}
 
     if ( VALID_CVALUE( int64, l->elements[i]) && VALID_CVALUE(uint64, dimension->upper_limit))
       if ( cmp_unsigned_signed( GET_CVALUE(uint64, dimension->upper_limit), GET_CVALUE( int64, l->elements[i])) < 0 )
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds."); continue;}
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (should be <= %"PRIu64").", GET_CVALUE(uint64, dimension->upper_limit)); continue;}
 
     if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE(uint64, dimension->upper_limit))
       if ( GET_CVALUE(uint64, l->elements[i])   >  GET_CVALUE(uint64, dimension->upper_limit))
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds."); continue;}
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (should be <= %"PRIu64").", GET_CVALUE(uint64, dimension->upper_limit)); continue;}
       
     if ( VALID_CVALUE(uint64, l->elements[i]) && VALID_CVALUE( int64, dimension->upper_limit))
       if ( cmp_unsigned_signed(GET_CVALUE(uint64, l->elements[i]), GET_CVALUE( int64, dimension->upper_limit)) > 0 )
-      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds."); continue;}
+      {STAGE3_ERROR(0, symbol, symbol, "Array access out of bounds (should be <= %"PRId64").", GET_CVALUE( int64, dimension->upper_limit)); continue;}
       
   }
 }
--- a/stage3/array_range_check.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/array_range_check.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -41,8 +41,6 @@
 
   private:
     search_varfb_instance_type_c *search_varfb_instance_type;
-    // search_var_instance_decl_c *search_var_instance_decl;
-    search_base_type_c search_base_type;
     int error_count;
     int current_display_error_level;
 
--- a/stage3/constant_folding.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/constant_folding.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -32,6 +32,16 @@
 
 
 
+/* TODO: 
+ *         - Add support for comparison (= and !=) of enumeration literals!
+ *              We will need to add another const_value entry to the symbol_c, containing the 
+ *              possible enumeration value of the enum constant!
+ *              Doing this will allow us to more easily implement a constant_propagation_c later on!
+ *
+ *         - Add support for comparison (= and !=) of the exact same variable
+ *                (e.g. if (int_v = int_v) then ...)
+ */
+
 
 
 /* Do constant folding...
@@ -165,31 +175,36 @@
 
 
 
-#define SET_CVALUE(dtype, symbol, new_value)  ((symbol)->const_value._##dtype.value) = new_value; ((symbol)->const_value._##dtype.status) = symbol_c::cs_const_value;
+#define SET_CVALUE(dtype, symbol, new_value) {((symbol)->const_value._##dtype.value) = new_value; ((symbol)->const_value._##dtype.status) = symbol_c::cs_const_value;}
 #define GET_CVALUE(dtype, symbol)             ((symbol)->const_value._##dtype.value)
 #define SET_OVFLOW(dtype, symbol)             ((symbol)->const_value._##dtype.status) = symbol_c::cs_overflow
 #define SET_NONCONST(dtype, symbol)           ((symbol)->const_value._##dtype.status) = symbol_c::cs_non_const
 
 #define VALID_CVALUE(dtype, symbol)           (symbol_c::cs_const_value == (symbol)->const_value._##dtype.status)
+#define IS_OVFLOW(dtype, symbol)              (symbol_c::cs_overflow    == (symbol)->const_value._##dtype.status)
+#define IS_NONCONST(dtype, symbol)            (symbol_c::cs_non_const   == (symbol)->const_value._##dtype.status)
 #define ISZERO_CVALUE(dtype, symbol)          ((VALID_CVALUE(dtype, symbol)) && (GET_CVALUE(dtype, symbol) == 0))
 
 #define ISEQUAL_CVALUE(dtype, symbol1, symbol2) \
 	(VALID_CVALUE(dtype, symbol1) && VALID_CVALUE(dtype, symbol2) && (GET_CVALUE(dtype, symbol1) == GET_CVALUE(dtype, symbol2))) 
 
-#define DO_BINARY_OPER(dtype, oper, otype)\
-	if (VALID_CVALUE(dtype, symbol->r_exp) && VALID_CVALUE(dtype, symbol->l_exp)) {                                \
-		SET_CVALUE(otype, symbol, GET_CVALUE(dtype, symbol->l_exp) oper GET_CVALUE(dtype, symbol->r_exp));     \
-	}
-
-#define DO_BINARY_OPER_(oper_type, operation, res_type, operand1, operand2)\
-	if (VALID_CVALUE(oper_type, operand1) && VALID_CVALUE(oper_type, operand2)) {                                     \
-		SET_CVALUE(res_type, symbol, GET_CVALUE(oper_type, operand1) operation GET_CVALUE(oper_type, operand2));  \
-	}
-
-#define DO_UNARY_OPER(dtype, operation, operand)\
-	if (VALID_CVALUE(dtype, operand)) {                                                                               \
-		SET_CVALUE(dtype, symbol, operation GET_CVALUE(dtype, operand));                                          \
-	}
+#define DO_BINARY_OPER(oper_type, operation, res_type, operand1, operand2) {                                              \
+	if      (VALID_CVALUE(oper_type, operand1) && VALID_CVALUE(oper_type, operand2))                                  \
+		{SET_CVALUE(res_type, symbol, GET_CVALUE(oper_type, operand1) operation GET_CVALUE(oper_type, operand2));}\
+	else if (IS_OVFLOW   (oper_type, operand1) || IS_OVFLOW   (oper_type, operand2))                                  \
+		{SET_OVFLOW(res_type, symbol);}  /* does it really make sense to set OVFLOW when restype is boolean??  */ \
+	else if (IS_NONCONST (oper_type, operand1) || IS_NONCONST (oper_type, operand2))                                  \
+		{SET_NONCONST(res_type, symbol);}                                                                         \
+}
+
+#define DO_UNARY_OPER(dtype, operation, operand) {                                                                        \
+	if      (VALID_CVALUE(dtype, operand))                                                                            \
+		{SET_CVALUE(dtype, symbol, operation GET_CVALUE(dtype, operand));}                                        \
+	else if (IS_OVFLOW   (dtype, operand))                                                                            \
+		{SET_OVFLOW(dtype, symbol);}                                                                              \
+	else if (IS_NONCONST (dtype, operand))                                                                            \
+		{SET_NONCONST(dtype, symbol);}                                                                            \
+}
 
 
 
@@ -215,7 +230,11 @@
    * by having it resolve the call to the overloaded function. For the C++ compiler to be able
    * to resolve this ambiguity, we need to add a dummy parameter to each function!
    *
-   * TODO: support platforms in which int64_t is mapped onto int !! Is this really needed?
+   * TODO: support platforms (where the compiler will run) in which int64_t is mapped onto int !!
+   *       Is this really needed?
+   *       Currently, when trying to compile matiec on sych a platform, the C++ compiler will not
+   *       find any apropriate matiec_strtoint64() to call, so matiec will not be able to be compiled.
+   *       If you need this, you are welcome to fix it yourself...
    */
 static  int64_t matiec_strtoint64 (         long      int *dummy, const char *nptr, char **endptr, int base) {return strtol  (nptr, endptr, base);}
 static  int64_t matiec_strtoint64 (         long long int *dummy, const char *nptr, char **endptr, int base) {return strtoll (nptr, endptr, base);}
@@ -423,6 +442,18 @@
 }
 
 
+/* res = - a */
+static void CHECK_OVERFLOW_uint64_NEG(symbol_c *res, symbol_c *a) {
+	/* The only legal operation is res = -0, everything else is an overflow! */
+	if (VALID_CVALUE(uint64, a) && (GET_CVALUE(uint64, a) != 0))
+		SET_OVFLOW(uint64, res);
+}
+
+
+
+
+
+
 /* res = a + b */
 static void CHECK_OVERFLOW_int64_SUM(symbol_c *res, symbol_c *a_ptr, symbol_c *b_ptr) {
 	if (!VALID_CVALUE(int64, res))
@@ -494,16 +525,16 @@
 
 
 /* res = - a */
-static void CHECK_OVERFLOW_int64_NEG(symbol_c *res, symbol_c *a_ptr) {
+static void CHECK_OVERFLOW_int64_NEG(symbol_c *res, symbol_c *a) {
 	if (!VALID_CVALUE(int64, res))
 		return;
-	int64_t a = GET_CVALUE(int64, a_ptr);
-	if (a == INT64_MIN)
+	if (GET_CVALUE(int64, a) == INT64_MIN)
 		SET_OVFLOW(int64, res);
 }
 
 
 
+
 static void CHECK_OVERFLOW_real64(symbol_c *res_ptr) {
 	if (!VALID_CVALUE(real64, res_ptr))
 		return;
@@ -532,10 +563,10 @@
 /* static void *handle_cmp(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2, OPERATION) */
 #define handle_cmp(symbol, oper1, oper2, operation) {               \
 	if ((NULL == oper1) || (NULL == oper2)) return NULL;        \
-	DO_BINARY_OPER_(  bool, operation, bool, oper1, oper2);     \
-	DO_BINARY_OPER_(uint64, operation, bool, oper1, oper2);     \
-	DO_BINARY_OPER_( int64, operation, bool, oper1, oper2);     \
-	DO_BINARY_OPER_(real64, operation, bool, oper1, oper2);     \
+	DO_BINARY_OPER(  bool, operation, bool, oper1, oper2);     \
+	DO_BINARY_OPER(uint64, operation, bool, oper1, oper2);     \
+	DO_BINARY_OPER( int64, operation, bool, oper1, oper2);     \
+	DO_BINARY_OPER(real64, operation, bool, oper1, oper2);     \
 	return NULL;                                                \
 }
 
@@ -550,7 +581,17 @@
 
 /* unary negation (multiply by -1) */
 static void *handle_neg(symbol_c *symbol, symbol_c *oper) {
-	DO_UNARY_OPER( int64, -, oper);	CHECK_OVERFLOW_int64_NEG(symbol, oper);
+	if (NULL == oper) return NULL;
+	/* NOTE: The oper may never be an integer/real literal, '-1' and '-2.2' are stored as an neg_integer_c/neg_real_c instead.
+	 *       Because of this, we MUST NOT handle the INT_MIN special situation that is handled in neg_integer_c visitor!
+	 *
+	 *       VAR v1, v2, v3 : UINT; END_VAR;
+	 *       v1 =  9223372036854775808 ; (* |INT64_MIN| == -INT64_MIN *)   <------ LEGAL
+	 *       v2 =  -(-v1);                                                 <------ ILLEGAL (since it -v1 is overflow!)
+	 *       v2 =  -(-9223372036854775808 );                               <------ MUST also be ILLEGAL 
+	 */
+	DO_UNARY_OPER(uint64, -, oper);	CHECK_OVERFLOW_uint64_NEG(symbol, oper);  /* handle the uint_v := -0 situation! */
+	DO_UNARY_OPER( int64, -, oper);	CHECK_OVERFLOW_int64_NEG (symbol, oper);
 	DO_UNARY_OPER(real64, -, oper);	CHECK_OVERFLOW_real64(symbol);
 	return NULL;
 }
@@ -567,60 +608,60 @@
 
 static void *handle_or (symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
 	if ((NULL == oper1) || (NULL == oper2)) return NULL;
-	DO_BINARY_OPER_(  bool, ||, bool  , oper1, oper2);
-	DO_BINARY_OPER_(uint64, | , uint64, oper1, oper2);
+	DO_BINARY_OPER(  bool, ||, bool  , oper1, oper2);
+	DO_BINARY_OPER(uint64, | , uint64, oper1, oper2);
 	return NULL;
 }
 
 
 static void *handle_xor(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
 	if ((NULL == oper1) || (NULL == oper2)) return NULL;
-	DO_BINARY_OPER_(  bool, ^, bool  , oper1, oper2);
-	DO_BINARY_OPER_(uint64, ^, uint64, oper1, oper2);
+	DO_BINARY_OPER(  bool, ^, bool  , oper1, oper2);
+	DO_BINARY_OPER(uint64, ^, uint64, oper1, oper2);
 	return NULL;
 }
 
 
 static void *handle_and(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
 	if ((NULL == oper1) || (NULL == oper2)) return NULL;
-	DO_BINARY_OPER_(  bool, &&, bool, oper1, oper2);
-	DO_BINARY_OPER_(uint64, & , uint64, oper1, oper2);
+	DO_BINARY_OPER(  bool, &&, bool, oper1, oper2);
+	DO_BINARY_OPER(uint64, & , uint64, oper1, oper2);
 	return NULL;
 }
 
 
 static void *handle_add(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
 	if ((NULL == oper1) || (NULL == oper2)) return NULL;
-	DO_BINARY_OPER_(uint64, +, uint64, oper1, oper2);   CHECK_OVERFLOW_uint64_SUM(symbol, oper1, oper2);
-	DO_BINARY_OPER_( int64, +,  int64, oper1, oper2);   CHECK_OVERFLOW_int64_SUM (symbol, oper1, oper2);
-	DO_BINARY_OPER_(real64, +, real64, oper1, oper2);   CHECK_OVERFLOW_real64    (symbol);
+	DO_BINARY_OPER(uint64, +, uint64, oper1, oper2);   CHECK_OVERFLOW_uint64_SUM(symbol, oper1, oper2);
+	DO_BINARY_OPER( int64, +,  int64, oper1, oper2);   CHECK_OVERFLOW_int64_SUM (symbol, oper1, oper2);
+	DO_BINARY_OPER(real64, +, real64, oper1, oper2);   CHECK_OVERFLOW_real64    (symbol);
 	return NULL;
 }
 
 
 static void *handle_sub(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
 	if ((NULL == oper1) || (NULL == oper2)) return NULL;
-	DO_BINARY_OPER_(uint64, -, uint64, oper1, oper2);   CHECK_OVERFLOW_uint64_SUB(symbol, oper1, oper2);
-	DO_BINARY_OPER_( int64, -,  int64, oper1, oper2);   CHECK_OVERFLOW_int64_SUB (symbol, oper1, oper2);
-	DO_BINARY_OPER_(real64, -, real64, oper1, oper2);   CHECK_OVERFLOW_real64    (symbol);
+	DO_BINARY_OPER(uint64, -, uint64, oper1, oper2);   CHECK_OVERFLOW_uint64_SUB(symbol, oper1, oper2);
+	DO_BINARY_OPER( int64, -,  int64, oper1, oper2);   CHECK_OVERFLOW_int64_SUB (symbol, oper1, oper2);
+	DO_BINARY_OPER(real64, -, real64, oper1, oper2);   CHECK_OVERFLOW_real64    (symbol);
 	return NULL;
 }
 
 
 static void *handle_mul(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
 	if ((NULL == oper1) || (NULL == oper2)) return NULL;
-	DO_BINARY_OPER_(uint64, *, uint64, oper1, oper2);   CHECK_OVERFLOW_uint64_MUL(symbol, oper1, oper2);
-	DO_BINARY_OPER_( int64, *,  int64, oper1, oper2);   CHECK_OVERFLOW_int64_MUL (symbol, oper1, oper2);
-	DO_BINARY_OPER_(real64, *, real64, oper1, oper2);   CHECK_OVERFLOW_real64    (symbol);
+	DO_BINARY_OPER(uint64, *, uint64, oper1, oper2);   CHECK_OVERFLOW_uint64_MUL(symbol, oper1, oper2);
+	DO_BINARY_OPER( int64, *,  int64, oper1, oper2);   CHECK_OVERFLOW_int64_MUL (symbol, oper1, oper2);
+	DO_BINARY_OPER(real64, *, real64, oper1, oper2);   CHECK_OVERFLOW_real64    (symbol);
 	return NULL;
 }
 
 
 static void *handle_div(symbol_c *symbol, symbol_c *oper1, symbol_c *oper2) {
 	if ((NULL == oper1) || (NULL == oper2)) return NULL;
-	if (ISZERO_CVALUE(uint64, oper2))  {SET_OVFLOW(uint64, symbol);} else {DO_BINARY_OPER_(uint64, /, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_DIV(symbol, oper1, oper2);};
-	if (ISZERO_CVALUE( int64, oper2))  {SET_OVFLOW( int64, symbol);} else {DO_BINARY_OPER_( int64, /,  int64, oper1, oper2); CHECK_OVERFLOW_int64_DIV (symbol, oper1, oper2);};
-	if (ISZERO_CVALUE(real64, oper2))  {SET_OVFLOW(real64, symbol);} else {DO_BINARY_OPER_(real64, /, real64, oper1, oper2); CHECK_OVERFLOW_real64(symbol);};
+	if (ISZERO_CVALUE(uint64, oper2))  {SET_OVFLOW(uint64, symbol);} else {DO_BINARY_OPER(uint64, /, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_DIV(symbol, oper1, oper2);};
+	if (ISZERO_CVALUE( int64, oper2))  {SET_OVFLOW( int64, symbol);} else {DO_BINARY_OPER( int64, /,  int64, oper1, oper2); CHECK_OVERFLOW_int64_DIV (symbol, oper1, oper2);};
+	if (ISZERO_CVALUE(real64, oper2))  {SET_OVFLOW(real64, symbol);} else {DO_BINARY_OPER(real64, /, real64, oper1, oper2); CHECK_OVERFLOW_real64(symbol);};
 	return NULL;
 }
 
@@ -633,8 +674,8 @@
 	 * Note that, when IN1 = INT64_MIN, and IN2 = -1, an overflow occurs in the division,
 	 * so although the MOD operation should be OK, acording to the above definition, we actually have an overflow!!
 	 */
-	if (ISZERO_CVALUE(uint64, oper2))  {SET_CVALUE(uint64, symbol, 0);} else {DO_BINARY_OPER_(uint64, %, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_MOD(symbol, oper1, oper2);};
-	if (ISZERO_CVALUE( int64, oper2))  {SET_CVALUE( int64, symbol, 0);} else {DO_BINARY_OPER_( int64, %,  int64, oper1, oper2); CHECK_OVERFLOW_int64_MOD (symbol, oper1, oper2);};
+	if (ISZERO_CVALUE(uint64, oper2))  {SET_CVALUE(uint64, symbol, 0);} else {DO_BINARY_OPER(uint64, %, uint64, oper1, oper2); CHECK_OVERFLOW_uint64_MOD(symbol, oper1, oper2);};
+	if (ISZERO_CVALUE( int64, oper2))  {SET_CVALUE( int64, symbol, 0);} else {DO_BINARY_OPER( int64, %,  int64, oper1, oper2); CHECK_OVERFLOW_int64_MOD (symbol, oper1, oper2);};
 	return NULL;
 }
 
@@ -698,6 +739,9 @@
     error_count = 0;
     warning_found = false;
     current_display_error_level = 0;
+    il_operand = NULL;
+    search_varfb_instance_type = NULL;
+    prev_il_instruction = NULL;
     
     /* check whether the platform on which the compiler is being run implements IEC 559 floating point data types. */
     symbol_c null_symbol;
@@ -744,19 +788,39 @@
 
 void *constant_folding_c::visit(neg_real_c *symbol) {
 	symbol->exp->accept(*this);
-	DO_UNARY_OPER(real64, -, symbol->exp);
-	CHECK_OVERFLOW_real64(symbol);
-	return NULL;
-}
+	DO_UNARY_OPER(real64, -, symbol->exp); CHECK_OVERFLOW_real64(symbol);
+	if (IS_OVFLOW(real64, symbol->exp)) SET_OVFLOW(real64, symbol);
+	return NULL;
+}
+
+
 
 /* | '-' integer	{$$ = new neg_integer_c($2, locloc(@$));} */
 void *constant_folding_c::visit(neg_integer_c *symbol) {
 	symbol->exp->accept(*this);
-	DO_UNARY_OPER(int64, -, symbol->exp);
-	CHECK_OVERFLOW_int64_NEG(symbol, symbol->exp);
+	/* Note that due to syntax restrictions, the value of symbol->exp will always be positive. 
+	 * However, the following code does not depend on that restriction.
+	 */
+	/* The remainder of the code (for example, data type checking) considers the neg_integer_c as a leaf of the
+	 * abstract syntax tree, and therefore simply ignores the values of neg_integer_c->exp.
+	 * For this reason only, and in only this situation, we must guarantee that any 'overflow' situation in 
+	 * the cvalue of neg_integer_c->exp is also reflected back to this neg_integer_c symbol.
+	 * For the rest of the code we do NOT do this, as it would gurantee that a single overflow deep inside
+	 * an expression would imply that the expression itself would also be set to 'overflow' condition.
+	 * This in turn would then have the compiler produce a whole load of error messages where they are not wanted!
+	 */
+	DO_UNARY_OPER(uint64, -, symbol->exp); CHECK_OVERFLOW_uint64_NEG(symbol, symbol->exp);  /* handle the uintv := -0 situation */
+	if (IS_OVFLOW(uint64, symbol->exp)) SET_OVFLOW(uint64, symbol);
+	DO_UNARY_OPER( int64, -, symbol->exp); CHECK_OVERFLOW_int64_NEG (symbol, symbol->exp);
+	if (IS_OVFLOW( int64, symbol->exp)) SET_OVFLOW( int64, symbol);
 	/* NOTE 1: INT64_MIN = -(INT64_MAX + 1)   ---> assuming two's complement representation!!!
 	 * NOTE 2: if the user happens to want INT_MIN, that value will first be parsed as a positive integer, before being negated here.
 	 * However, the positive value cannot be stored inside an int64! So, in this case, we will get the value from the uint64 cvalue.
+	 *
+	 * This same situation is usually considered an overflow (check handle_neg() function). However, here we have a special
+	 * situation. If we do not allow this, then the user would never the able to use the following code:
+	 *  VAR v : LINT; END_VAR
+	 *    v := -9223372036854775809 ; (* - |INT64_MIN| == INT64_MIN *)
 	 */
 	// if (INT64_MIN == -INT64_MAX - 1) // We do not really need to check that the platform uses two's complement
 	if (VALID_CVALUE(uint64, symbol->exp) && (GET_CVALUE(uint64, symbol->exp) == (uint64_t)INT64_MAX+1)) {
--- a/stage3/constant_folding.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/constant_folding.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -47,7 +47,6 @@
 class constant_folding_c : public iterator_visitor_c {
   private:
     search_varfb_instance_type_c *search_varfb_instance_type;
-    search_base_type_c search_base_type;
     int error_count;
     bool warning_found;
     int current_display_error_level;
--- a/stage3/datatype_functions.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/datatype_functions.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -461,319 +461,6 @@
 
 
 
-/* A helper function... */
-bool is_ANY_ELEMENTARY_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  return is_ANY_MAGNITUDE_type(type_symbol)
-      || is_ANY_BIT_type      (type_symbol)
-      || is_ANY_STRING_type   (type_symbol)
-      || is_ANY_DATE_type     (type_symbol);
-}
-
-/* A helper function... */
-bool is_ANY_SAFEELEMENTARY_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  return is_ANY_SAFEMAGNITUDE_type(type_symbol)
-      || is_ANY_SAFEBIT_type      (type_symbol)
-      || is_ANY_SAFESTRING_type   (type_symbol)
-      || is_ANY_SAFEDATE_type     (type_symbol);
-}
-
-/* A helper function... */
-bool is_ANY_ELEMENTARY_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  /* NOTE: doing
-   *          return is_ANY_SAFEELEMENTARY_type() || is_ANY_ELEMENTARY_type()
-   *       is incorrect, as the literals would never be considered compatible...
-   */
-  return is_ANY_MAGNITUDE_compatible(type_symbol)
-      || is_ANY_BIT_compatible      (type_symbol)
-      || is_ANY_STRING_compatible   (type_symbol)
-      || is_ANY_DATE_compatible     (type_symbol);
-}
-
-
-/* A helper function... */
-bool is_ANY_MAGNITUDE_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;}
-  return is_ANY_NUM_type(type_symbol);
-}
-
-/* A helper function... */
-bool is_ANY_signed_MAGNITUDE_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(time_type_name_c)) {return true;}
-  return is_ANY_signed_NUM_type(type_symbol);
-}
-
-/* A helper function... */
-bool is_ANY_SAFEMAGNITUDE_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;}
-  return is_ANY_SAFENUM_type(type_symbol);
-}
-
-/* A helper function... */
-bool is_ANY_signed_SAFEMAGNITUDE_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(safetime_type_name_c)) {return true;}
-  return is_ANY_signed_SAFENUM_type(type_symbol);
-}
-
-/* A helper function... */
-bool is_ANY_MAGNITUDE_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_MAGNITUDE_type    (type_symbol))              {return true;}
-  if (is_ANY_SAFEMAGNITUDE_type(type_symbol))              {return true;}
-  return is_ANY_NUM_compatible(type_symbol);
-}
-
-/* A helper function... */
-bool is_ANY_signed_MAGNITUDE_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_signed_MAGNITUDE_type    (type_symbol))       {return true;}
-  if (is_ANY_signed_SAFEMAGNITUDE_type(type_symbol))       {return true;}
-  return is_ANY_signed_NUM_compatible(type_symbol);
-}
-
-/* A helper function... */
-bool is_ANY_NUM_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_REAL_type(type_symbol))                       {return true;}
-  if (is_ANY_INT_type(type_symbol))                        {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_signed_NUM_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_REAL_type(type_symbol))                       {return true;}
-  if (is_ANY_signed_INT_type(type_symbol))                 {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_SAFENUM_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  return is_ANY_SAFEREAL_type(type_symbol)
-      || is_ANY_SAFEINT_type (type_symbol);
-}
-
-/* A helper function... */
-bool is_ANY_signed_SAFENUM_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  return is_ANY_SAFEREAL_type(type_symbol)
-      || is_ANY_signed_SAFEINT_type (type_symbol);
-}
-
-/* A helper function... */
-bool is_ANY_NUM_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_REAL_compatible(type_symbol))                       {return true;}
-  if (is_ANY_INT_compatible(type_symbol))                        {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_signed_NUM_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_REAL_compatible(type_symbol))                       {return true;}
-  if (is_ANY_signed_INT_compatible(type_symbol))                 {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_DATE_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(date_type_name_c)) {return true;}
-  if (typeid(*type_symbol) == typeid(tod_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(dt_type_name_c))   {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_SAFEDATE_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(safedate_type_name_c)) {return true;}
-  if (typeid(*type_symbol) == typeid(safetod_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(safedt_type_name_c))   {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_DATE_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_DATE_type    (type_symbol))              {return true;}
-  if (is_ANY_SAFEDATE_type(type_symbol))              {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_STRING_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(string_type_name_c)) {return true;}
-  if (typeid(*type_symbol) == typeid(wstring_type_name_c)) {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_SAFESTRING_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(safestring_type_name_c)) {return true;}
-  if (typeid(*type_symbol) == typeid(safewstring_type_name_c)) {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_STRING_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_STRING_type    (type_symbol))              {return true;}
-  if (is_ANY_SAFESTRING_type(type_symbol))              {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_INT_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(sint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(int_type_name_c))   {return true;}
-  if (typeid(*type_symbol) == typeid(dint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(lint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(usint_type_name_c)) {return true;}
-  if (typeid(*type_symbol) == typeid(uint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(udint_type_name_c)) {return true;}
-  if (typeid(*type_symbol) == typeid(ulint_type_name_c)) {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_signed_INT_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(sint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(int_type_name_c))   {return true;}
-  if (typeid(*type_symbol) == typeid(dint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(lint_type_name_c))  {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_signed_SAFEINT_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(safesint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(safeint_type_name_c))   {return true;}
-  if (typeid(*type_symbol) == typeid(safedint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(safelint_type_name_c))  {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_SAFEINT_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(safesint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(safeint_type_name_c))   {return true;}
-  if (typeid(*type_symbol) == typeid(safedint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(safelint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(safeusint_type_name_c)) {return true;}
-  if (typeid(*type_symbol) == typeid(safeuint_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(safeudint_type_name_c)) {return true;}
-  if (typeid(*type_symbol) == typeid(safeulint_type_name_c)) {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_signed_INT_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_signed_INT_type    (type_symbol))              {return true;}
-  if (is_ANY_signed_SAFEINT_type(type_symbol))              {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_INT_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_INT_type    (type_symbol))              {return true;}
-  if (is_ANY_SAFEINT_type(type_symbol))              {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_REAL_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(real_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(lreal_type_name_c)) {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_SAFEREAL_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(safereal_type_name_c))  {return true;}
-  if (typeid(*type_symbol) == typeid(safelreal_type_name_c)) {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_REAL_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_REAL_type    (type_symbol))              {return true;}
-  if (is_ANY_SAFEREAL_type(type_symbol))              {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_BIT_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(bool_type_name_c))     {return true;}
-  if (typeid(*type_symbol) == typeid(byte_type_name_c))     {return true;}
-  if (typeid(*type_symbol) == typeid(word_type_name_c))     {return true;}
-  if (typeid(*type_symbol) == typeid(dword_type_name_c))    {return true;}
-  if (typeid(*type_symbol) == typeid(lword_type_name_c))    {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_SAFEBIT_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(safebool_type_name_c))     {return true;}
-  if (typeid(*type_symbol) == typeid(safebyte_type_name_c))     {return true;}
-  if (typeid(*type_symbol) == typeid(safeword_type_name_c))     {return true;}
-  if (typeid(*type_symbol) == typeid(safedword_type_name_c))    {return true;}
-  if (typeid(*type_symbol) == typeid(safelword_type_name_c))    {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_BIT_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_ANY_BIT_type    (type_symbol))              {return true;}
-  if (is_ANY_SAFEBIT_type(type_symbol))              {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_BOOL_type(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(bool_type_name_c))      {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_SAFEBOOL_type(symbol_c *type_symbol){
-  if (type_symbol == NULL) {return false;}
-  if (typeid(*type_symbol) == typeid(safebool_type_name_c))  {return true;}
-  return false;
-}
-
-/* A helper function... */
-bool is_ANY_BOOL_compatible(symbol_c *type_symbol) {
-  if (type_symbol == NULL) {return false;}
-  if (is_BOOL_type    (type_symbol))              {return true;}
-  if (is_SAFEBOOL_type(type_symbol))              {return true;}
-  return false;
-}
-
-
 
 
 
@@ -785,7 +472,7 @@
   if (typeid(*second_type) == typeid(invalid_type_name_c))
       return false;
     
-  if (is_ANY_ELEMENTARY_type(first_type)) {
+  if (get_datatype_info_c::is_ANY_ELEMENTARY(first_type)) {
       if (typeid(*first_type) == typeid(*second_type))
           return true;
   } else   /* ANY_DERIVED */
--- a/stage3/datatype_functions.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/datatype_functions.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -161,54 +161,6 @@
 
 
 
-/* A helper function... */
-bool is_ANY_ELEMENTARY_type                (symbol_c *type_symbol);
-bool is_ANY_SAFEELEMENTARY_type            (symbol_c *type_symbol);
-bool is_ANY_ELEMENTARY_compatible          (symbol_c *type_symbol);
-
-bool is_ANY_MAGNITUDE_type                 (symbol_c *type_symbol);
-bool is_ANY_SAFEMAGNITUDE_type             (symbol_c *type_symbol);
-bool is_ANY_MAGNITUDE_compatible           (symbol_c *type_symbol);
-
-bool is_ANY_signed_MAGNITUDE_type          (symbol_c *type_symbol);
-bool is_ANY_signed_SAFEMAGNITUDE_type      (symbol_c *type_symbol);
-bool is_ANY_signed_MAGNITUDE_compatible    (symbol_c *type_symbol);
-
-bool is_ANY_DATE_type                      (symbol_c *type_symbol);
-bool is_ANY_SAFEDATE_type                  (symbol_c *type_symbol);
-bool is_ANY_DATE_compatible                (symbol_c *type_symbol);
-
-bool is_ANY_STRING_type                    (symbol_c *type_symbol);
-bool is_ANY_SAFESTRING_type                (symbol_c *type_symbol);
-bool is_ANY_STRING_compatible              (symbol_c *type_symbol);
-
-bool is_ANY_INT_type                       (symbol_c *type_symbol);
-bool is_ANY_SAFEINT_type                   (symbol_c *type_symbol);
-bool is_ANY_INT_compatible                 (symbol_c *type_symbol);
-
-bool is_ANY_signed_INT_type                (symbol_c *type_symbol);
-bool is_ANY_signed_SAFEINT_type            (symbol_c *type_symbol);
-bool is_ANY_signed_INT_compatible          (symbol_c *type_symbol);
-
-bool is_ANY_REAL_type                      (symbol_c *type_symbol);
-bool is_ANY_SAFEREAL_type                  (symbol_c *type_symbol);
-bool is_ANY_REAL_compatible                (symbol_c *type_symbol);
-
-bool is_ANY_NUM_type                       (symbol_c *type_symbol);
-bool is_ANY_SAFENUM_type                   (symbol_c *type_symbol);
-bool is_ANY_NUM_compatible                 (symbol_c *type_symbol);
-
-bool is_ANY_signed_NUM_type                (symbol_c *type_symbol);
-bool is_ANY_signed_SAFENUM_type            (symbol_c *type_symbol);
-bool is_ANY_signed_NUM_compatible          (symbol_c *type_symbol);
-
-bool is_ANY_BIT_type                       (symbol_c *type_symbol);
-bool is_ANY_SAFEBIT_type                   (symbol_c *type_symbol);
-bool is_ANY_BIT_compatible                 (symbol_c *type_symbol);
-
-bool is_BOOL_type                          (symbol_c *type_symbol);
-bool is_SAFEBOOL_type                      (symbol_c *type_symbol);
-bool is_ANY_BOOL_compatible                (symbol_c *type_symbol);
 
 
 bool is_type_equal(symbol_c *first_type, symbol_c *second_type);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stage3/declaration_check.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -0,0 +1,179 @@
+/*
+ *  matiec - a compiler for the programming languages defined in IEC 61131-3
+ *
+ *  Copyright (C) 2003-2012  Mario de Sousa (msousa@fe.up.pt)
+ *  Copyright (C) 2012       Manuele Conti (conti.ma@alice.it)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+/*
+ * An IEC 61131-3 compiler.
+ *
+ * Based on the
+ * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
+ *
+ */
+
+
+/* Declaration sequence is a source code part needed to declare variables.
+ * There are some checks we need to do before start with other analysis:
+ *
+ *   - Check external option redefinition.
+ *   - Check external data type redefinition.
+ *   - Check initial values consistently with the data types of the variables/data types being declared.
+ *   - Check whether a function block uses a CONSTANT qualifier as described in 2.5.2.1.
+ *
+ */
+
+
+#include "declaration_check.hh"
+#include "datatype_functions.hh"
+
+#define FIRST_(symbol1, symbol2) (((symbol1)->first_order < (symbol2)->first_order)   ? (symbol1) : (symbol2))
+#define  LAST_(symbol1, symbol2) (((symbol1)->last_order  > (symbol2)->last_order)    ? (symbol1) : (symbol2))
+
+#define STAGE3_ERROR(error_level, symbol1, symbol2, ...) {                                                                  \
+  if (current_display_error_level >= error_level) {                                                                         \
+    fprintf(stderr, "%s:%d-%d..%d-%d: error: ",                                                                             \
+            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
+                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
+    fprintf(stderr, __VA_ARGS__);                                                                                           \
+    fprintf(stderr, "\n");                                                                                                  \
+    error_count++;                                                                                                     \
+  }                                                                                                                         \
+}
+
+
+#define STAGE3_WARNING(symbol1, symbol2, ...) {                                                                             \
+    fprintf(stderr, "%s:%d-%d..%d-%d: warning: ",                                                                           \
+            FIRST_(symbol1,symbol2)->first_file, FIRST_(symbol1,symbol2)->first_line, FIRST_(symbol1,symbol2)->first_column,\
+                                                 LAST_(symbol1,symbol2) ->last_line,  LAST_(symbol1,symbol2) ->last_column);\
+    fprintf(stderr, __VA_ARGS__);                                                                                           \
+    fprintf(stderr, "\n");                                                                                                  \
+    warning_found = true;                                                                                                   \
+}
+
+
+declaration_check_c::declaration_check_c(symbol_c *ignore) {
+  current_display_error_level = 0;
+  current_pou_decl = NULL;
+  error_count = 0;
+}
+
+declaration_check_c::~declaration_check_c(void) {
+
+}
+
+int declaration_check_c::get_error_count() {
+  return error_count;
+}
+
+void declaration_check_c::check_global_decl(symbol_c *p_decl) {
+	symbol_c *var_name;
+	search_base_type_c search_base_type;
+
+	search_var_instance_decl_c search_var_instance_glo_decl(current_pou_decl);
+	search_var_instance_decl_c search_var_instance_ext_decl(p_decl);
+	function_param_iterator_c fpi(p_decl);
+	while((var_name = fpi.next()) != NULL) {
+      if (fpi.param_direction() == function_param_iterator_c::direction_extref) {
+     	 /* found an external reference parameter. */
+     	symbol_c *glo_decl = search_var_instance_glo_decl.get_decl(var_name);
+        symbol_c *ext_decl = search_var_instance_ext_decl.get_decl(var_name);
+    	if (glo_decl == NULL) {
+    	  STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error an external doesn't mach with any global var.");
+    	  continue;
+    	}
+        if (search_var_instance_glo_decl.get_option(var_name) != search_var_instance_ext_decl.get_option(var_name))
+          STAGE3_ERROR(0, glo_decl, glo_decl, "Declaration error an external redefinition option.");
+
+        /* TODO: Check redefinition data type.
+         *       We need a new class (like search_base_type class) to get type id by variable declaration.
+         *  symbol_c *glo_type = ????;
+         *  symbol_c *ext_type = fpi.param_type();
+	 */
+	/* For the moment, we will just use search_base_type_c instead... */
+        symbol_c *glo_type = search_base_type.get_basetype_decl(glo_decl);
+        symbol_c *ext_type = search_base_type.get_basetype_decl(ext_decl);
+        if (! is_type_equal(glo_type, ext_type))
+          STAGE3_ERROR(0, ext_decl, ext_decl, "Declaration error an external redefinition data type.");
+      }
+	}
+
+}
+
+
+
+/*****************************/
+/* B 1.5.2 - Function Blocks */
+/*****************************/
+/*  FUNCTION_BLOCK derived_function_block_name io_OR_other_var_declarations function_block_body END_FUNCTION_BLOCK */
+// SYM_REF3(function_block_declaration_c, fblock_name, var_declarations, fblock_body)
+void *declaration_check_c::visit(function_block_declaration_c *symbol) {
+  current_pou_decl = symbol;
+  /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
+  if (NULL != symbol->var_declarations)
+    symbol->var_declarations->accept(*this);
+  return NULL;
+}
+
+/******************************************/
+/* B 1.5.3 - Declaration & Initialisation */
+/******************************************/
+/*  PROGRAM program_type_name program_var_declarations_list function_block_body END_PROGRAM */
+// SYM_REF3(program_declaration_c, program_type_name, var_declarations, function_block_body)
+void *declaration_check_c::visit(program_declaration_c *symbol) {
+  current_pou_decl = symbol;
+  /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
+  if (NULL != symbol->var_declarations)
+    symbol->var_declarations->accept(*this);
+  return NULL;
+}
+
+/********************************/
+/* B 1.7 Configuration elements */
+/********************************/
+/*
+ * CONFIGURATION configuration_name
+ *    optional_global_var_declarations
+ *    (resource_declaration_list | single_resource_declaration)
+ *    optional_access_declarations
+ *    optional_instance_specific_initializations
+ * END_CONFIGURATION
+ */
+//SYM_REF5(configuration_declaration_c, configuration_name, global_var_declarations, resource_declarations, access_declarations, instance_specific_initializations)
+void *declaration_check_c::visit(configuration_declaration_c *symbol) {
+  current_pou_decl = symbol;
+  /* check if any FB declared as a VAR has any incompatible VAR_EXTERNAL declarations */
+  if (NULL != symbol->resource_declarations)
+    symbol->resource_declarations->accept(*this);
+  return NULL;
+}
+
+void *declaration_check_c::visit(program_configuration_c *symbol) {
+  symbol_c *p_decl = program_type_symtable.find_value(symbol->program_type_name);
+  if (p_decl == program_type_symtable.end_value())
+    p_decl = function_block_type_symtable.find_value(symbol->program_type_name);
+  /* stage1_2 guarantees that we are sure to find a declaration in FB or Program symtable. */
+  if (p_decl == function_block_type_symtable.end_value())
+    ERROR;
+  check_global_decl(p_decl);
+  return NULL;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/stage3/declaration_check.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ *  matiec - a compiler for the programming languages defined in IEC 61131-3
+ *
+ *  Copyright (C) 2003-2012  Mario de Sousa (msousa@fe.up.pt)
+ *  Copyright (C) 2012       Manuele Conti (conti.ma@alice.it)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *
+ * This code is made available on the understanding that it will not be
+ * used in safety-critical situations without a full and competent review.
+ */
+
+/*
+ * An IEC 61131-3 compiler.
+ *
+ * Based on the
+ * FINAL DRAFT - IEC 61131-3, 2nd Ed. (2001-12-10)
+ *
+ */
+
+#include <vector>
+
+#include "../absyntax_utils/absyntax_utils.hh"
+
+
+class declaration_check_c : public iterator_visitor_c {
+    int error_count;
+    int current_display_error_level;
+    search_base_type_c search_base_type;
+    symbol_c *current_pou_decl;
+
+public:
+    declaration_check_c(symbol_c *ignore);
+    virtual ~declaration_check_c(void);
+    int get_error_count();
+
+    void check_global_decl(symbol_c *p_decl);
+
+    /*****************************/
+    /* B 1.5.2 - Function Blocks */
+    /*****************************/
+    void *visit(function_block_declaration_c *symbol);
+
+    /******************************************/
+    /* B 1.5.3 - Declaration & Initialisation */
+    /******************************************/
+    void *visit(program_declaration_c *symbol);
+
+    /********************************/
+    /* B 1.7 Configuration elements */
+    /********************************/
+    void *visit(configuration_declaration_c *symbol);
+    void *visit(program_configuration_c *symbol);
+};
--- a/stage3/fill_candidate_datatypes.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/fill_candidate_datatypes.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -72,6 +72,9 @@
 static int debug = 0;
 
 fill_candidate_datatypes_c::fill_candidate_datatypes_c(symbol_c *ignore) {
+	il_operand = NULL;
+	prev_il_instruction = NULL;
+	search_varfb_instance_type = NULL;
 }
 
 fill_candidate_datatypes_c::~fill_candidate_datatypes_c(void) {
@@ -403,6 +406,7 @@
 }
 
 
+
 /* handle a binary ST expression, like '+', '-', etc... */
 void *fill_candidate_datatypes_c::handle_binary_expression(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr) {
 	l_expr->accept(*this);
@@ -412,6 +416,22 @@
 
 
 
+/* handle the two equality comparison operations, i.e. = (euqal) and != (not equal) */
+/* This function is special, as it will also allow enumeration data types to be compared, with the result being a BOOL data type!
+ * This possibility os not expressed in the 'widening' tables, so we need to hard code it here
+ */
+void *fill_candidate_datatypes_c::handle_equality_comparison(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr) {
+	search_base_type_c search_base_type;
+	handle_binary_expression(widen_table, symbol, l_expr, r_expr);
+	for(unsigned int i = 0; i < l_expr->candidate_datatypes.size(); i++)
+		for(unsigned int j = 0; j < r_expr->candidate_datatypes.size(); j++) {
+			if ((l_expr->candidate_datatypes[i] == r_expr->candidate_datatypes[j]) && search_base_type.type_is_enumerated(l_expr->candidate_datatypes[i]))
+				add_datatype_to_candidate_list(symbol, &search_constant_type_c::bool_type_name);
+		}
+	return NULL;
+}
+
+
 
 /* a helper function... */
 symbol_c *fill_candidate_datatypes_c::base_type(symbol_c *symbol) {
@@ -466,7 +486,7 @@
 	if (search_in_candidate_datatype_list(symbol_type, symbol_value->candidate_datatypes) >= 0)
 		add_datatype_to_candidate_list(symbol, symbol_type);
 	remove_incompatible_datatypes(symbol);
-	if (debug) std::cout << "XXX_LITERAL [" << symbol->candidate_datatypes.size() << "]\n";
+	if (debug) std::cout << "ANY_LITERAL [" << symbol->candidate_datatypes.size() << "]\n";
 	return NULL;
 }
 
@@ -478,6 +498,7 @@
 
 
 void *fill_candidate_datatypes_c::visit(neg_integer_c *symbol) {
+	/* Please read the comment in neg_expression_c method, as it also applies here */
 	add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::int_type_name, &search_constant_type_c::safeint_type_name);
 	add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::sint_type_name, &search_constant_type_c::safesint_type_name);
 	add_2datatypes_to_candidate_list(symbol, &search_constant_type_c::dint_type_name, &search_constant_type_c::safedint_type_name);
@@ -1154,7 +1175,7 @@
 
 void *fill_candidate_datatypes_c::visit(LDN_operator_c *symbol) {
 	for(unsigned int i = 0; i < il_operand->candidate_datatypes.size(); i++) {
-		if      (is_ANY_BIT_compatible(il_operand->candidate_datatypes[i]))
+		if      (get_datatype_info_c::is_ANY_BIT_compatible(il_operand->candidate_datatypes[i]))
 			add_datatype_to_candidate_list(symbol, il_operand->candidate_datatypes[i]);
 	}
 	if (debug) std::cout << "LDN [" << il_operand->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
@@ -1185,7 +1206,7 @@
 		for(unsigned int j = 0; j < il_operand->candidate_datatypes.size(); j++) {
 			prev_instruction_type = prev_il_instruction->candidate_datatypes[i];
 			operand_type = il_operand->candidate_datatypes[j];
-			if (is_type_equal(prev_instruction_type,operand_type) && is_ANY_BIT_compatible(operand_type))
+			if (is_type_equal(prev_instruction_type,operand_type) && get_datatype_info_c::is_ANY_BIT_compatible(operand_type))
 				add_datatype_to_candidate_list(symbol, prev_instruction_type);
 		}
 	}
@@ -1202,7 +1223,7 @@
 	 */
 	if (NULL == prev_il_instruction) return NULL;
 	for (unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) {
-		if (is_ANY_BIT_compatible(prev_il_instruction->candidate_datatypes[i]))
+		if (get_datatype_info_c::is_ANY_BIT_compatible(prev_il_instruction->candidate_datatypes[i]))
 			add_datatype_to_candidate_list(symbol, prev_il_instruction->candidate_datatypes[i]);
 	}
 	if (debug) std::cout <<  "NOT_operator [" << prev_il_instruction->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
@@ -1223,7 +1244,7 @@
 			 * the prev_instruction_type MUST be BOOL compatible.
 			 * I am not too sure about operand_type, does it have to be BOOL compatible, or can it be ANY_BIT compatible? Must check!
 			 */
-			if (is_type_equal(prev_instruction_type,operand_type) && is_ANY_BOOL_compatible(operand_type))
+			if (is_type_equal(prev_instruction_type,operand_type) && get_datatype_info_c::is_BOOL_compatible(operand_type))
 				add_datatype_to_candidate_list(symbol, prev_instruction_type);
 		}
 	}
@@ -1245,7 +1266,7 @@
 			 * the prev_instruction_type MUST be BOOL compatible.
 			 * I am not too sure about operand_type, does it have to be BOOL compatible, or can it be ANY_BIT compatible? Must check!
 			 */
-			if (is_type_equal(prev_instruction_type,operand_type) && is_ANY_BOOL_compatible(operand_type))
+			if (is_type_equal(prev_instruction_type,operand_type) && get_datatype_info_c::is_BOOL_compatible(operand_type))
 				add_datatype_to_candidate_list(symbol, prev_instruction_type);
 		}
 	}
@@ -1288,7 +1309,7 @@
 void *fill_candidate_datatypes_c::handle_conditional_il_flow_control_operator(symbol_c *symbol) {
 	if (NULL == prev_il_instruction) return NULL;
 	for (unsigned int i = 0; i < prev_il_instruction->candidate_datatypes.size(); i++) {
-		if (is_ANY_BOOL_compatible(prev_il_instruction->candidate_datatypes[i]))
+		if (get_datatype_info_c::is_BOOL_compatible(prev_il_instruction->candidate_datatypes[i]))
 			add_datatype_to_candidate_list(symbol, prev_il_instruction->candidate_datatypes[i]);
 	}
 	return NULL;
@@ -1318,45 +1339,23 @@
 /***********************/
 /* B 3.1 - Expressions */
 /***********************/
-void *fill_candidate_datatypes_c::visit(   or_expression_c  *symbol) {return handle_binary_expression(widen_OR_table,  symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(   xor_expression_c *symbol) {return handle_binary_expression(widen_XOR_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(   and_expression_c *symbol) {return handle_binary_expression(widen_AND_table, symbol, symbol->l_exp, symbol->r_exp);}
-
-void *fill_candidate_datatypes_c::visit(   equ_expression_c *symbol) {return handle_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(notequ_expression_c *symbol) {return handle_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(    lt_expression_c *symbol) {return handle_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(    gt_expression_c *symbol) {return handle_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(    le_expression_c *symbol) {return handle_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(    ge_expression_c *symbol) {return handle_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-
-
-/* The following code is correct when handling the addition of 2 symbolic_variables
- * In this case, adding two variables (e.g. USINT_var1 + USINT_var2) will always yield
- * the same data type, even if the result of the adition could not fit inside the same
- * data type (due to overflowing)
- *
- * However, when adding two literals (e.g. USINT#42 + USINT#3)
- * we should be able to detect overflows of the result, and therefore not consider
- * that the result may be of type USINT.
- * Currently we do not yet detect these overflows, and allow handling the sum of two USINTs
- * as always resulting in an USINT, even in the following expression
- * (USINT#65535 + USINT#2).
- *
- * In the future we can add some code to reduce
- * all the expressions that are based on literals into the resulting literal
- * value (maybe some visitor class that will run before or after data type
- * checking). Since this class will have to be very careful to make sure it implements the same mathematical
- * details (e.g. how to round and truncate numbers) as defined in IEC 61131-3, we will leave this to the future.
- * Also, the question will arise if we should also replace calls to standard
- * functions if the input parameters are all literals (e.g. ADD(42, 42)). This
- * means this class will be more difficult than it appears at first.
- */
-void *fill_candidate_datatypes_c::visit(  add_expression_c *symbol) {return handle_binary_expression(widen_ADD_table,  symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(  sub_expression_c *symbol) {return handle_binary_expression(widen_SUB_table,  symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(  mul_expression_c *symbol) {return handle_binary_expression(widen_MUL_table,  symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(  div_expression_c *symbol) {return handle_binary_expression(widen_DIV_table,  symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(  mod_expression_c *symbol) {return handle_binary_expression(widen_MOD_table,  symbol, symbol->l_exp, symbol->r_exp);}
-void *fill_candidate_datatypes_c::visit(power_expression_c *symbol) {return handle_binary_expression(widen_EXPT_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(   or_expression_c  *symbol) {return handle_binary_expression  (widen_OR_table,  symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(   xor_expression_c *symbol) {return handle_binary_expression  (widen_XOR_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(   and_expression_c *symbol) {return handle_binary_expression  (widen_AND_table, symbol, symbol->l_exp, symbol->r_exp);}
+
+void *fill_candidate_datatypes_c::visit(   equ_expression_c *symbol) {return handle_equality_comparison(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(notequ_expression_c *symbol) {return handle_equality_comparison(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(    lt_expression_c *symbol) {return handle_binary_expression  (widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(    gt_expression_c *symbol) {return handle_binary_expression  (widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(    le_expression_c *symbol) {return handle_binary_expression  (widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(    ge_expression_c *symbol) {return handle_binary_expression  (widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+ 
+void *fill_candidate_datatypes_c::visit(   add_expression_c *symbol) {return handle_binary_expression  (widen_ADD_table,  symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(   sub_expression_c *symbol) {return handle_binary_expression  (widen_SUB_table,  symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(   mul_expression_c *symbol) {return handle_binary_expression  (widen_MUL_table,  symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(   div_expression_c *symbol) {return handle_binary_expression  (widen_DIV_table,  symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit(   mod_expression_c *symbol) {return handle_binary_expression  (widen_MOD_table,  symbol, symbol->l_exp, symbol->r_exp);}
+void *fill_candidate_datatypes_c::visit( power_expression_c *symbol) {return handle_binary_expression  (widen_EXPT_table, symbol, symbol->l_exp, symbol->r_exp);}
 
 
 void *fill_candidate_datatypes_c::visit(neg_expression_c *symbol) {
@@ -1371,11 +1370,19 @@
    *
    *       However, this would then mean that the following ST code would be 
    *       syntactically and semantically correct:
+   *       VAR uint_var : UINT END_VAR;
    *       uint_var := - (uint_var);
    *
-   *       According to the standard, the above code should result in a 
-   *       runtime error, when we try to apply a negative value to the
-   *       UINT typed variable 'uint_var'.
+   *       Assuming uint_var is not 0, the standard states that the above code should result in a 
+   *       runtime error since the operation will result in an overflow. Since the above operation
+   *       is only valid when uint_var=0, it would probably make more sense for the programmer to
+   *       use if (uint_var=0) ..., so we will simply assume that the above statement simply
+   *       does not make sense in any situation (whether or not uint_var is 0), and therefore
+   *       we will not allow it.
+   *       (Notice that doing so does not ago against the standard, as the standard does not
+   *       explicitly define the semantics of the NEG operator, nor the data types it may accept
+   *       as input. We are simply assuming that the NEG operator may not be applied to unsigned
+   *       ANY_NUM data types!).
    *
    *       It is much easier for the compiler to detect this at compile time,
    *       and it is probably safer to the resulting code too.
@@ -1383,10 +1390,12 @@
    *       To detect these tyes of errors at compile time, the easisest solution
    *       is to only allow ANY_NUM datatytpes that are signed.
    *        So, that is what we do here!
+   *
+   * NOTE: The above argument also applies to the neg_integer_c method!
    */
 	symbol->exp->accept(*this);
 	for (unsigned int i = 0; i < symbol->exp->candidate_datatypes.size(); i++) {
-		if (is_ANY_signed_MAGNITUDE_compatible(symbol->exp->candidate_datatypes[i]))
+		if (get_datatype_info_c::is_ANY_signed_MAGNITUDE_compatible(symbol->exp->candidate_datatypes[i]))
 			add_datatype_to_candidate_list(symbol, symbol->exp->candidate_datatypes[i]);
 	}
 	if (debug) std::cout << "neg [" << symbol->exp->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
@@ -1397,7 +1406,7 @@
 void *fill_candidate_datatypes_c::visit(not_expression_c *symbol) {
 	symbol->exp->accept(*this);
 	for (unsigned int i = 0; i < symbol->exp->candidate_datatypes.size(); i++) {
-		if      (is_ANY_BIT_compatible(symbol->exp->candidate_datatypes[i]))
+		if      (get_datatype_info_c::is_ANY_BIT_compatible(symbol->exp->candidate_datatypes[i]))
 			add_datatype_to_candidate_list(symbol, symbol->exp->candidate_datatypes[i]);
 	}
 	if (debug) std::cout << "not [" << symbol->exp->candidate_datatypes.size() << "] ==> "  << symbol->candidate_datatypes.size() << " result.\n";
--- a/stage3/fill_candidate_datatypes.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/fill_candidate_datatypes.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -99,8 +99,9 @@
     bool  match_formal_call   (symbol_c *f_call, symbol_c *f_decl, symbol_c **first_param_datatype = NULL);
     void  handle_function_call(symbol_c *fcall, generic_function_call_t fcall_data);
     void *handle_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration);
-    void *handle_binary_expression(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr);
-    void *handle_binary_operator  (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr);
+    void *handle_equality_comparison(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr);
+    void *handle_binary_expression  (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr);
+    void *handle_binary_operator    (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr);
     void *handle_conditional_il_flow_control_operator(symbol_c *symbol);
     
     /* a helper function... */
--- a/stage3/flow_control_analysis.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/flow_control_analysis.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -123,6 +123,8 @@
 flow_control_analysis_c::flow_control_analysis_c(symbol_c *ignore) {
   prev_il_instruction = NULL;
   curr_il_instruction = NULL;
+  prev_il_instruction_is_JMP_or_RET = false;
+  search_il_label = NULL;
 }
 
 flow_control_analysis_c::~flow_control_analysis_c(void) {
--- a/stage3/lvalue_check.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/lvalue_check.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -73,6 +73,8 @@
 	error_count = 0;
 	current_display_error_level = 0;
 	current_il_operand = NULL;
+	search_varfb_instance_type = NULL;
+	search_var_instance_decl = NULL;
 }
 
 lvalue_check_c::~lvalue_check_c(void) {
--- a/stage3/narrow_candidate_datatypes.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/narrow_candidate_datatypes.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -66,6 +66,11 @@
 static int debug = 0;
 
 narrow_candidate_datatypes_c::narrow_candidate_datatypes_c(symbol_c *ignore) {
+	prev_il_instructions = NULL;
+	search_varfb_instance_type = NULL;
+	prev_il_instructions_intersected_datatypes = NULL;
+	fake_prev_il_instruction = NULL;
+	il_operand = NULL;
 }
 
 narrow_candidate_datatypes_c::~narrow_candidate_datatypes_c(void) {
@@ -476,7 +481,7 @@
 void *narrow_candidate_datatypes_c::visit(subscript_list_c *symbol) {
 	for (int i = 0; i < symbol->n; i++) {
 		for (unsigned int k = 0; k < symbol->elements[i]->candidate_datatypes.size(); k++) {
-			if (is_ANY_INT_type(symbol->elements[i]->candidate_datatypes[k]))
+			if (get_datatype_info_c::is_ANY_INT(symbol->elements[i]->candidate_datatypes[k]))
 				symbol->elements[i]->datatype = symbol->elements[i]->candidate_datatypes[k];
 		}
 		symbol->elements[i]->accept(*this);
@@ -1005,7 +1010,7 @@
 	/* if the next IL instructions needs us to provide a datatype other than a bool, 
 	 * then we have an internal compiler error - most likely in fill_candidate_datatypes_c 
 	 */
-	if ((NULL != symbol->datatype) && (!is_ANY_BOOL_compatible(symbol->datatype))) ERROR;
+	if ((NULL != symbol->datatype) && (!get_datatype_info_c::is_BOOL_compatible(symbol->datatype))) ERROR;
 	if (symbol->candidate_datatypes.size() > 1) ERROR;
 
 	/* NOTE: If there is no IL instruction following this CALC, CALCN, JMPC, JMPC, ..., instruction,
@@ -1014,7 +1019,7 @@
 	 */
 	if (symbol->candidate_datatypes.size() == 0)    symbol->datatype = NULL;
 	else    symbol->datatype = symbol->candidate_datatypes[0]; /* i.e. a bool_type_name_c! */
-	if ((NULL != symbol->datatype) && (!is_ANY_BOOL_compatible(symbol->datatype))) ERROR;
+	if ((NULL != symbol->datatype) && (!get_datatype_info_c::is_BOOL_compatible(symbol->datatype))) ERROR;
 
 	/* set the required datatype of the previous IL instruction, i.e. a bool_type_name_c! */
 	set_datatype_in_prev_il_instructions(symbol->datatype, fake_prev_il_instruction);
@@ -1050,11 +1055,19 @@
 /***********************/
 /* B 3.1 - Expressions */
 /***********************/
-void *narrow_candidate_datatypes_c::narrow_binary_expression(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation) {
+/* allow_enums is FALSE by default!!
+ * deprecated_operation is NULL by default!!
+ * if (allow_enums) then consider that we are ectually processing an equ_expression or notequ_expression, where two enums of the same data type may also be legally compared 
+ *  e.g.      symbol := l_expr == r_expr              
+ *            symbol := l_expr != r_expr
+ *  In the above situation it is a legal operation when (l_expr.datatype == r_expr.datatype) && is_enumerated(r/l_expr.datatype) && is_bool(symbol.datatype)
+ */
+void *narrow_candidate_datatypes_c::narrow_binary_expression(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation, bool allow_enums) {
 	symbol_c *l_type, *r_type;
 	int count = 0;
-
-        if (NULL != deprecated_operation)
+	search_base_type_c search_base_type;
+
+	if (NULL != deprecated_operation)
 		*deprecated_operation = false;
 
 	for(unsigned int i = 0; i < l_expr->candidate_datatypes.size(); i++) {
@@ -1062,11 +1075,17 @@
 			/* test widening compatibility */
 			l_type = l_expr->candidate_datatypes[i];
 			r_type = r_expr->candidate_datatypes[j];
-			if (is_widening_compatible(widen_table, l_type, r_type, symbol->datatype, deprecated_operation)) {
+			if        (is_widening_compatible(widen_table, l_type, r_type, symbol->datatype, deprecated_operation)) {
+				l_expr->datatype = l_type;
+				r_expr->datatype = r_type;
+				count ++;
+			} else if ((l_type == r_type) && search_base_type.type_is_enumerated(l_type) && get_datatype_info_c::is_BOOL_compatible(symbol->datatype)) {
+				if (NULL != deprecated_operation)  *deprecated_operation = false;
 				l_expr->datatype = l_type;
 				r_expr->datatype = r_type;
 				count ++;
 			}
+			  
 		}
 	}
 // 	if (count > 1) ERROR; /* Since we also support SAFE data types, this assertion is not necessarily always tru! */
@@ -1078,24 +1097,28 @@
 }
 
 
-
-void *narrow_candidate_datatypes_c::visit(    or_expression_c *symbol) {return narrow_binary_expression( widen_OR_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *narrow_candidate_datatypes_c::visit(   xor_expression_c *symbol) {return narrow_binary_expression(widen_XOR_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *narrow_candidate_datatypes_c::visit(   and_expression_c *symbol) {return narrow_binary_expression(widen_AND_table, symbol, symbol->l_exp, symbol->r_exp);}
-
-void *narrow_candidate_datatypes_c::visit(   equ_expression_c *symbol) {return narrow_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *narrow_candidate_datatypes_c::visit(notequ_expression_c *symbol) {return narrow_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *narrow_candidate_datatypes_c::visit(    lt_expression_c *symbol) {return narrow_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *narrow_candidate_datatypes_c::visit(    gt_expression_c *symbol) {return narrow_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *narrow_candidate_datatypes_c::visit(    le_expression_c *symbol) {return narrow_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *narrow_candidate_datatypes_c::visit(    ge_expression_c *symbol) {return narrow_binary_expression(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
-
-void *narrow_candidate_datatypes_c::visit(   add_expression_c *symbol) {return narrow_binary_expression(widen_ADD_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
-void *narrow_candidate_datatypes_c::visit(   sub_expression_c *symbol) {return narrow_binary_expression(widen_SUB_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
-void *narrow_candidate_datatypes_c::visit(   mul_expression_c *symbol) {return narrow_binary_expression(widen_MUL_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
-void *narrow_candidate_datatypes_c::visit(   div_expression_c *symbol) {return narrow_binary_expression(widen_DIV_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
-void *narrow_candidate_datatypes_c::visit(   mod_expression_c *symbol) {return narrow_binary_expression(widen_MOD_table, symbol, symbol->l_exp, symbol->r_exp);}
-void *narrow_candidate_datatypes_c::visit( power_expression_c *symbol) {return narrow_binary_expression(widen_EXPT_table,symbol, symbol->l_exp, symbol->r_exp);}
+void *narrow_candidate_datatypes_c::narrow_equality_comparison(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation) {
+	return narrow_binary_expression(widen_table, symbol, l_expr, r_expr, deprecated_operation, true);
+}
+
+
+void *narrow_candidate_datatypes_c::visit(    or_expression_c *symbol) {return narrow_binary_expression  ( widen_OR_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *narrow_candidate_datatypes_c::visit(   xor_expression_c *symbol) {return narrow_binary_expression  (widen_XOR_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *narrow_candidate_datatypes_c::visit(   and_expression_c *symbol) {return narrow_binary_expression  (widen_AND_table, symbol, symbol->l_exp, symbol->r_exp);}
+
+void *narrow_candidate_datatypes_c::visit(   equ_expression_c *symbol) {return narrow_equality_comparison(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *narrow_candidate_datatypes_c::visit(notequ_expression_c *symbol) {return narrow_equality_comparison(widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *narrow_candidate_datatypes_c::visit(    lt_expression_c *symbol) {return narrow_binary_expression  (widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *narrow_candidate_datatypes_c::visit(    gt_expression_c *symbol) {return narrow_binary_expression  (widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *narrow_candidate_datatypes_c::visit(    le_expression_c *symbol) {return narrow_binary_expression  (widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *narrow_candidate_datatypes_c::visit(    ge_expression_c *symbol) {return narrow_binary_expression  (widen_CMP_table, symbol, symbol->l_exp, symbol->r_exp);}
+
+void *narrow_candidate_datatypes_c::visit(   add_expression_c *symbol) {return narrow_binary_expression  (widen_ADD_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
+void *narrow_candidate_datatypes_c::visit(   sub_expression_c *symbol) {return narrow_binary_expression  (widen_SUB_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
+void *narrow_candidate_datatypes_c::visit(   mul_expression_c *symbol) {return narrow_binary_expression  (widen_MUL_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
+void *narrow_candidate_datatypes_c::visit(   div_expression_c *symbol) {return narrow_binary_expression  (widen_DIV_table, symbol, symbol->l_exp, symbol->r_exp, &symbol->deprecated_operation);}
+void *narrow_candidate_datatypes_c::visit(   mod_expression_c *symbol) {return narrow_binary_expression  (widen_MOD_table, symbol, symbol->l_exp, symbol->r_exp);}
+void *narrow_candidate_datatypes_c::visit( power_expression_c *symbol) {return narrow_binary_expression  (widen_EXPT_table,symbol, symbol->l_exp, symbol->r_exp);}
 
 
 void *narrow_candidate_datatypes_c::visit(neg_expression_c *symbol) {
@@ -1182,7 +1205,7 @@
 
 void *narrow_candidate_datatypes_c::visit(if_statement_c *symbol) {
 	for(unsigned int i = 0; i < symbol->expression->candidate_datatypes.size(); i++) {
-		if (is_ANY_BOOL_compatible(symbol->expression->candidate_datatypes[i]))
+		if (get_datatype_info_c::is_BOOL_compatible(symbol->expression->candidate_datatypes[i]))
 			symbol->expression->datatype = symbol->expression->candidate_datatypes[i];
 	}
 	symbol->expression->accept(*this);
@@ -1198,7 +1221,7 @@
 
 void *narrow_candidate_datatypes_c::visit(elseif_statement_c *symbol) {
 	for (unsigned int i = 0; i < symbol->expression->candidate_datatypes.size(); i++) {
-		if (is_ANY_BOOL_compatible(symbol->expression->candidate_datatypes[i]))
+		if (get_datatype_info_c::is_BOOL_compatible(symbol->expression->candidate_datatypes[i]))
 			symbol->expression->datatype = symbol->expression->candidate_datatypes[i];
 	}
 	symbol->expression->accept(*this);
@@ -1211,7 +1234,7 @@
 // SYM_REF3(case_statement_c, expression, case_element_list, statement_list)
 void *narrow_candidate_datatypes_c::visit(case_statement_c *symbol) {
 	for (unsigned int i = 0; i < symbol->expression->candidate_datatypes.size(); i++) {
-		if ((is_ANY_INT_type(symbol->expression->candidate_datatypes[i]))
+		if ((get_datatype_info_c::is_ANY_INT(symbol->expression->candidate_datatypes[i]))
 				 || (search_base_type.type_is_enumerated(symbol->expression->candidate_datatypes[i])))
 			symbol->expression->datatype = symbol->expression->candidate_datatypes[i];
 	}
@@ -1264,7 +1287,7 @@
 void *narrow_candidate_datatypes_c::visit(for_statement_c *symbol) {
 	/* Control variable */
 	for(unsigned int i = 0; i < symbol->control_variable->candidate_datatypes.size(); i++) {
-		if (is_ANY_INT_type(symbol->control_variable->candidate_datatypes[i])) {
+		if (get_datatype_info_c::is_ANY_INT(symbol->control_variable->candidate_datatypes[i])) {
 			symbol->control_variable->datatype = symbol->control_variable->candidate_datatypes[i];
 		}
 	}
@@ -1272,7 +1295,7 @@
 	/* BEG expression */
 	for(unsigned int i = 0; i < symbol->beg_expression->candidate_datatypes.size(); i++) {
 		if (is_type_equal(symbol->control_variable->datatype,symbol->beg_expression->candidate_datatypes[i]) &&
-				is_ANY_INT_type(symbol->beg_expression->candidate_datatypes[i])) {
+				get_datatype_info_c::is_ANY_INT(symbol->beg_expression->candidate_datatypes[i])) {
 			symbol->beg_expression->datatype = symbol->beg_expression->candidate_datatypes[i];
 		}
 	}
@@ -1280,7 +1303,7 @@
 	/* END expression */
 	for(unsigned int i = 0; i < symbol->end_expression->candidate_datatypes.size(); i++) {
 		if (is_type_equal(symbol->control_variable->datatype,symbol->end_expression->candidate_datatypes[i]) &&
-				is_ANY_INT_type(symbol->end_expression->candidate_datatypes[i])) {
+				get_datatype_info_c::is_ANY_INT(symbol->end_expression->candidate_datatypes[i])) {
 			symbol->end_expression->datatype = symbol->end_expression->candidate_datatypes[i];
 		}
 	}
@@ -1289,7 +1312,7 @@
 	if (NULL != symbol->by_expression) {
 		for(unsigned int i = 0; i < symbol->by_expression->candidate_datatypes.size(); i++) {
 			if (is_type_equal(symbol->control_variable->datatype,symbol->by_expression->candidate_datatypes[i]) &&
-					is_ANY_INT_type(symbol->by_expression->candidate_datatypes[i])) {
+					get_datatype_info_c::is_ANY_INT(symbol->by_expression->candidate_datatypes[i])) {
 				symbol->by_expression->datatype = symbol->by_expression->candidate_datatypes[i];
 			}
 		}
@@ -1302,7 +1325,7 @@
 
 void *narrow_candidate_datatypes_c::visit(while_statement_c *symbol) {
 	for (unsigned int i = 0; i < symbol->expression->candidate_datatypes.size(); i++) {
-		if(is_BOOL_type(symbol->expression->candidate_datatypes[i]))
+		if(get_datatype_info_c::is_BOOL(symbol->expression->candidate_datatypes[i]))
 			symbol->expression->datatype = symbol->expression->candidate_datatypes[i];
 	}
 	symbol->expression->accept(*this);
@@ -1313,7 +1336,7 @@
 
 void *narrow_candidate_datatypes_c::visit(repeat_statement_c *symbol) {
 	for (unsigned int i = 0; i < symbol->expression->candidate_datatypes.size(); i++) {
-		if(is_BOOL_type(symbol->expression->candidate_datatypes[i]))
+		if(get_datatype_info_c::is_BOOL(symbol->expression->candidate_datatypes[i]))
 			symbol->expression->datatype = symbol->expression->candidate_datatypes[i];
 	}
 	symbol->expression->accept(*this);
--- a/stage3/narrow_candidate_datatypes.hh	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/narrow_candidate_datatypes.hh	Thu Oct 04 15:10:45 2012 +0100
@@ -75,8 +75,9 @@
     void *narrow_implicit_il_fb_call(symbol_c *il_instruction, const char *param_name, symbol_c *&called_fb_declaration);
 
     void *handle_il_instruction(symbol_c *symbol);
-    void *narrow_binary_operator  (const struct widen_entry widen_table[], symbol_c *symbol,                                     bool *deprecated_operation = NULL);
-    void *narrow_binary_expression(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation = NULL);
+    void *narrow_binary_operator    (const struct widen_entry widen_table[], symbol_c *symbol,                                     bool *deprecated_operation = NULL);
+    void *narrow_binary_expression  (const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation = NULL, bool allow_enums = false);
+    void *narrow_equality_comparison(const struct widen_entry widen_table[], symbol_c *symbol, symbol_c *l_expr, symbol_c *r_expr, bool *deprecated_operation = NULL);
 
     void *narrow_conditional_flow_control_IL_instruction(symbol_c *symbol);
 
--- a/stage3/stage3.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage3/stage3.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -41,8 +41,13 @@
 #include "lvalue_check.hh"
 #include "array_range_check.hh"
 #include "constant_folding.hh"
+#include "declaration_check.hh"
 
-
+static int declaration_safety(symbol_c *tree_root){
+    declaration_check_c declaration_check(tree_root);
+    tree_root->accept(declaration_check);
+    return declaration_check.get_error_count();
+}
 
 static int flow_control_analysis(symbol_c *tree_root){
     flow_control_analysis_c flow_control_analysis(tree_root);
@@ -99,6 +104,7 @@
 
 int stage3(symbol_c *tree_root){
 	int error_count = 0;
+	error_count += declaration_safety(tree_root);
 	error_count += flow_control_analysis(tree_root);
 	error_count += constant_folding(tree_root);
 	error_count += type_safety(tree_root);
--- a/stage4/Makefile.in	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage4/Makefile.in	Thu Oct 04 15:10:45 2012 +0100
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -209,6 +209,7 @@
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
+$(srcdir)/../common.mk:
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -427,10 +428,15 @@
 
 installcheck: installcheck-recursive
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
--- a/stage4/generate_c/Makefile.in	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage4/generate_c/Makefile.in	Thu Oct 04 15:10:45 2012 +0100
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -64,6 +64,12 @@
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LIBRARIES = $(lib_LIBRARIES)
 AR = ar
@@ -213,6 +219,7 @@
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
+$(srcdir)/../../common.mk:
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -248,13 +255,11 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(libdir)' && rm -f "$$files" )"; \
-	cd "$(DESTDIR)$(libdir)" && rm -f $$files
+	dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir)
 
 clean-libLIBRARIES:
 	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
-libstage4_c.a: $(libstage4_c_a_OBJECTS) $(libstage4_c_a_DEPENDENCIES) 
+libstage4_c.a: $(libstage4_c_a_OBJECTS) $(libstage4_c_a_DEPENDENCIES) $(EXTRA_libstage4_c_a_DEPENDENCIES) 
 	-rm -f libstage4_c.a
 	$(libstage4_c_a_AR) libstage4_c.a $(libstage4_c_a_OBJECTS) $(libstage4_c_a_LIBADD)
 	$(RANLIB) libstage4_c.a
@@ -380,10 +385,15 @@
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic:
--- a/stage4/generate_c/generate_c.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage4/generate_c/generate_c.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -416,7 +416,7 @@
   };
   ERROR; // should never reach this point!
   return 0; // humour the compiler!
-};
+}
 
 /***********************************************************************/
 /***********************************************************************/
@@ -575,7 +575,7 @@
     typedef enum {
       none_im,
       arrayname_im,
-      arraydeclaration_im,
+      arraydeclaration_im
     } inlinearray_mode_t;
 
   private:
@@ -2287,7 +2287,7 @@
     typedef enum {
       none_gm,
       datatypes_gm,
-      pous_gm,
+      pous_gm
     } generate_mode_t;
 
   protected:
--- a/stage4/generate_c/generate_c_il.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage4/generate_c/generate_c_il.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -234,8 +234,6 @@
     search_varfb_instance_type_c *search_varfb_instance_type;
     search_var_instance_decl_c   *search_var_instance_decl;
 
-    search_base_type_c search_base_type;
-
     symbol_c* current_array_type;
     symbol_c* current_param_type;
 
@@ -1889,63 +1887,12 @@
   return NULL;
 }
 
-void *visit(GT_operator_c *symbol)	{
-  if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
-      search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    CMP_operator(this->current_operand, "GT_");
-  } else {
-    ERROR;
-  }
-  return NULL;
-}
-
-void *visit(GE_operator_c *symbol)	{
-  if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
-      search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    CMP_operator(this->current_operand, "GE_");
-  } else {
-    ERROR;
-  }
-  return NULL;
-}
-
-void *visit(EQ_operator_c *symbol)	{
-  if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    CMP_operator(this->current_operand, "EQ_");
-  } else {
-    ERROR;
-  }
-  return NULL;
-}
-
-void *visit(LT_operator_c *symbol)	{
-  if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
-      search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    CMP_operator(this->current_operand, "LT_");
-  } else {
-    ERROR;
-  }
-  return NULL;
-}
-
-void *visit(LE_operator_c *symbol)	{
-  if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
-      search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    CMP_operator(this->current_operand, "LE_");
-  } else {
-    ERROR;
-  }
-  return NULL;
-}
-
-void *visit(NE_operator_c *symbol)	{
-  if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    CMP_operator(this->current_operand, "NE_");
-  } else {
-    ERROR;
-  }
-  return NULL;
-}
+void *visit(GT_operator_c *symbol)	{CMP_operator(this->current_operand, "GT_"); return NULL;}
+void *visit(GE_operator_c *symbol)	{CMP_operator(this->current_operand, "GE_"); return NULL;}
+void *visit(EQ_operator_c *symbol)	{CMP_operator(this->current_operand, "EQ_"); return NULL;}
+void *visit(LT_operator_c *symbol)	{CMP_operator(this->current_operand, "LT_"); return NULL;}
+void *visit(LE_operator_c *symbol)	{CMP_operator(this->current_operand, "LE_"); return NULL;}
+void *visit(NE_operator_c *symbol)	{CMP_operator(this->current_operand, "NE_"); return NULL;}
 
 
 //SYM_REF0(CAL_operator_c)
--- a/stage4/generate_c/generate_c_inlinefcall.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage4/generate_c/generate_c_inlinefcall.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -972,57 +972,12 @@
       return NULL;
     }
 
-    void *visit(GT_operator_c *symbol)	{
-      if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
-          search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-        CMP_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(GE_operator_c *symbol)	{
-      if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
-          search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-        CMP_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(EQ_operator_c *symbol)	{
-      if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-        CMP_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(LT_operator_c *symbol)	{
-      if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
-          search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-        CMP_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(LE_operator_c *symbol)	{
-      if (!search_base_type.type_is_enumerated(this->default_variable_name.current_type) &&
-          search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-        CMP_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(NE_operator_c *symbol)	{
-      if (search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-        CMP_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
+    void *visit(GT_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
+    void *visit(GE_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
+    void *visit(EQ_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
+    void *visit(LT_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
+    void *visit(LE_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
+    void *visit(NE_operator_c *symbol)	{CMP_operator_result_type(); return NULL;}
 
     /***************************************/
     /* B.3 - Language ST (Structured Text) */
--- a/stage4/generate_c/generate_c_st.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage4/generate_c/generate_c_st.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -493,8 +493,7 @@
 void *visit(equ_expression_c *symbol) {
   symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
   symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
-  if (!search_expression_type->is_same_type(left_type, right_type))
-      ERROR;
+  // if (!search_expression_type->is_same_type(left_type, right_type))    ERROR;  // This check is no longer needed!
   if (search_expression_type->is_time_type(left_type) ||
       search_expression_type->is_string_type(left_type))
     return print_compare_function("EQ_", left_type, symbol->l_exp, symbol->r_exp);
@@ -504,8 +503,7 @@
 void *visit(notequ_expression_c *symbol) {
   symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
   symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
-  if (!search_expression_type->is_same_type(left_type, right_type))
-      ERROR;
+  // if (!search_expression_type->is_same_type(left_type, right_type))    ERROR;  // This check is no longer needed!
   if (search_expression_type->is_time_type(left_type) ||
       search_expression_type->is_string_type(left_type))
     return print_compare_function("NE_", left_type, symbol->l_exp, symbol->r_exp);
@@ -515,57 +513,41 @@
 void *visit(lt_expression_c *symbol) {
   symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
   symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
-  if (!search_expression_type->is_same_type(left_type, right_type))
-      ERROR;
+  // if (!search_expression_type->is_same_type(left_type, right_type))    ERROR;  // This check is no longer needed!
   if (search_expression_type->is_time_type(left_type) ||
       search_expression_type->is_string_type(left_type))
     return print_compare_function("LT_", left_type, symbol->l_exp, symbol->r_exp);
-  if (!search_base_type.type_is_enumerated(left_type))
-    return print_binary_expression(symbol->l_exp, symbol->r_exp, " < ");
-  ERROR;
-  return NULL;
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " < ");
 }
 
 void *visit(gt_expression_c *symbol) {
   symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
   symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
-  if (!search_expression_type->is_same_type(left_type, right_type))
-      ERROR;
+  // if (!search_expression_type->is_same_type(left_type, right_type))    ERROR;  // This check is no longer needed!
   if (search_expression_type->is_time_type(left_type) ||
       search_expression_type->is_string_type(left_type))
     return print_compare_function("GT_", left_type, symbol->l_exp, symbol->r_exp);
-  if (!search_base_type.type_is_enumerated(left_type))
-    return print_binary_expression(symbol->l_exp, symbol->r_exp, " > ");
-  ERROR;
-  return NULL;
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " > ");
 }
 
 void *visit(le_expression_c *symbol) {
   symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
   symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
-  if (!search_expression_type->is_same_type(left_type, right_type))
-      ERROR;
+  // if (!search_expression_type->is_same_type(left_type, right_type))    ERROR;  // This check is no longer needed!
   if (search_expression_type->is_time_type(left_type) ||
       search_expression_type->is_string_type(left_type))
     return print_compare_function("LE_", left_type, symbol->l_exp, symbol->r_exp);
-  if (!search_base_type.type_is_enumerated(left_type))
-    return print_binary_expression(symbol->l_exp, symbol->r_exp, " <= ");
-  ERROR;
-  return NULL;
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " <= ");
 }
 
 void *visit(ge_expression_c *symbol) {
   symbol_c *left_type = search_expression_type->get_type(symbol->l_exp);
   symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
-  if (!search_expression_type->is_same_type(left_type, right_type))
-      ERROR;
+  // if (!search_expression_type->is_same_type(left_type, right_type))    ERROR;  // This check is no longer needed!
   if (search_expression_type->is_time_type(left_type) ||
       search_expression_type->is_string_type(left_type))
     return print_compare_function("GE_", left_type, symbol->l_exp, symbol->r_exp);
-  if (!search_base_type.type_is_enumerated(left_type))
-    return print_binary_expression(symbol->l_exp, symbol->r_exp, " >= ");
-  ERROR;
-  return NULL;
+  return print_binary_expression(symbol->l_exp, symbol->r_exp, " >= ");
 }
 
 void *visit(add_expression_c *symbol) {
--- a/stage4/generate_c/generate_c_typedecl.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage4/generate_c/generate_c_typedecl.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -58,7 +58,7 @@
       enumerated_td,
       subrange_td,
       array_td,
-      struct_td,
+      struct_td
     } typedefinition_t;
 
     typedefinition_t current_typedefinition;
--- a/stage4/generate_c/generate_c_vardecl.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage4/generate_c/generate_c_vardecl.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -826,7 +826,7 @@
                   init_vf,
                   constructorinit_vf,
                   globalinit_vf,
-                  globalprototype_vf,
+                  globalprototype_vf
                  } varformat_t;
 
 
--- a/stage4/generate_c/generate_var_list.cc	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage4/generate_c/generate_var_list.cc	Thu Oct 04 15:10:45 2012 +0100
@@ -206,7 +206,7 @@
       external_vcc,
       located_input_vcc,
       located_memory_vcc,
-      located_output_vcc,
+      located_output_vcc
     } varclasscategory_t;
 
     varclasscategory_t current_var_class_category;
@@ -330,11 +330,14 @@
           this->current_var_type_name->accept(*this);
           s4o.print(";\n");
           SYMBOL *current_name;
+          symbol_c *tmp_var_type;
           current_name = new SYMBOL;
           current_name->symbol = symbol;
+          tmp_var_type = this->current_var_type_symbol;
           current_symbol_list.push_back(*current_name);
           this->current_var_type_symbol->accept(*this);
           current_symbol_list.pop_back();
+          this->current_var_type_symbol = tmp_var_type;
           break;
         case search_type_symbol_c::array_vtc:
           this->current_var_type_name->accept(*this);
--- a/stage4/generate_iec/Makefile.in	Thu Sep 13 16:35:10 2012 +0200
+++ b/stage4/generate_iec/Makefile.in	Thu Oct 04 15:10:45 2012 +0100
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.3 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+# Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
@@ -64,6 +64,12 @@
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 am__installdirs = "$(DESTDIR)$(libdir)"
 LIBRARIES = $(lib_LIBRARIES)
 AR = ar
@@ -213,6 +219,7 @@
 	    echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
 	    cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
 	esac;
+$(srcdir)/../../common.mk:
 
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
 	cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
@@ -248,13 +255,11 @@
 	@$(NORMAL_UNINSTALL)
 	@list='$(lib_LIBRARIES)'; test -n "$(libdir)" || list=; \
 	files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-	test -n "$$files" || exit 0; \
-	echo " ( cd '$(DESTDIR)$(libdir)' && rm -f "$$files" )"; \
-	cd "$(DESTDIR)$(libdir)" && rm -f $$files
+	dir='$(DESTDIR)$(libdir)'; $(am__uninstall_files_from_dir)
 
 clean-libLIBRARIES:
 	-test -z "$(lib_LIBRARIES)" || rm -f $(lib_LIBRARIES)
-libstage4_iec.a: $(libstage4_iec_a_OBJECTS) $(libstage4_iec_a_DEPENDENCIES) 
+libstage4_iec.a: $(libstage4_iec_a_OBJECTS) $(libstage4_iec_a_DEPENDENCIES) $(EXTRA_libstage4_iec_a_DEPENDENCIES) 
 	-rm -f libstage4_iec.a
 	$(libstage4_iec_a_AR) libstage4_iec.a $(libstage4_iec_a_OBJECTS) $(libstage4_iec_a_LIBADD)
 	$(RANLIB) libstage4_iec.a
@@ -380,10 +385,15 @@
 
 installcheck: installcheck-am
 install-strip:
-	$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-	  install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-	  `test -z '$(STRIP)' || \
-	    echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+	if test -z '$(STRIP)'; then \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	      install; \
+	else \
+	  $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+	    install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+	    "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+	fi
 mostlyclean-generic:
 
 clean-generic: