Adding support for declaring function block instances as global and external variables
authorLaurent Bessard
Thu, 15 Nov 2012 22:28:53 +0100
changeset 706 31553c22f318
parent 705 f2323f79252e
child 707 e666763ac743
Adding support for declaring function block instances as global and external variables
absyntax_utils/search_base_type.cc
absyntax_utils/search_base_type.hh
absyntax_utils/search_fb_instance_decl.cc
absyntax_utils/search_fb_instance_decl.hh
absyntax_utils/search_var_instance_decl.cc
absyntax_utils/search_var_instance_decl.hh
lib/accessor.h
lib/iec_std_lib.h
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_c_typedecl.cc
stage4/generate_c/generate_c_vardecl.cc
stage4/generate_c/generate_var_list.cc
--- a/absyntax_utils/search_base_type.cc	Thu Nov 08 18:55:57 2012 +0100
+++ b/absyntax_utils/search_base_type.cc	Thu Nov 15 22:28:53 2012 +0100
@@ -88,6 +88,11 @@
   return this->is_enumerated;
 }
 
+bool search_base_type_c::type_is_fb(symbol_c* type_decl) {
+  this->is_fb = false;
+  type_decl->accept(*this);
+  return this->is_fb;
+}
 
 /*************************/
 /* B.1 - Common elements */
@@ -335,7 +340,10 @@
 /*****************************/
 /*  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 *search_base_type_c::visit(function_block_declaration_c *symbol)                   {return (void *)symbol;}
+void *search_base_type_c::visit(function_block_declaration_c *symbol)                   {
+	this->is_fb = true;
+	return (void *)symbol;
+}
 
 
 
--- a/absyntax_utils/search_base_type.hh	Thu Nov 08 18:55:57 2012 +0100
+++ b/absyntax_utils/search_base_type.hh	Thu Nov 15 22:28:53 2012 +0100
@@ -55,6 +55,7 @@
     bool is_array;
     bool is_subrange;
     bool is_enumerated;
+    bool is_fb;
 
   public:
     search_base_type_c(void);
@@ -64,6 +65,7 @@
     symbol_c *get_basetype_id  (symbol_c *symbol);
     bool type_is_subrange(symbol_c* type_decl);
     bool type_is_enumerated(symbol_c* type_decl);
+    bool type_is_fb(symbol_c* type_decl);
 
   public:
   /*************************/
@@ -116,7 +118,7 @@
     void *visit(lreal_type_name_c *symbol);
     void *visit(date_type_name_c *symbol);
     void *visit(tod_type_name_c *symbol);
-    void *visit(dt_type_name_c *symbol)	;
+    void *visit(dt_type_name_c *symbol);
     void *visit(byte_type_name_c *symbol);
     void *visit(word_type_name_c *symbol);
     void *visit(dword_type_name_c *symbol);
@@ -145,7 +147,7 @@
     void *visit(safelreal_type_name_c *symbol);
     void *visit(safedate_type_name_c *symbol);
     void *visit(safetod_type_name_c *symbol);
-    void *visit(safedt_type_name_c *symbol)	;
+    void *visit(safedt_type_name_c *symbol);
     void *visit(safebyte_type_name_c *symbol);
     void *visit(safeword_type_name_c *symbol);
     void *visit(safedword_type_name_c *symbol);
@@ -222,7 +224,7 @@
     void *visit(structure_element_initialization_c *symbol);
   /*  string_type_name ':' elementary_string_type_name string_type_declaration_size string_type_declaration_init */
   /*
-  SYM_REF4(string_type_declaration_c,	string_type_name,
+  SYM_REF4(string_type_declaration_c, string_type_name,
   					elementary_string_type_name,
   					string_type_declaration_size,
   					string_type_declaration_init) // may be == NULL!
--- a/absyntax_utils/search_fb_instance_decl.cc	Thu Nov 08 18:55:57 2012 +0100
+++ b/absyntax_utils/search_fb_instance_decl.cc	Thu Nov 15 22:28:53 2012 +0100
@@ -102,6 +102,13 @@
   return NULL;
 }
 
+/* name_list ',' fb_name */
+void *search_fb_instance_decl_c::visit(external_declaration_c *symbol) {
+  if (compare_identifiers(symbol->global_var_name, search_name) == 0)
+	return symbol->specification;
+  return NULL;
+}
+
 /**************************************/
 /* B.1.5 - Program organization units */
 /**************************************/
--- a/absyntax_utils/search_fb_instance_decl.hh	Thu Nov 08 18:55:57 2012 +0100
+++ b/absyntax_utils/search_fb_instance_decl.hh	Thu Nov 15 22:28:53 2012 +0100
@@ -88,6 +88,9 @@
     void *visit(fb_name_decl_c *symbol);
   /* name_list ',' fb_name */
     void *visit(fb_name_list_c *symbol);
+  /*  global_var_name ':' (simple_specification|subrange_specification|enumerated_specification|array_specification|prev_declared_structure_type_name|function_block_type_name */
+    void *visit(external_declaration_c *symbol);
+
 
   /**************************************/
   /* B.1.5 - Program organization units */
--- a/absyntax_utils/search_var_instance_decl.cc	Thu Nov 08 18:55:57 2012 +0100
+++ b/absyntax_utils/search_var_instance_decl.cc	Thu Nov 15 22:28:53 2012 +0100
@@ -144,12 +144,19 @@
           (typeid( *(decl) ) == typeid( structure_type_declaration_c         )) ||  
           (typeid( *(decl) ) == typeid( structure_element_declaration_list_c )) ||
 //        (typeid( *(decl) ) == typeid( structure_type_declaration_c         )) ||  /* does not seem to be necessary */
-          (typeid( *(decl) ) == typeid( initialized_structure_c              ))
-          
+          (typeid( *(decl) ) == typeid( initialized_structure_c              )) ||
+          (search_base_type.type_is_fb(decl) && current_vartype == external_vt)
          );
 }
 
-
+bool search_var_instance_decl_c::type_is_fb(symbol_c *symbol) {
+    symbol_c *decl;
+    search_base_type_c search_base_type;
+
+    decl = this->get_decl(symbol);
+    if (NULL == decl) ERROR;
+    return search_base_type.type_is_fb(decl);
+}
 
 /***************************/
 /* B 0 - Programming Model */
--- a/absyntax_utils/search_var_instance_decl.hh	Thu Nov 08 18:55:57 2012 +0100
+++ b/absyntax_utils/search_var_instance_decl.hh	Thu Nov 15 22:28:53 2012 +0100
@@ -140,7 +140,7 @@
      */
     bool type_is_complex(symbol_c *variable_name);
 
-    
+    bool type_is_fb(symbol_c *symbol);
     
   private:
     symbol_c *search_scope;
--- a/lib/accessor.h	Thu Nov 08 18:55:57 2012 +0100
+++ b/lib/accessor.h	Thu Nov 15 22:28:53 2012 +0100
@@ -18,6 +18,12 @@
 	type* __GET_GLOBAL_##name(void) {\
 		return &((*GLOBAL__##name).value);\
 	}
+#define __DECLARE_GLOBAL_FB(type, domain, name)\
+	type domain##__##name;\
+	static type *GLOBAL__##name = &(domain##__##name);\
+	type* __GET_GLOBAL_##name(void) {\
+		return &(*GLOBAL__##name);\
+	}
 #define __DECLARE_GLOBAL_LOCATION(type, location)\
 	extern type *location;
 #define __DECLARE_GLOBAL_LOCATED(type, resource, name)\
@@ -36,6 +42,8 @@
     extern type* __GET_GLOBAL_##name();
 #define __DECLARE_EXTERNAL(type, name)\
 	__IEC_##type##_p name;
+#define __DECLARE_EXTERNAL_FB(type, name)\
+	type* name;
 #define __DECLARE_LOCATED(type, name)\
 	__IEC_##type##_p name;
 
@@ -52,6 +60,8 @@
 	    __INIT_GLOBAL_##name(temp);\
 	    __INIT_RETAIN((*GLOBAL__##name), retained)\
     }
+#define __INIT_GLOBAL_FB(type, name, retained)\
+	type##_init__(&(*GLOBAL__##name), retained);
 #define __INIT_GLOBAL_LOCATED(domain, name, location, retained)\
 	domain##__##name.value = location;\
 	__INIT_RETAIN(domain##__##name, retained)
@@ -60,6 +70,8 @@
 		name.value = __GET_GLOBAL_##global();\
 		__INIT_RETAIN(name, retained)\
     }
+#define __INIT_EXTERNAL_FB(type, global, name, retained)\
+	name = __GET_GLOBAL_##global();
 #define __INIT_LOCATED(type, location, name, retained)\
 	{\
 		extern type *location;\
@@ -75,12 +87,16 @@
 	name.value __VA_ARGS__
 #define __GET_EXTERNAL(name, ...)\
 	((name.flags & __IEC_FORCE_FLAG) ? name.fvalue __VA_ARGS__ : (*(name.value)) __VA_ARGS__)
+#define __GET_EXTERNAL_FB(name, ...)\
+	__GET_VAR(((*name) __VA_ARGS__))
 #define __GET_LOCATED(name, ...)\
 	((name.flags & __IEC_FORCE_FLAG) ? name.fvalue __VA_ARGS__ : (*(name.value)) __VA_ARGS__)
 #define __GET_VAR_BY_REF(name, ...)\
 	((name.flags & __IEC_FORCE_FLAG) ? &(name.fvalue __VA_ARGS__) : &(name.value __VA_ARGS__))
 #define __GET_EXTERNAL_BY_REF(name, ...)\
 	((name.flags & __IEC_FORCE_FLAG) ? &(name.fvalue __VA_ARGS__) : &((*(name.value)) __VA_ARGS__))
+#define __GET_EXTERNAL_FB_BY_REF(name, ...)\
+	__GET_EXTERNAL_BY_REF(((*name) __VA_ARGS__))
 #define __GET_LOCATED_BY_REF(name, ...)\
 	((name.flags & __IEC_FORCE_FLAG) ? &(name.fvalue __VA_ARGS__) : &((*(name.value)) __VA_ARGS__))
 
@@ -90,6 +106,8 @@
 #define __SET_EXTERNAL(prefix, name, new_value, ...)\
 	if (!(prefix name.flags & __IEC_FORCE_FLAG || __IS_GLOBAL_##name##_FORCED()))\
 		(*(prefix name.value)) __VA_ARGS__ = new_value
+#define __SET_EXTERNAL_FB(prefix, name, new_value, ...)\
+	__SET_VAR((*(prefix name)), __VA_ARGS__, new_value)
 #define __SET_LOCATED(prefix, name, new_value, ...)\
 	if (!(prefix name.flags & __IEC_FORCE_FLAG)) *(prefix name.value) __VA_ARGS__ = new_value
 
--- a/lib/iec_std_lib.h	Thu Nov 08 18:55:57 2012 +0100
+++ b/lib/iec_std_lib.h	Thu Nov 15 22:28:53 2012 +0100
@@ -241,8 +241,6 @@
   if ((time_t)(-1) == epoch_seconds)
     __iec_error();
 
-  printf("Seconds = %d\n", (int)epoch_seconds);
-
   ts.tv_sec = epoch_seconds;
   ts.tv_nsec = 0;
 
--- a/stage4/generate_c/generate_c.cc	Thu Nov 08 18:55:57 2012 +0100
+++ b/stage4/generate_c/generate_c.cc	Thu Nov 15 22:28:53 2012 +0100
@@ -109,31 +109,38 @@
 /* Variable declaration symbol for accessor macros */
 #define DECLARE_VAR "__DECLARE_VAR"
 #define DECLARE_GLOBAL "__DECLARE_GLOBAL"
+#define DECLARE_GLOBAL_FB "__DECLARE_GLOBAL_FB"
 #define DECLARE_GLOBAL_LOCATION "__DECLARE_GLOBAL_LOCATION"
 #define DECLARE_GLOBAL_LOCATED "__DECLARE_GLOBAL_LOCATED"
 #define DECLARE_EXTERNAL "__DECLARE_EXTERNAL"
+#define DECLARE_EXTERNAL_FB "__DECLARE_EXTERNAL_FB"
 #define DECLARE_LOCATED "__DECLARE_LOCATED"
 #define DECLARE_GLOBAL_PROTOTYPE "__DECLARE_GLOBAL_PROTOTYPE"
 
 /* Variable declaration symbol for accessor macros */
 #define INIT_VAR "__INIT_VAR"
 #define INIT_GLOBAL "__INIT_GLOBAL"
+#define INIT_GLOBAL_FB "__INIT_GLOBAL_FB"
 #define INIT_GLOBAL_LOCATED "__INIT_GLOBAL_LOCATED"
 #define INIT_EXTERNAL "__INIT_EXTERNAL"
+#define INIT_EXTERNAL_FB "__INIT_EXTERNAL_FB"
 #define INIT_LOCATED "__INIT_LOCATED"
 #define INIT_LOCATED_VALUE "__INIT_LOCATED_VALUE"
 
 /* Variable getter symbol for accessor macros */
 #define GET_VAR "__GET_VAR"
 #define GET_EXTERNAL "__GET_EXTERNAL"
+#define GET_EXTERNAL_FB "__GET_EXTERNAL_FB"
 #define GET_LOCATED "__GET_LOCATED"
 #define GET_VAR_BY_REF "__GET_VAR_BY_REF"
 #define GET_EXTERNAL_BY_REF "__GET_EXTERNAL_BY_REF"
+#define GET_EXTERNAL_FB_BY_REF "__GET_EXTERNAL_FB_BY_REF"
 #define GET_LOCATED_BY_REF "__GET_LOCATED_BY_REF"
 
 /* Variable setter symbol for accessor macros */
 #define SET_VAR "__SET_VAR"
 #define SET_EXTERNAL "__SET_EXTERNAL"
+#define SET_EXTERNAL_FB "__SET_EXTERNAL_FB"
 #define SET_LOCATED "__SET_LOCATED"
 
 /* Variable initial value symbol for accessor macros */
@@ -592,7 +599,7 @@
     };
     virtual ~generate_c_datatypes_c(void) {
       while (!inline_array_defined.empty()) {
-    	inline_array_defined.erase(inline_array_defined.begin());
+        inline_array_defined.erase(inline_array_defined.begin());
       }
     }
 
@@ -626,19 +633,19 @@
 
     #define HANDLE_ELEMENTARY_DATA_TYPE(datatype_symbol, datatype_name)\
     void *visit(datatype_symbol *symbol) {\
-	  switch (current_mode) {\
-		case arrayname_im:\
-		  current_array_name += datatype_name;\
-		  break;\
+      switch (current_mode) {\
+        case arrayname_im:\
+          current_array_name += datatype_name;\
+          break;\
         case arraydeclaration_im:\
           s4o_incl.print(datatype_name);\
           break;\
-		default:\
-		  return generate_c_base_c::visit(symbol);\
-		  break;\
-	  }\
-	  return NULL;\
-	}
+        default:\
+          return generate_c_base_c::visit(symbol);\
+          break;\
+      }\
+      return NULL;\
+    }
 
     HANDLE_ELEMENTARY_DATA_TYPE(time_type_name_c, "TIME")
     HANDLE_ELEMENTARY_DATA_TYPE(bool_type_name_c, "BOOL")
@@ -663,41 +670,41 @@
     HANDLE_ELEMENTARY_DATA_TYPE(wstring_type_name_c, "WSTRING")
 
     HANDLE_ELEMENTARY_DATA_TYPE(safetime_type_name_c, "TIME")
-	HANDLE_ELEMENTARY_DATA_TYPE(safebool_type_name_c, "BOOL")
-	HANDLE_ELEMENTARY_DATA_TYPE(safesint_type_name_c, "SINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeint_type_name_c, "INT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safedint_type_name_c, "DINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safelint_type_name_c, "LINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeusint_type_name_c, "USINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeuint_type_name_c, "UINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeudint_type_name_c, "UDINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeulint_type_name_c, "ULINT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safereal_type_name_c, "REAL")
-	HANDLE_ELEMENTARY_DATA_TYPE(safelreal_type_name_c, "LREAL")
-	HANDLE_ELEMENTARY_DATA_TYPE(safedate_type_name_c, "DATE")
-	HANDLE_ELEMENTARY_DATA_TYPE(safetod_type_name_c, "TOD")
-	HANDLE_ELEMENTARY_DATA_TYPE(safedt_type_name_c, "DT")
-	HANDLE_ELEMENTARY_DATA_TYPE(safebyte_type_name_c, "BYTE")
-	HANDLE_ELEMENTARY_DATA_TYPE(safeword_type_name_c, "WORD")
-	HANDLE_ELEMENTARY_DATA_TYPE(safedword_type_name_c, "DWORD")
-	HANDLE_ELEMENTARY_DATA_TYPE(safelword_type_name_c, "LWORD")
-	HANDLE_ELEMENTARY_DATA_TYPE(safestring_type_name_c, "STRING")
-	HANDLE_ELEMENTARY_DATA_TYPE(safewstring_type_name_c, "WSTRING")
+    HANDLE_ELEMENTARY_DATA_TYPE(safebool_type_name_c, "BOOL")
+    HANDLE_ELEMENTARY_DATA_TYPE(safesint_type_name_c, "SINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeint_type_name_c, "INT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safedint_type_name_c, "DINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safelint_type_name_c, "LINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeusint_type_name_c, "USINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeuint_type_name_c, "UINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeudint_type_name_c, "UDINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeulint_type_name_c, "ULINT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safereal_type_name_c, "REAL")
+    HANDLE_ELEMENTARY_DATA_TYPE(safelreal_type_name_c, "LREAL")
+    HANDLE_ELEMENTARY_DATA_TYPE(safedate_type_name_c, "DATE")
+    HANDLE_ELEMENTARY_DATA_TYPE(safetod_type_name_c, "TOD")
+    HANDLE_ELEMENTARY_DATA_TYPE(safedt_type_name_c, "DT")
+    HANDLE_ELEMENTARY_DATA_TYPE(safebyte_type_name_c, "BYTE")
+    HANDLE_ELEMENTARY_DATA_TYPE(safeword_type_name_c, "WORD")
+    HANDLE_ELEMENTARY_DATA_TYPE(safedword_type_name_c, "DWORD")
+    HANDLE_ELEMENTARY_DATA_TYPE(safelword_type_name_c, "LWORD")
+    HANDLE_ELEMENTARY_DATA_TYPE(safestring_type_name_c, "STRING")
+    HANDLE_ELEMENTARY_DATA_TYPE(safewstring_type_name_c, "WSTRING")
 
     /***********************************/
     /* B 1.3.2 - Generic Data Types    */
     /***********************************/
 
-	/*  structure_type_name ':' structure_specification */
-	//SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification)
-	void *visit(structure_type_declaration_c *symbol) {
+    /*  structure_type_name ':' structure_specification */
+    //SYM_REF2(structure_type_declaration_c, structure_type_name, structure_specification)
+    void *visit(structure_type_declaration_c *symbol) {
       current_mode = arraydeclaration_im;
       symbol->structure_specification->accept(*this);
       current_mode = arrayname_im;
       generate_c_typedecl_c::visit(symbol);
-	  current_mode = none_im;
-	  return NULL;
-	}
+      current_mode = none_im;
+      return NULL;
+    }
 
     /* helper symbol for structure_declaration */
     /* structure_declaration:  STRUCT structure_element_declaration_list END_STRUCT */
@@ -705,12 +712,12 @@
     //SYM_LIST(structure_element_declaration_list_c)
     void *visit(structure_element_declaration_list_c *symbol) {
       switch (current_mode) {
-    	case arraydeclaration_im:
-    	  iterator_visitor_c::visit(symbol);
-    	  break;
+        case arraydeclaration_im:
+          iterator_visitor_c::visit(symbol);
+          break;
         default:
-    	  generate_c_typedecl_c::visit(symbol);
-    	  break;
+          generate_c_typedecl_c::visit(symbol);
+          break;
       }
       return NULL;
     }
@@ -719,16 +726,16 @@
     //SYM_REF2(structure_element_declaration_c, structure_element_name, spec_init)
     void *visit(structure_element_declaration_c *symbol) {
       switch (current_mode) {
-    	case arraydeclaration_im:
-    	  {
-			array_spec_init_c *spec_init = dynamic_cast<array_spec_init_c*>(symbol->spec_init);
-			if (spec_init != NULL) {
-			  symbol->spec_init->accept(*this);
-			}
-		  }
-    	  break;
-    	default:
-    	  generate_c_typedecl_c::visit(symbol);
+        case arraydeclaration_im:
+          {
+            array_spec_init_c *spec_init = dynamic_cast<array_spec_init_c*>(symbol->spec_init);
+            if (spec_init != NULL) {
+              symbol->spec_init->accept(*this);
+            }
+          }
+          break;
+        default:
+          generate_c_typedecl_c::visit(symbol);
           break;
       }
       return NULL;
@@ -772,16 +779,16 @@
     /* array_initialization may be NULL ! */
     void *visit(array_spec_init_c *symbol) {
       switch (current_mode) {
-    	case arraydeclaration_im:
-    	case arrayname_im:
-    	  {
-    	    array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
+        case arraydeclaration_im:
+        case arrayname_im:
+          {
+            array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
             if (specification != NULL)
               symbol->array_specification->accept(*this);
           }
           break;
-    	default:
-    	  return generate_c_typedecl_c::visit(symbol);
+        default:
+          return generate_c_typedecl_c::visit(symbol);
           break;
       }
       return NULL;
@@ -792,7 +799,7 @@
       switch (current_mode) {
         case arraydeclaration_im:
           {
-        	current_mode = arrayname_im;
+            current_mode = arrayname_im;
             std::map<std::string,int>::iterator definition;
             current_array_name = "__";
             symbol->non_generic_type_name->accept(*this);
@@ -815,11 +822,11 @@
           break;
         case arrayname_im:
           {
-        	  std::map<std::string,int>::iterator definition;
-			  current_array_name = "__";
-			  symbol->non_generic_type_name->accept(*this);
-			  symbol->array_subrange_list->accept(*this);
-			  s4o_incl.print(current_array_name);
+              std::map<std::string,int>::iterator definition;
+              current_array_name = "__";
+              symbol->non_generic_type_name->accept(*this);
+              symbol->array_subrange_list->accept(*this);
+              s4o_incl.print(current_array_name);
           }
           break;
         default:
@@ -881,7 +888,7 @@
     //SYM_REF2(array_var_declaration_c, var1_list, array_specification)
     void *visit(array_var_declaration_c *symbol) {
       array_specification_c *specification = dynamic_cast<array_specification_c*>(symbol->array_specification);
-	  if (specification != NULL) {
+      if (specification != NULL) {
         current_mode = arraydeclaration_im;
         symbol->array_specification->accept(*this);
         current_mode = none_im;
@@ -923,9 +930,9 @@
     void *visit(located_var_decl_c *symbol) {
       array_spec_init_c* array_spec_init = dynamic_cast<array_spec_init_c*>(symbol->located_var_spec_init);
       if (array_spec_init != NULL) {
-    	current_mode = arraydeclaration_im;
-    	symbol->located_var_spec_init->accept(*this);
-    	current_mode = none_im;
+        current_mode = arraydeclaration_im;
+        symbol->located_var_spec_init->accept(*this);
+        current_mode = none_im;
       }
       return NULL;
     }
--- a/stage4/generate_c/generate_c_il.cc	Thu Nov 08 18:55:57 2012 +0100
+++ b/stage4/generate_c/generate_c_il.cc	Thu Nov 15 22:28:53 2012 +0100
@@ -441,20 +441,28 @@
     void *print_getter(symbol_c *symbol) {
       unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
       if (wanted_variablegeneration == fparam_output_vg) {
-      	if (vartype == search_var_instance_decl_c::external_vt)
-          s4o.print(GET_EXTERNAL_BY_REF);
+        if (vartype == search_var_instance_decl_c::external_vt) {
+          if (search_var_instance_decl->type_is_fb(symbol))
+            s4o.print(GET_EXTERNAL_FB_BY_REF);
+          else
+            s4o.print(GET_EXTERNAL_BY_REF);
+        }
         else if (vartype == search_var_instance_decl_c::located_vt)
           s4o.print(GET_LOCATED_BY_REF);
         else
           s4o.print(GET_VAR_BY_REF);
       }
       else {
-    	if (vartype == search_var_instance_decl_c::external_vt)
-    	  s4o.print(GET_EXTERNAL);
-    	else if (vartype == search_var_instance_decl_c::located_vt)
-    	  s4o.print(GET_LOCATED);
-    	else
-    	  s4o.print(GET_VAR);
+        if (vartype == search_var_instance_decl_c::external_vt) {
+          if (search_var_instance_decl->type_is_fb(symbol))
+            s4o.print(GET_EXTERNAL_FB);
+          else
+            s4o.print(GET_EXTERNAL);
+        }
+        else if (vartype == search_var_instance_decl_c::located_vt)
+          s4o.print(GET_LOCATED);
+        else
+          s4o.print(GET_VAR);
       }
       s4o.print("(");
 
@@ -471,25 +479,33 @@
     }
 
     void *print_setter(symbol_c* symbol,
-    		symbol_c* type,
-    		symbol_c* value,
-    		symbol_c* fb_symbol = NULL,
-    		symbol_c* fb_value = NULL,
-    		bool negative = false) {
-
-      bool type_is_complex = false;
+            symbol_c* type,
+            symbol_c* value,
+            symbol_c* fb_symbol = NULL,
+            symbol_c* fb_value = NULL,
+            bool negative = false) {
+
+      bool type_is_complex = search_var_instance_decl->type_is_complex(symbol);
       if (fb_symbol == NULL) {
         unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
-        type_is_complex = search_var_instance_decl->type_is_complex(symbol);
-        if (vartype == search_var_instance_decl_c::external_vt)
-          s4o.print(SET_EXTERNAL);
+        if (vartype == search_var_instance_decl_c::external_vt) {
+          if (search_var_instance_decl->type_is_fb(symbol))
+            s4o.print(SET_EXTERNAL_FB);
+          else
+            s4o.print(SET_EXTERNAL);
+        }
         else if (vartype == search_var_instance_decl_c::located_vt)
           s4o.print(SET_LOCATED);
         else
           s4o.print(SET_VAR);
       }
-      else
-        s4o.print(SET_VAR);
+      else {
+        unsigned int vartype = search_var_instance_decl->get_vartype(fb_symbol);
+        if (vartype == search_var_instance_decl_c::external_vt)
+          s4o.print(SET_EXTERNAL_FB);
+        else
+          s4o.print(SET_VAR);
+      }
       s4o.print("(");
 
       if (fb_symbol != NULL) {
@@ -505,10 +521,10 @@
       symbol->accept(*this);
       s4o.print(",");
       if (negative) {
-	    if (search_expression_type->is_bool_type(this->current_operand_type))
-		  s4o.print("!");
-	    else
-		  s4o.print("~");
+        if (search_expression_type->is_bool_type(this->current_operand_type))
+          s4o.print("!");
+        else
+          s4o.print("~");
       }
       wanted_variablegeneration = expression_vg;
       print_check_function(type, value, fb_value);
@@ -588,10 +604,10 @@
       generate_c_base_c::visit(symbol);
       break;
     case complextype_suffix_vg:
-	  break;
+      break;
     default:
       if (this->is_variable_prefix_null()) {
-	    vartype = search_var_instance_decl->get_vartype(symbol);
+        vartype = search_var_instance_decl->get_vartype(symbol);
         if (wanted_variablegeneration == fparam_output_vg) {
           s4o.print("&(");
           generate_c_base_c::visit(symbol);
@@ -618,14 +634,14 @@
   if (strlen(symbol->value) == 0) ERROR;
   if (this->is_variable_prefix_null()) {
     if (wanted_variablegeneration != fparam_output_vg)
-	  s4o.print("*(");
+      s4o.print("*(");
   }
   else {
     switch (wanted_variablegeneration) {
       case expression_vg:
-  	    s4o.print(GET_LOCATED);
-  	    s4o.print("(");
-  	    break;
+        s4o.print(GET_LOCATED);
+        s4o.print("(");
+        break;
       case fparam_output_vg:
         s4o.print(GET_LOCATED_BY_REF);
         s4o.print("(");
@@ -637,7 +653,7 @@
   this->print_variable_prefix();
   s4o.printlocation(symbol->value + 1);
   if ((this->is_variable_prefix_null() && wanted_variablegeneration != fparam_output_vg) ||
-	  wanted_variablegeneration != assignment_vg)
+      wanted_variablegeneration != assignment_vg)
     s4o.print(")");
   return NULL;
 }
@@ -660,25 +676,25 @@
       }
       break;
     case complextype_suffix_vg:
-	  symbol->record_variable->accept(*this);
-	  if (type_is_complex) {
-		s4o.print(".");
-		symbol->field_selector->accept(*this);
-	  }
-	  break;
-	case assignment_vg:
-	  symbol->record_variable->accept(*this);
-	  s4o.print(".");
-	  symbol->field_selector->accept(*this);
-	  break;
+      symbol->record_variable->accept(*this);
+      if (type_is_complex) {
+        s4o.print(".");
+        symbol->field_selector->accept(*this);
+      }
+      break;
+    case assignment_vg:
+      symbol->record_variable->accept(*this);
+      s4o.print(".");
+      symbol->field_selector->accept(*this);
+      break;
     default:
       if (this->is_variable_prefix_null()) {
-    	symbol->record_variable->accept(*this);
-    	s4o.print(".");
-    	symbol->field_selector->accept(*this);
+        symbol->record_variable->accept(*this);
+        s4o.print(".");
+        symbol->field_selector->accept(*this);
       }
       else
-    	print_getter(symbol);
+        print_getter(symbol);
       break;
   }
   return NULL;
@@ -716,7 +732,7 @@
         current_array_type = NULL;
       }
       else
-    	print_getter(symbol);
+        print_getter(symbol);
       break;
   }
   return NULL;
@@ -727,9 +743,9 @@
   array_dimension_iterator_c* array_dimension_iterator = new array_dimension_iterator_c(current_array_type);
   for (int i =  0; i < symbol->n; i++) {
     symbol_c* dimension = array_dimension_iterator->next();
-	if (dimension == NULL) ERROR;
-
-	s4o.print("[(");
+    if (dimension == NULL) ERROR;
+
+    s4o.print("[(");
     symbol->elements[i]->accept(*this);
     s4o.print(") - (");
     dimension->accept(*this);
@@ -968,7 +984,7 @@
     s4o.print(")");
   }
   if (function_type_suffix != NULL) {
-  	function_type_suffix = search_expression_type->default_literal_type(function_type_suffix);
+    function_type_suffix = search_expression_type->default_literal_type(function_type_suffix);
   }
   if (has_output_params) {
     fcall_number++;
@@ -993,7 +1009,7 @@
             print_function_parameter_data_types_c overloaded_func_suf(&s4o);
             f_decl->accept(overloaded_func_suf);
           }
-    }	  
+    }
     if (function_type_suffix != NULL)
       function_type_suffix->accept(*this);
   }
@@ -1169,13 +1185,13 @@
     if (param_value != NULL)
       if ((param_direction == function_param_iterator_c::direction_in) ||
           (param_direction == function_param_iterator_c::direction_inout)) {
-    	if (this->is_variable_prefix_null()) {
-    	  symbol->fb_name->accept(*this);
+        if (this->is_variable_prefix_null()) {
+          symbol->fb_name->accept(*this);
           s4o.print(".");
           param_name->accept(*this);
           s4o.print(" = ");
           print_check_function(param_type, param_value);
-    	}
+        }
         else {
           print_setter(param_name, param_type, param_value, symbol->fb_name);
         }
@@ -1186,7 +1202,9 @@
   /* now call the function... */
   function_block_type_name->accept(*this);
   s4o.print(FB_FUNCTION_SUFFIX);
-  s4o.print("(&");
+  s4o.print("(");
+  if (search_var_instance_decl->get_vartype(symbol->fb_name) != search_var_instance_decl_c::external_vt)
+    s4o.print("&");
   print_variable_prefix();
   symbol->fb_name->accept(*this);
   s4o.print(")");
@@ -1217,12 +1235,12 @@
         s4o.print(";\n" + s4o.indent_spaces);
         if (this->is_variable_prefix_null()) {
           param_value->accept(*this);
-		  s4o.print(" = ");
-		  print_check_function(param_type, param_name, symbol->fb_name);
-		}
-		else {
-		  print_setter(param_value, param_type, param_name, NULL, symbol->fb_name);
-		}
+          s4o.print(" = ");
+          print_check_function(param_type, param_name, symbol->fb_name);
+        }
+        else {
+          print_setter(param_value, param_type, param_name, NULL, symbol->fb_name);
+        }
       }
   } /* for(...) */
 
@@ -1376,7 +1394,7 @@
     s4o.print(")");
   }
   if (function_type_suffix != NULL) {
-  	function_type_suffix = search_expression_type->default_literal_type(function_type_suffix);
+    function_type_suffix = search_expression_type->default_literal_type(function_type_suffix);
   }
   if (has_output_params) {
     fcall_number++;
@@ -1574,7 +1592,7 @@
 }
 
 // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
-void *visit(il_simple_instruction_c *symbol)	{
+void *visit(il_simple_instruction_c *symbol) {
   return symbol->il_simple_instruction->accept(*this);
 }
 
@@ -1597,7 +1615,7 @@
 /* B 2.2 Operators */
 /*******************/
 
-void *visit(LD_operator_c *symbol)	{
+void *visit(LD_operator_c *symbol) {
   if (wanted_variablegeneration != expression_vg) {
     s4o.print("LD");
     return NULL;
@@ -1609,7 +1627,7 @@
   return NULL;
 }
 
-void *visit(LDN_operator_c *symbol)	{
+void *visit(LDN_operator_c *symbol) {
   /* the data type resulting from this operation... */
   this->default_variable_name.current_type = this->current_operand_type;
   XXX_operator(&(this->default_variable_name),
@@ -1618,10 +1636,10 @@
   return NULL;
 }
 
-void *visit(ST_operator_c *symbol)	{
+void *visit(ST_operator_c *symbol) {
   symbol_c *operand_type = search_varfb_instance_type->get_type_id(this->current_operand);
   if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type) ||
-  	  search_expression_type->is_literal_real_type(this->default_variable_name.current_type))
+      search_expression_type->is_literal_real_type(this->default_variable_name.current_type))
       this->default_variable_name.current_type = this->current_operand_type;
   if (this->is_variable_prefix_null()) {
     this->current_operand->accept(*this);
@@ -1629,16 +1647,16 @@
     print_check_function(operand_type, (symbol_c*)&(this->default_variable_name));
   }
   else {
-	print_setter(this->current_operand, operand_type, (symbol_c*)&(this->default_variable_name));
+    print_setter(this->current_operand, operand_type, (symbol_c*)&(this->default_variable_name));
   }
   /* the data type resulting from this operation is unchanged. */
   return NULL;
 }
 
-void *visit(STN_operator_c *symbol)	{
+void *visit(STN_operator_c *symbol) {
   symbol_c *operand_type = search_varfb_instance_type->get_type_id(this->current_operand);
   if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type))
-	this->default_variable_name.current_type = this->current_operand_type;
+    this->default_variable_name.current_type = this->current_operand_type;
   
   if (this->is_variable_prefix_null()) {
     this->current_operand->accept(*this);
@@ -1646,17 +1664,17 @@
     if (search_expression_type->is_bool_type(this->current_operand_type))
       s4o.print("!");
     else
-	  s4o.print("~");
+      s4o.print("~");
     this->default_variable_name.accept(*this);
   }
   else {
-	print_setter(this->current_operand, operand_type, (symbol_c*)&(this->default_variable_name), NULL, NULL, true);
+    print_setter(this->current_operand, operand_type, (symbol_c*)&(this->default_variable_name), NULL, NULL, true);
   }
   /* the data type resulting from this operation is unchanged. */
   return NULL;
 }
 
-void *visit(NOT_operator_c *symbol)	{
+void *visit(NOT_operator_c *symbol) {
   /* NOTE: the standard allows syntax in which the NOT operator is followed by an optional <il_operand>
    *              NOT [<il_operand>]
    *       However, it does not define the semantic of the NOT operation when the <il_operand> is specified.
@@ -1671,7 +1689,7 @@
   return NULL;
 }
 
-void *visit(S_operator_c *symbol)	{
+void *visit(S_operator_c *symbol) {
   if (wanted_variablegeneration != expression_vg) {
     s4o.print("LD");
     return NULL;
@@ -1694,7 +1712,7 @@
   return NULL;
 }
 
-void *visit(R_operator_c *symbol)	{
+void *visit(R_operator_c *symbol) {
   if (wanted_variablegeneration != expression_vg) {
     s4o.print("LD");
     return NULL;
@@ -1726,11 +1744,11 @@
 void *visit(IN_operator_c *symbol)	{return XXX_CAL_operator("IN", this->current_operand);}
 void *visit(PT_operator_c *symbol)	{return XXX_CAL_operator("PT", this->current_operand);}
 
-void *visit(AND_operator_c *symbol)	{
+void *visit(AND_operator_c *symbol) {
   if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	BYTE_operator_result_type();
-	XXX_operator(&(this->default_variable_name), " &= ", this->current_operand);
+    BYTE_operator_result_type();
+    XXX_operator(&(this->default_variable_name), " &= ", this->current_operand);
     /* the data type resulting from this operation... */
     this->default_variable_name.current_type = this->current_operand_type;
   }
@@ -1738,11 +1756,11 @@
   return NULL;
 }
 
-void *visit(OR_operator_c *symbol)	{
+void *visit(OR_operator_c *symbol) {
   if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	BYTE_operator_result_type();
-	XXX_operator(&(this->default_variable_name), " |= ", this->current_operand);
+    BYTE_operator_result_type();
+    XXX_operator(&(this->default_variable_name), " |= ", this->current_operand);
     /* the data type resulting from this operation... */
     this->default_variable_name.current_type = this->current_operand_type;
   }
@@ -1750,11 +1768,11 @@
   return NULL;
 }
 
-void *visit(XOR_operator_c *symbol)	{
+void *visit(XOR_operator_c *symbol) {
   if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	BYTE_operator_result_type();
-	// '^' is a bit by bit exclusive OR !! Also seems to work with boolean types!
+    BYTE_operator_result_type();
+    // '^' is a bit by bit exclusive OR !! Also seems to work with boolean types!
     XXX_operator(&(this->default_variable_name), " ^= ", this->current_operand);
     /* the data type resulting from this operation... */
     this->default_variable_name.current_type = this->current_operand_type;
@@ -1763,11 +1781,11 @@
   return NULL;
 }
 
-void *visit(ANDN_operator_c *symbol)	{
+void *visit(ANDN_operator_c *symbol) {
   if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	BYTE_operator_result_type();
-	XXX_operator(&(this->default_variable_name),
+    BYTE_operator_result_type();
+    XXX_operator(&(this->default_variable_name),
                  search_expression_type->is_bool_type(this->current_operand_type)?" &= !":" &= ~",
                  this->current_operand);
     /* the data type resulting from this operation... */
@@ -1777,11 +1795,11 @@
   return NULL;
 }
 
-void *visit(ORN_operator_c *symbol)	{
+void *visit(ORN_operator_c *symbol) {
   if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	BYTE_operator_result_type();
-	XXX_operator(&(this->default_variable_name),
+    BYTE_operator_result_type();
+    XXX_operator(&(this->default_variable_name),
                  search_expression_type->is_bool_type(this->current_operand_type)?" |= !":" |= ~",
                  this->current_operand);
     /* the data type resulting from this operation... */
@@ -1791,11 +1809,11 @@
   return NULL;
 }
 
-void *visit(XORN_operator_c *symbol)	{
+void *visit(XORN_operator_c *symbol) {
   if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	BYTE_operator_result_type();
-	XXX_operator(&(this->default_variable_name),
+    BYTE_operator_result_type();
+    XXX_operator(&(this->default_variable_name),
                  // bit by bit exclusive OR !! Also seems to work with boolean types!
                  search_expression_type->is_bool_type(this->current_operand_type)?" ^= !":" ^= ~",
                  this->current_operand);
@@ -1806,7 +1824,7 @@
   return NULL;
 }
 
-void *visit(ADD_operator_c *symbol)	{
+void *visit(ADD_operator_c *symbol) {
   if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       search_expression_type->is_time_type(this->current_operand_type)) {
     XXX_function("__time_add", &(this->default_variable_name), this->current_operand);
@@ -1815,8 +1833,8 @@
   }
   else if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	NUM_operator_result_type();
-	XXX_operator(&(this->default_variable_name), " += ", this->current_operand);
+    NUM_operator_result_type();
+    XXX_operator(&(this->default_variable_name), " += ", this->current_operand);
     /* the data type resulting from this operation... */
     this->default_variable_name.current_type = this->current_operand_type;
   }
@@ -1824,7 +1842,7 @@
   return NULL;
 }
 
-void *visit(SUB_operator_c *symbol)	{
+void *visit(SUB_operator_c *symbol) {
   if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       search_expression_type->is_time_type(this->current_operand_type)) {
     XXX_function("__time_sub", &(this->default_variable_name), this->current_operand);
@@ -1833,8 +1851,8 @@
   }
   else if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	NUM_operator_result_type();
-	XXX_operator(&(this->default_variable_name), " -= ", this->current_operand);
+    NUM_operator_result_type();
+    XXX_operator(&(this->default_variable_name), " -= ", this->current_operand);
     /* the data type resulting from this operation... */
     this->default_variable_name.current_type = this->current_operand_type;
   }
@@ -1842,7 +1860,7 @@
   return NULL;
 }
 
-void *visit(MUL_operator_c *symbol)	{
+void *visit(MUL_operator_c *symbol) {
   if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       search_expression_type->is_integer_type(this->current_operand_type)) {
     XXX_function("__time_mul", &(this->default_variable_name), this->current_operand);
@@ -1850,7 +1868,7 @@
   }
   else if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	NUM_operator_result_type();
+    NUM_operator_result_type();
     XXX_operator(&(this->default_variable_name), " *= ", this->current_operand);
     /* the data type resulting from this operation... */
     this->default_variable_name.current_type = this->current_operand_type;
@@ -1859,7 +1877,7 @@
   return NULL;
 }
 
-void *visit(DIV_operator_c *symbol)	{
+void *visit(DIV_operator_c *symbol) {
   if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
       search_expression_type->is_integer_type(this->current_operand_type)) {
     XXX_function("__time_div", &(this->default_variable_name), this->current_operand);
@@ -1867,8 +1885,8 @@
   }
   else if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	NUM_operator_result_type();
-	XXX_operator(&(this->default_variable_name), " /= ", this->current_operand);
+    NUM_operator_result_type();
+    XXX_operator(&(this->default_variable_name), " /= ", this->current_operand);
     /* the data type resulting from this operation... */
     this->default_variable_name.current_type = this->current_operand_type;
     return NULL;
@@ -1877,11 +1895,11 @@
   return NULL;
 }
 
-void *visit(MOD_operator_c *symbol)	{
+void *visit(MOD_operator_c *symbol) {
   if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
       search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-	NUM_operator_result_type();
-	XXX_operator(&(this->default_variable_name), " %= ", this->current_operand);
+    NUM_operator_result_type();
+    XXX_operator(&(this->default_variable_name), " %= ", this->current_operand);
     /* the data type resulting from this operation... */
     this->default_variable_name.current_type = this->current_operand_type;
   }
@@ -1889,7 +1907,7 @@
   return NULL;
 }
 
-void *visit(GT_operator_c *symbol)	{
+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_");
@@ -1899,7 +1917,7 @@
   return NULL;
 }
 
-void *visit(GE_operator_c *symbol)	{
+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_");
@@ -1909,7 +1927,7 @@
   return NULL;
 }
 
-void *visit(EQ_operator_c *symbol)	{
+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 {
@@ -1918,7 +1936,7 @@
   return NULL;
 }
 
-void *visit(LT_operator_c *symbol)	{
+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_");
@@ -1928,7 +1946,7 @@
   return NULL;
 }
 
-void *visit(LE_operator_c *symbol)	{
+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_");
@@ -1938,7 +1956,7 @@
   return NULL;
 }
 
-void *visit(NE_operator_c *symbol)	{
+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 {
@@ -1992,7 +2010,7 @@
 }
 
 //SYM_REF0(JMP_operator_c)
-void *visit(JMP_operator_c *symbol)	{
+void *visit(JMP_operator_c *symbol) {
   if (NULL == this->jump_label) ERROR;
 
   s4o.print("goto ");
@@ -2002,7 +2020,7 @@
 }
 
 // SYM_REF0(JMPC_operator_c)
-void *visit(JMPC_operator_c *symbol)	{
+void *visit(JMPC_operator_c *symbol) {
   if (NULL == this->jump_label) ERROR;
 
   C_modifier();
@@ -2013,7 +2031,7 @@
 }
 
 // SYM_REF0(JMPCN_operator_c)
-void *visit(JMPCN_operator_c *symbol)	{
+void *visit(JMPCN_operator_c *symbol) {
   if (NULL == this->jump_label) ERROR;
 
   CN_modifier();
--- a/stage4/generate_c/generate_c_inlinefcall.cc	Thu Nov 08 18:55:57 2012 +0100
+++ b/stage4/generate_c/generate_c_inlinefcall.cc	Thu Nov 15 22:28:53 2012 +0100
@@ -39,69 +39,69 @@
   private:
 
     /* The initial value that should be given to the IL default variable
-	 * imediately after a parenthesis is opened.
-	 * This variable is only used to pass data from the
-	 * il_expression_c visitor to the simple_instr_list_c visitor.
-	 *
-	 * e.g.:
-	 *         LD var1
-	 *         AND ( var2
-	 *         OR var3
-	 *         )
-	 *
-	 * In the above code sample, the line 'AND ( var2' constitutes
-	 * an il_expression_c, where var2 should be loaded into the
-	 * il default variable before continuing with the expression
-	 * inside the parenthesis.
-	 * Unfortunately, only the simple_instr_list_c may do the
-	 * initial laoding of the var2 bariable following the parenthesis,
-	 * so the il_expression_c visitor will have to pass 'var2' as a
-	 * parameter to the simple_instr_list_c visitor.
-	 * Ergo, the existance of the following parameter...!
-	 */
-	symbol_c *il_default_variable_init_value;
+     * imediately after a parenthesis is opened.
+     * This variable is only used to pass data from the
+     * il_expression_c visitor to the simple_instr_list_c visitor.
+     *
+     * e.g.:
+     *         LD var1
+     *         AND ( var2
+     *         OR var3
+     *         )
+     *
+     * In the above code sample, the line 'AND ( var2' constitutes
+     * an il_expression_c, where var2 should be loaded into the
+     * il default variable before continuing with the expression
+     * inside the parenthesis.
+     * Unfortunately, only the simple_instr_list_c may do the
+     * initial laoding of the var2 bariable following the parenthesis,
+     * so the il_expression_c visitor will have to pass 'var2' as a
+     * parameter to the simple_instr_list_c visitor.
+     * Ergo, the existance of the following parameter...!
+     */
+    symbol_c *il_default_variable_init_value;
 
     /* Operand to the IL operation currently being processed... */
-	/* These variables are used to pass data from the
-	 * il_simple_operation_c and il_expression_c visitors
-	 * to the il operator visitors (i.e. LD_operator_c,
-	 * LDN_operator_c, ST_operator_c, STN_operator_c, ...)
-	 */
-	symbol_c *current_operand;
-	symbol_c *current_operand_type;
-
-	 /* The result of the comparison IL operations (GT, EQ, LT, ...)
-	 * is a boolean variable.
-	 * This class keeps track of the current data type stored in the
-	 * il default variable. This is usually done by keeping a reference
-	 * to the data type of the last operand. Nevertheless, in the case of
-	 * the comparison IL operators, the data type of the result (a boolean)
-	 * is not the data type of the operand. We therefore need an object
-	 * of the boolean data type to keep as a reference of the current
-	 * data type.
-	 * The following object is it...
-	 */
-	bool_type_name_c bool_type;
-	lint_type_name_c lint_type;
-	lword_type_name_c lword_type;
-	lreal_type_name_c lreal_type;
+    /* These variables are used to pass data from the
+     * il_simple_operation_c and il_expression_c visitors
+     * to the il operator visitors (i.e. LD_operator_c,
+     * LDN_operator_c, ST_operator_c, STN_operator_c, ...)
+     */
+    symbol_c *current_operand;
+    symbol_c *current_operand_type;
+
+     /* The result of the comparison IL operations (GT, EQ, LT, ...)
+     * is a boolean variable.
+     * This class keeps track of the current data type stored in the
+     * il default variable. This is usually done by keeping a reference
+     * to the data type of the last operand. Nevertheless, in the case of
+     * the comparison IL operators, the data type of the result (a boolean)
+     * is not the data type of the operand. We therefore need an object
+     * of the boolean data type to keep as a reference of the current
+     * data type.
+     * The following object is it...
+     */
+    bool_type_name_c bool_type;
+    lint_type_name_c lint_type;
+    lword_type_name_c lword_type;
+    lreal_type_name_c lreal_type;
 
     /* The name of the IL default variable... */
-	#define IL_DEFVAR   VAR_LEADER "IL_DEFVAR"
-
-	/* The name of the variable used to pass the result of a
-	 * parenthesised instruction list to the immediately preceding
-	 * scope ...
-	 */
+    #define IL_DEFVAR   VAR_LEADER "IL_DEFVAR"
+
+    /* The name of the variable used to pass the result of a
+     * parenthesised instruction list to the immediately preceding
+     * scope ...
+     */
     #define IL_DEFVAR_BACK   VAR_LEADER "IL_DEFVAR_BACK"
     il_default_variable_c default_variable_name;
-	il_default_variable_c default_variable_back_name;
-
-	symbol_c* current_array_type;
-
-	int fcall_number;
-	bool generating_inlinefunction;
-	symbol_c *fbname;
+    il_default_variable_c default_variable_back_name;
+
+    symbol_c* current_array_type;
+
+    int fcall_number;
+    bool generating_inlinefunction;
+    symbol_c *fbname;
 
     search_expression_type_c *search_expression_type;
 
@@ -142,7 +142,7 @@
       function_call_iterator_c fc_iterator(symbol);
       symbol_c* function_call;
       while ((function_call = fc_iterator.next()) != NULL) {
-    	function_call->accept(*this);
+        function_call->accept(*this);
       }
     }
 
@@ -175,7 +175,7 @@
         s4o.print("__");
         print_function_parameter_data_types_c overloaded_func_suf(&s4o);
         f_decl->accept(overloaded_func_suf);
-      }	
+      }
       if (function_type_suffix) {
         function_type_suffix->accept(*this);
       }
@@ -224,8 +224,8 @@
       s4o.print(" = ");
       function_name->accept(*this);
       if (f_decl != NULL) {
-    	/* function being called is overloaded! */
-    	s4o.print("__");
+        /* function being called is overloaded! */
+        s4o.print("__");
         print_function_parameter_data_types_c overloaded_func_suf(&s4o);
         f_decl->accept(overloaded_func_suf);
       }
@@ -273,59 +273,63 @@
   private:
 
     /* A helper function... */
-	void CMP_operator_result_type() {
-	  /* the data type resulting from this operation... */
-	  this->default_variable_name.current_type = &(this->bool_type);
-	}
-
-	/* A helper function... */
+    void CMP_operator_result_type() {
+      /* the data type resulting from this operation... */
+      this->default_variable_name.current_type = &(this->bool_type);
+    }
+
+    /* A helper function... */
     void BYTE_operator_result_type(void) {
-	  if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) {
-		if (search_expression_type->is_literal_integer_type(this->current_operand_type))
-		  this->default_variable_name.current_type = &(this->lword_type);
-		else
-		  this->default_variable_name.current_type = this->current_operand_type;
-	  }
-	  else if (search_expression_type->is_literal_integer_type(this->current_operand_type))
-		  this->current_operand_type = this->default_variable_name.current_type;
-	}
+      if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) {
+        if (search_expression_type->is_literal_integer_type(this->current_operand_type))
+          this->default_variable_name.current_type = &(this->lword_type);
+        else
+          this->default_variable_name.current_type = this->current_operand_type;
+      }
+      else if (search_expression_type->is_literal_integer_type(this->current_operand_type))
+          this->current_operand_type = this->default_variable_name.current_type;
+    }
 
     /* A helper function... */
     void NUM_operator_result_type(void) {
-	  if (search_expression_type->is_literal_real_type(this->default_variable_name.current_type)) {
-		if (search_expression_type->is_literal_integer_type(this->current_operand_type) ||
-			search_expression_type->is_literal_real_type(this->current_operand_type))
-		  this->default_variable_name.current_type = &(this->lreal_type);
-		else
-		  this->default_variable_name.current_type = this->current_operand_type;
-	  }
-	  else if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) {
-		if (search_expression_type->is_literal_integer_type(this->current_operand_type))
-		  this->default_variable_name.current_type = &(this->lint_type);
-		else if (search_expression_type->is_literal_real_type(this->current_operand_type))
-		  this->default_variable_name.current_type = &(this->lreal_type);
-		else
-		  this->default_variable_name.current_type = this->current_operand_type;
-	  }
-	  else if (search_expression_type->is_literal_integer_type(this->current_operand_type) ||
-			   search_expression_type->is_literal_real_type(this->current_operand_type))
-		this->current_operand_type = this->default_variable_name.current_type;
-	}
+      if (search_expression_type->is_literal_real_type(this->default_variable_name.current_type)) {
+        if (search_expression_type->is_literal_integer_type(this->current_operand_type) ||
+            search_expression_type->is_literal_real_type(this->current_operand_type))
+          this->default_variable_name.current_type = &(this->lreal_type);
+        else
+          this->default_variable_name.current_type = this->current_operand_type;
+      }
+      else if (search_expression_type->is_literal_integer_type(this->default_variable_name.current_type)) {
+        if (search_expression_type->is_literal_integer_type(this->current_operand_type))
+          this->default_variable_name.current_type = &(this->lint_type);
+        else if (search_expression_type->is_literal_real_type(this->current_operand_type))
+          this->default_variable_name.current_type = &(this->lreal_type);
+        else
+          this->default_variable_name.current_type = this->current_operand_type;
+      }
+      else if (search_expression_type->is_literal_integer_type(this->current_operand_type) ||
+               search_expression_type->is_literal_real_type(this->current_operand_type))
+        this->current_operand_type = this->default_variable_name.current_type;
+    }
 
     void *print_getter(symbol_c *symbol) {
       unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
-      if (vartype == search_var_instance_decl_c::external_vt)
-    	s4o.print(GET_EXTERNAL);
+      if (vartype == search_var_instance_decl_c::external_vt) {
+        if (search_var_instance_decl->type_is_fb(symbol))
+          s4o.print(GET_EXTERNAL_FB);
+        else
+          s4o.print(GET_EXTERNAL);
+      }
       else if (vartype == search_var_instance_decl_c::located_vt)
-    	s4o.print(GET_LOCATED);
+        s4o.print(GET_LOCATED);
       else
-    	s4o.print(GET_VAR);
+        s4o.print(GET_VAR);
       s4o.print("(");
 
       wanted_variablegeneration = complextype_base_vg;
       symbol->accept(*this);
       if (search_var_instance_decl->type_is_complex(symbol))
-    	s4o.print(",");
+        s4o.print(",");
       wanted_variablegeneration = complextype_suffix_vg;
       symbol->accept(*this);
       s4o.print(")");
@@ -334,11 +338,15 @@
     }
 
     void *print_setter(symbol_c* symbol,
-    		symbol_c* type,
-    		symbol_c* value) {
+            symbol_c* type,
+            symbol_c* value) {
       unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
-      if (vartype == search_var_instance_decl_c::external_vt)
-        s4o.print(SET_EXTERNAL);
+      if (vartype == search_var_instance_decl_c::external_vt) {
+        if (search_var_instance_decl->type_is_fb(symbol))
+          s4o.print(SET_EXTERNAL_FB);
+         else
+          s4o.print(SET_EXTERNAL);
+      }
       else if (vartype == search_var_instance_decl_c::located_vt)
         s4o.print(SET_LOCATED);
       else
@@ -407,8 +415,8 @@
           case complextype_base_vg:
             symbol->record_variable->accept(*this);
             if (!type_is_complex) {
-          	  s4o.print(".");
-          	  symbol->field_selector->accept(*this);
+                s4o.print(".");
+                symbol->field_selector->accept(*this);
             }
             break;
           case complextype_suffix_vg:
@@ -828,88 +836,88 @@
       iterator_visitor_c::visit(symbol);
 
       /* copy the result in the default variable to the variable
-	   * used to pass the data out to the scope enclosing
-	   * the current scope!
-	   *
-	   * We also need to update the data type currently stored within
-	   * the variable used to pass the data to the outside scope...
-	   */
-	  this->default_variable_back_name.current_type = this->default_variable_name.current_type;
-	  return NULL;
+       * used to pass the data out to the scope enclosing
+       * the current scope!
+       *
+       * We also need to update the data type currently stored within
+       * the variable used to pass the data to the outside scope...
+       */
+      this->default_variable_back_name.current_type = this->default_variable_name.current_type;
+      return NULL;
     }
     
     // SYM_REF1(il_simple_instruction_c, il_simple_instruction, symbol_c *prev_il_instruction;)
-    void *visit(il_simple_instruction_c *symbol)	{
+    void *visit(il_simple_instruction_c *symbol) {
       return symbol->il_simple_instruction->accept(*this);
     }
 
-    void *visit(LD_operator_c *symbol)	{
+    void *visit(LD_operator_c *symbol) {
       /* the data type resulting from this operation... */
       this->default_variable_name.current_type = this->current_operand_type;
       return NULL;
     }
 
-    void *visit(LDN_operator_c *symbol)	{
+    void *visit(LDN_operator_c *symbol) {
       /* the data type resulting from this operation... */
       this->default_variable_name.current_type = this->current_operand_type;
       return NULL;
     }
 
-    void *visit(AND_operator_c *symbol)	{
+    void *visit(AND_operator_c *symbol) {
       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    	BYTE_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(OR_operator_c *symbol)	{
+        BYTE_operator_result_type();
+      }
+      else {ERROR;}
+      return NULL;
+    }
+
+    void *visit(OR_operator_c *symbol) {
       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    	BYTE_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(XOR_operator_c *symbol)	{
+        BYTE_operator_result_type();
+      }
+      else {ERROR;}
+      return NULL;
+    }
+
+    void *visit(XOR_operator_c *symbol) {
       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    	BYTE_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(ANDN_operator_c *symbol)	{
+        BYTE_operator_result_type();
+      }
+      else {ERROR;}
+      return NULL;
+    }
+
+    void *visit(ANDN_operator_c *symbol) {
       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    	BYTE_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(ORN_operator_c *symbol)	{
+        BYTE_operator_result_type();
+      }
+      else {ERROR;}
+      return NULL;
+    }
+
+    void *visit(ORN_operator_c *symbol) {
       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    	BYTE_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(XORN_operator_c *symbol)	{
+        BYTE_operator_result_type();
+      }
+      else {ERROR;}
+      return NULL;
+    }
+
+    void *visit(XORN_operator_c *symbol) {
       if (search_expression_type->is_binary_type(this->default_variable_name.current_type) &&
           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    	BYTE_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(ADD_operator_c *symbol)	{
+        BYTE_operator_result_type();
+      }
+      else {ERROR;}
+      return NULL;
+    }
+
+    void *visit(ADD_operator_c *symbol) {
       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
           search_expression_type->is_time_type(this->current_operand_type)) {
         /* the data type resulting from this operation... */
@@ -923,7 +931,7 @@
       return NULL;
     }
 
-    void *visit(SUB_operator_c *symbol)	{
+    void *visit(SUB_operator_c *symbol) {
       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
           search_expression_type->is_time_type(this->current_operand_type)) {
         /* the data type resulting from this operation... */
@@ -931,26 +939,26 @@
       }
       else if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    	NUM_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(MUL_operator_c *symbol)	{
+        NUM_operator_result_type();
+      }
+      else {ERROR;}
+      return NULL;
+    }
+
+    void *visit(MUL_operator_c *symbol) {
       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
           search_expression_type->is_integer_type(this->current_operand_type)) {
         /* the data type resulting from this operation is unchanged! */
       }
       else if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
-    	NUM_operator_result_type();
-      }
-      else {ERROR;}
-      return NULL;
-    }
-
-    void *visit(DIV_operator_c *symbol)	{
+        NUM_operator_result_type();
+      }
+      else {ERROR;}
+      return NULL;
+    }
+
+    void *visit(DIV_operator_c *symbol) {
       if (search_expression_type->is_time_type(this->default_variable_name.current_type) &&
           search_expression_type->is_integer_type(this->current_operand_type)) {
         /* the data type resulting from this operation is unchanged! */
@@ -963,7 +971,7 @@
       return NULL;
     }
 
-    void *visit(MOD_operator_c *symbol)	{
+    void *visit(MOD_operator_c *symbol) {
       if (search_expression_type->is_num_type(this->default_variable_name.current_type) &&
           search_expression_type->is_same_type(this->default_variable_name.current_type, this->current_operand_type)) {
         NUM_operator_result_type();
@@ -972,7 +980,7 @@
       return NULL;
     }
 
-    void *visit(GT_operator_c *symbol)	{
+    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();
@@ -981,7 +989,7 @@
       return NULL;
     }
 
-    void *visit(GE_operator_c *symbol)	{
+    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();
@@ -990,7 +998,7 @@
       return NULL;
     }
 
-    void *visit(EQ_operator_c *symbol)	{
+    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();
       }
@@ -998,7 +1006,7 @@
       return NULL;
     }
 
-    void *visit(LT_operator_c *symbol)	{
+    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();
@@ -1007,7 +1015,7 @@
       return NULL;
     }
 
-    void *visit(LE_operator_c *symbol)	{
+    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();
@@ -1016,7 +1024,7 @@
       return NULL;
     }
 
-    void *visit(NE_operator_c *symbol)	{
+    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();
       }
@@ -1032,13 +1040,13 @@
     /***********************/
 
     void *visit(statement_list_c *symbol) {
-	  function_call_iterator_c fc_iterator(symbol);
-	  symbol_c* function_call;
-	  while ((function_call = fc_iterator.next()) != NULL) {
-		function_call->accept(*this);
-	  }
-	  return NULL;
-	}
+      function_call_iterator_c fc_iterator(symbol);
+      symbol_c* function_call;
+      while ((function_call = fc_iterator.next()) != NULL) {
+        function_call->accept(*this);
+      }
+      return NULL;
+    }
 
     void *visit(function_invocation_c *symbol) {
       symbol_c* function_type_prefix = NULL;
@@ -1170,43 +1178,43 @@
       return NULL;
     }
 
-	/*********************************************/
-	/* B.1.6  Sequential function chart elements */
-	/*********************************************/
-
-	void *visit(initial_step_c *symbol) {
-		return NULL;
-	}
-
-	void *visit(step_c *symbol) {
-		return NULL;
-	}
-
-	void *visit(transition_c *symbol) {
-		return symbol->transition_condition->accept(*this);
-	}
-
-	void *visit(transition_condition_c *symbol) {
-		// Transition condition is in IL
-		if (symbol->transition_condition_il != NULL) {
-			symbol->transition_condition_il->accept(*this);
-		}
-
-		// Transition condition is in ST
-		if (symbol->transition_condition_st != NULL) {
-			function_call_iterator_c fc_iterator(symbol->transition_condition_st);
-			symbol_c* function_call;
-			while ((function_call = fc_iterator.next()) != NULL) {
-				function_call->accept(*this);
-			}
-		}
-
-		return NULL;
-	}
-
-	void *visit(action_c *symbol) {
-		return symbol->function_block_body->accept(*this);
-	}
+    /*********************************************/
+    /* B.1.6  Sequential function chart elements */
+    /*********************************************/
+
+    void *visit(initial_step_c *symbol) {
+        return NULL;
+    }
+
+    void *visit(step_c *symbol) {
+        return NULL;
+    }
+
+    void *visit(transition_c *symbol) {
+        return symbol->transition_condition->accept(*this);
+    }
+
+    void *visit(transition_condition_c *symbol) {
+        // Transition condition is in IL
+        if (symbol->transition_condition_il != NULL) {
+            symbol->transition_condition_il->accept(*this);
+        }
+
+        // Transition condition is in ST
+        if (symbol->transition_condition_st != NULL) {
+            function_call_iterator_c fc_iterator(symbol->transition_condition_st);
+            symbol_c* function_call;
+            while ((function_call = fc_iterator.next()) != NULL) {
+                function_call->accept(*this);
+            }
+        }
+
+        return NULL;
+    }
+
+    void *visit(action_c *symbol) {
+        return symbol->function_block_body->accept(*this);
+    }
 
 };  /* generate_c_inlinefcall_c */
 
--- a/stage4/generate_c/generate_c_st.cc	Thu Nov 08 18:55:57 2012 +0100
+++ b/stage4/generate_c/generate_c_st.cc	Thu Nov 15 22:28:53 2012 +0100
@@ -144,16 +144,24 @@
 void *print_getter(symbol_c *symbol) {
   unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
   if (wanted_variablegeneration == fparam_output_vg) {
-    if (vartype == search_var_instance_decl_c::external_vt)
-      s4o.print(GET_EXTERNAL_BY_REF);
+    if (vartype == search_var_instance_decl_c::external_vt) {
+      if (search_var_instance_decl->type_is_fb(symbol))
+        s4o.print(GET_EXTERNAL_FB_BY_REF);
+      else
+        s4o.print(GET_EXTERNAL_BY_REF);
+    }
     else if (vartype == search_var_instance_decl_c::located_vt)
       s4o.print(GET_LOCATED_BY_REF);
     else
       s4o.print(GET_VAR_BY_REF);
   }
   else {
-    if (vartype == search_var_instance_decl_c::external_vt)
-      s4o.print(GET_EXTERNAL);
+    if (vartype == search_var_instance_decl_c::external_vt) {
+      if (search_var_instance_decl->type_is_fb(symbol))
+        s4o.print(GET_EXTERNAL_FB);
+      else
+        s4o.print(GET_EXTERNAL);
+    }
     else if (vartype == search_var_instance_decl_c::located_vt)
       s4o.print(GET_LOCATED);
     else
@@ -174,24 +182,33 @@
 }
 
 void *print_setter(symbol_c* symbol,
-		symbol_c* type,
-		symbol_c* value,
-		symbol_c* fb_symbol = NULL,
-		symbol_c* fb_value = NULL) {
+        symbol_c* type,
+        symbol_c* value,
+        symbol_c* fb_symbol = NULL,
+        symbol_c* fb_value = NULL) {
   
   bool type_is_complex = false;
   if (fb_symbol == NULL) {
     unsigned int vartype = search_var_instance_decl->get_vartype(symbol);
     type_is_complex = search_var_instance_decl->type_is_complex(symbol);
-    if (vartype == search_var_instance_decl_c::external_vt)
-      s4o.print(SET_EXTERNAL);
+    if (vartype == search_var_instance_decl_c::external_vt) {
+      if (search_var_instance_decl->type_is_fb(symbol))
+        s4o.print(SET_EXTERNAL_FB);
+      else
+        s4o.print(SET_EXTERNAL);
+    }
     else if (vartype == search_var_instance_decl_c::located_vt)
       s4o.print(SET_LOCATED);
     else
       s4o.print(SET_VAR);
   }
-  else
-	s4o.print(SET_VAR);
+  else {
+    unsigned int vartype = search_var_instance_decl->get_vartype(fb_symbol);
+    if (vartype == search_var_instance_decl_c::external_vt)
+      s4o.print(SET_EXTERNAL_FB);
+    else
+      s4o.print(SET_VAR);
+  }
   s4o.print("(");
 
   if (fb_symbol != NULL) {
@@ -288,14 +305,14 @@
   if (strlen(symbol->value) == 0) ERROR;
   if (this->is_variable_prefix_null()) {
     if (wanted_variablegeneration != fparam_output_vg)
-	  s4o.print("*(");
+      s4o.print("*(");
   }
   else {
     switch (wanted_variablegeneration) {
       case expression_vg:
-  	    s4o.print(GET_LOCATED);
-  	    s4o.print("(");
-  	    break;
+        s4o.print(GET_LOCATED);
+        s4o.print("(");
+        break;
       case fparam_output_vg:
         s4o.print(GET_LOCATED_BY_REF);
         s4o.print("(");
@@ -307,7 +324,7 @@
   this->print_variable_prefix();
   s4o.printlocation(symbol->value + 1);
   if ((this->is_variable_prefix_null() && wanted_variablegeneration != fparam_output_vg) ||
-	  wanted_variablegeneration != assignment_vg)
+      wanted_variablegeneration != assignment_vg)
     s4o.print(")");
   return NULL;
 }
@@ -325,8 +342,8 @@
     case complextype_base_assignment_vg:
       symbol->record_variable->accept(*this);
       if (!type_is_complex) {
-    	s4o.print(".");
-    	symbol->field_selector->accept(*this);
+        s4o.print(".");
+        symbol->field_selector->accept(*this);
       }
       break;
     case complextype_suffix_vg:
@@ -343,12 +360,12 @@
       break;
     default:
       if (this->is_variable_prefix_null()) {
-    	symbol->record_variable->accept(*this);
-    	s4o.print(".");
-    	symbol->field_selector->accept(*this);
+        symbol->record_variable->accept(*this);
+        s4o.print(".");
+        symbol->field_selector->accept(*this);
       }
       else
-    	print_getter(symbol);
+        print_getter(symbol);
       break;
   }
   return NULL;
@@ -377,18 +394,18 @@
       break;
     default:
       if (this->is_variable_prefix_null()) {
-    	symbol->subscripted_variable->accept(*this);
-
-    	current_array_type = search_varfb_instance_type->get_basetype_decl(symbol->subscripted_variable);
-    	if (current_array_type == NULL) ERROR;
-
-    	s4o.print(".table");
+        symbol->subscripted_variable->accept(*this);
+
+        current_array_type = search_varfb_instance_type->get_basetype_decl(symbol->subscripted_variable);
+        if (current_array_type == NULL) ERROR;
+
+        s4o.print(".table");
         symbol->subscript_list->accept(*this);
 
         current_array_type = NULL;
       }
       else
-    	print_getter(symbol);
+        print_getter(symbol);
       break;
   }
   return NULL;
@@ -399,9 +416,9 @@
   array_dimension_iterator_c* array_dimension_iterator = new array_dimension_iterator_c(current_array_type);
   for (int i =  0; i < symbol->n; i++) {
     symbol_c* dimension = array_dimension_iterator->next();
-	if (dimension == NULL) ERROR;
-
-	s4o.print("[(");
+    if (dimension == NULL) ERROR;
+
+    s4o.print("[(");
     symbol->elements[i]->accept(*this);
     s4o.print(") - (");
     dimension->accept(*this);
@@ -570,8 +587,8 @@
 
 void *visit(add_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 ((typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) ||
+  symbol_c *right_type = search_expression_type->get_type(symbol->r_exp);
+  if ((typeid(*left_type) == typeid(time_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) ||
       (typeid(*left_type) == typeid(tod_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)) ||
       (typeid(*left_type) == typeid(dt_type_name_c) && typeid(*right_type) == typeid(time_type_name_c)))
     return print_binary_function("__time_add", symbol->l_exp, symbol->r_exp);
@@ -650,15 +667,15 @@
   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_real_type(left_type) && search_expression_type->is_num_type(right_type)) {
-	s4o.print("EXPT__LREAL__LREAL__LREAL((BOOL)__BOOL_LITERAL(TRUE),\n");
-	s4o.indent_right();
-	s4o.print(s4o.indent_spaces + "NULL,\n");
-	s4o.print(s4o.indent_spaces + "(LREAL)(");
-	symbol->l_exp->accept(*this);
-	s4o.print("),\n");
-	s4o.print(s4o.indent_spaces + "(LREAL)(");
-	symbol->r_exp->accept(*this);
-	s4o.print("))");
+    s4o.print("EXPT__LREAL__LREAL__LREAL((BOOL)__BOOL_LITERAL(TRUE),\n");
+    s4o.indent_right();
+    s4o.print(s4o.indent_spaces + "NULL,\n");
+    s4o.print(s4o.indent_spaces + "(LREAL)(");
+    symbol->l_exp->accept(*this);
+    s4o.print("),\n");
+    s4o.print(s4o.indent_spaces + "(LREAL)(");
+    symbol->r_exp->accept(*this);
+    s4o.print("))");
     return NULL;
   }
   ERROR;
@@ -824,9 +841,9 @@
           
     switch (PARAM_DIRECTION) {
       case function_param_iterator_c::direction_in:
-    	if (nb_param > 0)
-    	  s4o.print(",\n"+s4o.indent_spaces);
-    	if (param_value == NULL) {
+        if (nb_param > 0)
+          s4o.print(",\n"+s4o.indent_spaces);
+        if (param_value == NULL) {
           /* If not, get the default value of this variable's type */
           param_value = (symbol_c *)current_param_type->accept(*type_initial_value_c::instance());
         }
@@ -844,18 +861,18 @@
         break;
       case function_param_iterator_c::direction_out:
       case function_param_iterator_c::direction_inout:
-    	if (!has_output_params) {
+        if (!has_output_params) {
           if (nb_param > 0)
-        	s4o.print(",\n"+s4o.indent_spaces);
-    	  if (param_value == NULL)
+            s4o.print(",\n"+s4o.indent_spaces);
+          if (param_value == NULL)
             s4o.print("NULL");
           else {
             wanted_variablegeneration = fparam_output_vg;
             param_value->accept(*this);
             wanted_variablegeneration = expression_vg;
           }
-    	  nb_param++;
-    	}
+          nb_param++;
+        }
         break;
       case function_param_iterator_c::direction_extref:
         /* TODO! */
@@ -895,7 +912,7 @@
     print_check_function(left_type, symbol->r_exp);
   }
   else {
-	print_setter(symbol->l_exp, left_type, symbol->r_exp);
+    print_setter(symbol->l_exp, left_type, symbol->r_exp);
   }
   return NULL;
 }
@@ -970,7 +987,9 @@
   /* now call the function... */
   function_block_type_name->accept(*this);
   s4o.print(FB_FUNCTION_SUFFIX);
-  s4o.print("(&");
+  s4o.print("(");
+  if (search_var_instance_decl->get_vartype(symbol->fb_name) != search_var_instance_decl_c::external_vt)
+    s4o.print("&");
   print_variable_prefix();
   symbol->fb_name->accept(*this);
   s4o.print(")");
@@ -1111,9 +1130,9 @@
   s4o.indent_right();
   s4o.print(s4o.indent_spaces);
   if (search_expression_type->is_literal_integer_type(expression_type))
-	search_expression_type->lint_type_name.accept(*this);
+    search_expression_type->lint_type_name.accept(*this);
   else if (search_expression_type->is_literal_real_type(expression_type))
-	search_expression_type->lreal_type_name.accept(*this);
+    search_expression_type->lreal_type_name.accept(*this);
   else
     expression_type->accept(*this);
   s4o.print(" __case_expression = ");
@@ -1128,10 +1147,10 @@
   first_subrange_case_list = true;
   symbol->case_element_list->accept(*this);
   if (symbol->statement_list != NULL) {
-	if (!first_subrange_case_list) {
+    if (!first_subrange_case_list) {
       s4o.print(s4o.indent_spaces + "else {\n");
       s4o.indent_right();
-	}
+    }
     symbol->statement_list->accept(*this);
     if (!first_subrange_case_list) {
       s4o.indent_left();
@@ -1161,7 +1180,7 @@
       case_element_iterator = new case_element_iterator_c(symbol->case_list, case_element_iterator_c::element_single);
       for (element = case_element_iterator->next(); element != NULL; element = case_element_iterator->next()) {
         if (first_element) first_element = false;
-    	s4o.print(s4o.indent_spaces + "case ");
+        s4o.print(s4o.indent_spaces + "case ");
         element->accept(*this);
         s4o.print(":\n");
       }
@@ -1177,7 +1196,7 @@
             first_subrange_case_list = false;
           }
           else {
-        	  s4o.print(s4o.indent_spaces + "else if (");
+            s4o.print(s4o.indent_spaces + "else if (");
           }
           first_element = false;
         }
@@ -1205,9 +1224,9 @@
         s4o.indent_left();
         break;
       case subrange_cg:
-    	s4o.indent_left();
-  	    s4o.print(s4o.indent_spaces + "}\n");
-  	    break;
+        s4o.indent_left();
+        s4o.print(s4o.indent_spaces + "}\n");
+        break;
       default:
         break;
     }
--- a/stage4/generate_c/generate_c_typedecl.cc	Thu Nov 08 18:55:57 2012 +0100
+++ b/stage4/generate_c/generate_c_typedecl.cc	Thu Nov 15 22:28:53 2012 +0100
@@ -100,6 +100,9 @@
       return NULL;
     }
 
+    bool type_is_fb(symbol_c* type_decl) {
+      return search_base_type.type_is_fb(type_decl);
+    }
 
 /***************************/
 /* B 0 - Programming Model */
@@ -343,19 +346,19 @@
   current_basetypedeclaration = none_bd;
 
   if (array_is_derived)
-	s4o_incl.print("__DECLARE_DERIVED_TYPE(");
+    s4o_incl.print("__DECLARE_DERIVED_TYPE(");
   else
-	s4o_incl.print("__DECLARE_ARRAY_TYPE(");
+    s4o_incl.print("__DECLARE_ARRAY_TYPE(");
   current_type_name->accept(*basedecl);
   s4o_incl.print(",");
   current_basetypedeclaration = arraybasetypeincl_bd;
   symbol->array_spec_init->accept(*this);
   current_basetypedeclaration = none_bd;
   if (!array_is_derived) {
-	s4o_incl.print(",");
-	current_basetypedeclaration = arraysubrange_bd;
-	symbol->array_spec_init->accept(*this);
-	current_basetypedeclaration = none_bd;
+    s4o_incl.print(",");
+    current_basetypedeclaration = arraysubrange_bd;
+    symbol->array_spec_init->accept(*this);
+    current_basetypedeclaration = none_bd;
   }
   s4o_incl.print(")\n");
 
@@ -372,19 +375,19 @@
   
   if (current_typedefinition == array_td) {
     switch (current_basetypedeclaration) {
-	  case arrayderiveddeclaration_bd:
-	    array_is_derived = dynamic_cast<identifier_c *>(symbol->array_specification) != NULL;
-	    break;
-	  default:
-	    if (array_is_derived)
-		  symbol->array_specification->accept(*basedecl);
-	    else
-		  symbol->array_specification->accept(*this);
-	    break;
+      case arrayderiveddeclaration_bd:
+        array_is_derived = dynamic_cast<identifier_c *>(symbol->array_specification) != NULL;
+        break;
+      default:
+        if (array_is_derived)
+          symbol->array_specification->accept(*basedecl);
+        else
+          symbol->array_specification->accept(*this);
+        break;
     }
   }
   else {
-	symbol->array_specification->accept(*basedecl);
+    symbol->array_specification->accept(*basedecl);
   }
   return NULL;
 }
@@ -439,11 +442,11 @@
   s4o_incl.print(")\n");
 
   if (search_base_type.type_is_subrange(symbol->simple_type_name)) {
-	s4o.print("#define __CHECK_");
-	current_type_name->accept(*this);
-	s4o.print(" __CHECK_");
-	symbol->simple_spec_init->accept(*this);
-	s4o.print("\n");
+    s4o.print("#define __CHECK_");
+    current_type_name->accept(*this);
+    s4o.print(" __CHECK_");
+    symbol->simple_spec_init->accept(*this);
+    s4o.print("\n");
   }
 
   return NULL;
--- a/stage4/generate_c/generate_c_vardecl.cc	Thu Nov 08 18:55:57 2012 +0100
+++ b/stage4/generate_c/generate_c_vardecl.cc	Thu Nov 15 22:28:53 2012 +0100
@@ -26,31 +26,31 @@
 
 class initialization_analyzer_c: public null_visitor_c {
   public:
-	typedef enum {
-	  simple_it,
-	  array_it,
-	  struct_it
-	} initialization_type_t;
+    typedef enum {
+      simple_it,
+      array_it,
+      struct_it
+    } initialization_type_t;
 
   private:
 
-	initialization_type_t current_type;
+    initialization_type_t current_type;
 
   public:
-	initialization_analyzer_c(symbol_c* symbol) {
-	  current_type = simple_it;
+    initialization_analyzer_c(symbol_c* symbol) {
+      current_type = simple_it;
       symbol->accept(*this);
-	}
-	~initialization_analyzer_c(void) {}
-
-	initialization_type_t get_initialization_type(void) {
-	  return current_type;
-	}
-
-	void *visit(array_initial_elements_list_c *symbol) {
+    }
+    ~initialization_analyzer_c(void) {}
+
+    initialization_type_t get_initialization_type(void) {
+      return current_type;
+    }
+
+    void *visit(array_initial_elements_list_c *symbol) {
       current_type = array_it;
       return NULL;
-	}
+    }
 
     void *visit(structure_element_initialization_list_c *symbol) {
       current_type = struct_it;
@@ -254,7 +254,7 @@
               array_initial_elements_c *array_initial_element = dynamic_cast<array_initial_elements_c *>(symbol->elements[i]);
             
               if (array_initial_element != NULL) {
-            	  symbol->elements[i]->accept(*this);
+                symbol->elements[i]->accept(*this);
               }
             }
             current_initialization_count++;
@@ -273,7 +273,7 @@
  
       /* This code assumes that unsigned long long int is >= uint64_t */
       if (std::numeric_limits< uint64_t >::max() > std::numeric_limits< unsigned long long int >::max()) 
-	ERROR_MSG("Assertion (sizeof(uint64_t) > sizeof(unsigned long long int)) failed! Compiler cannot execute correctly on the current platform!");
+        ERROR_MSG("Assertion (sizeof(uint64_t) > sizeof(unsigned long long int)) failed! Compiler cannot execute correctly on the current platform!");
       
       switch (current_mode) {
         case initializationvalue_am:
@@ -654,7 +654,7 @@
       generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
       array_initialization->init_array_size(current_element_type);
       if (current_element_default_value != NULL)
-    	array_initialization->set_array_default_initialisation(current_element_default_value);
+        array_initialization->set_array_default_initialisation(current_element_default_value);
       array_initialization->init_array_values(symbol);
       delete array_initialization;
       return NULL;
@@ -911,17 +911,17 @@
     symbol_c *globalnamespace;
 
     void *print_retain(void) {
-	  s4o.print(",");
+      s4o.print(",");
       switch (current_varqualifier) {
-		case retain_vq:
+        case retain_vq:
           s4o.print("1");
           break;
         case non_retain_vq:
           s4o.print("0");
           break;
-		default:
-		  s4o.print("retain");
-		  break;
+        default:
+          s4o.print("retain");
+          break;
       }
       return NULL;
     }
@@ -943,32 +943,32 @@
         for(int i = 0; i < list->n; i++) {
           s4o.print(s4o.indent_spaces);
           if (wanted_varformat == local_vf) {
-        	if (!is_fb) {
-        	  s4o.print(DECLARE_VAR);
-        	  s4o.print("(");
-        	}
-        	this->current_var_type_symbol->accept(*this);
-        	if (is_fb)
-        	  s4o.print(" ");
-        	else
-        	  s4o.print(",");
-        	print_variable_prefix();
+            if (!is_fb) {
+              s4o.print(DECLARE_VAR);
+              s4o.print("(");
+            }
+            this->current_var_type_symbol->accept(*this);
+            if (is_fb)
+              s4o.print(" ");
+            else
+              s4o.print(",");
+            print_variable_prefix();
           }
           else if (wanted_varformat == localinit_vf) {
-        	this->current_var_type_symbol->accept(*this);
+            this->current_var_type_symbol->accept(*this);
             s4o.print(" ");
             print_variable_prefix();
           }
           else if (wanted_varformat == init_vf) {
-        	s4o.print(SET_VAR);
-        	s4o.print("(");
-        	print_variable_prefix();
-        	s4o.print(",");
+            s4o.print(SET_VAR);
+            s4o.print("(");
+            print_variable_prefix();
+            s4o.print(",");
           }
           list->elements[i]->accept(*this);
           if (wanted_varformat != local_vf) {
-        	if (wanted_varformat == localinit_vf &&
-        		(current_vartype & inoutput_vt) != 0) {
+            if (wanted_varformat == localinit_vf &&
+                (current_vartype & inoutput_vt) != 0) {
               s4o.print(";\n");
               s4o.print(s4o.indent_spaces);
               s4o.print("if (__");
@@ -999,13 +999,13 @@
               s4o.print(s4o.indent_spaces);
               s4o.print("}\n");
             }
-        	else if (wanted_varformat == init_vf) {
-        	  s4o.print(",");
-        	  this->current_var_init_symbol->accept(*this);
-        	  s4o.print(");\n");
-        	}
-        	else {
-        	  if (this->current_var_init_symbol != NULL) {
+            else if (wanted_varformat == init_vf) {
+              s4o.print(",");
+              this->current_var_init_symbol->accept(*this);
+              s4o.print(");\n");
+            }
+            else {
+              if (this->current_var_init_symbol != NULL) {
                 s4o.print(" = ");
                 this->current_var_init_symbol->accept(*this);
               }
@@ -1013,7 +1013,7 @@
             }
           }
           else if (is_fb)
-        	s4o.print(";\n");
+            s4o.print(";\n");
           else
             s4o.print(")\n");
         }
@@ -1277,9 +1277,9 @@
         (wanted_varformat == localinit_vf)) {
       s4o.print(s4o.indent_spaces);
       if (wanted_varformat == local_vf) {
-    	s4o.print(DECLARE_VAR);
-    	s4o.print("(");
-    	symbol->type->accept(*this);
+        s4o.print(DECLARE_VAR);
+        s4o.print("(");
+        symbol->type->accept(*this);
         s4o.print(",");
       }
       else if (wanted_varformat == localinit_vf) {
@@ -1289,7 +1289,7 @@
       print_variable_prefix();
       symbol->name->accept(*this);
       if (wanted_varformat == local_vf)
-    	s4o.print(")\n");
+        s4o.print(")\n");
       else {
         s4o.print(" = ");
         symbol->value->accept(*this);
@@ -1335,8 +1335,8 @@
         (wanted_varformat == localinit_vf)) {
       s4o.print(s4o.indent_spaces);
       if (wanted_varformat == local_vf) {
-    	s4o.print(DECLARE_VAR);
-    	s4o.print("(");
+        s4o.print(DECLARE_VAR);
+        s4o.print("(");
         symbol->type->accept(*this);
         s4o.print(",");
       }
@@ -1347,9 +1347,9 @@
       print_variable_prefix();
       symbol->name->accept(*this);
       if (wanted_varformat == local_vf)
-    	s4o.print(")\n");
+        s4o.print(")\n");
       else
-    	s4o.print(" = __BOOL_LITERAL(TRUE);\n");
+        s4o.print(" = __BOOL_LITERAL(TRUE);\n");
     }
 
     if (wanted_varformat == foutputassign_vf) {
@@ -1580,10 +1580,10 @@
 
 void *visit(array_initial_elements_list_c *symbol) {
   if (wanted_varformat == localinit_vf || wanted_varformat == constructorinit_vf) {
-	generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
-	array_initialization->init_array_size(this->current_var_type_symbol);
-	array_initialization->init_array_values(this->current_var_init_symbol);
-	delete array_initialization;
+    generate_c_array_initialization_c *array_initialization = new generate_c_array_initialization_c(&s4o);
+    array_initialization->init_array_size(this->current_var_type_symbol);
+    array_initialization->init_array_values(this->current_var_init_symbol);
+    delete array_initialization;
   }
   return NULL;
 }
@@ -1625,7 +1625,7 @@
     generate_c_structure_initialization_c *structure_initialization = new generate_c_structure_initialization_c(&s4o);
     structure_initialization->init_structure_default(this->current_var_type_symbol);
     structure_initialization->init_structure_values(this->current_var_init_symbol);
-	delete structure_initialization;
+    delete structure_initialization;
   }
   return NULL;
 }
@@ -1740,15 +1740,15 @@
       print_retain();
       s4o.print(")\n");
       if (this->current_var_init_symbol != NULL) {
-    	s4o.print(s4o.indent_spaces);
-    	s4o.print(INIT_LOCATED_VALUE);
-    	s4o.print("(");
-    	print_variable_prefix();
-    	if (symbol->variable_name != NULL)
+        s4o.print(s4o.indent_spaces);
+        s4o.print(INIT_LOCATED_VALUE);
+        s4o.print("(");
+        print_variable_prefix();
+        if (symbol->variable_name != NULL)
           symbol->variable_name->accept(*this);
         else
           symbol->location->accept(*this);
-    	s4o.print(",");
+        s4o.print(",");
         this->current_var_init_symbol->accept(*this);
         s4o.print(")");
       }
@@ -1848,13 +1848,17 @@
    */
   this->current_var_type_symbol = symbol->specification;
   this->current_var_init_symbol = NULL;
+  bool is_fb = type_is_fb(this->current_var_type_symbol);
 
   /* now to produce the c equivalent... */
   switch (wanted_varformat) {
     case local_vf:
     case localinit_vf:
       s4o.print(s4o.indent_spaces);
-      s4o.print(DECLARE_EXTERNAL);
+      if (is_fb)
+        s4o.print(DECLARE_EXTERNAL_FB);
+      else
+        s4o.print(DECLARE_EXTERNAL);
       s4o.print("(");
       this->current_var_type_symbol->accept(*this);
       s4o.print(",");
@@ -1864,7 +1868,10 @@
 
     case constructorinit_vf:
       s4o.print(nv->get());
-      s4o.print(INIT_EXTERNAL);
+      if (is_fb)
+        s4o.print(INIT_EXTERNAL_FB);
+      else
+        s4o.print(INIT_EXTERNAL);
       s4o.print("(");
       this->current_var_type_symbol->accept(*this);
       s4o.print(",");
@@ -1993,50 +2000,50 @@
 
     case constructorinit_vf:
       if (symbol->global_var_name != NULL) {
-    	s4o.print(nv->get());
-    	s4o.print(INIT_GLOBAL_LOCATED);
-    	s4o.print("(");
-    	if (this->resource_name != NULL) {
-    	  this->resource_name->accept(*this);
-    	}
+        s4o.print(nv->get());
+        s4o.print(INIT_GLOBAL_LOCATED);
+        s4o.print("(");
+        if (this->resource_name != NULL) {
+          this->resource_name->accept(*this);
+        }
         s4o.print(",");
         symbol->global_var_name->accept(*this);
-      	s4o.print(",");
-      	symbol->location->accept(*this);
+        s4o.print(",");
+        symbol->location->accept(*this);
         print_retain();
-      	s4o.print(")");
+        s4o.print(")");
       }
       if (this->current_var_init_symbol != NULL) {
-	    s4o.print(nv->get());
-	    s4o.print(INIT_GLOBAL);
-	    s4o.print("(");
-	    this->current_var_type_symbol->accept(*this);
-	    s4o.print(",");
-	    if (symbol->global_var_name != NULL)
-		  symbol->global_var_name->accept(*this);
-	    else
-		  symbol->location->accept(*this);
-	    s4o.print(",");
-	    s4o.print(INITIAL_VALUE);
-	    s4o.print("(");
-	    this->current_var_init_symbol->accept(*this);
-	    s4o.print(")");
-	    print_retain();
-	    s4o.print(")");
+        s4o.print(nv->get());
+        s4o.print(INIT_GLOBAL);
+        s4o.print("(");
+        this->current_var_type_symbol->accept(*this);
+        s4o.print(",");
+        if (symbol->global_var_name != NULL)
+          symbol->global_var_name->accept(*this);
+        else
+	      symbol->location->accept(*this);
+        s4o.print(",");
+        s4o.print(INITIAL_VALUE);
+        s4o.print("(");
+        this->current_var_init_symbol->accept(*this);
+        s4o.print(")");
+        print_retain();
+        s4o.print(")");
       }
       break;
     
     case globalprototype_vf:
       s4o.print(s4o.indent_spaces);
       s4o.print(DECLARE_GLOBAL_PROTOTYPE);
-	  s4o.print("(");
-	  this->current_var_type_symbol->accept(*this);
-	  s4o.print(",");
-	  if (symbol->global_var_name != NULL)
-		symbol->global_var_name->accept(*this);
-	  else
-		symbol->location->accept(*this);
-	  s4o.print(")\n");
+      s4o.print("(");
+      this->current_var_type_symbol->accept(*this);
+      s4o.print(",");
+      if (symbol->global_var_name != NULL)
+        symbol->global_var_name->accept(*this);
+      else
+        symbol->location->accept(*this);
+      s4o.print(")\n");
       break;
     
     default:
@@ -2061,6 +2068,7 @@
 void *visit(global_var_list_c *symbol) {
   TRACE("global_var_list_c");
   list_c *list = dynamic_cast<list_c *>(symbol);
+  bool is_fb = type_is_fb(this->current_var_type_symbol);
   /* should NEVER EVER occur!! */
   if (list == NULL) ERROR;
 
@@ -2069,9 +2077,12 @@
     case local_vf:
     case localinit_vf:
       for(int i = 0; i < list->n; i++) {
-    	s4o.print(s4o.indent_spaces);
-    	s4o.print(DECLARE_GLOBAL);
-    	s4o.print("(");
+        s4o.print(s4o.indent_spaces);
+        if (is_fb)
+          s4o.print(DECLARE_GLOBAL_FB);
+        else
+          s4o.print(DECLARE_GLOBAL);
+        s4o.print("(");
         this->current_var_type_symbol->accept(*this);
         s4o.print(",");
         if(this->resource_name != NULL)
@@ -2083,27 +2094,32 @@
       break;
 
     case constructorinit_vf:
-      if (this->current_var_init_symbol != NULL) {
+      if (this->current_var_init_symbol != NULL || is_fb) {
         for(int i = 0; i < list->n; i++) {
           s4o.print(nv->get());
 
-          s4o.print(INIT_GLOBAL);
+          if (is_fb)
+            s4o.print(INIT_GLOBAL_FB);
+          else
+            s4o.print(INIT_GLOBAL);
           s4o.print("(");
           this->current_var_type_symbol->accept(*this);
           s4o.print(",");
           list->elements[i]->accept(*this);
-          s4o.print(",");
-          s4o.print(INITIAL_VALUE);
-          s4o.print("(");
-          this->current_var_init_symbol->accept(*this);
-          s4o.print(")");
+          if (this->current_var_init_symbol != NULL) {
+            s4o.print(",");
+            s4o.print(INITIAL_VALUE);
+            s4o.print("(");
+            this->current_var_init_symbol->accept(*this);
+            s4o.print(")");
+          }
           print_retain();
           s4o.print(")");
 #if 0
- 	  /* The following code would be for globalinit_vf !!
-	   * But it is not currently required...
-	   */
-	  s4o.print(s4o.indent_spaces + "__ext_element_c<");
+      /* The following code would be for globalinit_vf !!
+       * But it is not currently required...
+       */
+      s4o.print(s4o.indent_spaces + "__ext_element_c<");
           this->current_var_type_symbol->accept(*this);
           s4o.print("> ");
           if (this->globalnamespace != NULL) {
@@ -2119,7 +2135,7 @@
             s4o.print(">(");
             this->current_var_init_symbol->accept(*this);
             s4o.print(")");
-	  }
+      }
           s4o.print(";\n");
 #endif
         }
@@ -2526,19 +2542,19 @@
       case function_param_iterator_c::direction_extref:
 #if 0
         if (param_value == NULL)
-	  /* This is illegal in ST and IL languages.
-	   * All variables declared in a VAR_EXTERNAL __must__
-	   * be initialised to reference a specific VAR_GLOBAL variable!!
-	   *
-	   * The semantic checker should have caught this, we check again just the
-	   * same (especially since the semantic checker has not yet been written!).
-	   */
-	  ERROR;
+      /* This is illegal in ST and IL languages.
+       * All variables declared in a VAR_EXTERNAL __must__
+       * be initialised to reference a specific VAR_GLOBAL variable!!
+       *
+       * The semantic checker should have caught this, we check again just the
+       * same (especially since the semantic checker has not yet been written!).
+       */
+      ERROR;
         s4o.print(nv->get());
         s4o.print("&");
         param_value->accept(*this);
 #endif
-	break;
+    break;
     } /* switch */
   } /* for(...) */
 
--- a/stage4/generate_c/generate_var_list.cc	Thu Nov 08 18:55:57 2012 +0100
+++ b/stage4/generate_c/generate_var_list.cc	Thu Nov 15 22:28:53 2012 +0100
@@ -132,14 +132,14 @@
       var_type_symbol->accept(*this);
 
       if (this->current_var_type_symbol == NULL)
-    	this->current_var_type_symbol = var_type_symbol;
+        this->current_var_type_symbol = var_type_symbol;
 
       return (this->current_var_type_symbol);
     }
 
     symbol_c *get_current_type_name(void) {
       if (this->current_var_type_name == NULL)
-    	return (this->current_var_type_symbol);
+        return (this->current_var_type_symbol);
 
       return (this->current_var_type_name);
     }
@@ -188,8 +188,7 @@
 class generate_var_list_c: protected generate_c_typedecl_c {
   
   public:
-    typedef struct
-    {
+    typedef struct {
       symbol_c *symbol;
     } SYMBOL;
 
@@ -329,12 +328,14 @@
         case search_type_symbol_c::function_block_vtc:
           this->current_var_type_name->accept(*this);
           s4o.print(";\n");
-          SYMBOL *current_name;
-          current_name = new SYMBOL;
-          current_name->symbol = symbol;
-          current_symbol_list.push_back(*current_name);
-          this->current_var_type_symbol->accept(*this);
-          current_symbol_list.pop_back();
+          if (this->current_var_class_category != external_vcc) {
+              SYMBOL *current_name;
+              current_name = new SYMBOL;
+              current_name->symbol = symbol;
+              current_symbol_list.push_back(*current_name);
+              this->current_var_type_symbol->accept(*this);
+              current_symbol_list.pop_back();
+          }
           break;
         case search_type_symbol_c::array_vtc:
           this->current_var_type_name->accept(*this);
@@ -372,7 +373,7 @@
       s4o.print(str);
     }
     
-    void print_symbol_list(void) {
+    void print_symbol_list() {
       std::list<SYMBOL>::iterator pt;
       for(pt = current_symbol_list.begin(); pt != current_symbol_list.end(); pt++) {
         pt->symbol->accept(*this);
@@ -648,20 +649,20 @@
     // SYM_REF2(global_var_spec_c, global_var_name, location)
     void *visit(global_var_spec_c *symbol) {
       search_location_type_c search_location_type;
-	  switch (search_location_type.get_location_type(symbol->location)) {
-		case search_location_type_c::input_lt:
-		  this->current_var_class_category = located_input_vcc;
-		  break;
-		case search_location_type_c::memory_lt:
-		  this->current_var_class_category = located_memory_vcc;
-		  break;
-		case search_location_type_c::output_lt:
-		  this->current_var_class_category = located_output_vcc;
-		  break;
-		default:
-		  ERROR;
-	      break;
-	  }
+      switch (search_location_type.get_location_type(symbol->location)) {
+        case search_location_type_c::input_lt:
+          this->current_var_class_category = located_input_vcc;
+          break;
+        case search_location_type_c::memory_lt:
+          this->current_var_class_category = located_memory_vcc;
+          break;
+        case search_location_type_c::output_lt:
+          this->current_var_class_category = located_output_vcc;
+          break;
+        default:
+          ERROR;
+          break;
+      }
 
       if (symbol->global_var_name != NULL)
         declare_variable(symbol->global_var_name);