/* do not edit automatically generated by mc from decl.  */
/* decl.mod declaration nodes used to create the AST.

Copyright (C) 2015-2025 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius@glam.ac.uk>.

This file is part of GNU Modula-2.

GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Modula-2; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include <stdbool.h>
#   if !defined (PROC_D)
#      define PROC_D
       typedef void (*PROC_t) (void);
       typedef struct { PROC_t proc; } PROC;
#   endif

#   if !defined (TRUE)
#      define TRUE (1==1)
#   endif

#   if !defined (FALSE)
#      define FALSE (1==0)
#   endif

#   include "GStorage.h"
#   include "Gmcrts.h"
#if defined(__cplusplus)
#   undef NULL
#   define NULL 0
#endif
#define _decl_C

#include "Gdecl.h"
#   include "GASCII.h"
#   include "GsymbolKey.h"
#   include "GmcDebug.h"
#   include "GStorage.h"
#   include "GnameKey.h"
#   include "GSFIO.h"
#   include "GFIO.h"
#   include "GDynamicStrings.h"
#   include "GStringConvert.h"
#   include "GmcOptions.h"
#   include "GFormatStrings.h"
#   include "Glibc.h"
#   include "GmcMetaError.h"
#   include "GmcError.h"
#   include "GmcLexBuf.h"
#   include "GmcComment.h"
#   include "GStrLib.h"
#   include "GmcPretty.h"
#   include "GIndexing.h"
#   include "Galists.h"
#   include "Gwlists.h"
#   include "Gkeyc.h"
#   include "GmcStream.h"
#   include "GM2RTS.h"

typedef struct decl_isNodeF_p decl_isNodeF;

#   define indentation 3
#   define indentationC 2
#   define debugScopes false
#   define debugDecl false
#   define caseException true
#   define returnException true
#   define forceCompoundStatement true
#   define enableDefForCStrings false
#   define enableMemsetOnAllocation true
#   define forceQualified true
#   define debugOpaque false
typedef struct decl_nodeRec_r decl_nodeRec;

typedef struct decl_opaqueCastState_r decl_opaqueCastState;

typedef struct decl_opaquecastT_r decl_opaquecastT;

typedef struct decl_intrinsicT_r decl_intrinsicT;

typedef struct decl_fixupInfo_r decl_fixupInfo;

typedef struct decl_explistT_r decl_explistT;

typedef struct decl_setvalueT_r decl_setvalueT;

typedef struct decl_identlistT_r decl_identlistT;

typedef struct decl_funccallT_r decl_funccallT;

typedef struct decl_commentT_r decl_commentT;

typedef struct decl_stmtT_r decl_stmtT;

typedef struct decl_returnT_r decl_returnT;

typedef struct decl_exitT_r decl_exitT;

typedef struct decl_vardeclT_r decl_vardeclT;

typedef struct decl_typeT_r decl_typeT;

typedef struct decl_recordT_r decl_recordT;

typedef struct decl_varientT_r decl_varientT;

typedef struct decl_varT_r decl_varT;

typedef struct decl_enumerationT_r decl_enumerationT;

typedef struct decl_subrangeT_r decl_subrangeT;

typedef struct decl_subscriptT_r decl_subscriptT;

typedef struct decl_arrayT_r decl_arrayT;

typedef struct decl_stringT_r decl_stringT;

typedef struct decl_literalT_r decl_literalT;

typedef struct decl_constT_r decl_constT;

typedef struct decl_varparamT_r decl_varparamT;

typedef struct decl_paramT_r decl_paramT;

typedef struct decl_varargsT_r decl_varargsT;

typedef struct decl_optargT_r decl_optargT;

typedef struct decl_pointerT_r decl_pointerT;

typedef struct decl_recordfieldT_r decl_recordfieldT;

typedef struct decl_varientfieldT_r decl_varientfieldT;

typedef struct decl_enumerationfieldT_r decl_enumerationfieldT;

typedef struct decl_setT_r decl_setT;

typedef struct decl_componentrefT_r decl_componentrefT;

typedef struct decl_pointerrefT_r decl_pointerrefT;

typedef struct decl_arrayrefT_r decl_arrayrefT;

typedef struct decl_commentPair_r decl_commentPair;

typedef struct decl_assignmentT_r decl_assignmentT;

typedef struct decl_ifT_r decl_ifT;

typedef struct decl_elsifT_r decl_elsifT;

typedef struct decl_loopT_r decl_loopT;

typedef struct decl_whileT_r decl_whileT;

typedef struct decl_repeatT_r decl_repeatT;

typedef struct decl_caseT_r decl_caseT;

typedef struct decl_caselabellistT_r decl_caselabellistT;

typedef struct decl_caselistT_r decl_caselistT;

typedef struct decl_rangeT_r decl_rangeT;

typedef struct decl_forT_r decl_forT;

typedef struct decl_statementT_r decl_statementT;

typedef struct decl_scopeT_r decl_scopeT;

typedef struct decl_procedureT_r decl_procedureT;

typedef struct decl_proctypeT_r decl_proctypeT;

typedef struct decl_binaryT_r decl_binaryT;

typedef struct decl_unaryT_r decl_unaryT;

typedef struct decl_moduleT_r decl_moduleT;

typedef struct decl_defT_r decl_defT;

typedef struct decl_impT_r decl_impT;

typedef struct decl_where_r decl_where;

typedef struct decl_nodeProcedure_p decl_nodeProcedure;

typedef struct decl_cnameT_r decl_cnameT;

typedef struct decl__T1_r decl__T1;

typedef decl__T1 *decl_group;

typedef enum {decl_explist, decl_funccall, decl_exit, decl_return, decl_stmtseq, decl_comment, decl_halt, decl_new, decl_dispose, decl_inc, decl_dec, decl_incl, decl_excl, decl_length, decl_nil, decl_true, decl_false, decl_address, decl_loc, decl_byte, decl_word, decl_csizet, decl_cssizet, decl_cofft, decl_cardinal64, decl_char, decl_cardinal, decl_longcard, decl_shortcard, decl_integer, decl_longint, decl_shortint, decl_real, decl_longreal, decl_shortreal, decl_bitset, decl_boolean, decl_proc, decl_ztype, decl_rtype, decl_complex, decl_longcomplex, decl_shortcomplex, decl_type, decl_record, decl_varient, decl_var, decl_enumeration, decl_subrange, decl_array, decl_subscript, decl_string, decl_const, decl_literal, decl_varparam, decl_param, decl_varargs, decl_optarg, decl_pointer, decl_recordfield, decl_varientfield, decl_enumerationfield, decl_set, decl_proctype, decl_procedure, decl_def, decl_imp, decl_module, decl_loop, decl_while, decl_for, decl_repeat, decl_case, decl_caselabellist, decl_caselist, decl_range, decl_assignment, decl_if, decl_elsif, decl_constexp, decl_neg, decl_cast, decl_val, decl_plus, decl_sub, decl_div, decl_mod, decl_mult, decl_divide, decl_in, decl_adr, decl_size, decl_tsize, decl_ord, decl_float, decl_trunc, decl_chr, decl_abs, decl_cap, decl_high, decl_throw, decl_unreachable, decl_cmplx, decl_re, decl_im, decl_min, decl_max, decl_componentref, decl_pointerref, decl_arrayref, decl_deref, decl_equal, decl_notequal, decl_less, decl_greater, decl_greequal, decl_lessequal, decl_lsl, decl_lsr, decl_lor, decl_land, decl_lnot, decl_lxor, decl_and, decl_or, decl_not, decl_identlist, decl_vardecl, decl_setvalue, decl_opaquecast} decl_nodeT;

typedef enum {decl_ansiC, decl_ansiCP, decl_pim4} decl_language;

typedef enum {decl_completed, decl_blocked, decl_partial, decl_recursive} decl_dependentState;

typedef enum {decl_text, decl_punct, decl_space} decl_outputStates;

typedef decl_nodeRec *decl_node__opaque;

struct decl_opaqueCastState_r {
                                bool opaque;
                                bool voidStar;
                              };

struct decl_fixupInfo_r {
                          unsigned int count;
                          Indexing_Index info;
                        };

struct decl_explistT_r {
                         Indexing_Index exp;
                       };

struct decl_setvalueT_r {
                          decl_node__opaque type;
                          Indexing_Index values;
                        };

struct decl_identlistT_r {
                           wlists_wlist names;
                           bool cnamed;
                         };

struct decl_commentT_r {
                         mcComment_commentDesc content;
                       };

struct decl_stmtT_r {
                      Indexing_Index statements;
                    };

struct decl_exitT_r {
                      decl_node__opaque loop;
                    };

struct decl_vardeclT_r {
                         wlists_wlist names;
                         decl_node__opaque type;
                         decl_node__opaque scope;
                       };

struct decl_typeT_r {
                      nameKey_Name name;
                      decl_node__opaque type;
                      decl_node__opaque scope;
                      bool isOpaque;
                      bool isHidden;
                      bool isInternal;
                    };

struct decl_recordT_r {
                        symbolKey_symbolTree localSymbols;
                        Indexing_Index listOfSons;
                        decl_node__opaque scope;
                      };

struct decl_varientT_r {
                         Indexing_Index listOfSons;
                         decl_node__opaque varient;
                         decl_node__opaque tag;
                         decl_node__opaque scope;
                       };

struct decl_enumerationT_r {
                             unsigned int noOfElements;
                             symbolKey_symbolTree localSymbols;
                             Indexing_Index listOfSons;
                             decl_node__opaque low;
                             decl_node__opaque high;
                             decl_node__opaque scope;
                           };

struct decl_subrangeT_r {
                          decl_node__opaque low;
                          decl_node__opaque high;
                          decl_node__opaque type;
                          decl_node__opaque scope;
                        };

struct decl_subscriptT_r {
                           decl_node__opaque type;
                           decl_node__opaque expr;
                         };

struct decl_stringT_r {
                        nameKey_Name name;
                        unsigned int length;
                        bool isCharCompatible;
                        DynamicStrings_String cstring;
                        unsigned int clength;
                        DynamicStrings_String cchar;
                      };

struct decl_literalT_r {
                         nameKey_Name name;
                         decl_node__opaque type;
                       };

struct decl_constT_r {
                       nameKey_Name name;
                       decl_node__opaque type;
                       decl_node__opaque value;
                       decl_node__opaque scope;
                     };

struct decl_varargsT_r {
                         decl_node__opaque scope;
                       };

struct decl_optargT_r {
                        decl_node__opaque namelist;
                        decl_node__opaque type;
                        decl_node__opaque scope;
                        decl_node__opaque init;
                      };

struct decl_varientfieldT_r {
                              nameKey_Name name;
                              decl_node__opaque parent;
                              decl_node__opaque varient;
                              bool simple;
                              Indexing_Index listOfSons;
                              decl_node__opaque scope;
                            };

struct decl_setT_r {
                     decl_node__opaque type;
                     decl_node__opaque scope;
                   };

struct decl_commentPair_r {
                            decl_node__opaque after;
                            decl_node__opaque body;
                          };

struct decl_loopT_r {
                      decl_node__opaque statements;
                      unsigned int labelno;
                    };

struct decl_caseT_r {
                      decl_node__opaque expression;
                      Indexing_Index caseLabelList;
                      decl_node__opaque else_;
                    };

struct decl_caselabellistT_r {
                               decl_node__opaque caseList;
                               decl_node__opaque statements;
                             };

struct decl_caselistT_r {
                          Indexing_Index rangePairs;
                        };

struct decl_rangeT_r {
                       decl_node__opaque lo;
                       decl_node__opaque hi;
                     };

struct decl_forT_r {
                     decl_node__opaque des;
                     decl_node__opaque start;
                     decl_node__opaque end;
                     decl_node__opaque increment;
                     decl_node__opaque statements;
                   };

struct decl_statementT_r {
                           Indexing_Index sequence;
                         };

struct decl_scopeT_r {
                       symbolKey_symbolTree symbols;
                       Indexing_Index constants;
                       Indexing_Index types;
                       Indexing_Index procedures;
                       Indexing_Index variables;
                     };

struct decl_binaryT_r {
                        decl_node__opaque left;
                        decl_node__opaque right;
                        decl_node__opaque resultType;
                      };

struct decl_unaryT_r {
                       decl_node__opaque arg;
                       decl_node__opaque resultType;
                     };

struct decl_where_r {
                      unsigned int defDeclared;
                      unsigned int modDeclared;
                      unsigned int firstUsed;
                    };

typedef void (*decl_nodeProcedure_t) (decl_node);
struct decl_nodeProcedure_p { decl_nodeProcedure_t proc; };

struct decl_cnameT_r {
                       nameKey_Name name;
                       bool init;
                     };

struct decl__T1_r {
                    alists_alist todoQ;
                    alists_alist partialQ;
                    alists_alist doneQ;
                    decl_group next;
                  };

struct decl_opaquecastT_r {
                            decl_node__opaque exp;
                            decl_opaqueCastState opaqueState;
                          };

struct decl_intrinsicT_r {
                           decl_node__opaque args;
                           unsigned int noArgs;
                           decl_node__opaque type;
                           decl_commentPair intrinsicComment;
                           bool postUnreachable;
                         };

struct decl_funccallT_r {
                          decl_node__opaque function;
                          decl_node__opaque args;
                          decl_node__opaque type;
                          decl_commentPair funccallComment;
                          decl_opaqueCastState opaqueState;
                        };

struct decl_returnT_r {
                        decl_node__opaque exp;
                        decl_node__opaque scope;
                        decl_commentPair returnComment;
                      };

struct decl_varT_r {
                     nameKey_Name name;
                     decl_node__opaque type;
                     decl_node__opaque decl;
                     decl_node__opaque scope;
                     bool isInitialised;
                     bool isParameter;
                     bool isVarParameter;
                     bool isUsed;
                     decl_cnameT cname;
                     decl_opaqueCastState opaqueState;
                   };

struct decl_arrayT_r {
                       decl_node__opaque subr;
                       decl_node__opaque type;
                       decl_node__opaque scope;
                       bool isUnbounded;
                       decl_opaqueCastState opaqueState;
                     };

struct decl_varparamT_r {
                          decl_node__opaque namelist;
                          decl_node__opaque type;
                          decl_node__opaque scope;
                          bool isUnbounded;
                          bool isForC;
                          bool isUsed;
                          decl_opaqueCastState opaqueState;
                        };

struct decl_paramT_r {
                       decl_node__opaque namelist;
                       decl_node__opaque type;
                       decl_node__opaque scope;
                       bool isUnbounded;
                       bool isForC;
                       bool isUsed;
                       decl_opaqueCastState opaqueState;
                     };

struct decl_pointerT_r {
                         decl_node__opaque type;
                         decl_node__opaque scope;
                         decl_opaqueCastState opaqueState;
                       };

struct decl_recordfieldT_r {
                             nameKey_Name name;
                             decl_node__opaque type;
                             bool tag;
                             decl_node__opaque parent;
                             decl_node__opaque varient;
                             decl_node__opaque scope;
                             decl_cnameT cname;
                             decl_opaqueCastState opaqueState;
                           };

struct decl_enumerationfieldT_r {
                                  nameKey_Name name;
                                  decl_node__opaque type;
                                  decl_node__opaque scope;
                                  unsigned int value;
                                  decl_cnameT cname;
                                };

struct decl_componentrefT_r {
                              decl_node__opaque rec;
                              decl_node__opaque field;
                              decl_node__opaque resultType;
                              decl_opaqueCastState opaqueState;
                            };

struct decl_pointerrefT_r {
                            decl_node__opaque ptr;
                            decl_node__opaque field;
                            decl_node__opaque resultType;
                            decl_opaqueCastState opaqueState;
                          };

struct decl_arrayrefT_r {
                          decl_node__opaque array;
                          decl_node__opaque index;
                          decl_node__opaque resultType;
                          decl_opaqueCastState opaqueState;
                        };

struct decl_assignmentT_r {
                            decl_node__opaque des;
                            decl_node__opaque expr;
                            decl_commentPair assignComment;
                          };

struct decl_ifT_r {
                    decl_node__opaque expr;
                    decl_node__opaque elsif;
                    decl_node__opaque then;
                    decl_node__opaque else_;
                    decl_commentPair ifComment;
                    decl_commentPair elseComment;
                    decl_commentPair endComment;
                  };

struct decl_elsifT_r {
                       decl_node__opaque expr;
                       decl_node__opaque elsif;
                       decl_node__opaque then;
                       decl_node__opaque else_;
                       decl_commentPair elseComment;
                     };

struct decl_whileT_r {
                       decl_node__opaque expr;
                       decl_node__opaque statements;
                       decl_commentPair doComment;
                       decl_commentPair endComment;
                     };

struct decl_repeatT_r {
                        decl_node__opaque expr;
                        decl_node__opaque statements;
                        decl_commentPair repeatComment;
                        decl_commentPair untilComment;
                      };

struct decl_procedureT_r {
                           nameKey_Name name;
                           decl_scopeT decls;
                           decl_node__opaque scope;
                           Indexing_Index parameters;
                           bool isForC;
                           bool built;
                           bool checking;
                           bool returnopt;
                           bool vararg;
                           bool noreturnused;
                           bool noreturn;
                           unsigned int paramcount;
                           decl_node__opaque optarg_;
                           decl_node__opaque returnType;
                           decl_node__opaque beginStatements;
                           decl_cnameT cname;
                           mcComment_commentDesc defComment;
                           mcComment_commentDesc modComment;
                           decl_opaqueCastState opaqueState;
                         };

struct decl_proctypeT_r {
                          Indexing_Index parameters;
                          bool returnopt;
                          bool vararg;
                          decl_node__opaque optarg_;
                          decl_node__opaque scope;
                          decl_node__opaque returnType;
                          decl_opaqueCastState opaqueState;
                        };

struct decl_moduleT_r {
                        nameKey_Name name;
                        nameKey_Name source;
                        Indexing_Index importedModules;
                        decl_fixupInfo constFixup;
                        decl_fixupInfo enumFixup;
                        decl_scopeT decls;
                        decl_node__opaque beginStatements;
                        decl_node__opaque finallyStatements;
                        bool enumsComplete;
                        bool constsComplete;
                        bool visited;
                        decl_commentPair com;
                      };

struct decl_defT_r {
                     nameKey_Name name;
                     nameKey_Name source;
                     bool unqualified;
                     bool hasHidden;
                     bool forC;
                     Indexing_Index exported;
                     Indexing_Index importedModules;
                     decl_fixupInfo constFixup;
                     decl_fixupInfo enumFixup;
                     decl_scopeT decls;
                     bool enumsComplete;
                     bool constsComplete;
                     bool visited;
                     decl_commentPair com;
                   };

struct decl_impT_r {
                     nameKey_Name name;
                     nameKey_Name source;
                     Indexing_Index importedModules;
                     decl_fixupInfo constFixup;
                     decl_fixupInfo enumFixup;
                     decl_node__opaque beginStatements;
                     decl_node__opaque finallyStatements;
                     decl_node__opaque definitionModule;
                     decl_scopeT decls;
                     bool enumsComplete;
                     bool constsComplete;
                     bool visited;
                     decl_commentPair com;
                   };

struct decl_nodeRec_r {
                        decl_nodeT kind;  /* case tag */
                        union {
                                decl_intrinsicT intrinsicF;
                                decl_explistT explistF;
                                decl_exitT exitF;
                                decl_returnT returnF;
                                decl_stmtT stmtF;
                                decl_commentT commentF;
                                decl_typeT typeF;
                                decl_recordT recordF;
                                decl_varientT varientF;
                                decl_varT varF;
                                decl_enumerationT enumerationF;
                                decl_subrangeT subrangeF;
                                decl_subscriptT subscriptF;
                                decl_arrayT arrayF;
                                decl_stringT stringF;
                                decl_constT constF;
                                decl_literalT literalF;
                                decl_varparamT varparamF;
                                decl_paramT paramF;
                                decl_varargsT varargsF;
                                decl_optargT optargF;
                                decl_pointerT pointerF;
                                decl_recordfieldT recordfieldF;
                                decl_varientfieldT varientfieldF;
                                decl_enumerationfieldT enumerationfieldF;
                                decl_setT setF;
                                decl_proctypeT proctypeF;
                                decl_procedureT procedureF;
                                decl_defT defF;
                                decl_impT impF;
                                decl_moduleT moduleF;
                                decl_loopT loopF;
                                decl_whileT whileF;
                                decl_forT forF;
                                decl_repeatT repeatF;
                                decl_caseT caseF;
                                decl_caselabellistT caselabellistF;
                                decl_caselistT caselistF;
                                decl_rangeT rangeF;
                                decl_ifT ifF;
                                decl_elsifT elsifF;
                                decl_assignmentT assignmentF;
                                decl_arrayrefT arrayrefF;
                                decl_pointerrefT pointerrefF;
                                decl_componentrefT componentrefF;
                                decl_binaryT binaryF;
                                decl_unaryT unaryF;
                                decl_identlistT identlistF;
                                decl_vardeclT vardeclF;
                                decl_funccallT funccallF;
                                decl_setvalueT setvalueF;
                                decl_opaquecastT opaquecastF;
                              };
                        decl_where at;
                      };

static decl_group freeGroup;
static decl_group globalGroup;
static FIO_File outputFile;
static decl_language lang;
static decl_node__opaque charStarN;
static decl_node__opaque constCharStarN;
static decl_node__opaque bitsperunitN;
static decl_node__opaque bitsperwordN;
static decl_node__opaque bitspercharN;
static decl_node__opaque unitsperwordN;
static decl_node__opaque mainModule;
static decl_node__opaque currentModule;
static decl_node__opaque defModule;
static decl_node__opaque systemN;
static decl_node__opaque addressN;
static decl_node__opaque locN;
static decl_node__opaque byteN;
static decl_node__opaque wordN;
static decl_node__opaque csizetN;
static decl_node__opaque cssizetN;
static decl_node__opaque cofftN;
static decl_node__opaque cardinal64N;
static decl_node__opaque adrN;
static decl_node__opaque sizeN;
static decl_node__opaque tsizeN;
static decl_node__opaque newN;
static decl_node__opaque disposeN;
static decl_node__opaque lengthN;
static decl_node__opaque incN;
static decl_node__opaque decN;
static decl_node__opaque inclN;
static decl_node__opaque exclN;
static decl_node__opaque highN;
static decl_node__opaque m2rtsN;
static decl_node__opaque haltN;
static decl_node__opaque throwN;
static decl_node__opaque chrN;
static decl_node__opaque capN;
static decl_node__opaque absN;
static decl_node__opaque floatN;
static decl_node__opaque truncN;
static decl_node__opaque ordN;
static decl_node__opaque valN;
static decl_node__opaque minN;
static decl_node__opaque maxN;
static decl_node__opaque booleanN;
static decl_node__opaque procN;
static decl_node__opaque charN;
static decl_node__opaque integerN;
static decl_node__opaque cardinalN;
static decl_node__opaque longcardN;
static decl_node__opaque shortcardN;
static decl_node__opaque longintN;
static decl_node__opaque shortintN;
static decl_node__opaque bitsetN;
static decl_node__opaque bitnumN;
static decl_node__opaque ztypeN;
static decl_node__opaque rtypeN;
static decl_node__opaque complexN;
static decl_node__opaque longcomplexN;
static decl_node__opaque shortcomplexN;
static decl_node__opaque cmplxN;
static decl_node__opaque reN;
static decl_node__opaque imN;
static decl_node__opaque realN;
static decl_node__opaque longrealN;
static decl_node__opaque shortrealN;
static decl_node__opaque nilN;
static decl_node__opaque trueN;
static decl_node__opaque falseN;
static Indexing_Index scopeStack;
static Indexing_Index defUniverseI;
static Indexing_Index modUniverseI;
static symbolKey_symbolTree modUniverse;
static symbolKey_symbolTree defUniverse;
static symbolKey_symbolTree baseSymbols;
static decl_outputStates outputState;
static mcPretty_pretty doP;
static bool mustVisitScope;
static bool simplified;
static unsigned int tempCount;
static decl_node__opaque globalNode;

/*
   getDeclaredMod - returns the token number associated with the nodes declaration
                    in the implementation or program module.
*/

extern "C" unsigned int decl_getDeclaredMod (decl_node n);

/*
   getDeclaredDef - returns the token number associated with the nodes declaration
                    in the definition module.
*/

extern "C" unsigned int decl_getDeclaredDef (decl_node n);

/*
   getFirstUsed - returns the token number associated with the first use of
                  node, n.
*/

extern "C" unsigned int decl_getFirstUsed (decl_node n);

/*
   isDef - return TRUE if node, n, is a definition module.
*/

extern "C" bool decl_isDef (decl_node n);

/*
   isImp - return TRUE if node, n, is an implementation module.
*/

extern "C" bool decl_isImp (decl_node n);

/*
   isImpOrModule - returns TRUE if, n, is a program module or implementation module.
*/

extern "C" bool decl_isImpOrModule (decl_node n);

/*
   isVisited - returns TRUE if the node was visited.
*/

extern "C" bool decl_isVisited (decl_node n);

/*
   unsetVisited - unset the visited flag on a def/imp/module node.
*/

extern "C" void decl_unsetVisited (decl_node n);

/*
   setVisited - set the visited flag on a def/imp/module node.
*/

extern "C" void decl_setVisited (decl_node n);

/*
   setEnumsComplete - sets the field inside the def or imp or module, n.
*/

extern "C" void decl_setEnumsComplete (decl_node n);

/*
   getEnumsComplete - gets the field from the def or imp or module, n.
*/

extern "C" bool decl_getEnumsComplete (decl_node n);

/*
   resetEnumPos - resets the index into the saved list of enums inside
                  module, n.
*/

extern "C" void decl_resetEnumPos (decl_node n);

/*
   getNextEnum - returns the next enumeration node.
*/

extern "C" decl_node decl_getNextEnum (void);

/*
   isModule - return TRUE if node, n, is a program module.
*/

extern "C" bool decl_isModule (decl_node n);

/*
   isMainModule - return TRUE if node, n, is the main module specified
                  by the source file.  This might be a definition,
                  implementation or program module.
*/

extern "C" bool decl_isMainModule (decl_node n);

/*
   setMainModule - sets node, n, as the main module to be compiled.
*/

extern "C" void decl_setMainModule (decl_node n);

/*
   setCurrentModule - sets node, n, as the current module being compiled.
*/

extern "C" void decl_setCurrentModule (decl_node n);

/*
   lookupDef - returns a definition module node named, n.
*/

extern "C" decl_node decl_lookupDef (nameKey_Name n);

/*
   lookupImp - returns an implementation module node named, n.
*/

extern "C" decl_node decl_lookupImp (nameKey_Name n);

/*
   lookupModule - returns a module node named, n.
*/

extern "C" decl_node decl_lookupModule (nameKey_Name n);

/*
   putDefForC - the definition module was defined FOR "C".
*/

extern "C" void decl_putDefForC (decl_node n);

/*
   putDefUnqualified - the definition module uses unqualified.
*/

extern "C" void decl_putDefUnqualified (decl_node n);

/*
   isDefUnqualified - returns TRUE if the definition module uses unqualified.
*/

extern "C" bool decl_isDefUnqualified (decl_node n);

/*
   lookupInScope - looks up a symbol named, n, from, scope.
*/

extern "C" decl_node decl_lookupInScope (decl_node scope, nameKey_Name n);

/*
   isConst - returns TRUE if node, n, is a const.
*/

extern "C" bool decl_isConst (decl_node n);

/*
   isType - returns TRUE if node, n, is a type.
*/

extern "C" bool decl_isType (decl_node n);

/*
   putType - places, exp, as the type alias to des.
             TYPE des = exp ;
*/

extern "C" void decl_putType (decl_node des, decl_node exp);

/*
   getType - returns the type associated with node, n.
*/

extern "C" decl_node decl_getType (decl_node n);

/*
   skipType - skips over type aliases.
*/

extern "C" decl_node decl_skipType (decl_node n);

/*
   putTypeHidden - marks type, des, as being a hidden type.
                   TYPE des ;
*/

extern "C" void decl_putTypeHidden (decl_node des);

/*
   isTypeHidden - returns TRUE if type, n, is hidden.
*/

extern "C" bool decl_isTypeHidden (decl_node n);

/*
   hasHidden - returns TRUE if module, n, has a hidden type.
*/

extern "C" bool decl_hasHidden (decl_node n);

/*
   putTypeOpaque - marks type, des, as being an opaque type.
                   TYPE des ;
*/

extern "C" void decl_putTypeOpaque (decl_node des);

/*
   isTypeOpaque - returns TRUE if type, n, is an opaque type.
*/

extern "C" bool decl_isTypeOpaque (decl_node n);

/*
   isVar - returns TRUE if node, n, is a type.
*/

extern "C" bool decl_isVar (decl_node n);

/*
   isTemporary - returns TRUE if node, n, is a variable and temporary.
*/

extern "C" bool decl_isTemporary (decl_node n);

/*
   isExported - returns TRUE if symbol, n, is exported from
                the definition module.
*/

extern "C" bool decl_isExported (decl_node n);

/*
   getDeclScope - returns the node representing the
                  current declaration scope.
*/

extern "C" decl_node decl_getDeclScope (void);

/*
   getScope - returns the scope associated with node, n.
*/

extern "C" decl_node decl_getScope (decl_node n);

/*
   isLiteral - returns TRUE if, n, is a literal.
*/

extern "C" bool decl_isLiteral (decl_node n);

/*
   isConstSet - returns TRUE if, n, is a constant set.
*/

extern "C" bool decl_isConstSet (decl_node n);

/*
   isEnumerationField - returns TRUE if, n, is an enumeration field.
*/

extern "C" bool decl_isEnumerationField (decl_node n);

/*
   isEnumeration - returns TRUE if node, n, is an enumeration type.
*/

extern "C" bool decl_isEnumeration (decl_node n);

/*
   isUnbounded - returns TRUE if, n, is an unbounded array.
*/

extern "C" bool decl_isUnbounded (decl_node n);

/*
   isParameter - returns TRUE if, n, is a parameter.
*/

extern "C" bool decl_isParameter (decl_node n);

/*
   isVarParam - returns TRUE if, n, is a var parameter.
*/

extern "C" bool decl_isVarParam (decl_node n);

/*
   isParam - returns TRUE if, n, is a non var parameter.
*/

extern "C" bool decl_isParam (decl_node n);

/*
   isNonVarParam - is an alias to isParam.
*/

extern "C" bool decl_isNonVarParam (decl_node n);

/*
   addOptParameter - returns an optarg which has been created and added to
                     procedure node, proc.  It has a name, id, and, type,
                     and an initial value, init.
*/

extern "C" decl_node decl_addOptParameter (decl_node proc, nameKey_Name id, decl_node type, decl_node init);

/*
   isOptarg - returns TRUE if, n, is an optarg.
*/

extern "C" bool decl_isOptarg (decl_node n);

/*
   isRecord - returns TRUE if, n, is a record.
*/

extern "C" bool decl_isRecord (decl_node n);

/*
   isRecordField - returns TRUE if, n, is a record field.
*/

extern "C" bool decl_isRecordField (decl_node n);

/*
   isVarientField - returns TRUE if, n, is a varient field.
*/

extern "C" bool decl_isVarientField (decl_node n);

/*
   isArray - returns TRUE if, n, is an array.
*/

extern "C" bool decl_isArray (decl_node n);

/*
   isProcType - returns TRUE if, n, is a procedure type.
*/

extern "C" bool decl_isProcType (decl_node n);

/*
   isPointer - returns TRUE if, n, is a pointer.
*/

extern "C" bool decl_isPointer (decl_node n);

/*
   isProcedure - returns TRUE if node, n, is a procedure.
*/

extern "C" bool decl_isProcedure (decl_node n);

/*
   isVarient - returns TRUE if, n, is a varient record.
*/

extern "C" bool decl_isVarient (decl_node n);

/*
   isSet - returns TRUE if, n, is a set type.
*/

extern "C" bool decl_isSet (decl_node n);

/*
   isSubrange - returns TRUE if, n, is a subrange type.
*/

extern "C" bool decl_isSubrange (decl_node n);

/*
   isZtype - returns TRUE if, n, is the Z type.
*/

extern "C" bool decl_isZtype (decl_node n);

/*
   isRtype - returns TRUE if, n, is the R type.
*/

extern "C" bool decl_isRtype (decl_node n);

/*
   makeConst - create, initialise and return a const node.
*/

extern "C" decl_node decl_makeConst (nameKey_Name n);

/*
   putConst - places value, v, into node, n.
*/

extern "C" void decl_putConst (decl_node n, decl_node v);

/*
   makeType - create, initialise and return a type node.
*/

extern "C" decl_node decl_makeType (nameKey_Name n);

/*
   makeTypeImp - lookup a type in the definition module
                 and return it.  Otherwise create a new type.
*/

extern "C" decl_node decl_makeTypeImp (nameKey_Name n);

/*
   makeVar - create, initialise and return a var node.
*/

extern "C" decl_node decl_makeVar (nameKey_Name n);

/*
   putVar - places, type, as the type for var.
*/

extern "C" void decl_putVar (decl_node var, decl_node type, decl_node decl);

/*
   makeVarDecl - create a vardecl node and create a shadow variable in the
                 current scope.
*/

extern "C" decl_node decl_makeVarDecl (decl_node i, decl_node type);

/*
   makeEnum - creates an enumerated type and returns the node.
*/

extern "C" decl_node decl_makeEnum (void);

/*
   makeEnumField - returns an enumeration field, named, n.
*/

extern "C" decl_node decl_makeEnumField (decl_node e, nameKey_Name n);

/*
   makeSubrange - returns a subrange node, built from range: low..high.
*/

extern "C" decl_node decl_makeSubrange (decl_node low, decl_node high);

/*
   putSubrangeType - assigns, type, to the subrange type, sub.
*/

extern "C" void decl_putSubrangeType (decl_node sub, decl_node type);

/*
   makePointer - returns a pointer of, type, node.
*/

extern "C" decl_node decl_makePointer (decl_node type);

/*
   makeSet - returns a set of, type, node.
*/

extern "C" decl_node decl_makeSet (decl_node type);

/*
   makeArray - returns a node representing ARRAY subr OF type.
*/

extern "C" decl_node decl_makeArray (decl_node subr, decl_node type);

/*
   putUnbounded - sets array, n, as unbounded.
*/

extern "C" void decl_putUnbounded (decl_node n);

/*
   makeRecord - creates and returns a record node.
*/

extern "C" decl_node decl_makeRecord (void);

/*
   makeVarient - creates a new symbol, a varient symbol for record or varient field
                 symbol, r.
*/

extern "C" decl_node decl_makeVarient (decl_node r);

/*
   addFieldsToRecord - adds fields, i, of type, t, into a record, r.
                       It returns, r.
*/

extern "C" decl_node decl_addFieldsToRecord (decl_node r, decl_node v, decl_node i, decl_node t);

/*
   buildVarientSelector - builds a field of name, tag, of, type onto:
                          record or varient field, r.
                          varient, v.
*/

extern "C" void decl_buildVarientSelector (decl_node r, decl_node v, nameKey_Name tag, decl_node type);

/*
   buildVarientFieldRecord - builds a varient field into a varient symbol, v.
                             The varient field is returned.
*/

extern "C" decl_node decl_buildVarientFieldRecord (decl_node v, decl_node p);

/*
   getSymName - returns the name of symbol, n.
*/

extern "C" nameKey_Name decl_getSymName (decl_node n);

/*
   import - attempts to add node, n, into the scope of module, m.
            It might fail due to a name clash in which case the
            previous named symbol is returned.  On success, n,
            is returned.
*/

extern "C" decl_node decl_import (decl_node m, decl_node n);

/*
   lookupExported - attempts to lookup a node named, i, from definition
                    module, n.  The node is returned if found.
                    NIL is returned if not found.
*/

extern "C" decl_node decl_lookupExported (decl_node n, nameKey_Name i);

/*
   lookupSym - returns the symbol named, n, from the scope stack.
*/

extern "C" decl_node decl_lookupSym (nameKey_Name n);

/*
   addImportedModule - add module, i, to be imported by, m.
                       If scoped then module, i, is added to the
                       module, m, scope.
*/

extern "C" void decl_addImportedModule (decl_node m, decl_node i, bool scoped);

/*
   setSource - sets the source filename for module, n, to s.
*/

extern "C" void decl_setSource (decl_node n, nameKey_Name s);

/*
   getSource - returns the source filename for module, n.
*/

extern "C" nameKey_Name decl_getSource (decl_node n);

/*
   getMainModule - returns the main module node.
*/

extern "C" decl_node decl_getMainModule (void);

/*
   getCurrentModule - returns the current module being compiled.
*/

extern "C" decl_node decl_getCurrentModule (void);

/*
   foreachDefModuleDo - foreach definition node, n, in the module universe,
                        call p (n).
*/

extern "C" void decl_foreachDefModuleDo (symbolKey_performOperation p);

/*
   foreachModModuleDo - foreach implementation or module node, n, in the module universe,
                        call p (n).
*/

extern "C" void decl_foreachModModuleDo (symbolKey_performOperation p);

/*
   enterScope - pushes symbol, n, to the scope stack.
*/

extern "C" void decl_enterScope (decl_node n);

/*
   leaveScope - removes the top level scope.
*/

extern "C" void decl_leaveScope (void);

/*
   makeProcedure - create, initialise and return a procedure node.
*/

extern "C" decl_node decl_makeProcedure (nameKey_Name n);

/*
   putCommentDefProcedure - remembers the procedure comment (if it exists) as a
                            definition module procedure heading.  NIL is placed
                            if there is no procedure comment available.
*/

extern "C" void decl_putCommentDefProcedure (decl_node n);

/*
   putCommentModProcedure - remembers the procedure comment (if it exists) as an
                            implementation/program module procedure heading.  NIL is placed
                            if there is no procedure comment available.
*/

extern "C" void decl_putCommentModProcedure (decl_node n);

/*
   makeProcType - returns a proctype node.
*/

extern "C" decl_node decl_makeProcType (void);

/*
   putReturnType - sets the return type of procedure or proctype proc to type.
*/

extern "C" void decl_putReturnType (decl_node proc, decl_node type);

/*
   putOptReturn - sets, proctype or procedure, proc, to have an optional return type.
*/

extern "C" void decl_putOptReturn (decl_node proc);

/*
   makeVarParameter - returns a var parameter node with, name: type.
*/

extern "C" decl_node decl_makeVarParameter (decl_node l, decl_node type, decl_node proc, bool isused);

/*
   makeNonVarParameter - returns a non var parameter node with, name: type.
*/

extern "C" decl_node decl_makeNonVarParameter (decl_node l, decl_node type, decl_node proc, bool isused);

/*
   paramEnter - reset the parameter count.
*/

extern "C" void decl_paramEnter (decl_node n);

/*
   paramLeave - set paramater checking to TRUE from now onwards.
*/

extern "C" void decl_paramLeave (decl_node n);

/*
   makeIdentList - returns a node which will be used to maintain an ident list.
*/

extern "C" decl_node decl_makeIdentList (void);

/*
   putIdent - places ident, i, into identlist, n.  It returns TRUE if
              ident, i, is unique.
*/

extern "C" bool decl_putIdent (decl_node n, nameKey_Name i);

/*
   addVarParameters - adds the identlist, i, of, type, to be VAR parameters
                      in procedure, n.
*/

extern "C" void decl_addVarParameters (decl_node n, decl_node i, decl_node type, bool isused);

/*
   addNonVarParameters - adds the identlist, i, of, type, to be parameters
                         in procedure, n.
*/

extern "C" void decl_addNonVarParameters (decl_node n, decl_node i, decl_node type, bool isused);

/*
   makeVarargs - returns a varargs node.
*/

extern "C" decl_node decl_makeVarargs (void);

/*
   isVarargs - returns TRUE if, n, is a varargs node.
*/

extern "C" bool decl_isVarargs (decl_node n);

/*
   addParameter - adds a parameter, param, to procedure or proctype, proc.
*/

extern "C" void decl_addParameter (decl_node proc, decl_node param);

/*
   makeBinaryTok - creates and returns a boolean type node with,
                   l, and, r, nodes.
*/

extern "C" decl_node decl_makeBinaryTok (mcReserved_toktype op, decl_node l, decl_node r);

/*
   makeUnaryTok - creates and returns a boolean type node with,
                  e, node.
*/

extern "C" decl_node decl_makeUnaryTok (mcReserved_toktype op, decl_node e);

/*
   makeComponentRef - build a componentref node which accesses, field,
                      within, record, rec.
*/

extern "C" decl_node decl_makeComponentRef (decl_node rec, decl_node field);

/*
   makePointerRef - build a pointerref node which accesses, field,
                    within, pointer to record, ptr.
*/

extern "C" decl_node decl_makePointerRef (decl_node ptr, decl_node field);

/*
   isPointerRef - returns TRUE if, n, is a pointerref node.
*/

extern "C" bool decl_isPointerRef (decl_node n);

/*
   makeDeRef - dereferences the pointer defined by, n.
*/

extern "C" decl_node decl_makeDeRef (decl_node n);

/*
   makeArrayRef - build an arrayref node which access element,
                  index, in, array.  array is a variable/expression/constant
                  which has a type array.
*/

extern "C" decl_node decl_makeArrayRef (decl_node array, decl_node index);

/*
   getLastOp - return the right most non leaf node.
*/

extern "C" decl_node decl_getLastOp (decl_node n);

/*
   getCardinal - returns the cardinal type node.
*/

extern "C" decl_node decl_getCardinal (void);

/*
   makeLiteralInt - creates and returns a literal node based on an integer type.
*/

extern "C" decl_node decl_makeLiteralInt (nameKey_Name n);

/*
   makeLiteralReal - creates and returns a literal node based on a real type.
*/

extern "C" decl_node decl_makeLiteralReal (nameKey_Name n);

/*
   makeString - creates and returns a node containing string, n.
*/

extern "C" decl_node decl_makeString (nameKey_Name n);

/*
   makeSetValue - creates and returns a setvalue node.
*/

extern "C" decl_node decl_makeSetValue (void);

/*
   isSetValue - returns TRUE if, n, is a setvalue node.
*/

extern "C" bool decl_isSetValue (decl_node n);

/*
   putSetValue - assigns the type, t, to the set value, n.  The
                 node, n, is returned.
*/

extern "C" decl_node decl_putSetValue (decl_node n, decl_node t);

/*
   includeSetValue - includes the range l..h into the setvalue.
                     h might be NIL indicating that a single element
                       is to be included into the set.
                     n is returned.
*/

extern "C" decl_node decl_includeSetValue (decl_node n, decl_node l, decl_node h);

/*
   getBuiltinConst - creates and returns a builtin const if available.
*/

extern "C" decl_node decl_getBuiltinConst (nameKey_Name n);

/*
   makeExpList - creates and returns an expList node.
*/

extern "C" decl_node decl_makeExpList (void);

/*
   isExpList - returns TRUE if, n, is an explist node.
*/

extern "C" bool decl_isExpList (decl_node n);

/*
   putExpList - places, expression, e, within the explist, n.
*/

extern "C" void decl_putExpList (decl_node n, decl_node e);

/*
   makeConstExp - returns a constexp node.
*/

extern "C" decl_node decl_makeConstExp (void);

/*
   getNextConstExp - returns the next constexp node.
*/

extern "C" decl_node decl_getNextConstExp (void);

/*
   setConstExpComplete - sets the field inside the def or imp or module, n.
*/

extern "C" void decl_setConstExpComplete (decl_node n);

/*
   fixupConstExp - assign fixup expression, e, into the argument of, c.
*/

extern "C" decl_node decl_fixupConstExp (decl_node c, decl_node e);

/*
   resetConstExpPos - resets the index into the saved list of constexps inside
                      module, n.
*/

extern "C" void decl_resetConstExpPos (decl_node n);

/*
   makeFuncCall - builds a function call to c with param list, n.
*/

extern "C" decl_node decl_makeFuncCall (decl_node c, decl_node n);

/*
   makeStatementSequence - create and return a statement sequence node.
*/

extern "C" decl_node decl_makeStatementSequence (void);

/*
   isStatementSequence - returns TRUE if node, n, is a statement sequence.
*/

extern "C" bool decl_isStatementSequence (decl_node n);

/*
   addStatement - adds node, n, as a statement to statememt sequence, s.
*/

extern "C" void decl_addStatement (decl_node s, decl_node n);

/*
   addCommentBody - adds a body comment to a statement sequence node.
*/

extern "C" void decl_addCommentBody (decl_node n);

/*
   addCommentAfter - adds an after comment to a statement sequence node.
*/

extern "C" void decl_addCommentAfter (decl_node n);

/*
   addIfComments - adds the, body, and, after, comments to if node, n.
*/

extern "C" void decl_addIfComments (decl_node n, decl_node body, decl_node after);

/*
   addElseComments - adds the, body, and, after, comments to an, if, or an elsif, node, n.
*/

extern "C" void decl_addElseComments (decl_node n, decl_node body, decl_node after);

/*
   addIfEndComments - adds the, body, and, after, comments to an, if, node, n.
*/

extern "C" void decl_addIfEndComments (decl_node n, decl_node body, decl_node after);

/*
   makeReturn - creates and returns a return node.
*/

extern "C" decl_node decl_makeReturn (void);

/*
   isReturn - returns TRUE if node, n, is a return.
*/

extern "C" bool decl_isReturn (decl_node n);

/*
   putReturn - assigns node, e, as the expression on the return node.
*/

extern "C" void decl_putReturn (decl_node n, decl_node e);

/*
   makeWhile - creates and returns a while node.
*/

extern "C" decl_node decl_makeWhile (void);

/*
   putWhile - places an expression, e, and statement sequence, s, into the while
              node, n.
*/

extern "C" void decl_putWhile (decl_node n, decl_node e, decl_node s);

/*
   isWhile - returns TRUE if node, n, is a while.
*/

extern "C" bool decl_isWhile (decl_node n);

/*
   addWhileDoComment - adds body and after comments to while node, w.
*/

extern "C" void decl_addWhileDoComment (decl_node w, decl_node body, decl_node after);

/*
   addWhileEndComment - adds body and after comments to the end of a while node, w.
*/

extern "C" void decl_addWhileEndComment (decl_node w, decl_node body, decl_node after);

/*
   makeAssignment - creates and returns an assignment node.
                    The designator is, d, and expression, e.
*/

extern "C" decl_node decl_makeAssignment (decl_node d, decl_node e);

/*
   putBegin - assigns statements, s, to be the normal part in
              block, b.  The block may be a procedure or module,
              or implementation node.
*/

extern "C" void decl_putBegin (decl_node b, decl_node s);

/*
   putFinally - assigns statements, s, to be the final part in
                block, b.  The block may be a module
                or implementation node.
*/

extern "C" void decl_putFinally (decl_node b, decl_node s);

/*
   makeExit - creates and returns an exit node.
*/

extern "C" decl_node decl_makeExit (decl_node l, unsigned int n);

/*
   isExit - returns TRUE if node, n, is an exit.
*/

extern "C" bool decl_isExit (decl_node n);

/*
   makeLoop - creates and returns a loop node.
*/

extern "C" decl_node decl_makeLoop (void);

/*
   isLoop - returns TRUE if, n, is a loop node.
*/

extern "C" bool decl_isLoop (decl_node n);

/*
   putLoop - places statement sequence, s, into loop, l.
*/

extern "C" void decl_putLoop (decl_node l, decl_node s);

/*
   makeComment - creates and returns a comment node.
*/

extern "C" decl_node decl_makeComment (const char *a_, unsigned int _a_high);

/*
   makeCommentS - creates and returns a comment node.
*/

extern "C" decl_node decl_makeCommentS (mcComment_commentDesc c);

/*
   makeIf - creates and returns an if node.  The if node
            will have expression, e, and statement sequence, s,
            as the then component.
*/

extern "C" decl_node decl_makeIf (decl_node e, decl_node s);

/*
   isIf - returns TRUE if, n, is an if node.
*/

extern "C" bool decl_isIf (decl_node n);

/*
   makeElsif - creates and returns an elsif node.
               This node has an expression, e, and statement
               sequence, s.
*/

extern "C" decl_node decl_makeElsif (decl_node i, decl_node e, decl_node s);

/*
   isElsif - returns TRUE if node, n, is an elsif node.
*/

extern "C" bool decl_isElsif (decl_node n);

/*
   putElse - the else is grafted onto the if/elsif node, i,
             and the statement sequence will be, s.
*/

extern "C" void decl_putElse (decl_node i, decl_node s);

/*
   makeFor - creates and returns a for node.
*/

extern "C" decl_node decl_makeFor (void);

/*
   isFor - returns TRUE if node, n, is a for node.
*/

extern "C" bool decl_isFor (decl_node n);

/*
   putFor - assigns the fields of the for node with
            ident, i,
            start, s,
            end, e,
            increment, i,
            statements, sq.
*/

extern "C" void decl_putFor (decl_node f, decl_node i, decl_node s, decl_node e, decl_node b, decl_node sq);

/*
   makeRepeat - creates and returns a repeat node.
*/

extern "C" decl_node decl_makeRepeat (void);

/*
   isRepeat - returns TRUE if node, n, is a repeat node.
*/

extern "C" bool decl_isRepeat (decl_node n);

/*
   putRepeat - places statements, s, and expression, e, into
               repeat statement, n.
*/

extern "C" void decl_putRepeat (decl_node n, decl_node s, decl_node e);

/*
   addRepeatComment - adds body and after comments to repeat node, r.
*/

extern "C" void decl_addRepeatComment (decl_node r, decl_node body, decl_node after);

/*
   addUntilComment - adds body and after comments to the until section of a repeat node, r.
*/

extern "C" void decl_addUntilComment (decl_node r, decl_node body, decl_node after);

/*
   makeCase - builds and returns a case statement node.
*/

extern "C" decl_node decl_makeCase (void);

/*
   isCase - returns TRUE if node, n, is a case statement.
*/

extern "C" bool decl_isCase (decl_node n);

/*
   putCaseExpression - places expression, e, into case statement, n.
                       n is returned.
*/

extern "C" decl_node decl_putCaseExpression (decl_node n, decl_node e);

/*
   putCaseElse - places else statement, e, into case statement, n.
                 n is returned.
*/

extern "C" decl_node decl_putCaseElse (decl_node n, decl_node e);

/*
   putCaseStatement - places a caselist, l, and associated
                      statement sequence, s, into case statement, n.
                      n is returned.
*/

extern "C" decl_node decl_putCaseStatement (decl_node n, decl_node l, decl_node s);

/*
   makeCaseLabelList - creates and returns a caselabellist node.
*/

extern "C" decl_node decl_makeCaseLabelList (decl_node l, decl_node s);

/*
   isCaseLabelList - returns TRUE if, n, is a caselabellist.
*/

extern "C" bool decl_isCaseLabelList (decl_node n);

/*
   makeCaseList - creates and returns a case statement node.
*/

extern "C" decl_node decl_makeCaseList (void);

/*
   isCaseList - returns TRUE if, n, is a case list.
*/

extern "C" bool decl_isCaseList (decl_node n);

/*
   putCaseRange - places the case range lo..hi into caselist, n.
*/

extern "C" decl_node decl_putCaseRange (decl_node n, decl_node lo, decl_node hi);

/*
   makeRange - creates and returns a case range.
*/

extern "C" decl_node decl_makeRange (decl_node lo, decl_node hi);

/*
   isRange - returns TRUE if node, n, is a range.
*/

extern "C" bool decl_isRange (decl_node n);

/*
   setNoReturn - sets noreturn field inside procedure.
*/

extern "C" void decl_setNoReturn (decl_node n, bool value);

/*
   dupExpr - duplicate the expression nodes, it does not duplicate
             variables, literals, constants but only the expression
             operators (including function calls and parameter lists).
*/

extern "C" decl_node decl_dupExpr (decl_node n);

/*
   setLangC -
*/

extern "C" void decl_setLangC (void);

/*
   setLangCP -
*/

extern "C" void decl_setLangCP (void);

/*
   setLangM2 -
*/

extern "C" void decl_setLangM2 (void);

/*
   out - walks the tree of node declarations for the main module
         and writes the output to the outputFile specified in
         mcOptions.  It outputs the declarations in the language
         specified above.
*/

extern "C" void decl_out (void);

/*
   newNode - create and return a new node of kind k.
*/

static decl_node__opaque newNode (decl_nodeT k);

/*
   disposeNode - dispose node, n.
*/

static void disposeNode (decl_node__opaque *n);

/*
   newGroup -
*/

static void newGroup (decl_group *g);

/*
   initGroup - returns a group which with all lists initialized.
*/

static decl_group initGroup (void);

/*
   killGroup - deallocate the group and place the group record into the freeGroup list.
*/

static void killGroup (decl_group *g);

/*
   dupGroup - If g is not NIL then destroy g.
              Return a duplicate of GlobalGroup (not g).
*/

static decl_group dupGroup (decl_group g);

/*
   equalGroup - return TRUE if group left = right.
*/

static bool equalGroup (decl_group left, decl_group right);

/*
   isLocal - returns TRUE if symbol, n, is locally declared in a procedure.
*/

static bool isLocal (decl_node__opaque n);

/*
   importEnumFields - if, n, is an enumeration type import the all fields into module, m.
*/

static void importEnumFields (decl_node__opaque m, decl_node__opaque n);

/*
   checkGccType - check to see if node n is gcc tree or location_t
                  and record its use in keyc.
*/

static void checkGccType (decl_node__opaque n);

/*
   checkCDataTypes - check to see if node n is CharStar or ConstCharStar
                  and if necessary assign n to the global variable.
*/

static void checkCDataTypes (decl_node__opaque n);

/*
   isComplex - returns TRUE if, n, is the complex type.
*/

static bool isComplex (decl_node__opaque n);

/*
   isLongComplex - returns TRUE if, n, is the longcomplex type.
*/

static bool isLongComplex (decl_node__opaque n);

/*
   isShortComplex - returns TRUE if, n, is the shortcomplex type.
*/

static bool isShortComplex (decl_node__opaque n);

/*
   isAProcType - returns TRUE if, n, is a proctype or proc node.
*/

static bool isAProcType (decl_node__opaque n);

/*
   initFixupInfo - initialize the fixupInfo record.
*/

static decl_fixupInfo initFixupInfo (void);

/*
   makeDef - returns a definition module node named, n.
*/

static decl_node__opaque makeDef (nameKey_Name n);

/*
   makeImp - returns an implementation module node named, n.
*/

static decl_node__opaque makeImp (nameKey_Name n);

/*
   makeModule - returns a module node named, n.
*/

static decl_node__opaque makeModule (nameKey_Name n);

/*
   isDefForC - returns TRUE if the definition module was defined FOR "C".
*/

static bool isDefForC (decl_node__opaque n);

/*
   initDecls - initialize the decls, scopeT.
*/

static void initDecls (decl_scopeT *decls);

/*
   addTo - adds node, d, to scope decls and returns, d.
           It stores, d, in the symbols tree associated with decls.
*/

static decl_node__opaque addTo (decl_scopeT *decls, decl_node__opaque d);

/*
   export - export node, n, from definition module, d.
*/

static void export_ (decl_node__opaque d, decl_node__opaque n);

/*
   addToScope - adds node, n, to the current scope and returns, n.
*/

static decl_node__opaque addToScope (decl_node__opaque n);

/*
   addModuleToScope - adds module, i, to module, m, scope.
*/

static void addModuleToScope (decl_node__opaque m, decl_node__opaque i);

/*
   completedEnum - assign boolean enumsComplete to TRUE if a definition,
                   implementation or module symbol.
*/

static void completedEnum (decl_node__opaque n);

/*
   setUnary - sets a unary node to contain, arg, a, and type, t.
*/

static void setUnary (decl_node__opaque u, decl_nodeT k, decl_node__opaque a, decl_node__opaque t);

/*
   putVarBool - assigns the four booleans associated with a variable.
*/

static void putVarBool (decl_node__opaque v, bool init, bool param, bool isvar, bool isused);

/*
   checkPtr - in C++ we need to create a typedef for a pointer
              in case we need to use reinterpret_cast.
*/

static decl_node__opaque checkPtr (decl_node__opaque n);

/*
   isVarDecl - returns TRUE if, n, is a vardecl node.
*/

static bool isVarDecl (decl_node__opaque n);

/*
   makeVariablesFromParameters - creates variables which are really parameters.
*/

static void makeVariablesFromParameters (decl_node__opaque proc, decl_node__opaque id, decl_node__opaque type, bool isvar, bool isused);

/*
   addProcedureToScope - add a procedure name n and node d to the
                         current scope.
*/

static decl_node__opaque addProcedureToScope (decl_node__opaque d, nameKey_Name n);

/*
   putProcTypeReturn - sets the return type of, proc, to, type.
*/

static void putProcTypeReturn (decl_node__opaque proc, decl_node__opaque type);

/*
   putProcTypeOptReturn - sets, proc, to have an optional return type.
*/

static void putProcTypeOptReturn (decl_node__opaque proc);

/*
   makeOptParameter - creates and returns an optarg.
*/

static decl_node__opaque makeOptParameter (decl_node__opaque l, decl_node__opaque type, decl_node__opaque init);

/*
   setwatch - assign the globalNode to n.
*/

static bool setwatch (decl_node__opaque n);

/*
   runwatch - set the globalNode to an identlist.
*/

static bool runwatch (void);

/*
   isIdentList - returns TRUE if, n, is an identlist.
*/

static bool isIdentList (decl_node__opaque n);

/*
   identListLen - returns the length of identlist.
*/

static unsigned int identListLen (decl_node__opaque n);

/*
   checkParameters - placeholder for future parameter checking.
*/

static void checkParameters (decl_node__opaque p, decl_node__opaque i, decl_node__opaque type, bool isvar, bool isused);

/*
   checkMakeVariables - create shadow local variables for parameters providing that
                        procedure n has not already been built and we are compiling
                        a module or an implementation module.
*/

static void checkMakeVariables (decl_node__opaque n, decl_node__opaque i, decl_node__opaque type, bool isvar, bool isused);

/*
   makeVarientField - create a varient field within varient, v,
                      The new varient field is returned.
*/

static decl_node__opaque makeVarientField (decl_node__opaque v, decl_node__opaque p);

/*
   putFieldVarient - places the field varient, f, as a brother to, the
                     varient symbol, v, and also tells, f, that its varient
                     parent is, v.
*/

static void putFieldVarient (decl_node__opaque f, decl_node__opaque v);

/*
   putFieldRecord - create a new recordfield and place it into record r.
                    The new field has a tagname and type and can have a
                    variant field v.
*/

static decl_node__opaque putFieldRecord (decl_node__opaque r, nameKey_Name tag, decl_node__opaque type, decl_node__opaque v);

/*
   ensureOrder - ensures that, a, and, b, exist in, i, and also
                 ensure that, a, is before, b.
*/

static void ensureOrder (Indexing_Index i, decl_node__opaque a, decl_node__opaque b);

/*
   putVarientTag - places tag into variant v.
*/

static void putVarientTag (decl_node__opaque v, decl_node__opaque tag);

/*
   getParent - returns the parent field of recordfield or varientfield symbol, n.
*/

static decl_node__opaque getParent (decl_node__opaque n);

/*
   getRecord - returns the record associated with node, n.
               (Parental record).
*/

static decl_node__opaque getRecord (decl_node__opaque n);

/*
   isConstExp - return TRUE if the node kind is a constexp.
*/

static bool isConstExp (decl_node__opaque c);

/*
   addEnumToModule - adds enumeration type, e, into the list of enums
                     in module, m.
*/

static void addEnumToModule (decl_node__opaque m, decl_node__opaque e);

/*
   getNextFixup - return the next fixup from from f.
*/

static decl_node__opaque getNextFixup (decl_fixupInfo *f);

/*
   doMakeEnum - create an enumeration type and add it to the current module.
*/

static decl_node__opaque doMakeEnum (void);

/*
   doMakeEnumField - create an enumeration field name and add it to enumeration e.
                     Return the new field.
*/

static decl_node__opaque doMakeEnumField (decl_node__opaque e, nameKey_Name n);

/*
   getExpList - returns the, n, th argument in an explist.
*/

static decl_node__opaque getExpList (decl_node__opaque p, unsigned int n);

/*
   expListLen - returns the length of explist, p.
*/

static unsigned int expListLen (decl_node__opaque p);

/*
   getConstExpComplete - gets the field from the def or imp or module, n.
*/

static bool getConstExpComplete (decl_node__opaque n);

/*
   addConstToModule - adds const exp, e, into the list of constant
                      expressions in module, m.
*/

static void addConstToModule (decl_node__opaque m, decl_node__opaque e);

/*
   doMakeConstExp - create a constexp node and add it to the current module.
*/

static decl_node__opaque doMakeConstExp (void);

/*
   isAnyType - return TRUE if node n is any type kind.
*/

static bool isAnyType (decl_node__opaque n);

/*
   makeVal - creates a VAL (type, expression) node.
*/

static decl_node__opaque makeVal (decl_node__opaque params);

/*
   makeCast - creates a cast node TYPENAME (expr).
*/

static decl_node__opaque makeCast (decl_node__opaque c, decl_node__opaque p);
static decl_node__opaque makeIntrinsicProc (decl_nodeT k, unsigned int noArgs, decl_node__opaque p);

/*
   makeIntrinsicUnaryType - create an intrisic unary type.
*/

static decl_node__opaque makeIntrinsicUnaryType (decl_nodeT k, decl_node__opaque paramList, decl_node__opaque returnType);

/*
   makeIntrinsicBinaryType - create an intrisic binary type.
*/

static decl_node__opaque makeIntrinsicBinaryType (decl_nodeT k, decl_node__opaque paramList, decl_node__opaque returnType);

/*
   checkIntrinsic - checks to see if the function call to, c, with
                    parameter list, n, is really an intrinic.  If it
                    is an intrinic then an intrinic node is created
                    and returned.  Otherwise NIL is returned.
*/

static decl_node__opaque checkIntrinsic (decl_node__opaque c, decl_node__opaque n);

/*
   checkCHeaders - check to see if the function is a C system function and
                   requires a header file included.
*/

static void checkCHeaders (decl_node__opaque c);

/*
   isFuncCall - returns TRUE if, n, is a function/procedure call.
*/

static bool isFuncCall (decl_node__opaque n);

/*
   putTypeInternal - marks type, des, as being an internally generated type.
*/

static void putTypeInternal (decl_node__opaque des);

/*
   isTypeInternal - returns TRUE if type, n, is internal.
*/

static bool isTypeInternal (decl_node__opaque n);

/*
   lookupBase - return node named n from the base symbol scope.
*/

static decl_node__opaque lookupBase (nameKey_Name n);

/*
   dumpScopes - display the names of all the scopes stacked.
*/

static void dumpScopes (void);

/*
   out0 - write string a to StdOut.
*/

static void out0 (const char *a_, unsigned int _a_high);

/*
   out1 - write string a to StdOut using format specifier a.
*/

static void out1 (const char *a_, unsigned int _a_high, decl_node__opaque s);

/*
   out2 - write string a to StdOut using format specifier a.
*/

static void out2 (const char *a_, unsigned int _a_high, unsigned int c, decl_node__opaque s);

/*
   out3 - write string a to StdOut using format specifier a.
*/

static void out3 (const char *a_, unsigned int _a_high, unsigned int l, nameKey_Name n, decl_node__opaque s);

/*
   isUnary - returns TRUE if, n, is an unary node.
*/

static bool isUnary (decl_node__opaque n);

/*
   isBinary - returns TRUE if, n, is an binary node.
*/

static bool isBinary (decl_node__opaque n);

/*
   makeUnary - create a unary expression node with, e, as the argument
               and res as the return type.
*/

static decl_node__opaque makeUnary (decl_nodeT k, decl_node__opaque e, decl_node__opaque res);

/*
   isLeafString - returns TRUE if n is a leaf node which is a string constant.
*/

static bool isLeafString (decl_node__opaque n);

/*
   getLiteralStringContents - return the contents of a literal node as a string.
*/

static DynamicStrings_String getLiteralStringContents (decl_node__opaque n);

/*
   getStringContents - return the string contents of a constant, literal,
                       string or a constexp node.
*/

static DynamicStrings_String getStringContents (decl_node__opaque n);

/*
   addNames -
*/

static nameKey_Name addNames (decl_node__opaque a, decl_node__opaque b);

/*
   resolveString -
*/

static decl_node__opaque resolveString (decl_node__opaque n);

/*
   foldBinary -
*/

static decl_node__opaque foldBinary (decl_nodeT k, decl_node__opaque l, decl_node__opaque r, decl_node__opaque res);

/*
   makeBinary - create a binary node with left/right/result type:  l, r and resultType.
*/

static decl_node__opaque makeBinary (decl_nodeT k, decl_node__opaque l, decl_node__opaque r, decl_node__opaque resultType);

/*
   doMakeBinary - returns a binary node containing left/right/result values
                  l, r, res, with a node operator, k.
*/

static decl_node__opaque doMakeBinary (decl_nodeT k, decl_node__opaque l, decl_node__opaque r, decl_node__opaque res);

/*
   doMakeComponentRef -
*/

static decl_node__opaque doMakeComponentRef (decl_node__opaque rec, decl_node__opaque field);

/*
   isComponentRef -
*/

static bool isComponentRef (decl_node__opaque n);

/*
   isArrayRef - returns TRUE if the node was an arrayref.
*/

static bool isArrayRef (decl_node__opaque n);

/*
   isDeref - returns TRUE if, n, is a deref node.
*/

static bool isDeref (decl_node__opaque n);

/*
   makeBase - create a base type or constant.
              It only supports the base types and constants
              enumerated below.
*/

static decl_node__opaque makeBase (decl_nodeT k);

/*
   isOrdinal - returns TRUE if, n, is an ordinal type.
*/

static bool isOrdinal (decl_node__opaque n);

/*
   mixTypes -
*/

static decl_node__opaque mixTypes (decl_node__opaque a, decl_node__opaque b);

/*
   doSetExprType -
*/

static decl_node__opaque doSetExprType (decl_node__opaque *t, decl_node__opaque n);

/*
   getMaxMinType -
*/

static decl_node__opaque getMaxMinType (decl_node__opaque n);

/*
   doGetFuncType -
*/

static decl_node__opaque doGetFuncType (decl_node__opaque n);

/*
   doGetExprType - works out the type which is associated with node, n.
*/

static decl_node__opaque doGetExprType (decl_node__opaque n);

/*
   getExprType - return the expression type.
*/

static decl_node__opaque getExprType (decl_node__opaque n);

/*
   openOutput -
*/

static void openOutput (void);

/*
   closeOutput -
*/

static void closeOutput (void);

/*
   write - outputs a single char, ch.
*/

static void write_ (char ch);

/*
   writeln -
*/

static void writeln (void);

/*
   doIncludeC - include header file for definition module, n.
*/

static void doIncludeC (decl_node__opaque n);

/*
   getSymScope - returns the scope where node, n, was declared.
*/

static decl_node__opaque getSymScope (decl_node__opaque n);

/*
   isQualifiedForced - should the node be written with a module prefix?
*/

static bool isQualifiedForced (decl_node__opaque n);

/*
   getFQstring -
*/

static DynamicStrings_String getFQstring (decl_node__opaque n);

/*
   getFQDstring -
*/

static DynamicStrings_String getFQDstring (decl_node__opaque n, bool scopes);

/*
   getString - returns the name as a string.
*/

static DynamicStrings_String getString (decl_node__opaque n);

/*
   doNone - call HALT.
*/

static void doNone (decl_node__opaque n);

/*
   doNothing - does nothing!
*/

static void doNothing (decl_node__opaque n);

/*
   doConstC -
*/

static void doConstC (decl_node__opaque n);

/*
   needsParen - returns TRUE if expression, n, needs to be enclosed in ().
*/

static bool needsParen (decl_node__opaque n);

/*
   doUnary -
*/

static void doUnary (mcPretty_pretty p, const char *op_, unsigned int _op_high, decl_node__opaque expr, decl_node__opaque type, bool l, bool r);

/*
   doSetSub - perform  l & (~ r)
*/

static void doSetSub (mcPretty_pretty p, decl_node__opaque left, decl_node__opaque right);

/*
   doPolyBinary -
*/

static void doPolyBinary (mcPretty_pretty p, decl_nodeT op, decl_node__opaque left, decl_node__opaque right, bool l, bool r);

/*
   doBinary -
*/

static void doBinary (mcPretty_pretty p, const char *op_, unsigned int _op_high, decl_node__opaque left, decl_node__opaque right, bool l, bool r, bool unpackProc);

/*
   doPostUnary -
*/

static void doPostUnary (mcPretty_pretty p, const char *op_, unsigned int _op_high, decl_node__opaque expr);

/*
   doDeRefC -
*/

static decl_node__opaque doDeRefC (mcPretty_pretty p, decl_node__opaque expr);

/*
   doGetLastOp - returns, a, if b is a terminal otherwise walk right.
*/

static decl_node__opaque doGetLastOp (decl_node__opaque a, decl_node__opaque b);

/*
   doComponentRefC -
*/

static void doComponentRefC (mcPretty_pretty p, decl_node__opaque l, decl_node__opaque r);

/*
   doPointerRefC -
*/

static void doPointerRefC (mcPretty_pretty p, decl_node__opaque l, decl_node__opaque r);

/*
   doPreBinary -
*/

static void doPreBinary (mcPretty_pretty p, const char *op_, unsigned int _op_high, decl_node__opaque left, decl_node__opaque right, bool l, bool r);

/*
   doConstExpr -
*/

static void doConstExpr (mcPretty_pretty p, decl_node__opaque n);

/*
   doEnumerationField -
*/

static void doEnumerationField (mcPretty_pretty p, decl_node__opaque n);

/*
   isZero - returns TRUE if node, n, is zero.
*/

static bool isZero (decl_node__opaque n);

/*
   doArrayRef - perform an array reference.  If constCast
                then an unbounded array access will be const_cast
                (the constCast should be TRUE if an assignment to
                the array is required).
*/

static void doArrayRef (mcPretty_pretty p, decl_node__opaque n, bool constCast);

/*
   doProcedure -
*/

static void doProcedure (mcPretty_pretty p, decl_node__opaque n);

/*
   doRecordfield -
*/

static void doRecordfield (mcPretty_pretty p, decl_node__opaque n);

/*
   doCastC -
*/

static void doCastC (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque e);

/*
   doSetValueC -
*/

static void doSetValueC (mcPretty_pretty p, decl_node__opaque n);

/*
   getSetLow - returns the low value of the set type from
               expression, n.
*/

static decl_node__opaque getSetLow (decl_node__opaque n);

/*
   doInC - performs (((1 << (l)) & (r)) != 0)
*/

static void doInC (mcPretty_pretty p, decl_node__opaque l, decl_node__opaque r);

/*
   doThrowC -
*/

static void doThrowC (mcPretty_pretty p, decl_node__opaque n);

/*
   doUnreachableC -
*/

static void doUnreachableC (mcPretty_pretty p, decl_node__opaque n);

/*
   outNull -
*/

static void outNull (mcPretty_pretty p);

/*
   outTrue -
*/

static void outTrue (mcPretty_pretty p);

/*
   outFalse -
*/

static void outFalse (mcPretty_pretty p);

/*
   doExprC -
*/

static void doExprC (mcPretty_pretty p, decl_node__opaque n);

/*
   doExprCup -
*/

static decl_node__opaque doExprCup (mcPretty_pretty p, decl_node__opaque n, bool unpackProc, bool uncastConst);

/*
   doExprM2 -
*/

static void doExprM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doVar -
*/

static void doVar (mcPretty_pretty p, decl_node__opaque n);

/*
   doLiteralC -
*/

static void doLiteralC (mcPretty_pretty p, decl_node__opaque n);

/*
   doLiteral -
*/

static void doLiteral (mcPretty_pretty p, decl_node__opaque n);

/*
   isString - returns TRUE if node, n, is a string.
*/

static bool isString (decl_node__opaque n);

/*
   doString -
*/

static void doString (mcPretty_pretty p, decl_node__opaque n);

/*
   replaceChar - replace every occurance of, ch, by, a and return modified string, s.
*/

static DynamicStrings_String replaceChar (DynamicStrings_String s, char ch, const char *a_, unsigned int _a_high);

/*
   toCstring - translates string, n, into a C string
               and returns the new String.
*/

static DynamicStrings_String toCstring (nameKey_Name n);

/*
   toCchar -
*/

static DynamicStrings_String toCchar (nameKey_Name n);

/*
   countChar -
*/

static unsigned int countChar (DynamicStrings_String s, char ch);

/*
   lenCstring -
*/

static unsigned int lenCstring (DynamicStrings_String s);

/*
   outCstring -
*/

static void outCstring (mcPretty_pretty p, decl_node__opaque s, bool aString);

/*
   doStringC -
*/

static void doStringC (mcPretty_pretty p, decl_node__opaque n);

/*
   isPunct -
*/

static bool isPunct (char ch);

/*
   isWhite -
*/

static bool isWhite (char ch);

/*
   outText -
*/

static void outText (mcPretty_pretty p, const char *a_, unsigned int _a_high);

/*
   outRawS -
*/

static void outRawS (mcPretty_pretty p, DynamicStrings_String s);

/*
   outKm2 -
*/

static mcPretty_pretty outKm2 (mcPretty_pretty p, const char *a_, unsigned int _a_high);

/*
   outKc -
*/

static mcPretty_pretty outKc (mcPretty_pretty p, const char *a_, unsigned int _a_high);

/*
   outTextS -
*/

static void outTextS (mcPretty_pretty p, DynamicStrings_String s);

/*
   outCard -
*/

static void outCard (mcPretty_pretty p, unsigned int c);

/*
   outTextN -
*/

static void outTextN (mcPretty_pretty p, nameKey_Name n);

/*
   outputEnumerationC -
*/

static void outputEnumerationC (mcPretty_pretty p, decl_node__opaque n);

/*
   isDeclType - return TRUE if the current module should declare type.
*/

static bool isDeclType (decl_node__opaque type);

/*
   doEnumerationC -
*/

static void doEnumerationC (mcPretty_pretty p, decl_node__opaque n);

/*
   doNamesC -
*/

static void doNamesC (mcPretty_pretty p, nameKey_Name n);

/*
   doNameC -
*/

static void doNameC (mcPretty_pretty p, decl_node__opaque n);

/*
   initCname -
*/

static void initCname (decl_cnameT *c);

/*
   doCname -
*/

static nameKey_Name doCname (nameKey_Name n, decl_cnameT *c, bool scopes);

/*
   getDName -
*/

static nameKey_Name getDName (decl_node__opaque n, bool scopes);

/*
   doDNameC -
*/

static void doDNameC (mcPretty_pretty p, decl_node__opaque n, bool scopes);

/*
   doFQDNameC -
*/

static void doFQDNameC (mcPretty_pretty p, decl_node__opaque n, bool scopes);

/*
   doFQNameC -
*/

static void doFQNameC (mcPretty_pretty p, decl_node__opaque n);

/*
   doNameM2 -
*/

static void doNameM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doUsed -
*/

static void doUsed (mcPretty_pretty p, bool used);

/*
   doHighC -
*/

static void doHighC (mcPretty_pretty p, decl_node__opaque a, nameKey_Name n, bool isused);

/*
   doParamConstCast -
*/

static void doParamConstCast (mcPretty_pretty p, decl_node__opaque n);

/*
   getParameterVariable - returns the variable which shadows the parameter
                          named, m, in parameter block, n.
*/

static decl_node__opaque getParameterVariable (decl_node__opaque n, nameKey_Name m);

/*
   doParamTypeEmit - emit parameter type for C/C++.  It checks to see if the
                     parameter type is a procedure type and if it were declared
                     in a definition module for "C" and if so it uses the "C"
                     definition for a procedure type, rather than the mc
                     C++ version.
*/

static void doParamTypeEmit (mcPretty_pretty p, decl_node__opaque paramnode, decl_node__opaque paramtype);

/*
   doParamTypeNameModifier - Add an _ to an unbounded parameter which is non var.
*/

static void doParamTypeNameModifier (mcPretty_pretty p, decl_node__opaque ptype, bool varparam);

/*
   initOpaqueCastState - assign fields opaque and voidstar in opaquestate.
*/

static void initOpaqueCastState (decl_opaqueCastState *opaquestate, bool opaque, bool voidstar);

/*
   initNodeOpaqueCastState - assign opaque and currentvoidstar
*/

static void initNodeOpaqueCastState (decl_node__opaque n, bool opaque, bool voidstar);

/*
   setOpaqueCastState - set the voidStar field in opaquestate.
*/

static void setOpaqueCastState (decl_opaqueCastState *opaquestate, bool voidstar);

/*
   setNodeOpaqueVoidStar - sets the voidStar field in node to voidstar.
*/

static void setNodeOpaqueVoidStar (decl_node__opaque n, bool voidstar);

/*
   nodeUsesOpaque - return TRUE if node n uses an opaque type.
*/

static bool nodeUsesOpaque (decl_node__opaque n);

/*
   getNodeOpaqueVoidStar - return TRUE if the opaque type used by node n is a void *.
*/

static bool getNodeOpaqueVoidStar (decl_node__opaque n);

/*
   getOpaqueFlushNecessary - return TRUE if the value next differs from the opaque state.
*/

static bool getOpaqueFlushNecessary (decl_opaqueCastState state, bool next);

/*
   getNodeOpaqueFlushNecessary - return TRUE if the value of next requires a cast.
*/

static bool getNodeOpaqueFlushNecessary (decl_node__opaque n, bool next);

/*
   makeOpaqueCast - wrap node n with an opaquecast node and assign
                    voidstar into the new opaque state.
*/

static decl_node__opaque makeOpaqueCast (decl_node__opaque n, bool voidstar);

/*
   flushOpaque - perform a cast to voidstar (if necessary) and ignore the new
                 node which could be created.
*/

static void flushOpaque (mcPretty_pretty p, decl_node__opaque n, bool toVoidStar);

/*
   castOpaque - flushes the opaque type casts if necessary and changes the
                voidstar boolean value.   If necessary it creates a opaquecast
                and returns the new node otherwise return n.
*/

static decl_node__opaque castOpaque (mcPretty_pretty p, decl_node__opaque n, bool toVoidStar);

/*
   isTypeOpaqueDefImp - returns TRUE if type is an opaque type by checking
                        the def/imp pair of modules or fall back to the
                        definition module.
*/

static bool isTypeOpaqueDefImp (decl_node__opaque type);

/*
   isParamVoidStar - return TRUE if the procedure or proctype opaque type
                     parameter should be implemented as a (void * ).
*/

static bool isParamVoidStar (decl_node__opaque n);

/*
   isRefVoidStar - returns TRUE if the ref node uses an opaque type which
                   is represented as a (void * ).
*/

static bool isRefVoidStar (decl_node__opaque n);

/*
   isReturnVoidStar - return TRUE if the procedure or proctype opaque type
                      return type should be implemented as a (void * ).
*/

static bool isReturnVoidStar (decl_node__opaque proc, decl_node__opaque type);

/*
   isVarVoidStar - return TRUE if the variable using an opaque type should
                   be implemented as a (void * ).
*/

static bool isVarVoidStar (decl_node__opaque n);

/*
   initNodeOpaqueState - initialize the node opaque state.
*/

static void initNodeOpaqueState (decl_node__opaque n);

/*
   assignNodeOpaqueCastState - copy the opaqueCastState from src into dest.
*/

static void assignNodeOpaqueCastState (decl_node__opaque dest, decl_node__opaque src);

/*
   assignNodeOpaqueCastFalse - assign the voidstar field of dest to false.
                               It assigns the opaque field of dest to the value
                               of the src opaque field.
*/

static void assignNodeOpaqueCastFalse (decl_node__opaque dest, decl_node__opaque src);

/*
   dumpOpaqueState -
*/

static void dumpOpaqueState (decl_node__opaque n);

/*
   doParamC - emit parameter for C/C++.
*/

static void doParamC (mcPretty_pretty p, decl_node__opaque n);

/*
   doVarParamC - emit a VAR parameter for C/C++.
*/

static void doVarParamC (mcPretty_pretty p, decl_node__opaque n);

/*
   doOptargC -
*/

static void doOptargC (mcPretty_pretty p, decl_node__opaque n);

/*
   doParameterC -
*/

static void doParameterC (mcPretty_pretty p, decl_node__opaque n);

/*
   doProcTypeC -
*/

static void doProcTypeC (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque n);

/*
   isDeclInImp - returns TRUE if node type is declared as an opaque and
                 is declared fully in the current implementation module.
                 This should only be called if isType (type).  Its purpose
                 is specific to a type checking whether it is an opaque type
                 declared in the .def/.mod pair of the current imp module.
*/

static bool isDeclInImp (decl_node__opaque type);

/*
   doTypeNameModifier - adds the __opaque modifier to the type n provided
                        it is an opaque type which is being declared in the
                        implementation module.
*/

static void doTypeNameModifier (mcPretty_pretty p, decl_node__opaque n);

/*
   isGccType - return TRUE if n is tree or location_t.
*/

static bool isGccType (decl_node__opaque n);

/*
   doGccType - record whether we are going to declare tree or location_t
               so that the appropriate gcc header can be included instead.
*/

static void doGccType (mcPretty_pretty p, decl_node__opaque n);

/*
   isCDataType - return true if n is charStar or constCharStar.
*/

static bool isCDataType (decl_node__opaque n);

/*
   isCDataTypes - return TRUE if n is CharStar or ConstCharStar.
*/

static bool isCDataTypes (decl_node__opaque n);

/*
   doCDataTypes - if we are going to declare CharStar or ConstCharStar
               then generate a comment instead.
*/

static void doCDataTypes (mcPretty_pretty p, decl_node__opaque n);

/*
   doCDataTypesC - generate the C representation of the CDataTypes data types.
*/

static void doCDataTypesC (mcPretty_pretty p, decl_node__opaque n);

/*
   doTypeOrPointer - only declare type or pointer n providing that
                     the name is not location_t or tree and
                     the --gccConfigSystem option is enabled.
*/

static void doTypeOrPointer (mcPretty_pretty p, decl_node__opaque n);

/*
   doTypedef - generate a typedef for n provuiding it is not
*/

static void doTypedef (mcPretty_pretty p, decl_node__opaque n);

/*
   doTypesC -
*/

static void doTypesC (decl_node__opaque n);

/*
   doCompletePartialC -
*/

static void doCompletePartialC (decl_node__opaque n);

/*
   doCompletePartialRecord -
*/

static void doCompletePartialRecord (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque r);

/*
   doCompletePartialArray -
*/

static void doCompletePartialArray (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque r);

/*
   lookupConst -
*/

static decl_node__opaque lookupConst (decl_node__opaque type, nameKey_Name n);

/*
   doMin -
*/

static decl_node__opaque doMin (decl_node__opaque n);

/*
   doMax -
*/

static decl_node__opaque doMax (decl_node__opaque n);

/*
   getMax -
*/

static decl_node__opaque getMax (decl_node__opaque n);

/*
   getMin -
*/

static decl_node__opaque getMin (decl_node__opaque n);

/*
   doSubtractC -
*/

static void doSubtractC (mcPretty_pretty p, decl_node__opaque s);

/*
   doSubrC -
*/

static void doSubrC (mcPretty_pretty p, decl_node__opaque s);

/*
   doCompletePartialProcType -
*/

static void doCompletePartialProcType (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque n);

/*
   outputCompletePartialProcType -
*/

static void outputCompletePartialProcType (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque n);

/*
   isBase -
*/

static bool isBase (decl_node__opaque n);

/*
   doBoolC -
*/

static void doBoolC (mcPretty_pretty p);

/*
   doBaseC -
*/

static void doBaseC (mcPretty_pretty p, decl_node__opaque n);

/*
   isSystem -
*/

static bool isSystem (decl_node__opaque n);

/*
   doSystemC -
*/

static void doSystemC (mcPretty_pretty p, decl_node__opaque n);

/*
   doArrayC -
*/

static void doArrayC (mcPretty_pretty p, decl_node__opaque n);

/*
   doPointerC -
*/

static void doPointerC (mcPretty_pretty p, decl_node__opaque n, decl_node__opaque *m);

/*
   doRecordFieldC -
*/

static void doRecordFieldC (mcPretty_pretty p, decl_node__opaque f);

/*
   doVarientFieldC -
*/

static void doVarientFieldC (mcPretty_pretty p, decl_node__opaque n);

/*
   doVarientC -
*/

static void doVarientC (mcPretty_pretty p, decl_node__opaque n);

/*
   doRecordC -
*/

static void doRecordC (mcPretty_pretty p, decl_node__opaque n, decl_node__opaque *m);

/*
   isBitset -
*/

static bool isBitset (decl_node__opaque n);

/*
   isNegative - returns TRUE if expression, n, is negative.
*/

static bool isNegative (decl_node__opaque n);

/*
   doSubrangeC -
*/

static void doSubrangeC (mcPretty_pretty p, decl_node__opaque n);

/*
   doSetC - generates a C type which holds the set.
            Currently we only support sets of size WORD.
*/

static void doSetC (mcPretty_pretty p, decl_node__opaque n);

/*
   doTypeC -
*/

static void doTypeC (mcPretty_pretty p, decl_node__opaque n, decl_node__opaque *m);

/*
   doArrayNameC - it displays the array declaration (it might be an unbounded).
*/

static void doArrayNameC (mcPretty_pretty p, decl_node__opaque n);

/*
   doRecordNameC - emit the C/C++ record name <name of n>"_r".
*/

static void doRecordNameC (mcPretty_pretty p, decl_node__opaque n);

/*
   doPointerNameC - emit the C/C++ pointer type <name of n>*.
*/

static void doPointerNameC (mcPretty_pretty p, decl_node__opaque n);

/*
   doTypeNameC -
*/

static void doTypeNameC (mcPretty_pretty p, decl_node__opaque n);

/*
   isExternal - returns TRUE if symbol, n, was declared in another module.
*/

static bool isExternal (decl_node__opaque n);

/*
   doOpaqueModifier - adds postfix __opaque providing n uses an opaque type which is
                      not represented by ( void * ).  n is a non type node which might
                      be using an opaque type.  For example a var or param node.
*/

static void doOpaqueModifier (mcPretty_pretty p, decl_node__opaque n);

/*
   doDeclareVarC -
*/

static void doDeclareVarC (decl_node__opaque n);

/*
   doVarC - output a variable declaration.  Note that we do not generate
            a declaration if we are translating the implementation module
            and a variable is exported as the variable will be in the .h
            file to avoid all -Wodr issues.
*/

static void doVarC (decl_node__opaque n);

/*
   doExternCP -
*/

static void doExternCP (mcPretty_pretty p);

/*
   doProcedureCommentText -
*/

static void doProcedureCommentText (mcPretty_pretty p, DynamicStrings_String s);

/*
   doProcedureComment -
*/

static void doProcedureComment (mcPretty_pretty p, DynamicStrings_String s);

/*
   doProcedureHeadingC -
*/

static void doProcedureHeadingC (decl_node__opaque n, bool prototype);

/*
   checkDeclareUnboundedParamCopyC -
*/

static bool checkDeclareUnboundedParamCopyC (mcPretty_pretty p, decl_node__opaque n);

/*
   checkUnboundedParamCopyC -
*/

static void checkUnboundedParamCopyC (mcPretty_pretty p, decl_node__opaque n);

/*
   doUnboundedParamCopyC -
*/

static void doUnboundedParamCopyC (mcPretty_pretty p, decl_node__opaque n);

/*
   doPrototypeC -
*/

static void doPrototypeC (decl_node__opaque n);

/*
   addTodo - adds, n, to the todo list.
*/

static void addTodo (decl_node__opaque n);

/*
   addVariablesTodo -
*/

static void addVariablesTodo (decl_node__opaque n);

/*
   addTypesTodo -
*/

static void addTypesTodo (decl_node__opaque n);

/*
   tempName -
*/

static DynamicStrings_String tempName (void);

/*
   makeIntermediateType -
*/

static decl_node__opaque makeIntermediateType (DynamicStrings_String s, decl_node__opaque p);

/*
   simplifyType -
*/

static void simplifyType (alists_alist l, decl_node__opaque *p);

/*
   simplifyVar -
*/

static void simplifyVar (alists_alist l, decl_node__opaque n);

/*
   simplifyRecord -
*/

static void simplifyRecord (alists_alist l, decl_node__opaque n);

/*
   simplifyVarient -
*/

static void simplifyVarient (alists_alist l, decl_node__opaque n);

/*
   simplifyVarientField -
*/

static void simplifyVarientField (alists_alist l, decl_node__opaque n);

/*
   doSimplifyNode -
*/

static void doSimplifyNode (alists_alist l, decl_node__opaque n);

/*
   simplifyNode -
*/

static void simplifyNode (alists_alist l, decl_node__opaque n);

/*
   doSimplify -
*/

static void doSimplify (decl_node__opaque n);

/*
   simplifyTypes -
*/

static void simplifyTypes (decl_scopeT s);

/*
   outDeclsDefC -
*/

static void outDeclsDefC (mcPretty_pretty p, decl_node__opaque n);

/*
   includeConstType -
*/

static void includeConstType (decl_scopeT s);

/*
   includeVarProcedure -
*/

static void includeVarProcedure (decl_scopeT s);

/*
   includeVar -
*/

static void includeVar (decl_scopeT s);

/*
   includeExternals -
*/

static void includeExternals (decl_node__opaque n);

/*
   checkSystemInclude -
*/

static void checkSystemInclude (decl_node__opaque n);

/*
   addExported -
*/

static void addExported (decl_node__opaque n);

/*
   addExternal - only adds, n, if this symbol is external to the
                 implementation module and is not a hidden type.
*/

static void addExternal (decl_node__opaque n);

/*
   includeDefConstType -
*/

static void includeDefConstType (decl_node__opaque n);

/*
   runIncludeDefConstType -
*/

static void runIncludeDefConstType (decl_node__opaque n);

/*
   joinProcedures - copies procedures from definition module,
                    d, into implementation module, i.
*/

static void joinProcedures (decl_node__opaque i, decl_node__opaque d);

/*
   includeDefVarProcedure -
*/

static void includeDefVarProcedure (decl_node__opaque n);

/*
   foreachModuleDo -
*/

static void foreachModuleDo (decl_node__opaque n, symbolKey_performOperation p);

/*
   outDeclsImpC -
*/

static void outDeclsImpC (mcPretty_pretty p, decl_scopeT s);

/*
   doStatementSequenceC -
*/

static void doStatementSequenceC (mcPretty_pretty p, decl_node__opaque s);

/*
   isStatementSequenceEmpty -
*/

static bool isStatementSequenceEmpty (decl_node__opaque s);

/*
   isSingleStatement - returns TRUE if the statement sequence, s, has
                       only one statement.
*/

static bool isSingleStatement (decl_node__opaque s);

/*
   doCommentC -
*/

static void doCommentC (mcPretty_pretty p, decl_node__opaque s);

/*
   doAfterCommentC - emit an after comment, c, or a newline if, c, is empty.
*/

static void doAfterCommentC (mcPretty_pretty p, decl_node__opaque c);

/*
   doReturnC - issue a return statement and also place in an after comment if one exists.
*/

static void doReturnC (mcPretty_pretty p, decl_node__opaque s);

/*
   isZtypeEquivalent -
*/

static bool isZtypeEquivalent (decl_node__opaque type);

/*
   isEquivalentType - returns TRUE if type1 and type2 are equivalent.
*/

static bool isEquivalentType (decl_node__opaque type1, decl_node__opaque type2);

/*
   doExprCastC - build a cast if necessary.
*/

static void doExprCastC (mcPretty_pretty p, decl_node__opaque e, decl_node__opaque type);

/*
   requiresUnpackProc - returns TRUE if either the expr is a procedure or the proctypes differ.
*/

static bool requiresUnpackProc (decl_node__opaque s);

/*
   forceCastOpaque -
*/

static void forceCastOpaque (mcPretty_pretty p, decl_node__opaque des, decl_node__opaque expr, bool toVoidStar);

/*
   forceReintCastOpaque -
*/

static void forceReintCastOpaque (mcPretty_pretty p, decl_node__opaque des, decl_node__opaque expr, bool toVoidStar);

/*
   doUnConstCastUnbounded - if node n type is an unbounded array then
                            use const_cast to remove the const parameter
                            to allow the unbounded array to be modified.
*/

static void doUnConstCastUnbounded (mcPretty_pretty p, decl_node__opaque n);

/*
   doAssignmentC -
*/

static void doAssignmentC (mcPretty_pretty p, decl_node__opaque s);

/*
   containsStatement -
*/

static bool containsStatement (decl_node__opaque s);

/*
   doCompoundStmt -
*/

static void doCompoundStmt (mcPretty_pretty p, decl_node__opaque s);

/*
   doElsifC -
*/

static void doElsifC (mcPretty_pretty p, decl_node__opaque s);

/*
   noIfElse -
*/

static bool noIfElse (decl_node__opaque n);

/*
   noIfElseChained - returns TRUE if, n, is an IF statement which
                     has no associated ELSE statement.  An IF with an
                     ELSIF is also checked for no ELSE and will result
                     in a return value of TRUE.
*/

static bool noIfElseChained (decl_node__opaque n);

/*
   hasIfElse -
*/

static bool hasIfElse (decl_node__opaque n);

/*
   isIfElse -
*/

static bool isIfElse (decl_node__opaque n);

/*
   hasIfAndNoElse - returns TRUE if statement, n, is a single statement
                    which is an IF and it has no else statement.
*/

static bool hasIfAndNoElse (decl_node__opaque n);

/*
   doIfC - issue an if statement and also place in an after comment if one exists.
           The if statement might contain an else or elsif which are also handled.
*/

static void doIfC (mcPretty_pretty p, decl_node__opaque s);

/*
   doForIncCP -
*/

static void doForIncCP (mcPretty_pretty p, decl_node__opaque s);

/*
   doForIncC -
*/

static void doForIncC (mcPretty_pretty p, decl_node__opaque s);

/*
   doForInc -
*/

static void doForInc (mcPretty_pretty p, decl_node__opaque s);

/*
   doForC -
*/

static void doForC (mcPretty_pretty p, decl_node__opaque s);

/*
   doRepeatC -
*/

static void doRepeatC (mcPretty_pretty p, decl_node__opaque s);

/*
   doWhileC -
*/

static void doWhileC (mcPretty_pretty p, decl_node__opaque s);

/*
   doFuncHighC -
*/

static void doFuncHighC (mcPretty_pretty p, decl_node__opaque a);

/*
   doMultiplyBySize -
*/

static void doMultiplyBySize (mcPretty_pretty p, decl_node__opaque a);

/*
   doTotype -
*/

static void doTotype (mcPretty_pretty p, decl_node__opaque a, decl_node__opaque t);

/*
   doFuncUnbounded -
*/

static void doFuncUnbounded (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formalParam, decl_node__opaque formal, decl_node__opaque func);

/*
   doProcedureParamC -
*/

static void doProcedureParamC (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formal);

/*
   doAdrExprC -
*/

static void doAdrExprC (mcPretty_pretty p, decl_node__opaque n);

/*
   typePair -
*/

static bool typePair (decl_node__opaque a, decl_node__opaque b, decl_node__opaque x, decl_node__opaque y);

/*
   needsCast - return TRUE if the actual type parameter needs to be cast to
               the formal type.
*/

static bool needsCast (decl_node__opaque at, decl_node__opaque ft);

/*
   castDestType - emit the destination type ft
*/

static void castDestType (mcPretty_pretty p, decl_node__opaque formal, decl_node__opaque ft);

/*
   identifyPointer -
*/

static decl_node__opaque identifyPointer (decl_node__opaque type);

/*
   castPointer - provides a six way cast between ADDRESS (ie void * ),
                 char * and const char *.
*/

static unsigned int castPointer (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formal, decl_node__opaque at, decl_node__opaque ft);

/*
   checkSystemCast - checks to see if we are passing to/from
                     a system generic type (WORD, BYTE, ADDRESS)
                     and if so emit a cast.  It returns the number of
                     open parenthesis.
*/

static unsigned int checkSystemCast (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formal);

/*
   emitN -
*/

static void emitN (mcPretty_pretty p, const char *a_, unsigned int _a_high, unsigned int n);

/*
   isForC - return true if node n is a varparam, param or procedure
            which was declared inside a definition module for "C".
*/

static bool isForC (decl_node__opaque n);

/*
   isDefForCNode - return TRUE if node n was declared inside a definition module for "C".
*/

static bool isDefForCNode (decl_node__opaque n);

/*
   doFuncVarParam - detect whether the formal uses an opaque and ensure that the address of
                    the actual parameter is cast to the formal type.
*/

static void doFuncVarParam (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formal);

/*
   doFuncParamC -
*/

static void doFuncParamC (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formal, decl_node__opaque func);

/*
   getNthParamType - return the type of parameter, i, in list, l.
                     If the parameter is a vararg NIL is returned.
*/

static decl_node__opaque getNthParamType (Indexing_Index l, unsigned int i);

/*
   getNthParam - return the parameter, i, in list, l.
                 If the parameter is a vararg NIL is returned.
*/

static decl_node__opaque getNthParam (Indexing_Index l, unsigned int i);

/*
   doFuncArgsC -
*/

static void doFuncArgsC (mcPretty_pretty p, decl_node__opaque s, Indexing_Index l, bool needParen);

/*
   doProcTypeArgsC -
*/

static void doProcTypeArgsC (mcPretty_pretty p, decl_node__opaque s, Indexing_Index args, bool needParen);

/*
   doAdrArgC -
*/

static void doAdrArgC (mcPretty_pretty p, decl_node__opaque n);

/*
   doAdrC -
*/

static void doAdrC (mcPretty_pretty p, decl_node__opaque n);

/*
   doInc -
*/

static void doInc (mcPretty_pretty p, decl_node__opaque n);

/*
   doDec -
*/

static void doDec (mcPretty_pretty p, decl_node__opaque n);

/*
   doIncDecC -
*/

static void doIncDecC (mcPretty_pretty p, decl_node__opaque n, const char *op_, unsigned int _op_high);

/*
   doIncDecCP -
*/

static void doIncDecCP (mcPretty_pretty p, decl_node__opaque n, const char *op_, unsigned int _op_high);

/*
   doInclC -
*/

static void doInclC (mcPretty_pretty p, decl_node__opaque n);

/*
   doExclC -
*/

static void doExclC (mcPretty_pretty p, decl_node__opaque n);

/*
   doNewC -
*/

static void doNewC (mcPretty_pretty p, decl_node__opaque n);

/*
   doDisposeC -
*/

static void doDisposeC (mcPretty_pretty p, decl_node__opaque n);

/*
   doCapC -
*/

static void doCapC (mcPretty_pretty p, decl_node__opaque n);

/*
   doLengthC -
*/

static void doLengthC (mcPretty_pretty p, decl_node__opaque n);

/*
   doAbsC -
*/

static void doAbsC (mcPretty_pretty p, decl_node__opaque n);

/*
   doValC -
*/

static void doValC (mcPretty_pretty p, decl_node__opaque n);

/*
   doMinC -
*/

static void doMinC (mcPretty_pretty p, decl_node__opaque n);

/*
   doMaxC -
*/

static void doMaxC (mcPretty_pretty p, decl_node__opaque n);

/*
   isIntrinsic - returns if, n, is an intrinsic procedure.
                 The intrinsic functions are represented as unary and binary nodes.
*/

static bool isIntrinsic (decl_node__opaque n);

/*
   doHalt -
*/

static void doHalt (mcPretty_pretty p, decl_node__opaque n);

/*
   doCreal - emit the appropriate creal function.
*/

static void doCreal (mcPretty_pretty p, decl_node__opaque t);

/*
   doCimag - emit the appropriate cimag function.
*/

static void doCimag (mcPretty_pretty p, decl_node__opaque t);

/*
   doReC -
*/

static void doReC (mcPretty_pretty p, decl_node__opaque n);

/*
   doImC -
*/

static void doImC (mcPretty_pretty p, decl_node__opaque n);

/*
   doCmplx -
*/

static void doCmplx (mcPretty_pretty p, decl_node__opaque n);

/*
   doIntrinsicC -
*/

static void doIntrinsicC (mcPretty_pretty p, decl_node__opaque n);

/*
   isIntrinsicFunction - returns true if, n, is an instrinsic function.
*/

static bool isIntrinsicFunction (decl_node__opaque n);

/*
   doSizeC -
*/

static void doSizeC (mcPretty_pretty p, decl_node__opaque n);

/*
   doConvertC -
*/

static void doConvertC (mcPretty_pretty p, decl_node__opaque n, const char *conversion_, unsigned int _conversion_high);

/*
   doConvertSC -
*/

static void doConvertSC (mcPretty_pretty p, decl_node__opaque n, DynamicStrings_String conversion);

/*
   getFunction - return the function associate with funccall node n.
*/

static decl_node__opaque getFunction (decl_node__opaque n);

/*
   getFuncFromExpr -
*/

static decl_node__opaque getFuncFromExpr (decl_node__opaque n);

/*
   doFuncExprC -
*/

static void doFuncExprC (mcPretty_pretty p, decl_node__opaque n);

/*
   doFuncCallC -
*/

static void doFuncCallC (mcPretty_pretty p, decl_node__opaque n);

/*
   doCaseStatementC -
*/

static void doCaseStatementC (mcPretty_pretty p, decl_node__opaque n, bool needBreak);

/*
   doExceptionC -
*/

static void doExceptionC (mcPretty_pretty p, const char *a_, unsigned int _a_high, decl_node__opaque n);

/*
   doExceptionCP -
*/

static void doExceptionCP (mcPretty_pretty p, const char *a_, unsigned int _a_high, decl_node__opaque n);

/*
   doException -
*/

static void doException (mcPretty_pretty p, const char *a_, unsigned int _a_high, decl_node__opaque n);

/*
   doRangeListC -
*/

static void doRangeListC (mcPretty_pretty p, decl_node__opaque c);

/*
   doRangeIfListC -
*/

static void doRangeIfListC (mcPretty_pretty p, decl_node__opaque e, decl_node__opaque c);

/*
   doCaseLabels -
*/

static void doCaseLabels (mcPretty_pretty p, decl_node__opaque n, bool needBreak);

/*
   doCaseLabelListC -
*/

static void doCaseLabelListC (mcPretty_pretty p, decl_node__opaque n, bool haveElse);

/*
   doCaseIfLabels -
*/

static void doCaseIfLabels (mcPretty_pretty p, decl_node__opaque e, decl_node__opaque n, unsigned int i, unsigned int h);

/*
   doCaseIfLabelListC -
*/

static void doCaseIfLabelListC (mcPretty_pretty p, decl_node__opaque n);

/*
   doCaseElseC -
*/

static void doCaseElseC (mcPretty_pretty p, decl_node__opaque n);

/*
   doCaseIfElseC -
*/

static void doCaseIfElseC (mcPretty_pretty p, decl_node__opaque n);

/*
   canUseSwitchCaseLabels - returns TRUE if all the case labels are
                            single values and not ranges.
*/

static bool canUseSwitchCaseLabels (decl_node__opaque n);

/*
   canUseSwitch - returns TRUE if the case statement can be implement
                  by a switch statement.  This will be TRUE if all case
                  selectors are single values rather than ranges.
*/

static bool canUseSwitch (decl_node__opaque n);

/*
   doCaseC -
*/

static void doCaseC (mcPretty_pretty p, decl_node__opaque n);

/*
   doLoopC -
*/

static void doLoopC (mcPretty_pretty p, decl_node__opaque s);

/*
   doExitC -
*/

static void doExitC (mcPretty_pretty p, decl_node__opaque s);

/*
   doStatementsC -
*/

static void doStatementsC (mcPretty_pretty p, decl_node__opaque s);
static void localstop (void);

/*
   doLocalVarC -
*/

static void doLocalVarC (mcPretty_pretty p, decl_scopeT s);

/*
   doLocalConstTypesC -
*/

static void doLocalConstTypesC (mcPretty_pretty p, decl_scopeT s);

/*
   addParamDone -
*/

static void addParamDone (decl_node__opaque n);

/*
   includeParameters -
*/

static void includeParameters (decl_node__opaque n);

/*
   isHalt -
*/

static bool isHalt (decl_node__opaque n);

/*
   isReturnOrHalt -
*/

static bool isReturnOrHalt (decl_node__opaque n);

/*
   isLastStatementReturn -
*/

static bool isLastStatementReturn (decl_node__opaque n);

/*
   isLastStatementSequence -
*/

static bool isLastStatementSequence (decl_node__opaque n, decl_isNodeF q);

/*
   isLastStatementIf -
*/

static bool isLastStatementIf (decl_node__opaque n, decl_isNodeF q);

/*
   isLastStatementElsif -
*/

static bool isLastStatementElsif (decl_node__opaque n, decl_isNodeF q);

/*
   isLastStatementCase -
*/

static bool isLastStatementCase (decl_node__opaque n, decl_isNodeF q);

/*
   isLastStatement - returns TRUE if the last statement in, n, is, q.
*/

static bool isLastStatement (decl_node__opaque n, decl_isNodeF q);

/*
   doProcedureC -
*/

static void doProcedureC (decl_node__opaque n);

/*
   outProceduresC -
*/

static void outProceduresC (mcPretty_pretty p, decl_scopeT s);

/*
   output -
*/

static void output (decl_node__opaque n, decl_nodeProcedure c, decl_nodeProcedure t, decl_nodeProcedure v);

/*
   allDependants -
*/

static decl_dependentState allDependants (decl_node__opaque n);

/*
   walkDependants -
*/

static decl_dependentState walkDependants (alists_alist l, decl_node__opaque n);

/*
   walkType -
*/

static decl_dependentState walkType (alists_alist l, decl_node__opaque n);

/*
   db -
*/

static void db (const char *a_, unsigned int _a_high, decl_node__opaque n);

/*
   dbt -
*/

static void dbt (const char *a_, unsigned int _a_high);

/*
   dbs -
*/

static void dbs (decl_dependentState s, decl_node__opaque n);

/*
   dbq -
*/

static void dbq (decl_node__opaque n);

/*
   walkRecord -
*/

static decl_dependentState walkRecord (alists_alist l, decl_node__opaque n);

/*
   walkVarient -
*/

static decl_dependentState walkVarient (alists_alist l, decl_node__opaque n);

/*
   queueBlocked -
*/

static void queueBlocked (decl_node__opaque n);

/*
   walkVar -
*/

static decl_dependentState walkVar (alists_alist l, decl_node__opaque n);

/*
   walkEnumeration -
*/

static decl_dependentState walkEnumeration (alists_alist l, decl_node__opaque n);

/*
   walkSubrange -
*/

static decl_dependentState walkSubrange (alists_alist l, decl_node__opaque n);

/*
   walkSubscript -
*/

static decl_dependentState walkSubscript (alists_alist l, decl_node__opaque n);

/*
   walkPointer -
*/

static decl_dependentState walkPointer (alists_alist l, decl_node__opaque n);

/*
   walkArray -
*/

static decl_dependentState walkArray (alists_alist l, decl_node__opaque n);

/*
   walkConst -
*/

static decl_dependentState walkConst (alists_alist l, decl_node__opaque n);

/*
   walkVarParam -
*/

static decl_dependentState walkVarParam (alists_alist l, decl_node__opaque n);

/*
   walkParam -
*/

static decl_dependentState walkParam (alists_alist l, decl_node__opaque n);

/*
   walkOptarg -
*/

static decl_dependentState walkOptarg (alists_alist l, decl_node__opaque n);

/*
   walkRecordField -
*/

static decl_dependentState walkRecordField (alists_alist l, decl_node__opaque n);

/*
   walkVarientField -
*/

static decl_dependentState walkVarientField (alists_alist l, decl_node__opaque n);

/*
   walkEnumerationField -
*/

static decl_dependentState walkEnumerationField (alists_alist l, decl_node__opaque n);

/*
   walkSet -
*/

static decl_dependentState walkSet (alists_alist l, decl_node__opaque n);

/*
   walkProcType -
*/

static decl_dependentState walkProcType (alists_alist l, decl_node__opaque n);

/*
   walkProcedure -
*/

static decl_dependentState walkProcedure (alists_alist l, decl_node__opaque n);

/*
   walkParameters -
*/

static decl_dependentState walkParameters (alists_alist l, Indexing_Index p);

/*
   walkFuncCall -
*/

static decl_dependentState walkFuncCall (alists_alist l, decl_node__opaque n);

/*
   walkUnary -
*/

static decl_dependentState walkUnary (alists_alist l, decl_node__opaque n);

/*
   walkBinary -
*/

static decl_dependentState walkBinary (alists_alist l, decl_node__opaque n);

/*
   walkComponentRef -
*/

static decl_dependentState walkComponentRef (alists_alist l, decl_node__opaque n);

/*
   walkPointerRef -
*/

static decl_dependentState walkPointerRef (alists_alist l, decl_node__opaque n);

/*
   walkSetValue -
*/

static decl_dependentState walkSetValue (alists_alist l, decl_node__opaque n);

/*
   doDependants - return the dependentState depending upon whether
                  all dependants have been declared.
*/

static decl_dependentState doDependants (alists_alist l, decl_node__opaque n);

/*
   tryComplete - returns TRUE if node, n, can be and was completed.
*/

static bool tryComplete (decl_node__opaque n, decl_nodeProcedure c, decl_nodeProcedure t, decl_nodeProcedure v);

/*
   tryCompleteFromPartial -
*/

static bool tryCompleteFromPartial (decl_node__opaque n, decl_nodeProcedure t);

/*
   visitIntrinsicFunction -
*/

static void visitIntrinsicFunction (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitUnary -
*/

static void visitUnary (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitBinary -
*/

static void visitBinary (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitBoolean -
*/

static void visitBoolean (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitScope -
*/

static void visitScope (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitType -
*/

static void visitType (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitIndex -
*/

static void visitIndex (alists_alist v, Indexing_Index i, decl_nodeProcedure p);

/*
   visitRecord -
*/

static void visitRecord (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitVarient -
*/

static void visitVarient (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitVar -
*/

static void visitVar (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitEnumeration -
*/

static void visitEnumeration (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitSubrange -
*/

static void visitSubrange (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitPointer -
*/

static void visitPointer (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitArray -
*/

static void visitArray (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitConst -
*/

static void visitConst (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitVarParam -
*/

static void visitVarParam (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitParam -
*/

static void visitParam (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitOptarg -
*/

static void visitOptarg (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitRecordField -
*/

static void visitRecordField (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitVarientField -
*/

static void visitVarientField (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitEnumerationField -
*/

static void visitEnumerationField (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitSet -
*/

static void visitSet (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitProcType -
*/

static void visitProcType (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitSubscript -
*/

static void visitSubscript (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitDecls -
*/

static void visitDecls (alists_alist v, decl_scopeT s, decl_nodeProcedure p);

/*
   visitProcedure -
*/

static void visitProcedure (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitDef -
*/

static void visitDef (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitImp -
*/

static void visitImp (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitModule -
*/

static void visitModule (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitLoop -
*/

static void visitLoop (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitWhile -
*/

static void visitWhile (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitRepeat -
*/

static void visitRepeat (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitCase -
*/

static void visitCase (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitCaseLabelList -
*/

static void visitCaseLabelList (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitCaseList -
*/

static void visitCaseList (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitRange -
*/

static void visitRange (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitIf -
*/

static void visitIf (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitElsif -
*/

static void visitElsif (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitFor -
*/

static void visitFor (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitAssignment -
*/

static void visitAssignment (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitComponentRef -
*/

static void visitComponentRef (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitPointerRef -
*/

static void visitPointerRef (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitArrayRef -
*/

static void visitArrayRef (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitFunccall -
*/

static void visitFunccall (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitVarDecl -
*/

static void visitVarDecl (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitExplist -
*/

static void visitExplist (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitExit -
*/

static void visitExit (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitReturn -
*/

static void visitReturn (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitStmtSeq -
*/

static void visitStmtSeq (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitVarargs -
*/

static void visitVarargs (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitSetValue -
*/

static void visitSetValue (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitIntrinsic -
*/

static void visitIntrinsic (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitDependants - helper procedure function called from visitNode.
                     node n has just been visited, this procedure will
                     visit node, n, dependants.
*/

static void visitDependants (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   visitNode - visits node, n, if it is not already in the alist, v.
               It calls p(n) if the node is unvisited.
*/

static void visitNode (alists_alist v, decl_node__opaque n, decl_nodeProcedure p);

/*
   genKind - returns a string depending upon the kind of node, n.
*/

static DynamicStrings_String genKind (decl_node__opaque n);

/*
   gen - generate a small string describing node, n.
*/

static DynamicStrings_String gen (decl_node__opaque n);

/*
   dumpQ -
*/

static void dumpQ (const char *q_, unsigned int _q_high, alists_alist l);

/*
   dumpLists -
*/

static void dumpLists (void);

/*
   outputHidden -
*/

static void outputHidden (decl_node__opaque n);

/*
   outputHiddenComplete -
*/

static void outputHiddenComplete (decl_node__opaque n);

/*
   tryPartial -
*/

static bool tryPartial (decl_node__opaque n, decl_nodeProcedure pt);

/*
   outputPartialRecordArrayProcType -
*/

static void outputPartialRecordArrayProcType (decl_node__opaque n, decl_node__opaque q, unsigned int indirection);

/*
   outputPartial -
*/

static void outputPartial (decl_node__opaque n);

/*
   tryOutputTodo -
*/

static void tryOutputTodo (decl_nodeProcedure c, decl_nodeProcedure t, decl_nodeProcedure v, decl_nodeProcedure pt);

/*
   tryOutputPartial -
*/

static void tryOutputPartial (decl_nodeProcedure t);

/*
   debugList -
*/

static void debugList (const char *listName_, unsigned int _listName_high, const char *symName_, unsigned int _symName_high, alists_alist l);

/*
   debugLists -
*/

static void debugLists (void);

/*
   addEnumConst -
*/

static void addEnumConst (decl_node__opaque n);

/*
   populateTodo -
*/

static void populateTodo (decl_nodeProcedure p);

/*
   topologicallyOut - keep trying to resolve the todoQ and partialQ
                      until there is no change from the global group.
*/

static void topologicallyOut (decl_nodeProcedure c, decl_nodeProcedure t, decl_nodeProcedure v, decl_nodeProcedure tp, decl_nodeProcedure pc, decl_nodeProcedure pt, decl_nodeProcedure pv);

/*
   scaffoldStatic -
*/

static void scaffoldStatic (mcPretty_pretty p, decl_node__opaque n);

/*
   emitCtor -
*/

static void emitCtor (mcPretty_pretty p, decl_node__opaque n);

/*
   scaffoldDynamic -
*/

static void scaffoldDynamic (mcPretty_pretty p, decl_node__opaque n);

/*
   scaffoldMain -
*/

static void scaffoldMain (mcPretty_pretty p, decl_node__opaque n);

/*
   outImpInitC - emit the init/fini functions and main function if required.
*/

static void outImpInitC (mcPretty_pretty p, decl_node__opaque n);

/*
   runSimplifyTypes -
*/

static void runSimplifyTypes (decl_node__opaque n);

/*
   outDefC -
*/

static void outDefC (mcPretty_pretty p, decl_node__opaque n);

/*
   runPrototypeExported -
*/

static void runPrototypeExported (decl_node__opaque n);

/*
   runPrototypeDefC -
*/

static void runPrototypeDefC (decl_node__opaque n);

/*
   outImpC -
*/

static void outImpC (mcPretty_pretty p, decl_node__opaque n);

/*
   outDeclsModuleC -
*/

static void outDeclsModuleC (mcPretty_pretty p, decl_scopeT s);

/*
   outModuleInitC -
*/

static void outModuleInitC (mcPretty_pretty p, decl_node__opaque n);

/*
   outModuleC -
*/

static void outModuleC (mcPretty_pretty p, decl_node__opaque n);

/*
   outC -
*/

static void outC (mcPretty_pretty p, decl_node__opaque n);

/*
   doIncludeM2 - include modules in module, n.
*/

static void doIncludeM2 (decl_node__opaque n);

/*
   doConstM2 -
*/

static void doConstM2 (decl_node__opaque n);

/*
   doProcTypeM2 -
*/

static void doProcTypeM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doRecordFieldM2 -
*/

static void doRecordFieldM2 (mcPretty_pretty p, decl_node__opaque f);

/*
   doVarientFieldM2 -
*/

static void doVarientFieldM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doVarientM2 -
*/

static void doVarientM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doRecordM2 -
*/

static void doRecordM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doPointerM2 -
*/

static void doPointerM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doTypeAliasM2 -
*/

static void doTypeAliasM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doEnumerationM2 -
*/

static void doEnumerationM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doBaseM2 -
*/

static void doBaseM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doSystemM2 -
*/

static void doSystemM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doTypeM2 -
*/

static void doTypeM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doTypesM2 -
*/

static void doTypesM2 (decl_node__opaque n);

/*
   doVarM2 -
*/

static void doVarM2 (decl_node__opaque n);

/*
   doVarsM2 -
*/

static void doVarsM2 (decl_node__opaque n);

/*
   doTypeNameM2 -
*/

static void doTypeNameM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doParamM2 -
*/

static void doParamM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doVarParamM2 -
*/

static void doVarParamM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doParameterM2 -
*/

static void doParameterM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   doPrototypeM2 -
*/

static void doPrototypeM2 (decl_node__opaque n);

/*
   outputPartialM2 - just writes out record, array, and proctypes.
                     No need for forward declarations in Modula-2
                     but we need to keep topological sort happy.
                     So when asked to output partial we emit the
                     full type for these types and then do nothing
                     when trying to complete partial to full.
*/

static void outputPartialM2 (decl_node__opaque n);

/*
   outDeclsDefM2 -
*/

static void outDeclsDefM2 (mcPretty_pretty p, decl_scopeT s);

/*
   outDefM2 -
*/

static void outDefM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   outDeclsImpM2 -
*/

static void outDeclsImpM2 (mcPretty_pretty p, decl_scopeT s);

/*
   outImpM2 -
*/

static void outImpM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   outModuleM2 -
*/

static void outModuleM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   outM2 -
*/

static void outM2 (mcPretty_pretty p, decl_node__opaque n);

/*
   addDone - adds node, n, to the doneQ.
*/

static void addDone (decl_node__opaque n);

/*
   addDoneDef - adds node, n, to the doneQ providing
                it is not an opaque of the main module we are compiling.
*/

static void addDoneDef (decl_node__opaque n);

/*
   dbgAdd -
*/

static decl_node__opaque dbgAdd (alists_alist l, decl_node__opaque n);

/*
   dbgType -
*/

static void dbgType (alists_alist l, decl_node__opaque n);

/*
   dbgPointer -
*/

static void dbgPointer (alists_alist l, decl_node__opaque n);

/*
   dbgRecord -
*/

static void dbgRecord (alists_alist l, decl_node__opaque n);

/*
   dbgVarient -
*/

static void dbgVarient (alists_alist l, decl_node__opaque n);

/*
   dbgEnumeration -
*/

static void dbgEnumeration (alists_alist l, decl_node__opaque n);

/*
   dbgVar -
*/

static void dbgVar (alists_alist l, decl_node__opaque n);

/*
   dbgSubrange -
*/

static void dbgSubrange (alists_alist l, decl_node__opaque n);

/*
   dbgArray -
*/

static void dbgArray (alists_alist l, decl_node__opaque n);

/*
   doDbg -
*/

static void doDbg (alists_alist l, decl_node__opaque n);

/*
   dbg -
*/

static void dbg (const char *listName_, unsigned int _listName_high, const char *symName_, unsigned int _symName_high, decl_node__opaque n);

/*
   addGenericBody - adds comment node to funccall, return, assignment
                    nodes.
*/

static void addGenericBody (decl_node__opaque n, decl_node__opaque c);

/*
   addGenericAfter - adds comment node to funccall, return, assignment
                     nodes.
*/

static void addGenericAfter (decl_node__opaque n, decl_node__opaque c);

/*
   isAssignment -
*/

static bool isAssignment (decl_node__opaque n);

/*
   isComment - returns TRUE if node, n, is a comment.
*/

static bool isComment (decl_node__opaque n);

/*
   initPair - initialise the commentPair, c.
*/

static void initPair (decl_commentPair *c);

/*
   dupExplist -
*/

static decl_node__opaque dupExplist (decl_node__opaque n);

/*
   dupArrayref -
*/

static decl_node__opaque dupArrayref (decl_node__opaque n);

/*
   dupPointerref -
*/

static decl_node__opaque dupPointerref (decl_node__opaque n);

/*
   dupComponentref -
*/

static decl_node__opaque dupComponentref (decl_node__opaque n);

/*
   dupBinary -
*/

static decl_node__opaque dupBinary (decl_node__opaque n);

/*
   dupUnary -
*/

static decl_node__opaque dupUnary (decl_node__opaque n);

/*
   dupFunccall -
*/

static decl_node__opaque dupFunccall (decl_node__opaque n);

/*
   dupSetValue -
*/

static decl_node__opaque dupSetValue (decl_node__opaque n);

/*
   doDupExpr -
*/

static decl_node__opaque doDupExpr (decl_node__opaque n);

/*
   makeSystem -
*/

static void makeSystem (void);

/*
   makeM2rts -
*/

static void makeM2rts (void);

/*
   makeBitnum -
*/

static decl_node__opaque makeBitnum (void);

/*
   makeBaseSymbols -
*/

static void makeBaseSymbols (void);

/*
   makeBuiltins -
*/

static void makeBuiltins (void);

/*
   makeCDataTypes - assign the charStarN and constCharStarN to NIL.
*/

static void makeCDataTypes (void);

/*
   init -
*/

static void init (void);


/*
   newNode - create and return a new node of kind k.
*/

static decl_node__opaque newNode (decl_nodeT k)
{
  decl_node__opaque d;

  Storage_ALLOCATE ((void **) &d, sizeof (decl_nodeRec));
  if (enableMemsetOnAllocation)
    {
      d = static_cast<decl_node__opaque> (libc_memset (reinterpret_cast <void *> (d), 0, static_cast<size_t> (sizeof ((*d)))));
    }
  if (d == NULL)
    {
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  else
    {
      d->kind = k;
      d->at.defDeclared = 0;
      d->at.modDeclared = 0;
      d->at.firstUsed = 0;
      return d;
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   disposeNode - dispose node, n.
*/

static void disposeNode (decl_node__opaque *n)
{
  Storage_DEALLOCATE ((void **) &(*n), sizeof (decl_nodeRec));
  (*n) = static_cast<decl_node__opaque> (NULL);
}


/*
   newGroup -
*/

static void newGroup (decl_group *g)
{
  if (freeGroup == NULL)
    {
      Storage_ALLOCATE ((void **) &(*g), sizeof (decl__T1));
    }
  else
    {
      (*g) = freeGroup;
      freeGroup = freeGroup->next;
    }
}


/*
   initGroup - returns a group which with all lists initialized.
*/

static decl_group initGroup (void)
{
  decl_group g;

  newGroup (&g);
  g->todoQ = alists_initList ();
  g->partialQ = alists_initList ();
  g->doneQ = alists_initList ();
  g->next = NULL;
  return g;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   killGroup - deallocate the group and place the group record into the freeGroup list.
*/

static void killGroup (decl_group *g)
{
  alists_killList (&(*g)->todoQ);
  alists_killList (&(*g)->partialQ);
  alists_killList (&(*g)->doneQ);
  (*g)->next = freeGroup;
  freeGroup = (*g);
}


/*
   dupGroup - If g is not NIL then destroy g.
              Return a duplicate of GlobalGroup (not g).
*/

static decl_group dupGroup (decl_group g)
{
  if (g != NULL)
    {
      /* Kill old group.  */
      killGroup (&g);
    }
  newGroup (&g);
  /* Copy all lists.  */
  g->todoQ = alists_duplicateList (globalGroup->todoQ);
  g->partialQ = alists_duplicateList (globalGroup->partialQ);
  g->doneQ = alists_duplicateList (globalGroup->doneQ);
  g->next = NULL;
  return g;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   equalGroup - return TRUE if group left = right.
*/

static bool equalGroup (decl_group left, decl_group right)
{
  return (left == right) || (((alists_equalList (left->todoQ, right->todoQ)) && (alists_equalList (left->partialQ, right->partialQ))) && (alists_equalList (left->doneQ, right->doneQ)));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLocal - returns TRUE if symbol, n, is locally declared in a procedure.
*/

static bool isLocal (decl_node__opaque n)
{
  decl_node__opaque s;

  s = static_cast<decl_node__opaque> (decl_getScope (static_cast<decl_node> (n)));
  if (s != NULL)
    {
      return decl_isProcedure (static_cast<decl_node> (s));
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   importEnumFields - if, n, is an enumeration type import the all fields into module, m.
*/

static void importEnumFields (decl_node__opaque m, decl_node__opaque n)
{
  decl_node__opaque r;
  decl_node__opaque e;
  unsigned int i;
  unsigned int h;

  mcDebug_assert (((decl_isDef (static_cast<decl_node> (m))) || (decl_isModule (static_cast<decl_node> (m)))) || (decl_isImp (static_cast<decl_node> (m))));
  n = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (n)));
  if ((n != NULL) && (decl_isEnumeration (static_cast<decl_node> (n))))
    {
      i = Indexing_LowIndice (n->enumerationF.listOfSons);
      h = Indexing_HighIndice (n->enumerationF.listOfSons);
      while (i <= h)
        {
          e = static_cast<decl_node__opaque> (Indexing_GetIndice (n->enumerationF.listOfSons, i));
          r = static_cast<decl_node__opaque> (decl_import (static_cast<decl_node> (m), static_cast<decl_node> (e)));
          if (e != r)
            {
              mcMetaError_metaError2 ((const char *) "enumeration field {%1ad} cannot be imported implicitly into {%2d} due to a name clash", 85, (const unsigned char *) &e, (sizeof (e)-1), (const unsigned char *) &m, (sizeof (m)-1));
            }
          i += 1;
        }
    }
}


/*
   checkGccType - check to see if node n is gcc tree or location_t
                  and record its use in keyc.
*/

static void checkGccType (decl_node__opaque n)
{
  if (((mcOptions_getGccConfigSystem ()) && ((decl_getScope (static_cast<decl_node> (n))) != NULL)) && ((decl_getSymName (decl_getScope (static_cast<decl_node> (n)))) == (nameKey_makeKey ((const char *) "gcctypes", 8))))
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if ((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "location_t", 10)))
        {
          keyc_useGccLocation ();
        }
      else if ((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "tree", 4)))
        {
          /* avoid dangling else.  */
          keyc_useGccTree ();
        }
    }
}


/*
   checkCDataTypes - check to see if node n is CharStar or ConstCharStar
                  and if necessary assign n to the global variable.
*/

static void checkCDataTypes (decl_node__opaque n)
{
  if (((decl_getScope (static_cast<decl_node> (n))) != NULL) && ((decl_getSymName (decl_getScope (static_cast<decl_node> (n)))) == (nameKey_makeKey ((const char *) "CDataTypes", 10))))
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if ((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "CharStar", 8)))
        {
          charStarN = n;
        }
      else if ((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "ConstCharStar", 13)))
        {
          /* avoid dangling else.  */
          constCharStarN = n;
        }
    }
}


/*
   isComplex - returns TRUE if, n, is the complex type.
*/

static bool isComplex (decl_node__opaque n)
{
  return n == complexN;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLongComplex - returns TRUE if, n, is the longcomplex type.
*/

static bool isLongComplex (decl_node__opaque n)
{
  return n == longcomplexN;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isShortComplex - returns TRUE if, n, is the shortcomplex type.
*/

static bool isShortComplex (decl_node__opaque n)
{
  return n == shortcomplexN;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isAProcType - returns TRUE if, n, is a proctype or proc node.
*/

static bool isAProcType (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  return (decl_isProcType (static_cast<decl_node> (n))) || (n == procN);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   initFixupInfo - initialize the fixupInfo record.
*/

static decl_fixupInfo initFixupInfo (void)
{
  decl_fixupInfo f;

  f.count = 0;
  f.info = Indexing_InitIndex (1);
  return f;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeDef - returns a definition module node named, n.
*/

static decl_node__opaque makeDef (nameKey_Name n)
{
  decl_node__opaque d;

  d = newNode (decl_def);
  d->defF.name = n;
  d->defF.source = nameKey_NulName;
  d->defF.hasHidden = false;
  d->defF.forC = false;
  d->defF.unqualified = false;
  d->defF.exported = Indexing_InitIndex (1);
  d->defF.importedModules = Indexing_InitIndex (1);
  d->defF.constFixup = initFixupInfo ();
  d->defF.enumFixup = initFixupInfo ();
  initDecls (&d->defF.decls);
  d->defF.enumsComplete = false;
  d->defF.constsComplete = false;
  d->defF.visited = false;
  initPair (&d->defF.com);
  return d;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeImp - returns an implementation module node named, n.
*/

static decl_node__opaque makeImp (nameKey_Name n)
{
  decl_node__opaque d;

  d = newNode (decl_imp);
  d->impF.name = n;
  d->impF.source = nameKey_NulName;
  d->impF.importedModules = Indexing_InitIndex (1);
  d->impF.constFixup = initFixupInfo ();
  d->impF.enumFixup = initFixupInfo ();
  initDecls (&d->impF.decls);
  d->impF.beginStatements = static_cast<decl_node__opaque> (NULL);
  d->impF.finallyStatements = static_cast<decl_node__opaque> (NULL);
  d->impF.definitionModule = static_cast<decl_node__opaque> (NULL);
  d->impF.enumsComplete = false;
  d->impF.constsComplete = false;
  d->impF.visited = false;
  initPair (&d->impF.com);
  return d;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeModule - returns a module node named, n.
*/

static decl_node__opaque makeModule (nameKey_Name n)
{
  decl_node__opaque d;

  d = newNode (decl_module);
  d->moduleF.name = n;
  d->moduleF.source = nameKey_NulName;
  d->moduleF.importedModules = Indexing_InitIndex (1);
  d->moduleF.constFixup = initFixupInfo ();
  d->moduleF.enumFixup = initFixupInfo ();
  initDecls (&d->moduleF.decls);
  d->moduleF.beginStatements = static_cast<decl_node__opaque> (NULL);
  d->moduleF.finallyStatements = static_cast<decl_node__opaque> (NULL);
  d->moduleF.enumsComplete = false;
  d->moduleF.constsComplete = false;
  d->moduleF.visited = false;
  initPair (&d->moduleF.com);
  return d;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isDefForC - returns TRUE if the definition module was defined FOR "C".
*/

static bool isDefForC (decl_node__opaque n)
{
  return (decl_isDef (static_cast<decl_node> (n))) && n->defF.forC;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   initDecls - initialize the decls, scopeT.
*/

static void initDecls (decl_scopeT *decls)
{
  (*decls).symbols = symbolKey_initTree ();
  (*decls).constants = Indexing_InitIndex (1);
  (*decls).types = Indexing_InitIndex (1);
  (*decls).procedures = Indexing_InitIndex (1);
  (*decls).variables = Indexing_InitIndex (1);
}


/*
   addTo - adds node, d, to scope decls and returns, d.
           It stores, d, in the symbols tree associated with decls.
*/

static decl_node__opaque addTo (decl_scopeT *decls, decl_node__opaque d)
{
  nameKey_Name n;

  n = decl_getSymName (static_cast<decl_node> (d));
  if (n != nameKey_NulName)
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if ((symbolKey_getSymKey ((*decls).symbols, n)) == NULL)
        {
          symbolKey_putSymKey ((*decls).symbols, n, reinterpret_cast <void *> (d));
        }
      else
        {
          mcMetaError_metaError1 ((const char *) "{%1DMad} was declared", 21, (const unsigned char *) &d, (sizeof (d)-1));
          mcMetaError_metaError1 ((const char *) "{%1k} and is being declared again", 33, (const unsigned char *) &n, (sizeof (n)-1));
        }
    }
  if (decl_isConst (static_cast<decl_node> (d)))
    {
      Indexing_IncludeIndiceIntoIndex ((*decls).constants, reinterpret_cast <void *> (d));
    }
  else if (decl_isVar (static_cast<decl_node> (d)))
    {
      /* avoid dangling else.  */
      Indexing_IncludeIndiceIntoIndex ((*decls).variables, reinterpret_cast <void *> (d));
    }
  else if (decl_isType (static_cast<decl_node> (d)))
    {
      /* avoid dangling else.  */
      Indexing_IncludeIndiceIntoIndex ((*decls).types, reinterpret_cast <void *> (d));
    }
  else if (decl_isProcedure (static_cast<decl_node> (d)))
    {
      /* avoid dangling else.  */
      Indexing_IncludeIndiceIntoIndex ((*decls).procedures, reinterpret_cast <void *> (d));
      if (debugDecl)
        {
          libc_printf ((const char *) "%d procedures on the dynamic array\\n", 36, Indexing_HighIndice ((*decls).procedures));
        }
    }
  return d;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   export - export node, n, from definition module, d.
*/

static void export_ (decl_node__opaque d, decl_node__opaque n)
{
  mcDebug_assert (decl_isDef (static_cast<decl_node> (d)));
  Indexing_IncludeIndiceIntoIndex (d->defF.exported, reinterpret_cast <void *> (n));
}


/*
   addToScope - adds node, n, to the current scope and returns, n.
*/

static decl_node__opaque addToScope (decl_node__opaque n)
{
  decl_node__opaque s;
  unsigned int i;

  i = Indexing_HighIndice (scopeStack);
  s = static_cast<decl_node__opaque> (Indexing_GetIndice (scopeStack, i));
  if (decl_isProcedure (static_cast<decl_node> (s)))
    {
      if (debugDecl)
        {
          outText (doP, (const char *) "adding ", 7);
          doNameC (doP, n);
          outText (doP, (const char *) " to procedure\\n", 15);
        }
      return addTo (&s->procedureF.decls, n);
    }
  else if (decl_isModule (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      if (debugDecl)
        {
          outText (doP, (const char *) "adding ", 7);
          doNameC (doP, n);
          outText (doP, (const char *) " to module\\n", 12);
        }
      return addTo (&s->moduleF.decls, n);
    }
  else if (decl_isDef (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      if (debugDecl)
        {
          outText (doP, (const char *) "adding ", 7);
          doNameC (doP, n);
          outText (doP, (const char *) " to definition module\\n", 23);
        }
      export_ (s, n);
      return addTo (&s->defF.decls, n);
    }
  else if (decl_isImp (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      if (debugDecl)
        {
          outText (doP, (const char *) "adding ", 7);
          doNameC (doP, n);
          outText (doP, (const char *) " to implementation module\\n", 27);
        }
      return addTo (&s->impF.decls, n);
    }
  M2RTS_HALT (-1);
  __builtin_unreachable ();
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   addModuleToScope - adds module, i, to module, m, scope.
*/

static void addModuleToScope (decl_node__opaque m, decl_node__opaque i)
{
  mcDebug_assert ((decl_getDeclScope ()) == m);
  if ((decl_lookupSym (decl_getSymName (static_cast<decl_node> (i)))) == NULL)
    {
      i = addToScope (i);
    }
}


/*
   completedEnum - assign boolean enumsComplete to TRUE if a definition,
                   implementation or module symbol.
*/

static void completedEnum (decl_node__opaque n)
{
  mcDebug_assert (((decl_isDef (static_cast<decl_node> (n))) || (decl_isImp (static_cast<decl_node> (n)))) || (decl_isModule (static_cast<decl_node> (n))));
  if (decl_isDef (static_cast<decl_node> (n)))
    {
      n->defF.enumsComplete = true;
    }
  else if (decl_isImp (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      n->impF.enumsComplete = true;
    }
  else if (decl_isModule (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      n->moduleF.enumsComplete = true;
    }
}


/*
   setUnary - sets a unary node to contain, arg, a, and type, t.
*/

static void setUnary (decl_node__opaque u, decl_nodeT k, decl_node__opaque a, decl_node__opaque t)
{
  switch (k)
    {
      case decl_constexp:
      case decl_deref:
      case decl_chr:
      case decl_cap:
      case decl_abs:
      case decl_float:
      case decl_trunc:
      case decl_ord:
      case decl_high:
      case decl_throw:
      case decl_re:
      case decl_im:
      case decl_not:
      case decl_neg:
      case decl_adr:
      case decl_size:
      case decl_tsize:
      case decl_min:
      case decl_max:
        u->kind = k;
        u->unaryF.arg = a;
        u->unaryF.resultType = t;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   putVarBool - assigns the four booleans associated with a variable.
*/

static void putVarBool (decl_node__opaque v, bool init, bool param, bool isvar, bool isused)
{
  mcDebug_assert (decl_isVar (static_cast<decl_node> (v)));
  v->varF.isInitialised = init;
  v->varF.isParameter = param;
  v->varF.isVarParameter = isvar;
  v->varF.isUsed = isused;
}


/*
   checkPtr - in C++ we need to create a typedef for a pointer
              in case we need to use reinterpret_cast.
*/

static decl_node__opaque checkPtr (decl_node__opaque n)
{
  DynamicStrings_String s;
  decl_node__opaque p;

  if (lang == decl_ansiCP)
    {
      if (decl_isPointer (static_cast<decl_node> (n)))
        {
          s = tempName ();
          p = static_cast<decl_node__opaque> (decl_makeType (nameKey_makekey (DynamicStrings_string (s))));
          decl_putType (static_cast<decl_node> (p), static_cast<decl_node> (n));
          s = DynamicStrings_KillString (s);
          return p;
        }
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isVarDecl - returns TRUE if, n, is a vardecl node.
*/

static bool isVarDecl (decl_node__opaque n)
{
  return n->kind == decl_vardecl;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeVariablesFromParameters - creates variables which are really parameters.
*/

static void makeVariablesFromParameters (decl_node__opaque proc, decl_node__opaque id, decl_node__opaque type, bool isvar, bool isused)
{
  decl_node__opaque v;
  unsigned int i;
  unsigned int n;
  nameKey_Name m;
  DynamicStrings_String s;

  mcDebug_assert (decl_isProcedure (static_cast<decl_node> (proc)));
  mcDebug_assert (isIdentList (id));
  i = 1;
  n = wlists_noOfItemsInList (id->identlistF.names);
  while (i <= n)
    {
      m = static_cast<nameKey_Name> (wlists_getItemFromList (id->identlistF.names, i));
      v = static_cast<decl_node__opaque> (decl_makeVar (m));
      decl_putVar (static_cast<decl_node> (v), static_cast<decl_node> (type), static_cast<decl_node> (NULL));
      putVarBool (v, true, true, isvar, isused);
      if (debugScopes)
        {
          libc_printf ((const char *) "adding parameter variable into top scope\\n", 42);
          dumpScopes ();
          libc_printf ((const char *) " variable name is: ", 19);
          s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (m));
          if ((DynamicStrings_KillString (SFIO_WriteS (FIO_StdOut, s))) == NULL)
            {}  /* empty.  */
          libc_printf ((const char *) "\\n", 2);
        }
      i += 1;
    }
}


/*
   addProcedureToScope - add a procedure name n and node d to the
                         current scope.
*/

static decl_node__opaque addProcedureToScope (decl_node__opaque d, nameKey_Name n)
{
  decl_node__opaque m;
  unsigned int i;

  i = Indexing_HighIndice (scopeStack);
  m = static_cast<decl_node__opaque> (Indexing_GetIndice (scopeStack, i));
  if (((decl_isDef (static_cast<decl_node> (m))) && ((decl_getSymName (static_cast<decl_node> (m))) == (nameKey_makeKey ((const char *) "M2RTS", 5)))) && ((decl_getSymName (static_cast<decl_node> (d))) == (nameKey_makeKey ((const char *) "HALT", 4))))
    {
      haltN = d;
      symbolKey_putSymKey (baseSymbols, n, reinterpret_cast <void *> (haltN));
    }
  return addToScope (d);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putProcTypeReturn - sets the return type of, proc, to, type.
*/

static void putProcTypeReturn (decl_node__opaque proc, decl_node__opaque type)
{
  mcDebug_assert (decl_isProcType (static_cast<decl_node> (proc)));
  proc->proctypeF.returnType = type;
  initNodeOpaqueState (proc);
}


/*
   putProcTypeOptReturn - sets, proc, to have an optional return type.
*/

static void putProcTypeOptReturn (decl_node__opaque proc)
{
  mcDebug_assert (decl_isProcType (static_cast<decl_node> (proc)));
  proc->proctypeF.returnopt = true;
}


/*
   makeOptParameter - creates and returns an optarg.
*/

static decl_node__opaque makeOptParameter (decl_node__opaque l, decl_node__opaque type, decl_node__opaque init)
{
  decl_node__opaque n;

  n = newNode (decl_optarg);
  n->optargF.namelist = l;
  n->optargF.type = type;
  n->optargF.init = init;
  n->optargF.scope = static_cast<decl_node__opaque> (NULL);
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   setwatch - assign the globalNode to n.
*/

static bool setwatch (decl_node__opaque n)
{
  globalNode = n;
  return true;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   runwatch - set the globalNode to an identlist.
*/

static bool runwatch (void)
{
  return globalNode->kind == decl_identlist;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isIdentList - returns TRUE if, n, is an identlist.
*/

static bool isIdentList (decl_node__opaque n)
{
  return n->kind == decl_identlist;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   identListLen - returns the length of identlist.
*/

static unsigned int identListLen (decl_node__opaque n)
{
  if (n == NULL)
    {
      return 0;
    }
  else
    {
      mcDebug_assert (isIdentList (n));
      return wlists_noOfItemsInList (n->identlistF.names);
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   checkParameters - placeholder for future parameter checking.
*/

static void checkParameters (decl_node__opaque p, decl_node__opaque i, decl_node__opaque type, bool isvar, bool isused)
{
  /* do check.  */
  disposeNode (&i);
}


/*
   checkMakeVariables - create shadow local variables for parameters providing that
                        procedure n has not already been built and we are compiling
                        a module or an implementation module.
*/

static void checkMakeVariables (decl_node__opaque n, decl_node__opaque i, decl_node__opaque type, bool isvar, bool isused)
{
  if (((decl_isImp (static_cast<decl_node> (currentModule))) || (decl_isModule (static_cast<decl_node> (currentModule)))) && ! n->procedureF.built)
    {
      makeVariablesFromParameters (n, i, type, isvar, isused);
    }
}


/*
   makeVarientField - create a varient field within varient, v,
                      The new varient field is returned.
*/

static decl_node__opaque makeVarientField (decl_node__opaque v, decl_node__opaque p)
{
  decl_node__opaque n;

  n = newNode (decl_varientfield);
  n->varientfieldF.name = nameKey_NulName;
  n->varientfieldF.parent = p;
  n->varientfieldF.varient = v;
  n->varientfieldF.simple = false;
  n->varientfieldF.listOfSons = Indexing_InitIndex (1);
  n->varientfieldF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putFieldVarient - places the field varient, f, as a brother to, the
                     varient symbol, v, and also tells, f, that its varient
                     parent is, v.
*/

static void putFieldVarient (decl_node__opaque f, decl_node__opaque v)
{
  mcDebug_assert (decl_isVarient (static_cast<decl_node> (v)));
  mcDebug_assert (decl_isVarientField (static_cast<decl_node> (f)));
  switch (v->kind)
    {
      case decl_varient:
        Indexing_IncludeIndiceIntoIndex (v->varientF.listOfSons, reinterpret_cast <void *> (f));
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  switch (f->kind)
    {
      case decl_varientfield:
        f->varientfieldF.varient = v;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   putFieldRecord - create a new recordfield and place it into record r.
                    The new field has a tagname and type and can have a
                    variant field v.
*/

static decl_node__opaque putFieldRecord (decl_node__opaque r, nameKey_Name tag, decl_node__opaque type, decl_node__opaque v)
{
  decl_node__opaque f;
  decl_node__opaque n;
  decl_node__opaque p;

  n = newNode (decl_recordfield);
  switch (r->kind)
    {
      case decl_record:
        Indexing_IncludeIndiceIntoIndex (r->recordF.listOfSons, reinterpret_cast <void *> (n));
        /* ensure that field, n, is in the parents Local Symbols.  */
        if (tag != nameKey_NulName)
          {
            /* avoid gcc warning by using compound statement even if not strictly necessary.  */
            if ((symbolKey_getSymKey (r->recordF.localSymbols, tag)) == symbolKey_NulKey)
              {
                symbolKey_putSymKey (r->recordF.localSymbols, tag, reinterpret_cast <void *> (n));
              }
            else
              {
                f = static_cast<decl_node__opaque> (symbolKey_getSymKey (r->recordF.localSymbols, tag));
                mcMetaError_metaErrors1 ((const char *) "field record {%1Dad} has already been declared", 46, (const char *) "field record duplicate", 22, (const unsigned char *) &f, (sizeof (f)-1));
              }
          }
        break;

      case decl_varientfield:
        Indexing_IncludeIndiceIntoIndex (r->varientfieldF.listOfSons, reinterpret_cast <void *> (n));
        p = getParent (r);
        mcDebug_assert (p->kind == decl_record);
        if (tag != nameKey_NulName)
          {
            symbolKey_putSymKey (p->recordF.localSymbols, tag, reinterpret_cast <void *> (n));
          }
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  /* fill in, n.  */
  n->recordfieldF.type = type;
  n->recordfieldF.name = tag;
  n->recordfieldF.parent = r;
  n->recordfieldF.varient = v;
  n->recordfieldF.tag = false;
  n->recordfieldF.scope = static_cast<decl_node__opaque> (NULL);
  initCname (&n->recordfieldF.cname);
  /*
   IF r^.kind=record
   THEN
      doRecordM2 (doP, r)
   END ;
  */
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   ensureOrder - ensures that, a, and, b, exist in, i, and also
                 ensure that, a, is before, b.
*/

static void ensureOrder (Indexing_Index i, decl_node__opaque a, decl_node__opaque b)
{
  mcDebug_assert (Indexing_IsIndiceInIndex (i, reinterpret_cast <void *> (a)));
  mcDebug_assert (Indexing_IsIndiceInIndex (i, reinterpret_cast <void *> (b)));
  Indexing_RemoveIndiceFromIndex (i, reinterpret_cast <void *> (a));
  Indexing_RemoveIndiceFromIndex (i, reinterpret_cast <void *> (b));
  Indexing_IncludeIndiceIntoIndex (i, reinterpret_cast <void *> (a));
  Indexing_IncludeIndiceIntoIndex (i, reinterpret_cast <void *> (b));
  mcDebug_assert (Indexing_IsIndiceInIndex (i, reinterpret_cast <void *> (a)));
  mcDebug_assert (Indexing_IsIndiceInIndex (i, reinterpret_cast <void *> (b)));
}


/*
   putVarientTag - places tag into variant v.
*/

static void putVarientTag (decl_node__opaque v, decl_node__opaque tag)
{
  decl_node__opaque p;

  mcDebug_assert (decl_isVarient (static_cast<decl_node> (v)));
  switch (v->kind)
    {
      case decl_varient:
        v->varientF.tag = tag;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   getParent - returns the parent field of recordfield or varientfield symbol, n.
*/

static decl_node__opaque getParent (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_recordfield:
        return n->recordfieldF.parent;
        break;

      case decl_varientfield:
        return n->varientfieldF.parent;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getRecord - returns the record associated with node, n.
               (Parental record).
*/

static decl_node__opaque getRecord (decl_node__opaque n)
{
  mcDebug_assert (n->kind != decl_varient);  /* if this fails then we need to add parent field to varient.  */
  switch (n->kind)
    {
      case decl_record:
        return n;  /* if this fails then we need to add parent field to varient.  */
        break;

      case decl_varientfield:
        return getRecord (getParent (n));
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isConstExp - return TRUE if the node kind is a constexp.
*/

static bool isConstExp (decl_node__opaque c)
{
  mcDebug_assert (c != NULL);
  return c->kind == decl_constexp;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   addEnumToModule - adds enumeration type, e, into the list of enums
                     in module, m.
*/

static void addEnumToModule (decl_node__opaque m, decl_node__opaque e)
{
  mcDebug_assert ((decl_isEnumeration (static_cast<decl_node> (e))) || (decl_isEnumerationField (static_cast<decl_node> (e))));
  mcDebug_assert (((decl_isModule (static_cast<decl_node> (m))) || (decl_isDef (static_cast<decl_node> (m)))) || (decl_isImp (static_cast<decl_node> (m))));
  if (decl_isModule (static_cast<decl_node> (m)))
    {
      Indexing_IncludeIndiceIntoIndex (m->moduleF.enumFixup.info, reinterpret_cast <void *> (e));
    }
  else if (decl_isDef (static_cast<decl_node> (m)))
    {
      /* avoid dangling else.  */
      Indexing_IncludeIndiceIntoIndex (m->defF.enumFixup.info, reinterpret_cast <void *> (e));
    }
  else if (decl_isImp (static_cast<decl_node> (m)))
    {
      /* avoid dangling else.  */
      Indexing_IncludeIndiceIntoIndex (m->impF.enumFixup.info, reinterpret_cast <void *> (e));
    }
}


/*
   getNextFixup - return the next fixup from from f.
*/

static decl_node__opaque getNextFixup (decl_fixupInfo *f)
{
  (*f).count += 1;
  return static_cast<decl_node__opaque> (Indexing_GetIndice ((*f).info, (*f).count));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doMakeEnum - create an enumeration type and add it to the current module.
*/

static decl_node__opaque doMakeEnum (void)
{
  decl_node__opaque e;

  e = newNode (decl_enumeration);
  e->enumerationF.noOfElements = 0;
  e->enumerationF.localSymbols = symbolKey_initTree ();
  e->enumerationF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  e->enumerationF.listOfSons = Indexing_InitIndex (1);
  e->enumerationF.low = static_cast<decl_node__opaque> (NULL);
  e->enumerationF.high = static_cast<decl_node__opaque> (NULL);
  addEnumToModule (currentModule, e);
  return e;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doMakeEnumField - create an enumeration field name and add it to enumeration e.
                     Return the new field.
*/

static decl_node__opaque doMakeEnumField (decl_node__opaque e, nameKey_Name n)
{
  decl_node__opaque f;

  mcDebug_assert (decl_isEnumeration (static_cast<decl_node> (e)));
  f = static_cast<decl_node__opaque> (decl_lookupSym (n));
  if (f == NULL)
    {
      f = newNode (decl_enumerationfield);
      symbolKey_putSymKey (e->enumerationF.localSymbols, n, reinterpret_cast <void *> (f));
      Indexing_IncludeIndiceIntoIndex (e->enumerationF.listOfSons, reinterpret_cast <void *> (f));
      f->enumerationfieldF.name = n;
      f->enumerationfieldF.type = e;
      f->enumerationfieldF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
      f->enumerationfieldF.value = e->enumerationF.noOfElements;
      initCname (&f->enumerationfieldF.cname);
      e->enumerationF.noOfElements += 1;
      mcDebug_assert ((Indexing_GetIndice (e->enumerationF.listOfSons, e->enumerationF.noOfElements)) == f);
      addEnumToModule (currentModule, f);
      if (e->enumerationF.low == NULL)
        {
          e->enumerationF.low = f;
        }
      e->enumerationF.high = f;
      return addToScope (f);
    }
  else
    {
      mcMetaError_metaErrors2 ((const char *) "cannot create enumeration field {%1k} as the name is already in use", 67, (const char *) "{%2DMad} was declared elsewhere", 31, (const unsigned char *) &n, (sizeof (n)-1), (const unsigned char *) &f, (sizeof (f)-1));
    }
  return f;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getExpList - returns the, n, th argument in an explist.
*/

static decl_node__opaque getExpList (decl_node__opaque p, unsigned int n)
{
  mcDebug_assert (p != NULL);
  mcDebug_assert (decl_isExpList (static_cast<decl_node> (p)));
  mcDebug_assert (n <= (Indexing_HighIndice (p->explistF.exp)));
  return static_cast<decl_node__opaque> (Indexing_GetIndice (p->explistF.exp, n));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   expListLen - returns the length of explist, p.
*/

static unsigned int expListLen (decl_node__opaque p)
{
  if (p == NULL)
    {
      return 0;
    }
  else
    {
      mcDebug_assert (decl_isExpList (static_cast<decl_node> (p)));
      return Indexing_HighIndice (p->explistF.exp);
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getConstExpComplete - gets the field from the def or imp or module, n.
*/

static bool getConstExpComplete (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_def:
        return n->defF.constsComplete;
        break;

      case decl_imp:
        return n->impF.constsComplete;
        break;

      case decl_module:
        return n->moduleF.constsComplete;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   addConstToModule - adds const exp, e, into the list of constant
                      expressions in module, m.
*/

static void addConstToModule (decl_node__opaque m, decl_node__opaque e)
{
  mcDebug_assert (((decl_isModule (static_cast<decl_node> (m))) || (decl_isDef (static_cast<decl_node> (m)))) || (decl_isImp (static_cast<decl_node> (m))));
  if (decl_isModule (static_cast<decl_node> (m)))
    {
      Indexing_IncludeIndiceIntoIndex (m->moduleF.constFixup.info, reinterpret_cast <void *> (e));
    }
  else if (decl_isDef (static_cast<decl_node> (m)))
    {
      /* avoid dangling else.  */
      Indexing_IncludeIndiceIntoIndex (m->defF.constFixup.info, reinterpret_cast <void *> (e));
    }
  else if (decl_isImp (static_cast<decl_node> (m)))
    {
      /* avoid dangling else.  */
      Indexing_IncludeIndiceIntoIndex (m->impF.constFixup.info, reinterpret_cast <void *> (e));
    }
}


/*
   doMakeConstExp - create a constexp node and add it to the current module.
*/

static decl_node__opaque doMakeConstExp (void)
{
  decl_node__opaque c;

  c = makeUnary (decl_constexp, static_cast<decl_node__opaque> (NULL), static_cast<decl_node__opaque> (NULL));
  addConstToModule (currentModule, c);
  return c;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isAnyType - return TRUE if node n is any type kind.
*/

static bool isAnyType (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  switch (n->kind)
    {
      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_char:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
      case decl_bitset:
      case decl_boolean:
      case decl_proc:
      case decl_type:
        return true;
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeVal - creates a VAL (type, expression) node.
*/

static decl_node__opaque makeVal (decl_node__opaque params)
{
  mcDebug_assert (decl_isExpList (static_cast<decl_node> (params)));
  if ((expListLen (params)) == 2)
    {
      return makeBinary (decl_val, getExpList (params, 1), getExpList (params, 2), getExpList (params, 1));
    }
  else
    {
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   makeCast - creates a cast node TYPENAME (expr).
*/

static decl_node__opaque makeCast (decl_node__opaque c, decl_node__opaque p)
{
  mcDebug_assert (decl_isExpList (static_cast<decl_node> (p)));
  if ((expListLen (p)) == 1)
    {
      return makeBinary (decl_cast, c, getExpList (p, 1), c);
    }
  else
    {
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}

static decl_node__opaque makeIntrinsicProc (decl_nodeT k, unsigned int noArgs, decl_node__opaque p)
{
  decl_node__opaque f;

  /*
   makeIntrisicProc - create an intrinsic node.
  */
  f = newNode (k);
  f->intrinsicF.args = p;
  f->intrinsicF.noArgs = noArgs;
  f->intrinsicF.type = static_cast<decl_node__opaque> (NULL);
  f->intrinsicF.postUnreachable = k == decl_halt;
  initPair (&f->intrinsicF.intrinsicComment);
  return f;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeIntrinsicUnaryType - create an intrisic unary type.
*/

static decl_node__opaque makeIntrinsicUnaryType (decl_nodeT k, decl_node__opaque paramList, decl_node__opaque returnType)
{
  return makeUnary (k, getExpList (paramList, 1), returnType);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeIntrinsicBinaryType - create an intrisic binary type.
*/

static decl_node__opaque makeIntrinsicBinaryType (decl_nodeT k, decl_node__opaque paramList, decl_node__opaque returnType)
{
  return makeBinary (k, getExpList (paramList, 1), getExpList (paramList, 2), returnType);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   checkIntrinsic - checks to see if the function call to, c, with
                    parameter list, n, is really an intrinic.  If it
                    is an intrinic then an intrinic node is created
                    and returned.  Otherwise NIL is returned.
*/

static decl_node__opaque checkIntrinsic (decl_node__opaque c, decl_node__opaque n)
{
  if (isAnyType (c))
    {
      return makeCast (c, n);
    }
  else if (c == maxN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_max, n, static_cast<decl_node__opaque> (NULL));
    }
  else if (c == minN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_min, n, static_cast<decl_node__opaque> (NULL));
    }
  else if (c == haltN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicProc (decl_halt, expListLen (n), n);
    }
  else if (c == valN)
    {
      /* avoid dangling else.  */
      return makeVal (n);
    }
  else if (c == adrN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_adr, n, addressN);
    }
  else if (c == sizeN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_size, n, cardinalN);
    }
  else if (c == tsizeN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_tsize, n, cardinalN);
    }
  else if (c == floatN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_float, n, realN);
    }
  else if (c == truncN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_trunc, n, integerN);
    }
  else if (c == ordN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_ord, n, cardinalN);
    }
  else if (c == chrN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_chr, n, charN);
    }
  else if (c == capN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_cap, n, charN);
    }
  else if (c == absN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_abs, n, static_cast<decl_node__opaque> (NULL));
    }
  else if (c == imN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_im, n, static_cast<decl_node__opaque> (NULL));
    }
  else if (c == reN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_re, n, static_cast<decl_node__opaque> (NULL));
    }
  else if (c == cmplxN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicBinaryType (decl_cmplx, n, static_cast<decl_node__opaque> (NULL));
    }
  else if (c == highN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_high, n, cardinalN);
    }
  else if (c == incN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicProc (decl_inc, expListLen (n), n);
    }
  else if (c == decN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicProc (decl_dec, expListLen (n), n);
    }
  else if (c == inclN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicProc (decl_incl, expListLen (n), n);
    }
  else if (c == exclN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicProc (decl_excl, expListLen (n), n);
    }
  else if (c == newN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicProc (decl_new, 1, n);
    }
  else if (c == disposeN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicProc (decl_dispose, 1, n);
    }
  else if (c == lengthN)
    {
      /* avoid dangling else.  */
      return makeIntrinsicUnaryType (decl_length, n, cardinalN);
    }
  else if (c == throwN)
    {
      /* avoid dangling else.  */
      keyc_useThrow ();
      return makeIntrinsicProc (decl_throw, 1, n);
    }
  return static_cast<decl_node__opaque> (NULL);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   checkCHeaders - check to see if the function is a C system function and
                   requires a header file included.
*/

static void checkCHeaders (decl_node__opaque c)
{
  nameKey_Name name;
  decl_node__opaque s;

  if (decl_isProcedure (static_cast<decl_node> (c)))
    {
      s = static_cast<decl_node__opaque> (decl_getScope (static_cast<decl_node> (c)));
      if ((decl_getSymName (static_cast<decl_node> (s))) == (nameKey_makeKey ((const char *) "libc", 4)))
        {
          name = decl_getSymName (static_cast<decl_node> (c));
          if ((((name == (nameKey_makeKey ((const char *) "read", 4))) || (name == (nameKey_makeKey ((const char *) "write", 5)))) || (name == (nameKey_makeKey ((const char *) "open", 4)))) || (name == (nameKey_makeKey ((const char *) "close", 5))))
            {
              keyc_useUnistd ();
            }
        }
    }
}


/*
   isFuncCall - returns TRUE if, n, is a function/procedure call.
*/

static bool isFuncCall (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  return n->kind == decl_funccall;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putTypeInternal - marks type, des, as being an internally generated type.
*/

static void putTypeInternal (decl_node__opaque des)
{
  mcDebug_assert (des != NULL);
  mcDebug_assert (decl_isType (static_cast<decl_node> (des)));
  des->typeF.isInternal = true;
}


/*
   isTypeInternal - returns TRUE if type, n, is internal.
*/

static bool isTypeInternal (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  mcDebug_assert (decl_isType (static_cast<decl_node> (n)));
  return n->typeF.isInternal;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   lookupBase - return node named n from the base symbol scope.
*/

static decl_node__opaque lookupBase (nameKey_Name n)
{
  decl_node__opaque m;

  m = static_cast<decl_node__opaque> (symbolKey_getSymKey (baseSymbols, n));
  if (m == procN)
    {
      keyc_useProc ();
    }
  else if (((m == complexN) || (m == longcomplexN)) || (m == shortcomplexN))
    {
      /* avoid dangling else.  */
      keyc_useComplex ();
    }
  return m;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dumpScopes - display the names of all the scopes stacked.
*/

static void dumpScopes (void)
{
  unsigned int h;
  decl_node__opaque s;

  h = Indexing_HighIndice (scopeStack);
  libc_printf ((const char *) "total scopes stacked %d\\n", 25, h);
  while (h >= 1)
    {
      s = static_cast<decl_node__opaque> (Indexing_GetIndice (scopeStack, h));
      out2 ((const char *) " scope [%d] is %s\\n", 19, h, s);
      h -= 1;
    }
}


/*
   out0 - write string a to StdOut.
*/

static void out0 (const char *a_, unsigned int _a_high)
{
  DynamicStrings_String m;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  m = FormatStrings_Sprintf0 (DynamicStrings_InitString ((const char *) a, _a_high));
  m = DynamicStrings_KillString (SFIO_WriteS (FIO_StdOut, m));
}


/*
   out1 - write string a to StdOut using format specifier a.
*/

static void out1 (const char *a_, unsigned int _a_high, decl_node__opaque s)
{
  DynamicStrings_String m;
  unsigned int d;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  m = getFQstring (s);
  if (DynamicStrings_EqualArray (m, (const char *) "", 0))
    {
      d = (unsigned int ) ((long unsigned int ) (s));
      m = DynamicStrings_KillString (m);
      m = FormatStrings_Sprintf1 (DynamicStrings_InitString ((const char *) "[%d]", 4), (const unsigned char *) &d, (sizeof (d)-1));
    }
  m = FormatStrings_Sprintf1 (DynamicStrings_InitString ((const char *) a, _a_high), (const unsigned char *) &m, (sizeof (m)-1));
  m = DynamicStrings_KillString (SFIO_WriteS (FIO_StdOut, m));
}


/*
   out2 - write string a to StdOut using format specifier a.
*/

static void out2 (const char *a_, unsigned int _a_high, unsigned int c, decl_node__opaque s)
{
  DynamicStrings_String m;
  DynamicStrings_String m1;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  m1 = getString (s);
  m = FormatStrings_Sprintf2 (DynamicStrings_InitString ((const char *) a, _a_high), (const unsigned char *) &c, (sizeof (c)-1), (const unsigned char *) &m1, (sizeof (m1)-1));
  m = DynamicStrings_KillString (SFIO_WriteS (FIO_StdOut, m));
  m1 = DynamicStrings_KillString (m1);
}


/*
   out3 - write string a to StdOut using format specifier a.
*/

static void out3 (const char *a_, unsigned int _a_high, unsigned int l, nameKey_Name n, decl_node__opaque s)
{
  DynamicStrings_String m;
  DynamicStrings_String m1;
  DynamicStrings_String m2;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  m1 = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n));
  m2 = getString (s);
  m = FormatStrings_Sprintf3 (DynamicStrings_InitString ((const char *) a, _a_high), (const unsigned char *) &l, (sizeof (l)-1), (const unsigned char *) &m1, (sizeof (m1)-1), (const unsigned char *) &m2, (sizeof (m2)-1));
  m = DynamicStrings_KillString (SFIO_WriteS (FIO_StdOut, m));
  m1 = DynamicStrings_KillString (m1);
  m2 = DynamicStrings_KillString (m2);
}


/*
   isUnary - returns TRUE if, n, is an unary node.
*/

static bool isUnary (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  switch (n->kind)
    {
      case decl_length:
      case decl_re:
      case decl_im:
      case decl_deref:
      case decl_high:
      case decl_chr:
      case decl_cap:
      case decl_abs:
      case decl_ord:
      case decl_float:
      case decl_trunc:
      case decl_constexp:
      case decl_not:
      case decl_neg:
      case decl_adr:
      case decl_size:
      case decl_tsize:
      case decl_min:
      case decl_max:
        return true;
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isBinary - returns TRUE if, n, is an binary node.
*/

static bool isBinary (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  switch (n->kind)
    {
      case decl_cmplx:
      case decl_and:
      case decl_or:
      case decl_equal:
      case decl_notequal:
      case decl_less:
      case decl_greater:
      case decl_greequal:
      case decl_lessequal:
      case decl_val:
      case decl_cast:
      case decl_plus:
      case decl_sub:
      case decl_div:
      case decl_mod:
      case decl_mult:
      case decl_divide:
      case decl_in:
        return true;
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeUnary - create a unary expression node with, e, as the argument
               and res as the return type.
*/

static decl_node__opaque makeUnary (decl_nodeT k, decl_node__opaque e, decl_node__opaque res)
{
  decl_node__opaque n;

  if (k == decl_plus)
    {
      return e;
    }
  else
    {
      n = newNode (k);
      switch (n->kind)
        {
          case decl_min:
          case decl_max:
          case decl_throw:
          case decl_re:
          case decl_im:
          case decl_deref:
          case decl_high:
          case decl_chr:
          case decl_cap:
          case decl_abs:
          case decl_ord:
          case decl_float:
          case decl_trunc:
          case decl_length:
          case decl_constexp:
          case decl_not:
          case decl_neg:
          case decl_adr:
          case decl_size:
          case decl_tsize:
            n->unaryF.arg = e;
            n->unaryF.resultType = res;
            break;


          default:
            CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
            __builtin_unreachable ();
        }
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLeafString - returns TRUE if n is a leaf node which is a string constant.
*/

static bool isLeafString (decl_node__opaque n)
{
  return ((isString (n)) || ((decl_isLiteral (static_cast<decl_node> (n))) && ((decl_getType (static_cast<decl_node> (n))) == charN))) || ((decl_isConst (static_cast<decl_node> (n))) && ((getExprType (n)) == charN));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getLiteralStringContents - return the contents of a literal node as a string.
*/

static DynamicStrings_String getLiteralStringContents (decl_node__opaque n)
{
  DynamicStrings_String number;
  DynamicStrings_String content;
  DynamicStrings_String s;

  mcDebug_assert (n->kind == decl_literal);
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n->literalF.name));
  content = static_cast<DynamicStrings_String> (NULL);
  if (n->literalF.type == charN)
    {
      if ((DynamicStrings_char (s, -1)) == 'C')
        {
          if ((DynamicStrings_Length (s)) > 1)
            {
              number = DynamicStrings_Slice (s, 0, -1);
              content = DynamicStrings_InitStringChar ((char ) (StringConvert_ostoc (number)));
              number = DynamicStrings_KillString (number);
            }
          else
            {
              content = DynamicStrings_InitStringChar ('C');
            }
        }
      else
        {
          content = DynamicStrings_Dup (s);
        }
    }
  else
    {
      mcMetaError_metaError1 ((const char *) "cannot obtain string contents from {%1k}", 40, (const unsigned char *) &n->literalF.name, (sizeof (n->literalF.name)-1));
    }
  s = DynamicStrings_KillString (s);
  return content;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getStringContents - return the string contents of a constant, literal,
                       string or a constexp node.
*/

static DynamicStrings_String getStringContents (decl_node__opaque n)
{
  if (decl_isConst (static_cast<decl_node> (n)))
    {
      return getStringContents (n->constF.value);
    }
  else if (decl_isLiteral (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      return getLiteralStringContents (n);
    }
  else if (isString (n))
    {
      /* avoid dangling else.  */
      return getString (n);
    }
  else if (isConstExp (n))
    {
      /* avoid dangling else.  */
      return getStringContents (n->unaryF.arg);
    }
  M2RTS_HALT (-1);
  __builtin_unreachable ();
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   addNames -
*/

static nameKey_Name addNames (decl_node__opaque a, decl_node__opaque b)
{
  DynamicStrings_String sa;
  DynamicStrings_String sb;
  nameKey_Name n;

  sa = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (a))));
  sb = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (b))));
  sa = DynamicStrings_ConCat (sa, sb);
  n = nameKey_makekey (DynamicStrings_string (sa));
  sa = DynamicStrings_KillString (sa);
  sb = DynamicStrings_KillString (sb);
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   resolveString -
*/

static decl_node__opaque resolveString (decl_node__opaque n)
{
  while ((decl_isConst (static_cast<decl_node> (n))) || (isConstExp (n)))
    {
      if (decl_isConst (static_cast<decl_node> (n)))
        {
          n = n->constF.value;
        }
      else
        {
          n = n->unaryF.arg;
        }
    }
  if (n->kind == decl_plus)
    {
      n = static_cast<decl_node__opaque> (decl_makeString (addNames (resolveString (n->binaryF.left), resolveString (n->binaryF.right))));
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   foldBinary -
*/

static decl_node__opaque foldBinary (decl_nodeT k, decl_node__opaque l, decl_node__opaque r, decl_node__opaque res)
{
  decl_node__opaque n;
  DynamicStrings_String ls;
  DynamicStrings_String rs;

  n = static_cast<decl_node__opaque> (NULL);
  if (((k == decl_plus) && (isLeafString (l))) && (isLeafString (r)))
    {
      ls = getStringContents (l);
      rs = getStringContents (r);
      ls = DynamicStrings_Add (ls, rs);
      n = static_cast<decl_node__opaque> (decl_makeString (nameKey_makekey (DynamicStrings_string (ls))));
      ls = DynamicStrings_KillString (ls);
      rs = DynamicStrings_KillString (rs);
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeBinary - create a binary node with left/right/result type:  l, r and resultType.
*/

static decl_node__opaque makeBinary (decl_nodeT k, decl_node__opaque l, decl_node__opaque r, decl_node__opaque resultType)
{
  decl_node__opaque n;

  n = foldBinary (k, l, r, resultType);
  if (n == NULL)
    {
      n = doMakeBinary (k, l, r, resultType);
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doMakeBinary - returns a binary node containing left/right/result values
                  l, r, res, with a node operator, k.
*/

static decl_node__opaque doMakeBinary (decl_nodeT k, decl_node__opaque l, decl_node__opaque r, decl_node__opaque res)
{
  decl_node__opaque n;

  n = newNode (k);
  switch (n->kind)
    {
      case decl_cmplx:
      case decl_equal:
      case decl_notequal:
      case decl_less:
      case decl_greater:
      case decl_greequal:
      case decl_lessequal:
      case decl_and:
      case decl_or:
      case decl_cast:
      case decl_val:
      case decl_plus:
      case decl_sub:
      case decl_div:
      case decl_mod:
      case decl_mult:
      case decl_divide:
      case decl_in:
        n->binaryF.left = l;
        n->binaryF.right = r;
        n->binaryF.resultType = res;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doMakeComponentRef -
*/

static decl_node__opaque doMakeComponentRef (decl_node__opaque rec, decl_node__opaque field)
{
  decl_node__opaque n;

  n = newNode (decl_componentref);
  n->componentrefF.rec = rec;
  n->componentrefF.field = field;
  n->componentrefF.resultType = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (field)));
  initNodeOpaqueState (n);
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isComponentRef -
*/

static bool isComponentRef (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  return n->kind == decl_componentref;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isArrayRef - returns TRUE if the node was an arrayref.
*/

static bool isArrayRef (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  return n->kind == decl_arrayref;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isDeref - returns TRUE if, n, is a deref node.
*/

static bool isDeref (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  return n->kind == decl_deref;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeBase - create a base type or constant.
              It only supports the base types and constants
              enumerated below.
*/

static decl_node__opaque makeBase (decl_nodeT k)
{
  decl_node__opaque n;

  n = newNode (k);
  switch (k)
    {
      case decl_new:
      case decl_dispose:
      case decl_length:
      case decl_inc:
      case decl_dec:
      case decl_incl:
      case decl_excl:
      case decl_nil:
      case decl_true:
      case decl_false:
      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_csizet:
      case decl_cssizet:
      case decl_cofft:
      case decl_cardinal64:
      case decl_char:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_real:
      case decl_longreal:
      case decl_shortreal:
      case decl_bitset:
      case decl_boolean:
      case decl_proc:
      case decl_ztype:
      case decl_rtype:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
      case decl_adr:
      case decl_chr:
      case decl_cap:
      case decl_abs:
      case decl_float:
      case decl_trunc:
      case decl_ord:
      case decl_high:
      case decl_throw:
      case decl_re:
      case decl_im:
      case decl_cmplx:
      case decl_size:
      case decl_tsize:
      case decl_val:
      case decl_min:
      case decl_max:
        break;


      default:
        M2RTS_HALT (-1);  /* legal kind.  */
        __builtin_unreachable ();
        break;
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isOrdinal - returns TRUE if, n, is an ordinal type.
*/

static bool isOrdinal (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_csizet:
      case decl_cssizet:
      case decl_cofft:
      case decl_cardinal64:
      case decl_char:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_bitset:
        return true;
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   mixTypes -
*/

static decl_node__opaque mixTypes (decl_node__opaque a, decl_node__opaque b)
{
  if ((a == addressN) || (b == addressN))
    {
      return addressN;
    }
  return a;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doSetExprType -
*/

static decl_node__opaque doSetExprType (decl_node__opaque *t, decl_node__opaque n)
{
  if ((*t) == NULL)
    {
      (*t) = n;
    }
  return (*t);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getMaxMinType -
*/

static decl_node__opaque getMaxMinType (decl_node__opaque n)
{
  if ((decl_isVar (static_cast<decl_node> (n))) || (decl_isConst (static_cast<decl_node> (n))))
    {
      return static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
    }
  else if (isConstExp (n))
    {
      /* avoid dangling else.  */
      n = getExprType (n->unaryF.arg);
      if (n == bitsetN)
        {
          return ztypeN;
        }
      else
        {
          return n;
        }
    }
  else
    {
      /* avoid dangling else.  */
      return n;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doGetFuncType -
*/

static decl_node__opaque doGetFuncType (decl_node__opaque n)
{
  decl_node__opaque result;

  mcDebug_assert (isFuncCall (n));
  result = doSetExprType (&n->funccallF.type, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n->funccallF.function))));
  initNodeOpaqueState (n);  /* Update now that the return type is known.  */
  return result;  /* Update now that the return type is known.  */
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doGetExprType - works out the type which is associated with node, n.
*/

static decl_node__opaque doGetExprType (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_max:
      case decl_min:
        return getMaxMinType (n->unaryF.arg);
        break;

      case decl_cast:
      case decl_val:
        return doSetExprType (&n->binaryF.resultType, n->binaryF.left);
        break;

      case decl_halt:
      case decl_new:
      case decl_dispose:
        return static_cast<decl_node__opaque> (NULL);
        break;

      case decl_inc:
      case decl_dec:
      case decl_incl:
      case decl_excl:
        return static_cast<decl_node__opaque> (NULL);
        break;

      case decl_nil:
        return addressN;
        break;

      case decl_true:
      case decl_false:
        return booleanN;
        break;

      case decl_address:
        return n;
        break;

      case decl_loc:
        return n;
        break;

      case decl_byte:
        return n;
        break;

      case decl_word:
        return n;
        break;

      case decl_csizet:
        return n;
        break;

      case decl_cssizet:
        return n;
        break;

      case decl_cofft:
        return n;
        break;

      case decl_cardinal64:
        return n;
        break;

      case decl_boolean:
        /* base types.  */
        return n;
        break;

      case decl_proc:
        return n;
        break;

      case decl_char:
        return n;
        break;

      case decl_cardinal:
        return n;
        break;

      case decl_longcard:
        return n;
        break;

      case decl_shortcard:
        return n;
        break;

      case decl_integer:
        return n;
        break;

      case decl_longint:
        return n;
        break;

      case decl_shortint:
        return n;
        break;

      case decl_real:
        return n;
        break;

      case decl_longreal:
        return n;
        break;

      case decl_shortreal:
        return n;
        break;

      case decl_bitset:
        return n;
        break;

      case decl_ztype:
        return n;
        break;

      case decl_rtype:
        return n;
        break;

      case decl_complex:
        return n;
        break;

      case decl_longcomplex:
        return n;
        break;

      case decl_shortcomplex:
        return n;
        break;

      case decl_type:
        /* language features and compound type attributes.  */
        return n->typeF.type;
        break;

      case decl_record:
        return n;
        break;

      case decl_varient:
        return n;
        break;

      case decl_var:
        return n->varF.type;
        break;

      case decl_enumeration:
        return n;
        break;

      case decl_subrange:
        return n->subrangeF.type;
        break;

      case decl_array:
        return n->arrayF.type;
        break;

      case decl_string:
        return charN;
        break;

      case decl_const:
        return doSetExprType (&n->constF.type, getExprType (n->constF.value));
        break;

      case decl_literal:
        return n->literalF.type;
        break;

      case decl_varparam:
        return n->varparamF.type;
        break;

      case decl_param:
        return n->paramF.type;
        break;

      case decl_optarg:
        return n->optargF.type;
        break;

      case decl_pointer:
        return n->pointerF.type;
        break;

      case decl_recordfield:
        return n->recordfieldF.type;
        break;

      case decl_varientfield:
        return n;
        break;

      case decl_enumerationfield:
        return n->enumerationfieldF.type;
        break;

      case decl_set:
        return n->setF.type;
        break;

      case decl_proctype:
        return n->proctypeF.returnType;
        break;

      case decl_subscript:
        return n->subscriptF.type;
        break;

      case decl_procedure:
        /* blocks.  */
        return n->procedureF.returnType;
        break;

      case decl_throw:
        return static_cast<decl_node__opaque> (NULL);
        break;

      case decl_unreachable:
        return static_cast<decl_node__opaque> (NULL);
        break;

      case decl_def:
      case decl_imp:
      case decl_module:
      case decl_loop:
      case decl_while:
      case decl_for:
      case decl_repeat:
      case decl_if:
      case decl_elsif:
      case decl_assignment:
        /* statements.  */
        M2RTS_HALT (-1);
        __builtin_unreachable ();
        break;

      case decl_plus:
      case decl_sub:
      case decl_div:
      case decl_mod:
      case decl_mult:
      case decl_divide:
        /* expressions.  */
        return doSetExprType (&n->binaryF.resultType, mixTypes (getExprType (n->binaryF.left), getExprType (n->binaryF.right)));
        break;

      case decl_in:
      case decl_and:
      case decl_or:
      case decl_equal:
      case decl_notequal:
      case decl_less:
      case decl_greater:
      case decl_greequal:
      case decl_lessequal:
        return doSetExprType (&n->binaryF.resultType, booleanN);
        break;

      case decl_cmplx:
        return doSetExprType (&n->binaryF.resultType, complexN);
        break;

      case decl_abs:
      case decl_constexp:
      case decl_deref:
      case decl_neg:
        return doSetExprType (&n->unaryF.resultType, getExprType (n->unaryF.arg));
        break;

      case decl_adr:
        return doSetExprType (&n->unaryF.resultType, addressN);
        break;

      case decl_size:
      case decl_tsize:
        return doSetExprType (&n->unaryF.resultType, cardinalN);
        break;

      case decl_high:
      case decl_ord:
        return doSetExprType (&n->unaryF.resultType, cardinalN);
        break;

      case decl_float:
        return doSetExprType (&n->unaryF.resultType, realN);
        break;

      case decl_trunc:
        return doSetExprType (&n->unaryF.resultType, integerN);
        break;

      case decl_chr:
        return doSetExprType (&n->unaryF.resultType, charN);
        break;

      case decl_cap:
        return doSetExprType (&n->unaryF.resultType, charN);
        break;

      case decl_not:
        return doSetExprType (&n->unaryF.resultType, booleanN);
        break;

      case decl_re:
        return doSetExprType (&n->unaryF.resultType, realN);
        break;

      case decl_im:
        return doSetExprType (&n->unaryF.resultType, realN);
        break;

      case decl_arrayref:
        return n->arrayrefF.resultType;
        break;

      case decl_componentref:
        return n->componentrefF.resultType;
        break;

      case decl_pointerref:
        return n->pointerrefF.resultType;
        break;

      case decl_funccall:
        return doSetExprType (&n->funccallF.type, doGetFuncType (n));
        break;

      case decl_setvalue:
        return n->setvalueF.type;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  M2RTS_HALT (-1);
  __builtin_unreachable ();
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   getExprType - return the expression type.
*/

static decl_node__opaque getExprType (decl_node__opaque n)
{
  decl_node__opaque t;

  if (((isFuncCall (n)) && ((decl_getType (static_cast<decl_node> (n))) != NULL)) && (decl_isProcType (decl_skipType (decl_getType (static_cast<decl_node> (n))))))
    {
      return static_cast<decl_node__opaque> (decl_getType (decl_skipType (decl_getType (static_cast<decl_node> (n)))));
    }
  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (t == NULL)
    {
      t = doGetExprType (n);
    }
  return t;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   openOutput -
*/

static void openOutput (void)
{
  DynamicStrings_String s;

  s = mcOptions_getOutputFile ();
  if (DynamicStrings_EqualArray (s, (const char *) "-", 1))
    {
      outputFile = FIO_StdOut;
    }
  else
    {
      outputFile = SFIO_OpenToWrite (s);
    }
  mcStream_setDest (outputFile);
}


/*
   closeOutput -
*/

static void closeOutput (void)
{
  DynamicStrings_String s;

  s = mcOptions_getOutputFile ();
  outputFile = mcStream_combine ();
  if (! (DynamicStrings_EqualArray (s, (const char *) "-", 1)))
    {
      FIO_Close (outputFile);
    }
}


/*
   write - outputs a single char, ch.
*/

static void write_ (char ch)
{
  FIO_WriteChar (outputFile, ch);
  FIO_FlushBuffer (outputFile);
}


/*
   writeln -
*/

static void writeln (void)
{
  FIO_WriteLine (outputFile);
  FIO_FlushBuffer (outputFile);
}


/*
   doIncludeC - include header file for definition module, n.
*/

static void doIncludeC (decl_node__opaque n)
{
  DynamicStrings_String s;

  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
  if (mcOptions_getExtendedOpaque ())
    {}  /* empty.  */
  /* no include in this case.  */
  else if (decl_isDef (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      mcPretty_print (doP, (const char *) "#   include \"", 13);
      mcPretty_prints (doP, mcOptions_getHPrefix ());
      mcPretty_prints (doP, s);
      mcPretty_print (doP, (const char *) ".h\"\\n", 5);
      symbolKey_foreachNodeDo (n->defF.decls.symbols, (symbolKey_performOperation) {(symbolKey_performOperation_t) addDoneDef});
    }
  s = DynamicStrings_KillString (s);
}


/*
   getSymScope - returns the scope where node, n, was declared.
*/

static decl_node__opaque getSymScope (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_const:
        return n->constF.scope;
        break;

      case decl_type:
        return n->typeF.scope;
        break;

      case decl_var:
        return n->varF.scope;
        break;

      case decl_procedure:
        return n->procedureF.scope;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  M2RTS_HALT (-1);
  __builtin_unreachable ();
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   isQualifiedForced - should the node be written with a module prefix?
*/

static bool isQualifiedForced (decl_node__opaque n)
{
  return forceQualified && (((((decl_isType (static_cast<decl_node> (n))) || (decl_isRecord (static_cast<decl_node> (n)))) || (decl_isArray (static_cast<decl_node> (n)))) || (decl_isEnumeration (static_cast<decl_node> (n)))) || (decl_isEnumerationField (static_cast<decl_node> (n))));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getFQstring -
*/

static DynamicStrings_String getFQstring (decl_node__opaque n)
{
  DynamicStrings_String i;
  DynamicStrings_String s;

  if (((decl_getScope (static_cast<decl_node> (n))) == NULL) || (decl_isDefUnqualified (decl_getScope (static_cast<decl_node> (n)))))
    {
      return DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
    }
  else if (isQualifiedForced (n))
    {
      /* avoid dangling else.  */
      i = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
      s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (decl_getScope (static_cast<decl_node> (n)))));
      return FormatStrings_Sprintf2 (DynamicStrings_InitString ((const char *) "%s_%s", 5), (const unsigned char *) &s, (sizeof (s)-1), (const unsigned char *) &i, (sizeof (i)-1));
    }
  else if (((! (decl_isExported (static_cast<decl_node> (n)))) || (mcOptions_getIgnoreFQ ())) || (decl_isDefUnqualified (decl_getScope (static_cast<decl_node> (n)))))
    {
      /* avoid dangling else.  */
      return DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
    }
  else
    {
      /* avoid dangling else.  */
      i = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
      s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (decl_getScope (static_cast<decl_node> (n)))));
      return FormatStrings_Sprintf2 (DynamicStrings_InitString ((const char *) "%s_%s", 5), (const unsigned char *) &s, (sizeof (s)-1), (const unsigned char *) &i, (sizeof (i)-1));
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getFQDstring -
*/

static DynamicStrings_String getFQDstring (decl_node__opaque n, bool scopes)
{
  DynamicStrings_String i;
  DynamicStrings_String s;

  if (((decl_getScope (static_cast<decl_node> (n))) == NULL) || (decl_isDefUnqualified (decl_getScope (static_cast<decl_node> (n)))))
    {
      return DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (getDName (n, scopes)));
    }
  else if (isQualifiedForced (n))
    {
      /* avoid dangling else.  */
      /* we assume a qualified name will never conflict.  */
      i = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
      s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (decl_getScope (static_cast<decl_node> (n)))));
      return FormatStrings_Sprintf2 (DynamicStrings_InitString ((const char *) "%s_%s", 5), (const unsigned char *) &s, (sizeof (s)-1), (const unsigned char *) &i, (sizeof (i)-1));
    }
  else if (((! (decl_isExported (static_cast<decl_node> (n)))) || (mcOptions_getIgnoreFQ ())) || (decl_isDefUnqualified (decl_getScope (static_cast<decl_node> (n)))))
    {
      /* avoid dangling else.  */
      return DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (getDName (n, scopes)));
    }
  else
    {
      /* avoid dangling else.  */
      /* we assume a qualified name will never conflict.  */
      i = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
      s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (decl_getScope (static_cast<decl_node> (n)))));
      return FormatStrings_Sprintf2 (DynamicStrings_InitString ((const char *) "%s_%s", 5), (const unsigned char *) &s, (sizeof (s)-1), (const unsigned char *) &i, (sizeof (i)-1));
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getString - returns the name as a string.
*/

static DynamicStrings_String getString (decl_node__opaque n)
{
  if ((decl_getSymName (static_cast<decl_node> (n))) == nameKey_NulName)
    {
      return DynamicStrings_InitString ((const char *) "", 0);
    }
  else
    {
      return DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doNone - call HALT.
*/

static void doNone (decl_node__opaque n)
{
  M2RTS_HALT (-1);
  __builtin_unreachable ();
}


/*
   doNothing - does nothing!
*/

static void doNothing (decl_node__opaque n)
{
}


/*
   doConstC -
*/

static void doConstC (decl_node__opaque n)
{
  if (! (alists_isItemInList (globalGroup->doneQ, reinterpret_cast <void *> (n))))
    {
      mcPretty_print (doP, (const char *) "#   define ", 11);
      doFQNameC (doP, n);
      mcPretty_setNeedSpace (doP);
      doExprC (doP, n->constF.value);
      mcPretty_print (doP, (const char *) "\\n", 2);
      alists_includeItemIntoList (globalGroup->doneQ, reinterpret_cast <void *> (n));
    }
}


/*
   needsParen - returns TRUE if expression, n, needs to be enclosed in ().
*/

static bool needsParen (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  switch (n->kind)
    {
      case decl_nil:
      case decl_true:
      case decl_false:
        return false;
        break;

      case decl_constexp:
        return needsParen (n->unaryF.arg);
        break;

      case decl_neg:
        return needsParen (n->unaryF.arg);
        break;

      case decl_not:
        return needsParen (n->unaryF.arg);
        break;

      case decl_adr:
      case decl_size:
      case decl_tsize:
      case decl_ord:
      case decl_float:
      case decl_trunc:
      case decl_chr:
      case decl_cap:
      case decl_high:
        return false;
        break;

      case decl_deref:
        return false;
        break;

      case decl_equal:
      case decl_notequal:
      case decl_less:
      case decl_greater:
      case decl_greequal:
      case decl_lessequal:
        return true;
        break;

      case decl_componentref:
        return false;
        break;

      case decl_pointerref:
        return false;
        break;

      case decl_cast:
        return true;
        break;

      case decl_val:
        return true;
        break;

      case decl_abs:
        return false;
        break;

      case decl_plus:
      case decl_sub:
      case decl_div:
      case decl_mod:
      case decl_mult:
      case decl_divide:
      case decl_in:
        return true;
        break;

      case decl_literal:
      case decl_const:
      case decl_enumerationfield:
      case decl_string:
        return false;
        break;

      case decl_max:
        return true;
        break;

      case decl_min:
        return true;
        break;

      case decl_var:
        return false;
        break;

      case decl_arrayref:
        return false;
        break;

      case decl_and:
      case decl_or:
        return true;
        break;

      case decl_funccall:
        return true;
        break;

      case decl_recordfield:
        return false;
        break;

      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_type:
      case decl_char:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_real:
      case decl_longreal:
      case decl_shortreal:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
      case decl_bitset:
      case decl_boolean:
      case decl_proc:
        return false;
        break;

      case decl_setvalue:
        return false;
        break;

      case decl_address:
        return true;
        break;

      case decl_procedure:
        return false;
        break;

      case decl_length:
      case decl_cmplx:
      case decl_re:
      case decl_im:
        return true;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  return true;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doUnary -
*/

static void doUnary (mcPretty_pretty p, const char *op_, unsigned int _op_high, decl_node__opaque expr, decl_node__opaque type, bool l, bool r)
{
  char op[_op_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (op, op_, _op_high+1);

  if (l)
    {
      mcPretty_setNeedSpace (p);
    }
  mcPretty_print (p, (const char *) op, _op_high);
  if (r)
    {
      mcPretty_setNeedSpace (p);
    }
  if (needsParen (expr))
    {
      outText (p, (const char *) "(", 1);
      doExprC (p, expr);
      outText (p, (const char *) ")", 1);
    }
  else
    {
      doExprC (p, expr);
    }
}


/*
   doSetSub - perform  l & (~ r)
*/

static void doSetSub (mcPretty_pretty p, decl_node__opaque left, decl_node__opaque right)
{
  if (needsParen (left))
    {
      outText (p, (const char *) "(", 1);
      doExprC (p, left);
      outText (p, (const char *) ")", 1);
    }
  else
    {
      doExprC (p, left);
    }
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "&", 1);
  mcPretty_setNeedSpace (p);
  if (needsParen (right))
    {
      outText (p, (const char *) "(~(", 3);
      doExprC (p, right);
      outText (p, (const char *) "))", 2);
    }
  else
    {
      outText (p, (const char *) "(~", 2);
      doExprC (p, right);
      outText (p, (const char *) ")", 1);
    }
}


/*
   doPolyBinary -
*/

static void doPolyBinary (mcPretty_pretty p, decl_nodeT op, decl_node__opaque left, decl_node__opaque right, bool l, bool r)
{
  decl_node__opaque lt;
  decl_node__opaque rt;

  lt = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (getExprType (left))));
  rt = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (getExprType (right))));
  if (((lt != NULL) && ((decl_isSet (static_cast<decl_node> (lt))) || (isBitset (lt)))) || ((rt != NULL) && ((decl_isSet (static_cast<decl_node> (rt))) || (isBitset (rt)))))
    {
      switch (op)
        {
          case decl_plus:
            doBinary (p, (const char *) "|", 1, left, right, l, r, false);
            break;

          case decl_sub:
            doSetSub (p, left, right);
            break;

          case decl_mult:
            doBinary (p, (const char *) "&", 1, left, right, l, r, false);
            break;

          case decl_divide:
            doBinary (p, (const char *) "^", 1, left, right, l, r, false);
            break;


          default:
            CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
            __builtin_unreachable ();
        }
    }
  else
    {
      switch (op)
        {
          case decl_plus:
            doBinary (p, (const char *) "+", 1, left, right, l, r, false);
            break;

          case decl_sub:
            doBinary (p, (const char *) "-", 1, left, right, l, r, false);
            break;

          case decl_mult:
            doBinary (p, (const char *) "*", 1, left, right, l, r, false);
            break;

          case decl_divide:
            doBinary (p, (const char *) "/", 1, left, right, l, r, false);
            break;


          default:
            CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
            __builtin_unreachable ();
        }
    }
}


/*
   doBinary -
*/

static void doBinary (mcPretty_pretty p, const char *op_, unsigned int _op_high, decl_node__opaque left, decl_node__opaque right, bool l, bool r, bool unpackProc)
{
  char op[_op_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (op, op_, _op_high+1);

  if (needsParen (left))
    {
      outText (p, (const char *) "(", 1);
      left = doExprCup (p, left, unpackProc, false);
      outText (p, (const char *) ")", 1);
    }
  else
    {
      left = doExprCup (p, left, unpackProc, false);
    }
  if (l)
    {
      mcPretty_setNeedSpace (p);
    }
  outText (p, (const char *) op, _op_high);
  if (r)
    {
      mcPretty_setNeedSpace (p);
    }
  if (needsParen (right))
    {
      outText (p, (const char *) "(", 1);
      right = doExprCup (p, right, unpackProc, false);
      outText (p, (const char *) ")", 1);
    }
  else
    {
      right = doExprCup (p, right, unpackProc, false);
    }
}


/*
   doPostUnary -
*/

static void doPostUnary (mcPretty_pretty p, const char *op_, unsigned int _op_high, decl_node__opaque expr)
{
  char op[_op_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (op, op_, _op_high+1);

  doExprC (p, expr);
  outText (p, (const char *) op, _op_high);
}


/*
   doDeRefC -
*/

static decl_node__opaque doDeRefC (mcPretty_pretty p, decl_node__opaque expr)
{
  outText (p, (const char *) "(*", 2);
  expr = castOpaque (p, expr, false);
  outText (p, (const char *) ")", 1);
  return expr;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doGetLastOp - returns, a, if b is a terminal otherwise walk right.
*/

static decl_node__opaque doGetLastOp (decl_node__opaque a, decl_node__opaque b)
{
  switch (b->kind)
    {
      case decl_nil:
        return a;
        break;

      case decl_true:
        return a;
        break;

      case decl_false:
        return a;
        break;

      case decl_constexp:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_neg:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_not:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_adr:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_size:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_tsize:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_ord:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_float:
      case decl_trunc:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_chr:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_cap:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_high:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_deref:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_re:
      case decl_im:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_equal:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_notequal:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_less:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_greater:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_greequal:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_lessequal:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_componentref:
        return doGetLastOp (b, b->componentrefF.field);
        break;

      case decl_pointerref:
        return doGetLastOp (b, b->pointerrefF.field);
        break;

      case decl_cast:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_val:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_plus:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_sub:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_div:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_mod:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_mult:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_divide:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_in:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_and:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_or:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_cmplx:
        return doGetLastOp (b, b->binaryF.right);
        break;

      case decl_literal:
        return a;
        break;

      case decl_const:
        return a;
        break;

      case decl_enumerationfield:
        return a;
        break;

      case decl_string:
        return a;
        break;

      case decl_max:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_min:
        return doGetLastOp (b, b->unaryF.arg);
        break;

      case decl_var:
        return a;
        break;

      case decl_arrayref:
        return a;
        break;

      case decl_funccall:
        return a;
        break;

      case decl_procedure:
        return a;
        break;

      case decl_recordfield:
        return a;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doComponentRefC -
*/

static void doComponentRefC (mcPretty_pretty p, decl_node__opaque l, decl_node__opaque r)
{
  flushOpaque (p, l, false);
  outText (p, (const char *) ".", 1);
  doExprC (p, r);
}


/*
   doPointerRefC -
*/

static void doPointerRefC (mcPretty_pretty p, decl_node__opaque l, decl_node__opaque r)
{
  flushOpaque (p, l, false);
  outText (p, (const char *) "->", 2);
  doExprC (p, r);
}


/*
   doPreBinary -
*/

static void doPreBinary (mcPretty_pretty p, const char *op_, unsigned int _op_high, decl_node__opaque left, decl_node__opaque right, bool l, bool r)
{
  char op[_op_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (op, op_, _op_high+1);

  if (l)
    {
      mcPretty_setNeedSpace (p);
    }
  outText (p, (const char *) op, _op_high);
  if (r)
    {
      mcPretty_setNeedSpace (p);
    }
  outText (p, (const char *) "(", 1);
  doExprC (p, left);
  outText (p, (const char *) ",", 1);
  mcPretty_setNeedSpace (p);
  doExprC (p, right);
  outText (p, (const char *) ")", 1);
}


/*
   doConstExpr -
*/

static void doConstExpr (mcPretty_pretty p, decl_node__opaque n)
{
  doFQNameC (p, n);
}


/*
   doEnumerationField -
*/

static void doEnumerationField (mcPretty_pretty p, decl_node__opaque n)
{
  doFQDNameC (p, n, false);
}


/*
   isZero - returns TRUE if node, n, is zero.
*/

static bool isZero (decl_node__opaque n)
{
  if (isConstExp (n))
    {
      return isZero (n->unaryF.arg);
    }
  return (decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "0", 1));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doArrayRef - perform an array reference.  If constCast
                then an unbounded array access will be const_cast
                (the constCast should be TRUE if an assignment to
                the array is required).
*/

static void doArrayRef (mcPretty_pretty p, decl_node__opaque n, bool constCast)
{
  decl_node__opaque type;
  decl_node__opaque v;
  unsigned int i;
  unsigned int c;

  mcDebug_assert (n != NULL);
  mcDebug_assert (isArrayRef (n));
  type = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (n->arrayrefF.array))));
  if (decl_isUnbounded (static_cast<decl_node> (type)))
    {
      v = n->arrayrefF.array;
      if ((constCast && (decl_isVar (static_cast<decl_node> (n->arrayrefF.array)))) && (v->varF.isParameter || v->varF.isVarParameter))
        {
          outText (p, (const char *) "const_cast<", 11);
          doTypeNameC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (v))));
          outText (p, (const char *) ">(", 2);
          outTextN (p, decl_getSymName (static_cast<decl_node> (n->arrayrefF.array)));
          outText (p, (const char *) ")", 1);
        }
      else
        {
          outTextN (p, decl_getSymName (static_cast<decl_node> (n->arrayrefF.array)));
        }
    }
  else
    {
      doExprC (p, n->arrayrefF.array);
      mcDebug_assert (decl_isArray (static_cast<decl_node> (type)));
      outText (p, (const char *) ".array", 6);
    }
  outText (p, (const char *) "[", 1);
  i = 1;
  c = expListLen (n->arrayrefF.index);
  while (i <= c)
    {
      doExprC (p, getExpList (n->arrayrefF.index, i));
      if (decl_isUnbounded (static_cast<decl_node> (type)))
        {
          mcDebug_assert (c == 1);
        }
      else
        {
          doSubtractC (p, getMin (type->arrayF.subr));
          if (i < c)
            {
              mcDebug_assert (decl_isArray (static_cast<decl_node> (type)));
              outText (p, (const char *) "].array[", 8);
              type = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (type))));
            }
        }
      i += 1;
    }
  outText (p, (const char *) "]", 1);
}


/*
   doProcedure -
*/

static void doProcedure (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (decl_isProcedure (static_cast<decl_node> (n)));
  doFQDNameC (p, n, true);
}


/*
   doRecordfield -
*/

static void doRecordfield (mcPretty_pretty p, decl_node__opaque n)
{
  doDNameC (p, n, false);
}


/*
   doCastC -
*/

static void doCastC (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque e)
{
  decl_node__opaque et;

  outText (p, (const char *) "(", 1);
  doTypeNameC (p, t);
  outText (p, (const char *) ")", 1);
  mcPretty_setNeedSpace (p);
  et = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (e))));
  if (((et != NULL) && (isAProcType (et))) && (isAProcType (static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (t))))))
    {
      outText (p, (const char *) "{(", 2);
      doFQNameC (p, t);
      outText (p, (const char *) "_t)", 3);
      mcPretty_setNeedSpace (p);
      doExprC (p, e);
      outText (p, (const char *) ".proc}", 6);
    }
  else
    {
      outText (p, (const char *) "(", 1);
      doExprC (p, e);
      outText (p, (const char *) ")", 1);
    }
}


/*
   doSetValueC -
*/

static void doSetValueC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque lo;
  unsigned int i;
  unsigned int h;

  mcDebug_assert (decl_isSetValue (static_cast<decl_node> (n)));
  lo = getSetLow (n);
  if (n->setvalueF.type != NULL)
    {
      outText (p, (const char *) "(", 1);
      doTypeNameC (p, n->setvalueF.type);
      mcPretty_noSpace (p);
      outText (p, (const char *) ")", 1);
      mcPretty_setNeedSpace (p);
    }
  if ((Indexing_HighIndice (n->setvalueF.values)) == 0)
    {
      outText (p, (const char *) "0", 1);
    }
  else
    {
      i = Indexing_LowIndice (n->setvalueF.values);
      h = Indexing_HighIndice (n->setvalueF.values);
      outText (p, (const char *) "(", 1);
      while (i <= h)
        {
          outText (p, (const char *) "(1", 2);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "<<", 2);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "(", 1);
          doExprC (p, static_cast<decl_node__opaque> (Indexing_GetIndice (n->setvalueF.values, i)));
          doSubtractC (p, lo);
          outText (p, (const char *) ")", 1);
          outText (p, (const char *) ")", 1);
          if (i < h)
            {
              mcPretty_setNeedSpace (p);
              outText (p, (const char *) "|", 1);
              mcPretty_setNeedSpace (p);
            }
          i += 1;
        }
      outText (p, (const char *) ")", 1);
    }
}


/*
   getSetLow - returns the low value of the set type from
               expression, n.
*/

static decl_node__opaque getSetLow (decl_node__opaque n)
{
  decl_node__opaque type;

  if ((decl_getType (static_cast<decl_node> (n))) == NULL)
    {
      return static_cast<decl_node__opaque> (decl_makeLiteralInt (nameKey_makeKey ((const char *) "0", 1)));
    }
  else
    {
      type = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (n))));
      if (decl_isSet (static_cast<decl_node> (type)))
        {
          return getMin (static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (type)))));
        }
      else
        {
          return static_cast<decl_node__opaque> (decl_makeLiteralInt (nameKey_makeKey ((const char *) "0", 1)));
        }
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doInC - performs (((1 << (l)) & (r)) != 0)
*/

static void doInC (mcPretty_pretty p, decl_node__opaque l, decl_node__opaque r)
{
  decl_node__opaque lo;

  lo = getSetLow (r);
  outText (p, (const char *) "(((1", 4);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "<<", 2);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, l);
  doSubtractC (p, lo);
  outText (p, (const char *) "))", 2);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "&", 1);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, r);
  outText (p, (const char *) "))", 2);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "!=", 2);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "0)", 2);
}


/*
   doThrowC -
*/

static void doThrowC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isIntrinsic (n));
  outText (p, (const char *) "throw", 5);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  if ((expListLen (n->intrinsicF.args)) == 1)
    {
      doExprC (p, getExpList (n->intrinsicF.args, 1));
    }
  outText (p, (const char *) ")", 1);
}


/*
   doUnreachableC -
*/

static void doUnreachableC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isIntrinsic (n));
  outText (p, (const char *) "__builtin_unreachable", 21);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  mcDebug_assert ((expListLen (n->intrinsicF.args)) == 0);
  outText (p, (const char *) ")", 1);
}


/*
   outNull -
*/

static void outNull (mcPretty_pretty p)
{
  keyc_useNull ();
  outText (p, (const char *) "NULL", 4);
}


/*
   outTrue -
*/

static void outTrue (mcPretty_pretty p)
{
  keyc_useTrue ();
  if ((mcOptions_useBool ()) && (lang == decl_ansiCP))
    {
      outText (p, (const char *) "true", 4);
    }
  else
    {
      outText (p, (const char *) "TRUE", 4);
    }
}


/*
   outFalse -
*/

static void outFalse (mcPretty_pretty p)
{
  keyc_useFalse ();
  if ((mcOptions_useBool ()) && (lang == decl_ansiCP))
    {
      outText (p, (const char *) "false", 5);
    }
  else
    {
      outText (p, (const char *) "FALSE", 5);
    }
}


/*
   doExprC -
*/

static void doExprC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;

  mcDebug_assert (n != NULL);
  t = getExprType (n);
  switch (n->kind)
    {
      case decl_nil:
        outNull (p);
        break;

      case decl_true:
        outTrue (p);
        break;

      case decl_false:
        outFalse (p);
        break;

      case decl_constexp:
        doUnary (p, (const char *) "", 0, n->unaryF.arg, n->unaryF.resultType, false, false);
        break;

      case decl_neg:
        doUnary (p, (const char *) "-", 1, n->unaryF.arg, n->unaryF.resultType, false, false);
        break;

      case decl_not:
        doUnary (p, (const char *) "!", 1, n->unaryF.arg, n->unaryF.resultType, false, true);
        break;

      case decl_val:
        doValC (p, n);
        break;

      case decl_adr:
        doAdrC (p, n);
        break;

      case decl_size:
      case decl_tsize:
        doSizeC (p, n);
        break;

      case decl_float:
        doConvertSC (p, n, mcOptions_getCRealType ());
        break;

      case decl_trunc:
        doConvertC (p, n, (const char *) "int", 3);
        break;

      case decl_ord:
        doConvertC (p, n, (const char *) "unsigned int", 12);
        break;

      case decl_chr:
        doConvertC (p, n, (const char *) "char", 4);
        break;

      case decl_cap:
        doCapC (p, n);
        break;

      case decl_abs:
        doAbsC (p, n);
        break;

      case decl_high:
        doFuncHighC (p, n->unaryF.arg);
        break;

      case decl_length:
        doLengthC (p, n);
        break;

      case decl_min:
        doMinC (p, n);
        break;

      case decl_max:
        doMaxC (p, n);
        break;

      case decl_throw:
        doThrowC (p, n);
        break;

      case decl_unreachable:
        doUnreachableC (p, n);
        break;

      case decl_re:
        doReC (p, n);
        break;

      case decl_im:
        doImC (p, n);
        break;

      case decl_cmplx:
        doCmplx (p, n);
        break;

      case decl_deref:
        n->unaryF.arg = doDeRefC (p, n->unaryF.arg);
        break;

      case decl_equal:
        doBinary (p, (const char *) "==", 2, n->binaryF.left, n->binaryF.right, true, true, true);
        break;

      case decl_notequal:
        doBinary (p, (const char *) "!=", 2, n->binaryF.left, n->binaryF.right, true, true, true);
        break;

      case decl_less:
        doBinary (p, (const char *) "<", 1, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_greater:
        doBinary (p, (const char *) ">", 1, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_greequal:
        doBinary (p, (const char *) ">=", 2, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_lessequal:
        doBinary (p, (const char *) "<=", 2, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_componentref:
        doComponentRefC (p, n->componentrefF.rec, n->componentrefF.field);
        break;

      case decl_pointerref:
        doPointerRefC (p, n->pointerrefF.ptr, n->pointerrefF.field);
        break;

      case decl_cast:
        doCastC (p, n->binaryF.left, n->binaryF.right);
        break;

      case decl_plus:
        doPolyBinary (p, decl_plus, n->binaryF.left, n->binaryF.right, false, false);
        break;

      case decl_sub:
        doPolyBinary (p, decl_sub, n->binaryF.left, n->binaryF.right, false, false);
        break;

      case decl_div:
        doBinary (p, (const char *) "/", 1, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_mod:
        doBinary (p, (const char *) "%", 1, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_mult:
        doPolyBinary (p, decl_mult, n->binaryF.left, n->binaryF.right, false, false);
        break;

      case decl_divide:
        doPolyBinary (p, decl_divide, n->binaryF.left, n->binaryF.right, false, false);
        break;

      case decl_in:
        doInC (p, n->binaryF.left, n->binaryF.right);
        break;

      case decl_and:
        doBinary (p, (const char *) "&&", 2, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_or:
        doBinary (p, (const char *) "||", 2, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_literal:
        doLiteralC (p, n);
        break;

      case decl_const:
        doConstExpr (p, n);
        break;

      case decl_enumerationfield:
        doEnumerationField (p, n);
        break;

      case decl_string:
        doStringC (p, n);
        break;

      case decl_var:
        doVar (p, n);
        break;

      case decl_arrayref:
        doArrayRef (p, n, false);
        break;

      case decl_funccall:
        doFuncExprC (p, n);
        break;

      case decl_procedure:
        doProcedure (p, n);
        break;

      case decl_recordfield:
        doRecordfield (p, n);
        break;

      case decl_setvalue:
        doSetValueC (p, n);
        break;

      case decl_char:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
      case decl_real:
      case decl_longreal:
      case decl_shortreal:
      case decl_bitset:
      case decl_boolean:
      case decl_proc:
        doBaseC (p, n);
        break;

      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_csizet:
      case decl_cssizet:
      case decl_cofft:
      case decl_cardinal64:
        doSystemC (p, n);
        break;

      case decl_type:
        doTypeNameC (p, n);
        break;

      case decl_pointer:
        doTypeNameC (p, n);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   doExprCup -
*/

static decl_node__opaque doExprCup (mcPretty_pretty p, decl_node__opaque n, bool unpackProc, bool uncastConst)
{
  decl_node__opaque type;

  if (uncastConst && (isArrayRef (n)))
    {
      doArrayRef (p, n, true);
    }
  else
    {
      doExprC (p, n);
      if (unpackProc)
        {
          type = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (getExprType (n))));
          if ((type != NULL) && (isAProcType (type)))
            {
              outText (p, (const char *) ".proc", 5);
            }
        }
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doExprM2 -
*/

static void doExprM2 (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  switch (n->kind)
    {
      case decl_nil:
        outText (p, (const char *) "NIL", 3);
        break;

      case decl_true:
        outText (p, (const char *) "TRUE", 4);
        break;

      case decl_false:
        outText (p, (const char *) "FALSE", 5);
        break;

      case decl_constexp:
        doUnary (p, (const char *) "", 0, n->unaryF.arg, n->unaryF.resultType, false, false);
        break;

      case decl_neg:
        doUnary (p, (const char *) "-", 1, n->unaryF.arg, n->unaryF.resultType, false, false);
        break;

      case decl_not:
        doUnary (p, (const char *) "NOT", 3, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_adr:
        doUnary (p, (const char *) "ADR", 3, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_size:
        doUnary (p, (const char *) "SIZE", 4, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_tsize:
        doUnary (p, (const char *) "TSIZE", 5, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_float:
        doUnary (p, (const char *) "FLOAT", 5, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_trunc:
        doUnary (p, (const char *) "TRUNC", 5, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_ord:
        doUnary (p, (const char *) "ORD", 3, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_chr:
        doUnary (p, (const char *) "CHR", 3, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_cap:
        doUnary (p, (const char *) "CAP", 3, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_high:
        doUnary (p, (const char *) "HIGH", 4, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_re:
        doUnary (p, (const char *) "RE", 2, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_im:
        doUnary (p, (const char *) "IM", 2, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_deref:
        doPostUnary (p, (const char *) "^", 1, n->unaryF.arg);
        break;

      case decl_equal:
        doBinary (p, (const char *) "=", 1, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_notequal:
        doBinary (p, (const char *) "#", 1, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_less:
        doBinary (p, (const char *) "<", 1, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_greater:
        doBinary (p, (const char *) ">", 1, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_greequal:
        doBinary (p, (const char *) ">=", 2, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_lessequal:
        doBinary (p, (const char *) "<=", 2, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_componentref:
        doBinary (p, (const char *) ".", 1, n->componentrefF.rec, n->componentrefF.field, false, false, false);
        break;

      case decl_pointerref:
        doBinary (p, (const char *) "^.", 2, n->pointerrefF.ptr, n->pointerrefF.field, false, false, false);
        break;

      case decl_cast:
        doPreBinary (p, (const char *) "CAST", 4, n->binaryF.left, n->binaryF.right, true, true);
        break;

      case decl_val:
        doPreBinary (p, (const char *) "VAL", 3, n->binaryF.left, n->binaryF.right, true, true);
        break;

      case decl_cmplx:
        doPreBinary (p, (const char *) "CMPLX", 5, n->binaryF.left, n->binaryF.right, true, true);
        break;

      case decl_plus:
        doBinary (p, (const char *) "+", 1, n->binaryF.left, n->binaryF.right, false, false, false);
        break;

      case decl_sub:
        doBinary (p, (const char *) "-", 1, n->binaryF.left, n->binaryF.right, false, false, false);
        break;

      case decl_div:
        doBinary (p, (const char *) "DIV", 3, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_mod:
        doBinary (p, (const char *) "MOD", 3, n->binaryF.left, n->binaryF.right, true, true, false);
        break;

      case decl_mult:
        doBinary (p, (const char *) "*", 1, n->binaryF.left, n->binaryF.right, false, false, false);
        break;

      case decl_divide:
        doBinary (p, (const char *) "/", 1, n->binaryF.left, n->binaryF.right, false, false, false);
        break;

      case decl_literal:
        doLiteral (p, n);
        break;

      case decl_const:
        doConstExpr (p, n);
        break;

      case decl_enumerationfield:
        doEnumerationField (p, n);
        break;

      case decl_string:
        doString (p, n);
        break;

      case decl_max:
        doUnary (p, (const char *) "MAX", 3, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_min:
        doUnary (p, (const char *) "MIN", 3, n->unaryF.arg, n->unaryF.resultType, true, true);
        break;

      case decl_var:
        doVar (p, n);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   doVar -
*/

static void doVar (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (decl_isVar (static_cast<decl_node> (n)));
  if (n->varF.isVarParameter)
    {
      outText (p, (const char *) "(*", 2);
      doFQDNameC (p, n, true);
      outText (p, (const char *) ")", 1);
    }
  else
    {
      doFQDNameC (p, n, true);
    }
}


/*
   doLiteralC -
*/

static void doLiteralC (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  mcDebug_assert (decl_isLiteral (static_cast<decl_node> (n)));
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
  if (n->literalF.type == charN)
    {
      if ((DynamicStrings_char (s, -1)) == 'C')
        {
          s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, -1);
          if ((DynamicStrings_char (s, 0)) != '0')
            {
              s = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "0", 1), DynamicStrings_Mark (s));
            }
        }
      outText (p, (const char *) "(char)", 6);
      mcPretty_setNeedSpace (p);
    }
  else if ((DynamicStrings_char (s, -1)) == 'H')
    {
      /* avoid dangling else.  */
      outText (p, (const char *) "0x", 2);
      s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, -1);
    }
  else if ((DynamicStrings_char (s, -1)) == 'B')
    {
      /* avoid dangling else.  */
      outText (p, (const char *) "0", 1);
      s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, -1);
    }
  outTextS (p, s);
  s = DynamicStrings_KillString (s);
}


/*
   doLiteral -
*/

static void doLiteral (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  mcDebug_assert (decl_isLiteral (static_cast<decl_node> (n)));
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
  if (n->literalF.type == charN)
    {
      if ((DynamicStrings_char (s, -1)) == 'C')
        {
          s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, -1);
          if ((DynamicStrings_char (s, 0)) != '0')
            {
              s = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) "0", 1), DynamicStrings_Mark (s));
            }
        }
      outText (p, (const char *) "(char)", 6);
      mcPretty_setNeedSpace (p);
    }
  outTextS (p, s);
  s = DynamicStrings_KillString (s);
}


/*
   isString - returns TRUE if node, n, is a string.
*/

static bool isString (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  return n->kind == decl_string;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doString -
*/

static void doString (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  mcDebug_assert (isString (n));
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
  outTextS (p, s);
  s = DynamicStrings_KillString (s);
  /*
   IF DynamicStrings.Index (s, '"', 0)=-1
   THEN
      outText (p, '"') ;
      outTextS (p, s) ;
      outText (p, '"')
   ELSIF DynamicStrings.Index (s, "'", 0)=-1
   THEN
      outText (p, '"') ;
      outTextS (p, s) ;
      outText (p, '"')
   ELSE
      metaError1 ('illegal string {%1k}', n)
   END
  */
  M2RTS_HALT (-1);
  __builtin_unreachable ();
}


/*
   replaceChar - replace every occurance of, ch, by, a and return modified string, s.
*/

static DynamicStrings_String replaceChar (DynamicStrings_String s, char ch, const char *a_, unsigned int _a_high)
{
  int i;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  i = 0;
  for (;;)
  {
    i = DynamicStrings_Index (s, ch, static_cast<unsigned int> (i));
    if (i == 0)
      {
        s = DynamicStrings_ConCat (DynamicStrings_InitString ((const char *) a, _a_high), DynamicStrings_Slice (s, 1, 0));
        i = StrLib_StrLen ((const char *) a, _a_high);
      }
    else if (i > 0)
      {
        /* avoid dangling else.  */
        s = DynamicStrings_ConCat (DynamicStrings_ConCat (DynamicStrings_Slice (s, 0, i), DynamicStrings_Mark (DynamicStrings_InitString ((const char *) a, _a_high))), DynamicStrings_Slice (s, i+1, 0));
        i += StrLib_StrLen ((const char *) a, _a_high);
      }
    else
      {
        /* avoid dangling else.  */
        return s;
      }
  }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   toCstring - translates string, n, into a C string
               and returns the new String.
*/

static DynamicStrings_String toCstring (nameKey_Name n)
{
  DynamicStrings_String s;

  s = DynamicStrings_Slice (DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n)), 1, -1);
  return replaceChar (replaceChar (s, '\\', (const char *) "\\\\", 2), '"', (const char *) "\\\"", 2);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   toCchar -
*/

static DynamicStrings_String toCchar (nameKey_Name n)
{
  DynamicStrings_String s;

  s = DynamicStrings_Slice (DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n)), 1, -1);
  return replaceChar (replaceChar (s, '\\', (const char *) "\\\\", 2), '\'', (const char *) "\\'", 2);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   countChar -
*/

static unsigned int countChar (DynamicStrings_String s, char ch)
{
  int i;
  unsigned int c;

  c = 0;
  i = 0;
  for (;;)
  {
    i = DynamicStrings_Index (s, ch, static_cast<unsigned int> (i));
    if (i >= 0)
      {
        i += 1;
        c += 1;
      }
    else
      {
        return c;
      }
  }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   lenCstring -
*/

static unsigned int lenCstring (DynamicStrings_String s)
{
  return (DynamicStrings_Length (s))-(countChar (s, '\\'));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   outCstring -
*/

static void outCstring (mcPretty_pretty p, decl_node__opaque s, bool aString)
{
  if (aString)
    {
      outText (p, (const char *) "\"", 1);
      outRawS (p, s->stringF.cstring);
      outText (p, (const char *) "\"", 1);
    }
  else
    {
      outText (p, (const char *) "'", 1);
      outRawS (p, s->stringF.cchar);
      outText (p, (const char *) "'", 1);
    }
}


/*
   doStringC -
*/

static void doStringC (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  mcDebug_assert (isString (n));
  /*
   s := InitStringCharStar (keyToCharStar (getSymName (n))) ;
   IF DynamicStrings.Length (s)>3
   THEN
      IF DynamicStrings.Index (s, '"', 0)=-1
      THEN
         s := DynamicStrings.Slice (s, 1, -1) ;
         outText (p, '"') ;
         outCstring (p, s) ;
         outText (p, '"')
      ELSIF DynamicStrings.Index (s, "'", 0)=-1
      THEN
         s := DynamicStrings.Slice (s, 1, -1) ;
         outText (p, '"') ;
         outCstring (p, s) ;
         outText (p, '"')
      ELSE
         metaError1 ('illegal string {%1k}', n)
      END
   ELSIF DynamicStrings.Length (s) = 3
   THEN
      s := DynamicStrings.Slice (s, 1, -1) ;
      outText (p, "'") ;
      IF DynamicStrings.char (s, 0) = "'"
      THEN
         outText (p, "\'")
      ELSIF DynamicStrings.char (s, 0) = "\"
      THEN
         outText (p, "\\")
      ELSE
         outTextS (p, s)
      END ;
      outText (p, "'")
   ELSE
      outText (p, "'\0'")
   END ;
   s := KillString (s)
  */
  outCstring (p, n, ! n->stringF.isCharCompatible);
}


/*
   isPunct -
*/

static bool isPunct (char ch)
{
  return (((((((((ch == '.') || (ch == '(')) || (ch == ')')) || (ch == '^')) || (ch == ':')) || (ch == ';')) || (ch == '{')) || (ch == '}')) || (ch == ',')) || (ch == '*');
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isWhite -
*/

static bool isWhite (char ch)
{
  return ((ch == ' ') || (ch == ASCII_tab)) || (ch == ASCII_lf);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   outText -
*/

static void outText (mcPretty_pretty p, const char *a_, unsigned int _a_high)
{
  DynamicStrings_String s;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  s = DynamicStrings_InitString ((const char *) a, _a_high);
  outTextS (p, s);
  s = DynamicStrings_KillString (s);
}


/*
   outRawS -
*/

static void outRawS (mcPretty_pretty p, DynamicStrings_String s)
{
  mcPretty_raw (p, s);
}


/*
   outKm2 -
*/

static mcPretty_pretty outKm2 (mcPretty_pretty p, const char *a_, unsigned int _a_high)
{
  unsigned int i;
  DynamicStrings_String s;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  if (StrLib_StrEqual ((const char *) a, _a_high, (const char *) "RECORD", 6))
    {
      p = mcPretty_pushPretty (p);
      i = mcPretty_getcurpos (p);
      mcPretty_setindent (p, i);
      outText (p, (const char *) a, _a_high);
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, i+indentation);
    }
  else if (StrLib_StrEqual ((const char *) a, _a_high, (const char *) "END", 3))
    {
      /* avoid dangling else.  */
      p = mcPretty_popPretty (p);
      outText (p, (const char *) a, _a_high);
      p = mcPretty_popPretty (p);
    }
  return p;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   outKc -
*/

static mcPretty_pretty outKc (mcPretty_pretty p, const char *a_, unsigned int _a_high)
{
  int i;
  unsigned int c;
  DynamicStrings_String s;
  DynamicStrings_String t;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  s = DynamicStrings_InitString ((const char *) a, _a_high);
  i = DynamicStrings_Index (s, '\\', 0);
  if (i == -1)
    {
      t = static_cast<DynamicStrings_String> (NULL);
    }
  else
    {
      t = DynamicStrings_Slice (s, i, 0);
      s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, i);
    }
  if ((DynamicStrings_char (s, 0)) == '{')
    {
      p = mcPretty_pushPretty (p);
      c = mcPretty_getcurpos (p);
      mcPretty_setindent (p, c);
      outTextS (p, s);
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, c+indentationC);
    }
  else if ((DynamicStrings_char (s, 0)) == '}')
    {
      /* avoid dangling else.  */
      p = mcPretty_popPretty (p);
      outTextS (p, s);
      p = mcPretty_popPretty (p);
    }
  outTextS (p, t);
  t = DynamicStrings_KillString (t);
  s = DynamicStrings_KillString (s);
  return p;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   outTextS -
*/

static void outTextS (mcPretty_pretty p, DynamicStrings_String s)
{
  if (s != NULL)
    {
      mcPretty_prints (p, s);
    }
}


/*
   outCard -
*/

static void outCard (mcPretty_pretty p, unsigned int c)
{
  DynamicStrings_String s;

  s = StringConvert_CardinalToString (c, 0, ' ', 10, false);
  outTextS (p, s);
  s = DynamicStrings_KillString (s);
}


/*
   outTextN -
*/

static void outTextN (mcPretty_pretty p, nameKey_Name n)
{
  DynamicStrings_String s;

  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n));
  mcPretty_prints (p, s);
  s = DynamicStrings_KillString (s);
}


/*
   outputEnumerationC -
*/

static void outputEnumerationC (mcPretty_pretty p, decl_node__opaque n)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque s;
  DynamicStrings_String t;

  outText (p, (const char *) "enum {", 6);
  i = Indexing_LowIndice (n->enumerationF.listOfSons);
  h = Indexing_HighIndice (n->enumerationF.listOfSons);
  while (i <= h)
    {
      s = static_cast<decl_node__opaque> (Indexing_GetIndice (n->enumerationF.listOfSons, i));
      doFQDNameC (p, s, false);
      if (i < h)
        {
          outText (p, (const char *) ",", 1);
          mcPretty_setNeedSpace (p);
        }
      i += 1;
    }
  outText (p, (const char *) "}", 1);
}


/*
   isDeclType - return TRUE if the current module should declare type.
*/

static bool isDeclType (decl_node__opaque type)
{
  decl_node__opaque n;
  decl_node__opaque def;
  nameKey_Name name;

  if (decl_isImp (static_cast<decl_node> (currentModule)))
    {
      name = decl_getSymName (static_cast<decl_node> (type));
      if (name != nameKey_NulName)
        {
          /* Lookup the matching .def module.  */
          def = static_cast<decl_node__opaque> (decl_lookupDef (decl_getSymName (static_cast<decl_node> (currentModule))));
          if (def != NULL)
            {
              /* Return TRUE if the symbol has not already been declared in the .def.  */
              return (decl_lookupExported (static_cast<decl_node> (def), name)) == NULL;
            }
        }
    }
  return true;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doEnumerationC -
*/

static void doEnumerationC (mcPretty_pretty p, decl_node__opaque n)
{
  if (isDeclType (n))
    {
      outputEnumerationC (p, n);
    }
}


/*
   doNamesC -
*/

static void doNamesC (mcPretty_pretty p, nameKey_Name n)
{
  DynamicStrings_String s;

  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n));
  outTextS (p, s);
  s = DynamicStrings_KillString (s);
}


/*
   doNameC -
*/

static void doNameC (mcPretty_pretty p, decl_node__opaque n)
{
  if ((n != NULL) && ((decl_getSymName (static_cast<decl_node> (n))) != nameKey_NulName))
    {
      doNamesC (p, decl_getSymName (static_cast<decl_node> (n)));
    }
}


/*
   initCname -
*/

static void initCname (decl_cnameT *c)
{
  (*c).init = false;
}


/*
   doCname -
*/

static nameKey_Name doCname (nameKey_Name n, decl_cnameT *c, bool scopes)
{
  DynamicStrings_String s;

  if ((*c).init)
    {
      return (*c).name;
    }
  else
    {
      (*c).init = true;
      s = keyc_cname (n, scopes);
      if (s == NULL)
        {
          (*c).name = n;
        }
      else
        {
          (*c).name = nameKey_makekey (DynamicStrings_string (s));
          s = DynamicStrings_KillString (s);
        }
      return (*c).name;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getDName -
*/

static nameKey_Name getDName (decl_node__opaque n, bool scopes)
{
  nameKey_Name m;

  m = decl_getSymName (static_cast<decl_node> (n));
  switch (n->kind)
    {
      case decl_procedure:
        return doCname (m, &n->procedureF.cname, scopes);
        break;

      case decl_var:
        return doCname (m, &n->varF.cname, scopes);
        break;

      case decl_recordfield:
        return doCname (m, &n->recordfieldF.cname, scopes);
        break;

      case decl_enumerationfield:
        return doCname (m, &n->enumerationfieldF.cname, scopes);
        break;


      default:
        break;
    }
  return m;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doDNameC -
*/

static void doDNameC (mcPretty_pretty p, decl_node__opaque n, bool scopes)
{
  if ((n != NULL) && ((decl_getSymName (static_cast<decl_node> (n))) != nameKey_NulName))
    {
      doNamesC (p, getDName (n, scopes));
    }
}


/*
   doFQDNameC -
*/

static void doFQDNameC (mcPretty_pretty p, decl_node__opaque n, bool scopes)
{
  DynamicStrings_String s;

  s = getFQDstring (n, scopes);
  outTextS (p, s);
  s = DynamicStrings_KillString (s);
}


/*
   doFQNameC -
*/

static void doFQNameC (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  s = getFQstring (n);
  outTextS (p, s);
  s = DynamicStrings_KillString (s);
}


/*
   doNameM2 -
*/

static void doNameM2 (mcPretty_pretty p, decl_node__opaque n)
{
  doNameC (p, n);
}


/*
   doUsed -
*/

static void doUsed (mcPretty_pretty p, bool used)
{
  if (! used)
    {
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "__attribute__((unused))", 23);
    }
}


/*
   doHighC -
*/

static void doHighC (mcPretty_pretty p, decl_node__opaque a, nameKey_Name n, bool isused)
{
  if ((decl_isArray (static_cast<decl_node> (a))) && (decl_isUnbounded (static_cast<decl_node> (a))))
    {
      /* need to display high.  */
      mcPretty_print (p, (const char *) ",", 1);
      mcPretty_setNeedSpace (p);
      doTypeNameC (p, cardinalN);
      mcPretty_setNeedSpace (p);
      mcPretty_print (p, (const char *) "_", 1);
      outTextN (p, n);
      mcPretty_print (p, (const char *) "_high", 5);
      doUsed (p, isused);
    }
}


/*
   doParamConstCast -
*/

static void doParamConstCast (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque ptype;

  ptype = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (((decl_isArray (static_cast<decl_node> (ptype))) && (decl_isUnbounded (static_cast<decl_node> (ptype)))) && (lang == decl_ansiCP))
    {
      outText (p, (const char *) "const", 5);
      mcPretty_setNeedSpace (p);
    }
}


/*
   getParameterVariable - returns the variable which shadows the parameter
                          named, m, in parameter block, n.
*/

static decl_node__opaque getParameterVariable (decl_node__opaque n, nameKey_Name m)
{
  decl_node__opaque p;

  mcDebug_assert ((decl_isParam (static_cast<decl_node> (n))) || (decl_isVarParam (static_cast<decl_node> (n))));
  if (decl_isParam (static_cast<decl_node> (n)))
    {
      p = n->paramF.scope;
    }
  else
    {
      p = n->varparamF.scope;
    }
  mcDebug_assert (decl_isProcedure (static_cast<decl_node> (p)));
  return static_cast<decl_node__opaque> (decl_lookupInScope (static_cast<decl_node> (p), m));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doParamTypeEmit - emit parameter type for C/C++.  It checks to see if the
                     parameter type is a procedure type and if it were declared
                     in a definition module for "C" and if so it uses the "C"
                     definition for a procedure type, rather than the mc
                     C++ version.
*/

static void doParamTypeEmit (mcPretty_pretty p, decl_node__opaque paramnode, decl_node__opaque paramtype)
{
  mcDebug_assert ((decl_isParam (static_cast<decl_node> (paramnode))) || (decl_isVarParam (static_cast<decl_node> (paramnode))));
  if ((isForC (paramnode)) && (decl_isProcType (decl_skipType (static_cast<decl_node> (paramtype)))))
    {
      doFQNameC (p, paramtype);
      outText (p, (const char *) "_C", 2);
    }
  else
    {
      doTypeNameC (p, paramtype);
      doOpaqueModifier (p, paramnode);
    }
  /*
      IF nodeUsesOpaque (paramnode) AND (NOT getNodeOpaqueVoidStar (paramnode))
      THEN
         outText (p, '__opaque')
      END
  */
}


/*
   doParamTypeNameModifier - Add an _ to an unbounded parameter which is non var.
*/

static void doParamTypeNameModifier (mcPretty_pretty p, decl_node__opaque ptype, bool varparam)
{
  if ((! varparam && (decl_isArray (static_cast<decl_node> (ptype)))) && (decl_isUnbounded (static_cast<decl_node> (ptype))))
    {
      outText (p, (const char *) "_", 1);
    }
}


/*
   initOpaqueCastState - assign fields opaque and voidstar in opaquestate.
*/

static void initOpaqueCastState (decl_opaqueCastState *opaquestate, bool opaque, bool voidstar)
{
  (*opaquestate).opaque = opaque;
  (*opaquestate).voidStar = voidstar;
}


/*
   initNodeOpaqueCastState - assign opaque and currentvoidstar
*/

static void initNodeOpaqueCastState (decl_node__opaque n, bool opaque, bool voidstar)
{
  switch (n->kind)
    {
      case decl_opaquecast:
        initOpaqueCastState (&n->opaquecastF.opaqueState, opaque, voidstar);
        break;

      case decl_funccall:
        initOpaqueCastState (&n->funccallF.opaqueState, opaque, voidstar);
        break;

      case decl_var:
        initOpaqueCastState (&n->varF.opaqueState, opaque, voidstar);
        break;

      case decl_array:
        initOpaqueCastState (&n->arrayF.opaqueState, opaque, voidstar);
        break;

      case decl_varparam:
        initOpaqueCastState (&n->varparamF.opaqueState, opaque, voidstar);
        break;

      case decl_param:
        initOpaqueCastState (&n->paramF.opaqueState, opaque, voidstar);
        break;

      case decl_pointer:
        initOpaqueCastState (&n->pointerF.opaqueState, opaque, voidstar);
        break;

      case decl_recordfield:
        initOpaqueCastState (&n->recordfieldF.opaqueState, opaque, voidstar);
        break;

      case decl_componentref:
        initOpaqueCastState (&n->componentrefF.opaqueState, opaque, voidstar);
        break;

      case decl_pointerref:
        initOpaqueCastState (&n->pointerrefF.opaqueState, opaque, voidstar);
        break;

      case decl_arrayref:
        initOpaqueCastState (&n->arrayrefF.opaqueState, opaque, voidstar);
        break;

      case decl_procedure:
        initOpaqueCastState (&n->procedureF.opaqueState, opaque, voidstar);
        break;

      case decl_proctype:
        initOpaqueCastState (&n->proctypeF.opaqueState, opaque, voidstar);
        break;


      default:
        M2RTS_HALT (-1);
        __builtin_unreachable ();
        break;
    }
}


/*
   setOpaqueCastState - set the voidStar field in opaquestate.
*/

static void setOpaqueCastState (decl_opaqueCastState *opaquestate, bool voidstar)
{
  (*opaquestate).voidStar = voidstar;
}


/*
   setNodeOpaqueVoidStar - sets the voidStar field in node to voidstar.
*/

static void setNodeOpaqueVoidStar (decl_node__opaque n, bool voidstar)
{
  mcDebug_assert (nodeUsesOpaque (n));
  switch (n->kind)
    {
      case decl_opaquecast:
        setOpaqueCastState (&n->opaquecastF.opaqueState, voidstar);
        break;

      case decl_funccall:
        setOpaqueCastState (&n->funccallF.opaqueState, voidstar);
        break;

      case decl_var:
        setOpaqueCastState (&n->varF.opaqueState, voidstar);
        break;

      case decl_array:
        setOpaqueCastState (&n->arrayF.opaqueState, voidstar);
        break;

      case decl_varparam:
        setOpaqueCastState (&n->varparamF.opaqueState, voidstar);
        break;

      case decl_param:
        setOpaqueCastState (&n->paramF.opaqueState, voidstar);
        break;

      case decl_pointer:
        setOpaqueCastState (&n->pointerF.opaqueState, voidstar);
        break;

      case decl_recordfield:
        setOpaqueCastState (&n->recordfieldF.opaqueState, voidstar);
        break;

      case decl_componentref:
        mcDebug_assert (! voidstar);
        setOpaqueCastState (&n->componentrefF.opaqueState, voidstar);
        break;

      case decl_pointerref:
        mcDebug_assert (! voidstar);
        setOpaqueCastState (&n->pointerrefF.opaqueState, voidstar);
        break;

      case decl_arrayref:
        setOpaqueCastState (&n->arrayrefF.opaqueState, voidstar);
        break;

      case decl_procedure:
        setOpaqueCastState (&n->procedureF.opaqueState, voidstar);
        break;

      case decl_proctype:
        setOpaqueCastState (&n->proctypeF.opaqueState, voidstar);
        break;


      default:
        M2RTS_HALT (-1);
        __builtin_unreachable ();
        break;
    }
}


/*
   nodeUsesOpaque - return TRUE if node n uses an opaque type.
*/

static bool nodeUsesOpaque (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_opaquecast:
        return n->opaquecastF.opaqueState.opaque;
        break;

      case decl_funccall:
        return n->funccallF.opaqueState.opaque;
        break;

      case decl_var:
        return n->varF.opaqueState.opaque;
        break;

      case decl_array:
        return n->arrayF.opaqueState.opaque;
        break;

      case decl_varparam:
        return n->varparamF.opaqueState.opaque;
        break;

      case decl_param:
        return n->paramF.opaqueState.opaque;
        break;

      case decl_pointer:
        return n->pointerF.opaqueState.opaque;
        break;

      case decl_recordfield:
        return n->recordfieldF.opaqueState.opaque;
        break;

      case decl_componentref:
        return n->componentrefF.opaqueState.opaque;
        break;

      case decl_pointerref:
        return n->pointerrefF.opaqueState.opaque;
        break;

      case decl_arrayref:
        return n->arrayrefF.opaqueState.opaque;
        break;

      case decl_procedure:
        return n->procedureF.opaqueState.opaque;
        break;

      case decl_proctype:
        return n->proctypeF.opaqueState.opaque;
        break;

      case decl_deref:
        return nodeUsesOpaque (n->unaryF.arg);
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getNodeOpaqueVoidStar - return TRUE if the opaque type used by node n is a void *.
*/

static bool getNodeOpaqueVoidStar (decl_node__opaque n)
{
  mcDebug_assert (nodeUsesOpaque (n));
  switch (n->kind)
    {
      case decl_opaquecast:
        return n->opaquecastF.opaqueState.voidStar;
        break;

      case decl_funccall:
        return n->funccallF.opaqueState.voidStar;
        break;

      case decl_var:
        return n->varF.opaqueState.voidStar;
        break;

      case decl_array:
        return n->arrayF.opaqueState.voidStar;
        break;

      case decl_varparam:
        return n->varparamF.opaqueState.voidStar;
        break;

      case decl_param:
        return n->paramF.opaqueState.voidStar;
        break;

      case decl_pointer:
        return n->pointerF.opaqueState.voidStar;
        break;

      case decl_recordfield:
        return n->recordfieldF.opaqueState.voidStar;
        break;

      case decl_componentref:
        return n->componentrefF.opaqueState.voidStar;
        break;

      case decl_pointerref:
        return n->pointerrefF.opaqueState.voidStar;
        break;

      case decl_arrayref:
        return n->arrayrefF.opaqueState.voidStar;
        break;

      case decl_procedure:
        return n->procedureF.opaqueState.voidStar;
        break;

      case decl_proctype:
        return n->proctypeF.opaqueState.voidStar;
        break;

      case decl_deref:
        return false;
        break;


      default:
        M2RTS_HALT (-1);
        __builtin_unreachable ();
        break;
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   getOpaqueFlushNecessary - return TRUE if the value next differs from the opaque state.
*/

static bool getOpaqueFlushNecessary (decl_opaqueCastState state, bool next)
{
  return state.opaque && (state.voidStar != next);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getNodeOpaqueFlushNecessary - return TRUE if the value of next requires a cast.
*/

static bool getNodeOpaqueFlushNecessary (decl_node__opaque n, bool next)
{
  switch (n->kind)
    {
      case decl_opaquecast:
        return getOpaqueFlushNecessary (n->opaquecastF.opaqueState, next);
        break;

      case decl_funccall:
        return getOpaqueFlushNecessary (n->funccallF.opaqueState, next);
        break;

      case decl_var:
        return getOpaqueFlushNecessary (n->varF.opaqueState, next);
        break;

      case decl_array:
        return getOpaqueFlushNecessary (n->arrayF.opaqueState, next);
        break;

      case decl_varparam:
        return getOpaqueFlushNecessary (n->varparamF.opaqueState, next);
        break;

      case decl_param:
        return getOpaqueFlushNecessary (n->paramF.opaqueState, next);
        break;

      case decl_pointer:
        return getOpaqueFlushNecessary (n->pointerF.opaqueState, next);
        break;

      case decl_recordfield:
        return getOpaqueFlushNecessary (n->recordfieldF.opaqueState, next);
        break;

      case decl_componentref:
        return getOpaqueFlushNecessary (n->componentrefF.opaqueState, next);
        break;

      case decl_pointerref:
        return getOpaqueFlushNecessary (n->pointerrefF.opaqueState, next);
        break;

      case decl_arrayref:
        return getOpaqueFlushNecessary (n->arrayrefF.opaqueState, next);
        break;

      case decl_procedure:
        return getOpaqueFlushNecessary (n->procedureF.opaqueState, next);
        break;

      case decl_proctype:
        return getOpaqueFlushNecessary (n->proctypeF.opaqueState, next);
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeOpaqueCast - wrap node n with an opaquecast node and assign
                    voidstar into the new opaque state.
*/

static decl_node__opaque makeOpaqueCast (decl_node__opaque n, bool voidstar)
{
  decl_node__opaque o;

  o = newNode (decl_opaquecast);
  o->opaquecastF.exp = n;
  initOpaqueCastState (&o->opaquecastF.opaqueState, true, voidstar);
  return o;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   flushOpaque - perform a cast to voidstar (if necessary) and ignore the new
                 node which could be created.
*/

static void flushOpaque (mcPretty_pretty p, decl_node__opaque n, bool toVoidStar)
{
  decl_node__opaque o;

  o = castOpaque (p, n, toVoidStar);
}


/*
   castOpaque - flushes the opaque type casts if necessary and changes the
                voidstar boolean value.   If necessary it creates a opaquecast
                and returns the new node otherwise return n.
*/

static decl_node__opaque castOpaque (mcPretty_pretty p, decl_node__opaque n, bool toVoidStar)
{
  decl_node__opaque type;

  if (getNodeOpaqueFlushNecessary (n, toVoidStar))
    {
      type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
      if (toVoidStar)
        {
          /* next is true cast to void * opaque type.  */
          outText (p, (const char *) "static_cast<", 12);
          doTypeNameC (p, type);
          mcPretty_noSpace (p);
          outText (p, (const char *) "> (", 3);
          doExprC (p, n);
          outText (p, (const char *) ")", 1);
          return makeOpaqueCast (n, true);
        }
      else
        {
          /* next is false cast to __opaque opaque type.  */
          outText (p, (const char *) "static_cast<", 12);
          doTypeNameC (p, type);
          outText (p, (const char *) "__opaque", 8);
          mcPretty_noSpace (p);
          outText (p, (const char *) "> (", 3);
          doExprC (p, n);
          outText (p, (const char *) ")", 1);
          return makeOpaqueCast (n, false);
        }
    }
  else
    {
      if (debugOpaque)
        {
          doP = p;
          dumpOpaqueState (n);
          if (nodeUsesOpaque (n))
            {
              outText (p, (const char *) " /* no difference seen */ ", 26);
            }
          else
            {
              outText (p, (const char *) " /* no opaque used */ ", 22);
            }
        }
      doExprC (p, n);
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isTypeOpaqueDefImp - returns TRUE if type is an opaque type by checking
                        the def/imp pair of modules or fall back to the
                        definition module.
*/

static bool isTypeOpaqueDefImp (decl_node__opaque type)
{
  decl_node__opaque scope;
  decl_node__opaque def;
  decl_node__opaque opaque;

  if (type == NULL)
    {
      return false;
    }
  else if (decl_isType (static_cast<decl_node> (type)))
    {
      /* avoid dangling else.  */
      scope = static_cast<decl_node__opaque> (decl_getScope (static_cast<decl_node> (type)));
      if (decl_isImp (static_cast<decl_node> (scope)))
        {
          /* avoid dangling else.  */
          def = static_cast<decl_node__opaque> (decl_lookupDef (decl_getSymName (static_cast<decl_node> (scope))));
          if (def != NULL)
            {
              /* Lookup the type name in the matching definition module.  */
              opaque = static_cast<decl_node__opaque> (decl_lookupExported (static_cast<decl_node> (def), decl_getSymName (static_cast<decl_node> (type))));
              return ((opaque != NULL) && (decl_isType (static_cast<decl_node> (opaque)))) && (decl_isTypeOpaque (static_cast<decl_node> (opaque)));
            }
        }
      else
        {
          /* Otherwise just check the definition module.  */
          return decl_isTypeOpaque (static_cast<decl_node> (type));
        }
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isParamVoidStar - return TRUE if the procedure or proctype opaque type
                     parameter should be implemented as a (void * ).
*/

static bool isParamVoidStar (decl_node__opaque n)
{
  decl_node__opaque proc;
  decl_node__opaque type;

  proc = static_cast<decl_node__opaque> (decl_getScope (static_cast<decl_node> (n)));
  mcDebug_assert ((decl_isProcedure (static_cast<decl_node> (proc))) || (decl_isProcType (static_cast<decl_node> (proc))));
  type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  return isReturnVoidStar (proc, type);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isRefVoidStar - returns TRUE if the ref node uses an opaque type which
                   is represented as a (void * ).
*/

static bool isRefVoidStar (decl_node__opaque n)
{
  decl_node__opaque type;

  type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if ((! (decl_isType (static_cast<decl_node> (type)))) || (! (decl_isTypeOpaque (static_cast<decl_node> (type)))))
    {
      /* We should finish the procedure as the ref does not use an opaque.  */
      return true;
    }
  else
    {
      /* We check whether the opaque type was declared in the implementation
         module.  If it is declared in the implementation module then we
         return FALSE.  */
      return ! (isDeclInImp (type));
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isReturnVoidStar - return TRUE if the procedure or proctype opaque type
                      return type should be implemented as a (void * ).
*/

static bool isReturnVoidStar (decl_node__opaque proc, decl_node__opaque type)
{
  decl_node__opaque def;

  mcDebug_assert ((decl_isProcedure (static_cast<decl_node> (proc))) || (decl_isProcType (static_cast<decl_node> (proc))));
  if (decl_isExported (static_cast<decl_node> (proc)))
    {
      return true;
    }
  else
    {
      /* Not exported therefore local, we check whether the opaque type
         was declared in the implementation module.  */
      if (decl_isImp (static_cast<decl_node> (currentModule)))
        {
          if (decl_isType (static_cast<decl_node> (type)))
            {
              return ! (isDeclInImp (type));
            }
          else
            {
              return false;
            }
        }
      else
        {
          /* Always use void * in .def modules.  */
          return true;
        }
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isVarVoidStar - return TRUE if the variable using an opaque type should
                   be implemented as a (void * ).
*/

static bool isVarVoidStar (decl_node__opaque n)
{
  decl_node__opaque type;

  mcDebug_assert (decl_isVar (static_cast<decl_node> (n)));
  type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if ((! (decl_isType (static_cast<decl_node> (type)))) || (! (decl_isTypeOpaque (static_cast<decl_node> (type)))))
    {
      /* We should finish the procedure as the variable does not use an opaque.  */
      return true;
    }
  else if (decl_isExported (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      /* Exported variables using an opaque type will always be implemented
         with a (void * ).  */
      return true;
    }
  else
    {
      /* avoid dangling else.  */
      /* Not exported therefore static to the module (local or global non exported
         variable), we check whether the opaque type was declared in the
         implementation module.  If it is declared in the implementation module
         then we return FALSE.  */
      return ! (isDeclInImp (type));
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   initNodeOpaqueState - initialize the node opaque state.
*/

static void initNodeOpaqueState (decl_node__opaque n)
{
  decl_node__opaque type;

  switch (n->kind)
    {
      case decl_opaquecast:
        break;

      case decl_funccall:
        assignNodeOpaqueCastState (n, getFunction (n));  /* This must be done when the cast direction is known.  */
        break;

      case decl_var:
        type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
        if (n->varF.isParameter || n->varF.isVarParameter)
          {
            /* If the variable is really a parameter then it uses
                        the state of the parameter.  */
            initNodeOpaqueCastState (n, isTypeOpaqueDefImp (type), isParamVoidStar (n));
          }
        else
          {
            initNodeOpaqueCastState (n, isTypeOpaqueDefImp (type), isVarVoidStar (n));
          }
        break;

      case decl_array:
        type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
        initNodeOpaqueCastState (n, isTypeOpaqueDefImp (type), decl_isExported (static_cast<decl_node> (n)));
        break;

      case decl_varparam:
      case decl_param:
        mcDebug_assert ((decl_isProcedure (decl_getScope (static_cast<decl_node> (n)))) || (decl_isProcType (decl_getScope (static_cast<decl_node> (n)))));
        type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
        initNodeOpaqueCastState (n, isTypeOpaqueDefImp (type), isParamVoidStar (n));
        break;

      case decl_componentref:
      case decl_pointerref:
      case decl_pointer:
      case decl_recordfield:
      case decl_arrayref:
        type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
        /* In the future this should be revisited.  */
        initNodeOpaqueCastState (n, isTypeOpaqueDefImp (type), isRefVoidStar (n));
        break;

      case decl_proctype:
      case decl_procedure:
        type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));  /* We only consider the return type for a procedure or proctype.
                     The parameters and local vars are handled separately (see
                     above).  */
        if (type == NULL)
          {
            /* No return type, therefore no opaque type used.  */
            initNodeOpaqueCastState (n, false, false);
          }
        else
          {
            /* Init state from the return type.  Is type an opaque type?
                        Is the opaque type declared in this module?  */
            initNodeOpaqueCastState (n, isTypeOpaqueDefImp (type), isReturnVoidStar (n, type));
          }
        break;


      default:
        break;
    }
  if (debugOpaque)
    {
      dumpOpaqueState (n);
    }
}


/*
   assignNodeOpaqueCastState - copy the opaqueCastState from src into dest.
*/

static void assignNodeOpaqueCastState (decl_node__opaque dest, decl_node__opaque src)
{
  if (nodeUsesOpaque (src))
    {
      initNodeOpaqueCastState (dest, true, getNodeOpaqueVoidStar (src));
    }
  else
    {
      initNodeOpaqueCastState (dest, false, false);
    }
}


/*
   assignNodeOpaqueCastFalse - assign the voidstar field of dest to false.
                               It assigns the opaque field of dest to the value
                               of the src opaque field.
*/

static void assignNodeOpaqueCastFalse (decl_node__opaque dest, decl_node__opaque src)
{
  if (nodeUsesOpaque (src))
    {
      initNodeOpaqueCastState (dest, true, false);
    }
  else
    {
      initNodeOpaqueCastState (dest, false, false);
    }
}


/*
   dumpOpaqueState -
*/

static void dumpOpaqueState (decl_node__opaque n)
{
  decl_node__opaque o;

  switch (n->kind)
    {
      case decl_opaquecast:
      case decl_funccall:
      case decl_var:
      case decl_array:
      case decl_varparam:
      case decl_param:
      case decl_pointer:
      case decl_recordfield:
      case decl_componentref:
      case decl_arrayref:
      case decl_procedure:
      case decl_proctype:
        o = n;
        break;


      default:
        o = static_cast<decl_node__opaque> (NULL);
        break;
    }
  if (o != NULL)
    {
      outText (doP, (const char *) "/* ", 3);
      doNameC (doP, o);
      outText (doP, (const char *) "  ", 2);
      switch (o->kind)
        {
          case decl_opaquecast:
            outText (doP, (const char *) "opaquecast", 10);
            break;

          case decl_funccall:
            outText (doP, (const char *) "funccall", 8);
            break;

          case decl_var:
            outText (doP, (const char *) "var", 3);
            break;

          case decl_array:
            outText (doP, (const char *) "array", 5);
            break;

          case decl_varparam:
            outText (doP, (const char *) "varparam", 8);
            break;

          case decl_param:
            outText (doP, (const char *) "param", 5);
            break;

          case decl_pointer:
            outText (doP, (const char *) "pointer", 7);
            break;

          case decl_recordfield:
            outText (doP, (const char *) "recordfield", 11);
            break;

          case decl_componentref:
            outText (doP, (const char *) "componentref", 12);
            break;

          case decl_pointerref:
            outText (doP, (const char *) "pointerref", 10);
            break;

          case decl_arrayref:
            outText (doP, (const char *) "arrayref", 8);
            break;

          case decl_procedure:
            outText (doP, (const char *) "procedure", 9);
            break;

          case decl_proctype:
            outText (doP, (const char *) "proctype", 8);
            break;


          default:
            break;
        }
      if (nodeUsesOpaque (o))
        {
          /* avoid gcc warning by using compound statement even if not strictly necessary.  */
          if (getNodeOpaqueVoidStar (o))
            {
              outText (doP, (const char *) " uses (void *) opaque", 21);
            }
          else
            {
              outText (doP, (const char *) " uses opaque__full", 18);
            }
        }
      outText (doP, (const char *) " */ \\n", 6);
    }
}


/*
   doParamC - emit parameter for C/C++.
*/

static void doParamC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque v;
  decl_node__opaque ptype;
  nameKey_Name i;
  unsigned int c;
  unsigned int t;
  wlists_wlist l;

  mcDebug_assert (decl_isParam (static_cast<decl_node> (n)));
  ptype = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (n->paramF.namelist == NULL)
    {
      /* avoid dangling else.  */
      doParamConstCast (p, n);
      doTypeNameC (p, ptype);
      doUsed (p, n->paramF.isUsed);
      if ((decl_isArray (static_cast<decl_node> (ptype))) && (decl_isUnbounded (static_cast<decl_node> (ptype))))
        {
          outText (p, (const char *) ",", 1);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "unsigned int", 12);
        }
    }
  else
    {
      mcDebug_assert (isIdentList (n->paramF.namelist));
      l = n->paramF.namelist->identlistF.names;
      if (l == NULL)
        {
          /* avoid dangling else.  */
          doParamConstCast (p, n);
          doParamTypeEmit (p, n, ptype);
          if ((decl_isArray (static_cast<decl_node> (ptype))) && (decl_isUnbounded (static_cast<decl_node> (ptype))))
            {
              doUsed (p, n->paramF.isUsed);
              outText (p, (const char *) ",", 1);
              mcPretty_setNeedSpace (p);
              outText (p, (const char *) "unsigned int", 12);
            }
        }
      else
        {
          t = wlists_noOfItemsInList (l);
          c = 1;
          while (c <= t)
            {
              doParamConstCast (p, n);
              doParamTypeEmit (p, n, ptype);
              i = static_cast<nameKey_Name> (wlists_getItemFromList (l, c));
              if ((decl_isArray (static_cast<decl_node> (ptype))) && (decl_isUnbounded (static_cast<decl_node> (ptype))))
                {
                  mcPretty_noSpace (p);
                }
              else
                {
                  mcPretty_setNeedSpace (p);
                }
              v = getParameterVariable (n, i);
              if (v == NULL)
                {
                  doNamesC (p, keyc_cnamen (i, true));
                }
              else
                {
                  doFQDNameC (p, v, true);
                }
              doParamTypeNameModifier (p, ptype, false);
              doUsed (p, n->paramF.isUsed);
              doHighC (p, ptype, i, n->paramF.isUsed);
              if (c < t)
                {
                  outText (p, (const char *) ",", 1);
                  mcPretty_setNeedSpace (p);
                }
              c += 1;
            }
        }
    }
}


/*
   doVarParamC - emit a VAR parameter for C/C++.
*/

static void doVarParamC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque v;
  decl_node__opaque ptype;
  nameKey_Name i;
  unsigned int c;
  unsigned int t;
  wlists_wlist l;

  mcDebug_assert (decl_isVarParam (static_cast<decl_node> (n)));
  ptype = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (n->varparamF.namelist == NULL)
    {
      /* avoid dangling else.  */
      doTypeNameC (p, ptype);
      /* doTypeC (p, ptype, n) ;  */
      if (! (decl_isArray (static_cast<decl_node> (ptype))))
        {
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "*", 1);
        }
      doUsed (p, n->varparamF.isUsed);
      if ((decl_isArray (static_cast<decl_node> (ptype))) && (decl_isUnbounded (static_cast<decl_node> (ptype))))
        {
          outText (p, (const char *) ",", 1);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "unsigned int", 12);
        }
    }
  else
    {
      mcDebug_assert (isIdentList (n->varparamF.namelist));
      l = n->varparamF.namelist->identlistF.names;
      if (l == NULL)
        {
          doParamTypeEmit (p, n, ptype);
          doUsed (p, n->varparamF.isUsed);
        }
      else
        {
          t = wlists_noOfItemsInList (l);
          c = 1;
          while (c <= t)
            {
              doParamTypeEmit (p, n, ptype);
              if (! (decl_isArray (static_cast<decl_node> (ptype))))
                {
                  mcPretty_setNeedSpace (p);
                  outText (p, (const char *) "*", 1);
                }
              i = static_cast<nameKey_Name> (wlists_getItemFromList (l, c));
              v = getParameterVariable (n, i);
              if (v == NULL)
                {
                  doNamesC (p, keyc_cnamen (i, true));
                }
              else
                {
                  doFQDNameC (p, v, true);
                }
              doParamTypeNameModifier (p, ptype, true);
              doUsed (p, n->varparamF.isUsed);
              doHighC (p, ptype, i, n->varparamF.isUsed);
              if (c < t)
                {
                  outText (p, (const char *) ",", 1);
                  mcPretty_setNeedSpace (p);
                }
              c += 1;
            }
        }
    }
}


/*
   doOptargC -
*/

static void doOptargC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque ptype;
  nameKey_Name i;
  unsigned int t;
  wlists_wlist l;

  mcDebug_assert (decl_isOptarg (static_cast<decl_node> (n)));
  ptype = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  mcDebug_assert (n->optargF.namelist != NULL);
  mcDebug_assert (isIdentList (n->paramF.namelist));
  l = n->paramF.namelist->identlistF.names;
  mcDebug_assert (l != NULL);
  t = wlists_noOfItemsInList (l);
  mcDebug_assert (t == 1);
  doTypeNameC (p, ptype);
  i = static_cast<nameKey_Name> (wlists_getItemFromList (l, 1));
  mcPretty_setNeedSpace (p);
  doNamesC (p, i);
}


/*
   doParameterC -
*/

static void doParameterC (mcPretty_pretty p, decl_node__opaque n)
{
  if (decl_isParam (static_cast<decl_node> (n)))
    {
      doParamC (p, n);
    }
  else if (decl_isVarParam (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doVarParamC (p, n);
    }
  else if (decl_isVarargs (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      mcPretty_print (p, (const char *) "...", 3);
    }
  else if (decl_isOptarg (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doOptargC (p, n);
    }
}


/*
   doProcTypeC -
*/

static void doProcTypeC (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque n)
{
  mcDebug_assert (decl_isType (static_cast<decl_node> (t)));
  if ((isDeclType (t)) && (isDeclType (n)))
    {
      outputPartial (t);
      doCompletePartialProcType (p, t, n);
    }
}


/*
   isDeclInImp - returns TRUE if node type is declared as an opaque and
                 is declared fully in the current implementation module.
                 This should only be called if isType (type).  Its purpose
                 is specific to a type checking whether it is an opaque type
                 declared in the .def/.mod pair of the current imp module.
*/

static bool isDeclInImp (decl_node__opaque type)
{
  decl_node__opaque scope;
  decl_node__opaque def;
  nameKey_Name name;

  mcDebug_assert (decl_isType (static_cast<decl_node> (type)));
  scope = static_cast<decl_node__opaque> (decl_getScope (static_cast<decl_node> (type)));
  if ((isTypeOpaqueDefImp (type)) && (decl_isImp (static_cast<decl_node> (currentModule))))
    {
      name = decl_getSymName (static_cast<decl_node> (type));
      if (name != nameKey_NulName)
        {
          /* Lookup the matching .def module.  */
          def = static_cast<decl_node__opaque> (decl_lookupDef (decl_getSymName (static_cast<decl_node> (currentModule))));
          if ((def != NULL) && ((def == scope) || (currentModule == scope)))
            {
              /* Return TRUE if the symbol has already been declared in the .def.  */
              return (decl_lookupExported (static_cast<decl_node> (def), name)) != NULL;
            }
        }
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doTypeNameModifier - adds the __opaque modifier to the type n provided
                        it is an opaque type which is being declared in the
                        implementation module.
*/

static void doTypeNameModifier (mcPretty_pretty p, decl_node__opaque n)
{
  if ((isTypeOpaqueDefImp (n)) && (decl_isImp (static_cast<decl_node> (currentModule))))
    {
      outText (p, (const char *) "__opaque", 8);
    }
}


/*
   isGccType - return TRUE if n is tree or location_t.
*/

static bool isGccType (decl_node__opaque n)
{
  return (mcOptions_getGccConfigSystem ()) && (((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "location_t", 10))) || ((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "tree", 4))));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doGccType - record whether we are going to declare tree or location_t
               so that the appropriate gcc header can be included instead.
*/

static void doGccType (mcPretty_pretty p, decl_node__opaque n)
{
  if (mcOptions_getGccConfigSystem ())
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if ((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "location_t", 10)))
        {
          outText (p, (const char *) "/* Not going to declare ", 24);
          doTypeNameC (p, n);
          outText (p, (const char *) " as it is declared in the gcc header input.h.  */\\n\\n", 53);
          keyc_useGccLocation ();
        }
      else if ((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "tree", 4)))
        {
          /* avoid dangling else.  */
          outText (p, (const char *) "/* Not going to declare ", 24);
          doTypeNameC (p, n);
          outText (p, (const char *) " as it is declared in the gcc header tree.h.  */\\n\\n", 52);
          keyc_useGccTree ();
        }
    }
}


/*
   isCDataType - return true if n is charStar or constCharStar.
*/

static bool isCDataType (decl_node__opaque n)
{
  return (n != NULL) && ((n == charStarN) || (n == constCharStarN));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isCDataTypes - return TRUE if n is CharStar or ConstCharStar.
*/

static bool isCDataTypes (decl_node__opaque n)
{
  decl_node__opaque scope;

  scope = static_cast<decl_node__opaque> (decl_getScope (static_cast<decl_node> (n)));
  return ((scope != NULL) && ((decl_getSymName (static_cast<decl_node> (scope))) == (nameKey_makeKey ((const char *) "CDataTypes", 10)))) && (((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "CharStar", 8))) || ((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "ConstCharStar", 13))));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doCDataTypes - if we are going to declare CharStar or ConstCharStar
               then generate a comment instead.
*/

static void doCDataTypes (mcPretty_pretty p, decl_node__opaque n)
{
  if (isCDataTypes (n))
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if ((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "CharStar", 8)))
        {
          outText (p, (const char *) "/* Not going to declare ", 24);
          doTypeNameC (p, n);
          outText (p, (const char *) " as it is a C type.  */\\n\\n", 27);
          charStarN = n;
        }
      else if ((decl_getSymName (static_cast<decl_node> (n))) == (nameKey_makeKey ((const char *) "ConstCharStar", 13)))
        {
          /* avoid dangling else.  */
          outText (p, (const char *) "/* Not going to declare ", 24);
          doTypeNameC (p, n);
          outText (p, (const char *) " as it is a C type.  */\\n\\n", 27);
          constCharStarN = n;
        }
    }
}


/*
   doCDataTypesC - generate the C representation of the CDataTypes data types.
*/

static void doCDataTypesC (mcPretty_pretty p, decl_node__opaque n)
{
  if (n == charStarN)
    {
      outText (p, (const char *) "char *", 6);
      mcPretty_setNeedSpace (p);
    }
  else if (n == constCharStarN)
    {
      /* avoid dangling else.  */
      outText (p, (const char *) "const char *", 12);
      mcPretty_setNeedSpace (p);
    }
}


/*
   doTypeOrPointer - only declare type or pointer n providing that
                     the name is not location_t or tree and
                     the --gccConfigSystem option is enabled.
*/

static void doTypeOrPointer (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque m;

  if (isGccType (n))
    {
      doGccType (p, n);
    }
  else if (isCDataTypes (n))
    {
      /* avoid dangling else.  */
      doCDataTypes (p, n);
    }
  else
    {
      /* avoid dangling else.  */
      m = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
      outText (p, (const char *) "typedef", 7);
      mcPretty_setNeedSpace (p);
      doTypeC (p, m, &m);
      if (decl_isType (static_cast<decl_node> (m)))
        {
          mcPretty_setNeedSpace (p);
        }
      doTypeNameC (p, n);
      doTypeNameModifier (p, n);
      outText (p, (const char *) ";\\n\\n", 5);
    }
}


/*
   doTypedef - generate a typedef for n provuiding it is not
*/

static void doTypedef (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque m;

  if (isGccType (n))
    {
      doGccType (p, n);
    }
  else if (isCDataTypes (n))
    {
      /* avoid dangling else.  */
      doCDataTypes (p, n);
    }
  else
    {
      /* avoid dangling else.  */
      m = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
      outText (p, (const char *) "typedef", 7);
      mcPretty_setNeedSpace (p);
      doTypeC (p, m, &m);
      if (decl_isType (static_cast<decl_node> (m)))
        {
          mcPretty_setNeedSpace (p);
        }
      doTypeNameC (p, n);
      doTypeNameModifier (p, n);
      outText (p, (const char *) ";\\n\\n", 5);
    }
}


/*
   doTypesC -
*/

static void doTypesC (decl_node__opaque n)
{
  decl_node__opaque m;

  if (decl_isType (static_cast<decl_node> (n)))
    {
      m = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
      if (decl_isProcType (static_cast<decl_node> (m)))
        {
          doProcTypeC (doP, n, m);
        }
      else if ((decl_isType (static_cast<decl_node> (m))) || (decl_isPointer (static_cast<decl_node> (m))))
        {
          /* avoid dangling else.  */
          doTypeOrPointer (doP, n);
        }
      else if (decl_isEnumeration (static_cast<decl_node> (m)))
        {
          /* avoid dangling else.  */
          if (isDeclType (n))
            {
              outText (doP, (const char *) "typedef", 7);
              mcPretty_setNeedSpace (doP);
              doTypeC (doP, m, &m);
              mcPretty_setNeedSpace (doP);
              doTypeNameC (doP, n);
              outText (doP, (const char *) ";\\n\\n", 5);
            }
        }
      else
        {
          /* avoid dangling else.  */
          doTypedef (doP, n);
        }
    }
}


/*
   doCompletePartialC -
*/

static void doCompletePartialC (decl_node__opaque n)
{
  decl_node__opaque m;

  if (decl_isType (static_cast<decl_node> (n)))
    {
      m = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
      if (decl_isRecord (static_cast<decl_node> (m)))
        {
          doCompletePartialRecord (doP, n, m);
        }
      else if (decl_isArray (static_cast<decl_node> (m)))
        {
          /* avoid dangling else.  */
          doCompletePartialArray (doP, n, m);
        }
      else if (decl_isProcType (static_cast<decl_node> (m)))
        {
          /* avoid dangling else.  */
          doCompletePartialProcType (doP, n, m);
        }
    }
}


/*
   doCompletePartialRecord -
*/

static void doCompletePartialRecord (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque r)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque f;

  mcDebug_assert (decl_isRecord (static_cast<decl_node> (r)));
  mcDebug_assert (decl_isType (static_cast<decl_node> (t)));
  outText (p, (const char *) "struct", 6);
  mcPretty_setNeedSpace (p);
  doFQNameC (p, t);
  outText (p, (const char *) "_r", 2);
  mcPretty_setNeedSpace (p);
  p = outKc (p, (const char *) "{\\n", 3);
  i = Indexing_LowIndice (r->recordF.listOfSons);
  h = Indexing_HighIndice (r->recordF.listOfSons);
  while (i <= h)
    {
      f = static_cast<decl_node__opaque> (Indexing_GetIndice (r->recordF.listOfSons, i));
      if (decl_isRecordField (static_cast<decl_node> (f)))
        {
          /* avoid dangling else.  */
          if (! f->recordfieldF.tag)
            {
              doRecordFieldC (p, f);
              outText (p, (const char *) ";\\n", 3);
            }
        }
      else if (decl_isVarient (static_cast<decl_node> (f)))
        {
          /* avoid dangling else.  */
          doVarientC (p, f);
          outText (p, (const char *) ";\\n", 3);
        }
      else if (decl_isVarientField (static_cast<decl_node> (f)))
        {
          /* avoid dangling else.  */
          doVarientFieldC (p, f);
        }
      i += 1;
    }
  p = outKc (p, (const char *) "};\\n\\n", 6);
}


/*
   doCompletePartialArray -
*/

static void doCompletePartialArray (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque r)
{
  decl_node__opaque type;
  decl_node__opaque s;

  mcDebug_assert (decl_isArray (static_cast<decl_node> (r)));
  type = r->arrayF.type;
  s = static_cast<decl_node__opaque> (NULL);
  outText (p, (const char *) "struct", 6);
  mcPretty_setNeedSpace (p);
  doFQNameC (p, t);
  outText (p, (const char *) "_a {", 4);
  mcPretty_setNeedSpace (p);
  doTypeC (p, type, &s);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "array[", 6);
  doSubrC (p, r->arrayF.subr);
  outText (p, (const char *) "];", 2);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "};\\n", 4);
}


/*
   lookupConst -
*/

static decl_node__opaque lookupConst (decl_node__opaque type, nameKey_Name n)
{
  return static_cast<decl_node__opaque> (decl_makeLiteralInt (n));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doMin -
*/

static decl_node__opaque doMin (decl_node__opaque n)
{
  if (n == booleanN)
    {
      return falseN;
    }
  else if (n == integerN)
    {
      /* avoid dangling else.  */
      keyc_useIntMin ();
      return lookupConst (integerN, nameKey_makeKey ((const char *) "INT_MIN", 7));
    }
  else if (n == cardinalN)
    {
      /* avoid dangling else.  */
      keyc_useUIntMin ();
      return lookupConst (cardinalN, nameKey_makeKey ((const char *) "UINT_MIN", 8));
    }
  else if (n == longintN)
    {
      /* avoid dangling else.  */
      keyc_useLongMin ();
      return lookupConst (longintN, nameKey_makeKey ((const char *) "LONG_MIN", 8));
    }
  else if (n == longcardN)
    {
      /* avoid dangling else.  */
      keyc_useULongMin ();
      return lookupConst (longcardN, nameKey_makeKey ((const char *) "LONG_MIN", 8));
    }
  else if (n == charN)
    {
      /* avoid dangling else.  */
      keyc_useCharMin ();
      return lookupConst (charN, nameKey_makeKey ((const char *) "CHAR_MIN", 8));
    }
  else if (n == bitsetN)
    {
      /* avoid dangling else.  */
      mcDebug_assert (decl_isSubrange (static_cast<decl_node> (bitnumN)));
      return bitnumN->subrangeF.low;
    }
  else if (n == locN)
    {
      /* avoid dangling else.  */
      keyc_useUCharMin ();
      return lookupConst (locN, nameKey_makeKey ((const char *) "UCHAR_MIN", 9));
    }
  else if (n == byteN)
    {
      /* avoid dangling else.  */
      keyc_useUCharMin ();
      return lookupConst (byteN, nameKey_makeKey ((const char *) "UCHAR_MIN", 9));
    }
  else if (n == wordN)
    {
      /* avoid dangling else.  */
      keyc_useUIntMin ();
      return lookupConst (wordN, nameKey_makeKey ((const char *) "UCHAR_MIN", 9));
    }
  else if (n == addressN)
    {
      /* avoid dangling else.  */
      return lookupConst (addressN, nameKey_makeKey ((const char *) "((void *) 0)", 12));
    }
  else
    {
      /* avoid dangling else.  */
      M2RTS_HALT (-1);  /* finish the cacading elsif statement.  */
      __builtin_unreachable ();
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   doMax -
*/

static decl_node__opaque doMax (decl_node__opaque n)
{
  if (n == booleanN)
    {
      return trueN;
    }
  else if (n == integerN)
    {
      /* avoid dangling else.  */
      keyc_useIntMax ();
      return lookupConst (integerN, nameKey_makeKey ((const char *) "INT_MAX", 7));
    }
  else if (n == cardinalN)
    {
      /* avoid dangling else.  */
      keyc_useUIntMax ();
      return lookupConst (cardinalN, nameKey_makeKey ((const char *) "UINT_MAX", 8));
    }
  else if (n == longintN)
    {
      /* avoid dangling else.  */
      keyc_useLongMax ();
      return lookupConst (longintN, nameKey_makeKey ((const char *) "LONG_MAX", 8));
    }
  else if (n == longcardN)
    {
      /* avoid dangling else.  */
      keyc_useULongMax ();
      return lookupConst (longcardN, nameKey_makeKey ((const char *) "ULONG_MAX", 9));
    }
  else if (n == charN)
    {
      /* avoid dangling else.  */
      keyc_useCharMax ();
      return lookupConst (charN, nameKey_makeKey ((const char *) "CHAR_MAX", 8));
    }
  else if (n == bitsetN)
    {
      /* avoid dangling else.  */
      mcDebug_assert (decl_isSubrange (static_cast<decl_node> (bitnumN)));
      return bitnumN->subrangeF.high;
    }
  else if (n == locN)
    {
      /* avoid dangling else.  */
      keyc_useUCharMax ();
      return lookupConst (locN, nameKey_makeKey ((const char *) "UCHAR_MAX", 9));
    }
  else if (n == byteN)
    {
      /* avoid dangling else.  */
      keyc_useUCharMax ();
      return lookupConst (byteN, nameKey_makeKey ((const char *) "UCHAR_MAX", 9));
    }
  else if (n == wordN)
    {
      /* avoid dangling else.  */
      keyc_useUIntMax ();
      return lookupConst (wordN, nameKey_makeKey ((const char *) "UINT_MAX", 8));
    }
  else if (n == addressN)
    {
      /* avoid dangling else.  */
      mcMetaError_metaError1 ((const char *) "trying to obtain MAX ({%1ad}) is illegal", 40, (const unsigned char *) &n, (sizeof (n)-1));
      return static_cast<decl_node__opaque> (NULL);
    }
  else
    {
      /* avoid dangling else.  */
      M2RTS_HALT (-1);  /* finish the cacading elsif statement.  */
      __builtin_unreachable ();
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   getMax -
*/

static decl_node__opaque getMax (decl_node__opaque n)
{
  n = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (n)));
  if (decl_isSubrange (static_cast<decl_node> (n)))
    {
      return n->subrangeF.high;
    }
  else if (decl_isEnumeration (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      return n->enumerationF.high;
    }
  else
    {
      /* avoid dangling else.  */
      mcDebug_assert (isOrdinal (n));
      return doMax (n);
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getMin -
*/

static decl_node__opaque getMin (decl_node__opaque n)
{
  n = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (n)));
  if (decl_isSubrange (static_cast<decl_node> (n)))
    {
      return n->subrangeF.low;
    }
  else if (decl_isEnumeration (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      return n->enumerationF.low;
    }
  else
    {
      /* avoid dangling else.  */
      mcDebug_assert (isOrdinal (n));
      return doMin (n);
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doSubtractC -
*/

static void doSubtractC (mcPretty_pretty p, decl_node__opaque s)
{
  if (! (isZero (s)))
    {
      outText (p, (const char *) "-", 1);
      doExprC (p, s);
    }
}


/*
   doSubrC -
*/

static void doSubrC (mcPretty_pretty p, decl_node__opaque s)
{
  decl_node__opaque low;
  decl_node__opaque high;

  s = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (s)));
  if (isOrdinal (s))
    {
      low = getMin (s);
      high = getMax (s);
      doExprC (p, high);
      doSubtractC (p, low);
      outText (p, (const char *) "+1", 2);
    }
  else if (decl_isEnumeration (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      low = getMin (s);
      high = getMax (s);
      doExprC (p, high);
      doSubtractC (p, low);
      outText (p, (const char *) "+1", 2);
    }
  else
    {
      /* avoid dangling else.  */
      mcDebug_assert (decl_isSubrange (static_cast<decl_node> (s)));
      if ((s->subrangeF.high == NULL) || (s->subrangeF.low == NULL))
        {
          doSubrC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (s))));
        }
      else
        {
          doExprC (p, s->subrangeF.high);
          doSubtractC (p, s->subrangeF.low);
          outText (p, (const char *) "+1", 2);
        }
    }
}


/*
   doCompletePartialProcType -
*/

static void doCompletePartialProcType (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque n)
{
  if ((isDeclType (t)) && (isDeclType (n)))
    {
      outputCompletePartialProcType (p, t, n);
    }
}


/*
   outputCompletePartialProcType -
*/

static void outputCompletePartialProcType (mcPretty_pretty p, decl_node__opaque t, decl_node__opaque n)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque v;
  decl_node__opaque u;

  mcDebug_assert (decl_isProcType (static_cast<decl_node> (n)));
  u = static_cast<decl_node__opaque> (NULL);
  outText (p, (const char *) "typedef", 7);
  mcPretty_setNeedSpace (p);
  doTypeC (p, n->proctypeF.returnType, &u);
  doOpaqueModifier (p, n);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(*", 2);
  doFQNameC (p, t);
  outText (p, (const char *) "_t) (", 5);
  i = Indexing_LowIndice (n->proctypeF.parameters);
  h = Indexing_HighIndice (n->proctypeF.parameters);
  while (i <= h)
    {
      v = static_cast<decl_node__opaque> (Indexing_GetIndice (n->proctypeF.parameters, i));
      doParameterC (p, v);
      mcPretty_noSpace (p);
      if (i < h)
        {
          outText (p, (const char *) ",", 1);
          mcPretty_setNeedSpace (p);
        }
      i += 1;
    }
  if (h == 0)
    {
      outText (p, (const char *) "void", 4);
    }
  outText (p, (const char *) ");\\n", 4);
  if (isDefForCNode (n))
    {
      /* emit a C named type which differs from the m2 proctype.  */
      outText (p, (const char *) "typedef", 7);
      mcPretty_setNeedSpace (p);
      doFQNameC (p, t);
      outText (p, (const char *) "_t", 2);
      mcPretty_setNeedSpace (p);
      doFQNameC (p, t);
      outText (p, (const char *) "_C;\\n\\n", 7);
    }
  outText (p, (const char *) "struct", 6);
  mcPretty_setNeedSpace (p);
  doFQNameC (p, t);
  outText (p, (const char *) "_p {", 4);
  mcPretty_setNeedSpace (p);
  doFQNameC (p, t);
  outText (p, (const char *) "_t proc; };\\n\\n", 15);
}


/*
   isBase -
*/

static bool isBase (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_char:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
      case decl_real:
      case decl_longreal:
      case decl_shortreal:
      case decl_bitset:
      case decl_boolean:
      case decl_proc:
        return true;
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doBoolC -
*/

static void doBoolC (mcPretty_pretty p)
{
  if (mcOptions_useBool ())
    {
      outText (p, (const char *) "bool", 4);
    }
  else
    {
      outText (p, (const char *) "unsigned int", 12);
    }
}


/*
   doBaseC -
*/

static void doBaseC (mcPretty_pretty p, decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_char:
        outText (p, (const char *) "char", 4);
        break;

      case decl_cardinal:
        outText (p, (const char *) "unsigned int", 12);
        break;

      case decl_longcard:
        outText (p, (const char *) "long unsigned int", 17);
        break;

      case decl_shortcard:
        outText (p, (const char *) "short unsigned int", 18);
        break;

      case decl_integer:
        outText (p, (const char *) "int", 3);
        break;

      case decl_longint:
        outText (p, (const char *) "long int", 8);
        break;

      case decl_shortint:
        outText (p, (const char *) "short int", 9);
        break;

      case decl_complex:
        outText (p, (const char *) "double complex", 14);
        break;

      case decl_longcomplex:
        outText (p, (const char *) "long double complex", 19);
        break;

      case decl_shortcomplex:
        outText (p, (const char *) "float complex", 13);
        break;

      case decl_real:
        outTextS (p, mcOptions_getCRealType ());
        break;

      case decl_longreal:
        outTextS (p, mcOptions_getCLongRealType ());
        break;

      case decl_shortreal:
        outTextS (p, mcOptions_getCShortRealType ());
        break;

      case decl_bitset:
        outText (p, (const char *) "unsigned int", 12);
        break;

      case decl_boolean:
        doBoolC (p);
        break;

      case decl_proc:
        outText (p, (const char *) "PROC", 4);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  mcPretty_setNeedSpace (p);
}


/*
   isSystem -
*/

static bool isSystem (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_csizet:
      case decl_cssizet:
      case decl_cofft:
      case decl_cardinal64:
        return true;
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doSystemC -
*/

static void doSystemC (mcPretty_pretty p, decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_address:
        outText (p, (const char *) "void *", 6);
        break;

      case decl_loc:
        outText (p, (const char *) "unsigned char", 13);
        mcPretty_setNeedSpace (p);
        break;

      case decl_byte:
        outText (p, (const char *) "unsigned char", 13);
        mcPretty_setNeedSpace (p);
        break;

      case decl_word:
        outText (p, (const char *) "unsigned int", 12);
        mcPretty_setNeedSpace (p);
        break;

      case decl_csizet:
        outText (p, (const char *) "size_t", 6);
        mcPretty_setNeedSpace (p);
        keyc_useSize_t ();
        break;

      case decl_cssizet:
        outText (p, (const char *) "ssize_t", 7);
        mcPretty_setNeedSpace (p);
        keyc_useSSize_t ();
        break;

      case decl_cofft:
        outText (p, (const char *) "off_t", 5);
        mcPretty_setNeedSpace (p);
        break;

      case decl_cardinal64:
        outText (p, (const char *) "uint64_t", 8);
        mcPretty_setNeedSpace (p);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   doArrayC -
*/

static void doArrayC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;
  decl_node__opaque s;
  decl_node__opaque u;

  mcDebug_assert (decl_isArray (static_cast<decl_node> (n)));
  t = n->arrayF.type;
  s = n->arrayF.subr;
  u = static_cast<decl_node__opaque> (NULL);
  if (s == NULL)
    {
      doTypeC (p, t, &u);
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "*", 1);
    }
  else
    {
      outText (p, (const char *) "struct", 6);
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "{", 1);
      mcPretty_setNeedSpace (p);
      doTypeC (p, t, &u);
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "array[", 6);
      if (isZero (getMin (s)))
        {
          doExprC (p, getMax (s));
        }
      else
        {
          doExprC (p, getMax (s));
          doSubtractC (p, getMin (s));
        }
      outText (p, (const char *) "];", 2);
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "}", 1);
      mcPretty_setNeedSpace (p);
    }
}


/*
   doPointerC -
*/

static void doPointerC (mcPretty_pretty p, decl_node__opaque n, decl_node__opaque *m)
{
  decl_node__opaque t;
  decl_node__opaque s;

  t = n->pointerF.type;
  s = static_cast<decl_node__opaque> (NULL);
  doTypeC (p, t, &s);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "*", 1);
}


/*
   doRecordFieldC -
*/

static void doRecordFieldC (mcPretty_pretty p, decl_node__opaque f)
{
  decl_node__opaque m;

  m = static_cast<decl_node__opaque> (NULL);
  mcPretty_setNeedSpace (p);
  doTypeC (p, f->recordfieldF.type, &m);
  if ((decl_isType (static_cast<decl_node> (f->recordfieldF.type))) && (isDeclInImp (f->recordfieldF.type)))
    {
      outText (p, (const char *) "__opaque", 8);
    }
  mcPretty_setNeedSpace (p);
  doDNameC (p, f, false);
}


/*
   doVarientFieldC -
*/

static void doVarientFieldC (mcPretty_pretty p, decl_node__opaque n)
{
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  mcDebug_assert (decl_isVarientField (static_cast<decl_node> (n)));
  if (! n->varientfieldF.simple)
    {
      outText (p, (const char *) "struct", 6);
      mcPretty_setNeedSpace (p);
      p = outKc (p, (const char *) "{\\n", 3);
    }
  i = Indexing_LowIndice (n->varientfieldF.listOfSons);
  t = Indexing_HighIndice (n->varientfieldF.listOfSons);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->varientfieldF.listOfSons, i));
      if (decl_isRecordField (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          if (! q->recordfieldF.tag)
            {
              doRecordFieldC (p, q);
              outText (p, (const char *) ";\\n", 3);
            }
        }
      else if (decl_isVarient (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          doVarientC (p, q);
          outText (p, (const char *) ";\\n", 3);
        }
      else
        {
          /* avoid dangling else.  */
          M2RTS_HALT (-1);
          __builtin_unreachable ();
        }
      i += 1;
    }
  if (! n->varientfieldF.simple)
    {
      p = outKc (p, (const char *) "};\\n", 4);
    }
}


/*
   doVarientC -
*/

static void doVarientC (mcPretty_pretty p, decl_node__opaque n)
{
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  mcDebug_assert (decl_isVarient (static_cast<decl_node> (n)));
  if (n->varientF.tag != NULL)
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if (decl_isRecordField (static_cast<decl_node> (n->varientF.tag)))
        {
          doRecordFieldC (p, n->varientF.tag);
          outText (p, (const char *) ";  /* case tag */\\n", 19);
        }
      else if (decl_isVarientField (static_cast<decl_node> (n->varientF.tag)))
        {
          /* avoid dangling else.  */
          /* doVarientFieldC (p, n^.varientF.tag)  */
          M2RTS_HALT (-1);
          __builtin_unreachable ();
        }
      else
        {
          /* avoid dangling else.  */
          M2RTS_HALT (-1);
          __builtin_unreachable ();
        }
    }
  outText (p, (const char *) "union", 5);
  mcPretty_setNeedSpace (p);
  p = outKc (p, (const char *) "{\\n", 3);
  i = Indexing_LowIndice (n->varientF.listOfSons);
  t = Indexing_HighIndice (n->varientF.listOfSons);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->varientF.listOfSons, i));
      if (decl_isRecordField (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          if (! q->recordfieldF.tag)
            {
              doRecordFieldC (p, q);
              outText (p, (const char *) ";\\n", 3);
            }
        }
      else if (decl_isVarientField (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          doVarientFieldC (p, q);
        }
      else
        {
          /* avoid dangling else.  */
          M2RTS_HALT (-1);
          __builtin_unreachable ();
        }
      i += 1;
    }
  p = outKc (p, (const char *) "}", 1);
}


/*
   doRecordC -
*/

static void doRecordC (mcPretty_pretty p, decl_node__opaque n, decl_node__opaque *m)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque f;

  mcDebug_assert (decl_isRecord (static_cast<decl_node> (n)));
  outText (p, (const char *) "struct", 6);
  mcPretty_setNeedSpace (p);
  p = outKc (p, (const char *) "{", 1);
  i = Indexing_LowIndice (n->recordF.listOfSons);
  h = Indexing_HighIndice (n->recordF.listOfSons);
  mcPretty_setindent (p, (mcPretty_getcurpos (p))+indentation);
  outText (p, (const char *) "\\n", 2);
  while (i <= h)
    {
      f = static_cast<decl_node__opaque> (Indexing_GetIndice (n->recordF.listOfSons, i));
      if (decl_isRecordField (static_cast<decl_node> (f)))
        {
          /* avoid dangling else.  */
          if (! f->recordfieldF.tag)
            {
              doRecordFieldC (p, f);
              outText (p, (const char *) ";\\n", 3);
            }
        }
      else if (decl_isVarient (static_cast<decl_node> (f)))
        {
          /* avoid dangling else.  */
          doVarientC (p, f);
          outText (p, (const char *) ";\\n", 3);
        }
      else if (decl_isVarientField (static_cast<decl_node> (f)))
        {
          /* avoid dangling else.  */
          doVarientFieldC (p, f);
        }
      i += 1;
    }
  p = outKc (p, (const char *) "}", 1);
  mcPretty_setNeedSpace (p);
}


/*
   isBitset -
*/

static bool isBitset (decl_node__opaque n)
{
  return n == bitsetN;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isNegative - returns TRUE if expression, n, is negative.
*/

static bool isNegative (decl_node__opaque n)
{
  /* --fixme-- needs to be completed.  */
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doSubrangeC -
*/

static void doSubrangeC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (decl_isSubrange (static_cast<decl_node> (n)));
  if (isNegative (n->subrangeF.low))
    {
      outText (p, (const char *) "int", 3);
      mcPretty_setNeedSpace (p);
    }
  else
    {
      outText (p, (const char *) "unsigned int", 12);
      mcPretty_setNeedSpace (p);
    }
}


/*
   doSetC - generates a C type which holds the set.
            Currently we only support sets of size WORD.
*/

static void doSetC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (decl_isSet (static_cast<decl_node> (n)));
  outText (p, (const char *) "unsigned int", 12);
  mcPretty_setNeedSpace (p);
}


/*
   doTypeC -
*/

static void doTypeC (mcPretty_pretty p, decl_node__opaque n, decl_node__opaque *m)
{
  if (n == NULL)
    {
      outText (p, (const char *) "void", 4);
    }
  else if (isCDataTypes (n))
    {
      /* avoid dangling else.  */
      doCDataTypesC (p, n);
    }
  else if (isBase (n))
    {
      /* avoid dangling else.  */
      doBaseC (p, n);
    }
  else if (isSystem (n))
    {
      /* avoid dangling else.  */
      doSystemC (p, n);
    }
  else if (decl_isEnumeration (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doEnumerationC (p, n);
    }
  else if (decl_isType (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doFQNameC (p, n);
    }
  else if (decl_isProcType (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doProcTypeC (p, n, (*m));
    }
  else if (decl_isArray (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doArrayC (p, n);
    }
  else if (decl_isRecord (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doRecordC (p, n, m);
    }
  else if (decl_isPointer (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doPointerC (p, n, m);
    }
  else if (decl_isSubrange (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doSubrangeC (p, n);
    }
  else if (decl_isSet (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doSetC (p, n);
    }
  else if (isCDataTypes (n))
    {
      /* avoid dangling else.  */
      doCDataTypesC (p, n);
    }
  else
    {
      /* avoid dangling else.  */
      mcMetaError_metaError1 ((const char *) "expecting a type symbol rather than a {%1DMd} {%1DMa}", 53, (const unsigned char *) &n, (sizeof (n)-1));
      mcError_flushErrors ();
      mcError_errorAbort0 ((const char *) "terminating compilation", 23);
    }
}


/*
   doArrayNameC - it displays the array declaration (it might be an unbounded).
*/

static void doArrayNameC (mcPretty_pretty p, decl_node__opaque n)
{
  doTypeNameC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "*", 1);
}


/*
   doRecordNameC - emit the C/C++ record name <name of n>"_r".
*/

static void doRecordNameC (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  s = getFQstring (n);
  s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "_r", 2)));
  outTextS (p, s);
  s = DynamicStrings_KillString (s);
}


/*
   doPointerNameC - emit the C/C++ pointer type <name of n>*.
*/

static void doPointerNameC (mcPretty_pretty p, decl_node__opaque n)
{
  doTypeNameC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "*", 1);
}


/*
   doTypeNameC -
*/

static void doTypeNameC (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String t;

  if (n == NULL)
    {
      outText (p, (const char *) "void", 4);
      mcPretty_setNeedSpace (p);
    }
  else if (n == charStarN)
    {
      /* avoid dangling else.  */
      outText (p, (const char *) "char *", 6);
      mcPretty_setNeedSpace (p);
    }
  else if (n == constCharStarN)
    {
      /* avoid dangling else.  */
      outText (p, (const char *) "const char *", 12);
      mcPretty_setNeedSpace (p);
    }
  else if (isBase (n))
    {
      /* avoid dangling else.  */
      doBaseC (p, n);
    }
  else if (isSystem (n))
    {
      /* avoid dangling else.  */
      doSystemC (p, n);
    }
  else if (decl_isEnumeration (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      mcPretty_print (p, (const char *) "is enumeration type name required\\n", 35);
    }
  else if (decl_isType (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doFQNameC (p, n);
    }
  else if (decl_isProcType (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doFQNameC (p, n);
      outText (p, (const char *) "_t", 2);
    }
  else if (decl_isArray (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doArrayNameC (p, n);
    }
  else if (decl_isRecord (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doRecordNameC (p, n);
    }
  else if (decl_isPointer (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doPointerNameC (p, n);
    }
  else if (decl_isSubrange (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doSubrangeC (p, n);
    }
  else
    {
      /* avoid dangling else.  */
      mcPretty_print (p, (const char *) "is type unknown required\\n", 26);
    }
}


/*
   isExternal - returns TRUE if symbol, n, was declared in another module.
*/

static bool isExternal (decl_node__opaque n)
{
  decl_node__opaque s;

  s = static_cast<decl_node__opaque> (decl_getScope (static_cast<decl_node> (n)));
  return ((s != NULL) && (decl_isDef (static_cast<decl_node> (s)))) && (((decl_isImp (decl_getMainModule ())) && (s != (decl_lookupDef (decl_getSymName (decl_getMainModule ()))))) || (decl_isModule (decl_getMainModule ())));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doOpaqueModifier - adds postfix __opaque providing n uses an opaque type which is
                      not represented by ( void * ).  n is a non type node which might
                      be using an opaque type.  For example a var or param node.
*/

static void doOpaqueModifier (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (! (decl_isType (static_cast<decl_node> (n))));
  if (((decl_isImp (decl_getCurrentModule ())) && (nodeUsesOpaque (n))) && (! (getNodeOpaqueVoidStar (n))))
    {
      outText (doP, (const char *) "__opaque", 8);
    }
}


/*
   doDeclareVarC -
*/

static void doDeclareVarC (decl_node__opaque n)
{
  decl_node__opaque type;
  decl_node__opaque s;

  s = static_cast<decl_node__opaque> (NULL);
  type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  doTypeC (doP, type, &s);
  doOpaqueModifier (doP, n);
  mcPretty_setNeedSpace (doP);
  doFQDNameC (doP, n, false);
  mcPretty_print (doP, (const char *) ";\\n", 3);
}


/*
   doVarC - output a variable declaration.  Note that we do not generate
            a declaration if we are translating the implementation module
            and a variable is exported as the variable will be in the .h
            file to avoid all -Wodr issues.
*/

static void doVarC (decl_node__opaque n)
{
  if (decl_isDef (decl_getMainModule ()))
    {
      mcPretty_print (doP, (const char *) "EXTERN", 6);
      mcPretty_setNeedSpace (doP);
      doDeclareVarC (n);
    }
  else if ((! (decl_isExported (static_cast<decl_node> (n)))) && (! (isLocal (n))))
    {
      /* avoid dangling else.  */
      mcPretty_print (doP, (const char *) "static", 6);
      mcPretty_setNeedSpace (doP);
      doDeclareVarC (n);
    }
  else if (mcOptions_getExtendedOpaque ())
    {
      /* avoid dangling else.  */
      /* --fixme-- need to revisit extended opaque.  */
      if (isExternal (n))
        {
          /* different module declared this variable, therefore it is extern.  */
          mcPretty_print (doP, (const char *) "extern", 6);
          mcPretty_setNeedSpace (doP);
        }
      doDeclareVarC (n);
    }
  else if (isLocal (n))
    {
      /* avoid dangling else.  */
      doDeclareVarC (n);
    }
}


/*
   doExternCP -
*/

static void doExternCP (mcPretty_pretty p)
{
  if (lang == decl_ansiCP)
    {
      outText (p, (const char *) "extern \"C\"", 10);
      mcPretty_setNeedSpace (p);
    }
}


/*
   doProcedureCommentText -
*/

static void doProcedureCommentText (mcPretty_pretty p, DynamicStrings_String s)
{
  /* remove
   from the start of the comment.  */
  while (((DynamicStrings_Length (s)) > 0) && ((DynamicStrings_char (s, 0)) == ASCII_lf))
    {
      s = DynamicStrings_Slice (s, 1, 0);
    }
  outTextS (p, s);
}


/*
   doProcedureComment -
*/

static void doProcedureComment (mcPretty_pretty p, DynamicStrings_String s)
{
  if (s != NULL)
    {
      outText (p, (const char *) "\\n/*\\n", 6);
      doProcedureCommentText (p, s);
      outText (p, (const char *) "*/\\n\\n", 6);
    }
}


/*
   doProcedureHeadingC -
*/

static void doProcedureHeadingC (decl_node__opaque n, bool prototype)
{
  DynamicStrings_String s;
  unsigned int i;
  unsigned int h;
  decl_node__opaque p;
  decl_node__opaque q;

  mcDebug_assert (decl_isProcedure (static_cast<decl_node> (n)));
  s = getFQstring (n);
  if (DynamicStrings_EqualArray (s, (const char *) "M2Quads_BuildAssignment", 23))
    {
      localstop ();
    }
  s = DynamicStrings_KillString (s);
  mcPretty_noSpace (doP);
  if (decl_isDef (decl_getMainModule ()))
    {
      doProcedureComment (doP, mcComment_getContent (n->procedureF.defComment));
      outText (doP, (const char *) "EXTERN", 6);
      mcPretty_setNeedSpace (doP);
    }
  else if (decl_isExported (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doProcedureComment (doP, mcComment_getContent (n->procedureF.modComment));
      doExternCP (doP);
    }
  else
    {
      /* avoid dangling else.  */
      doProcedureComment (doP, mcComment_getContent (n->procedureF.modComment));
      outText (doP, (const char *) "static", 6);
      mcPretty_setNeedSpace (doP);
    }
  q = static_cast<decl_node__opaque> (NULL);
  doTypeC (doP, n->procedureF.returnType, &q);
  /*
   IF NOT isExported (n)
   THEN
      doTypeNameModifier (doP, n^.procedureF.returnType)
   END ;
  */
  doOpaqueModifier (doP, n);
  mcPretty_setNeedSpace (doP);
  doFQDNameC (doP, n, false);
  mcPretty_setNeedSpace (doP);
  outText (doP, (const char *) "(", 1);
  i = Indexing_LowIndice (n->procedureF.parameters);
  h = Indexing_HighIndice (n->procedureF.parameters);
  while (i <= h)
    {
      p = static_cast<decl_node__opaque> (Indexing_GetIndice (n->procedureF.parameters, i));
      doParameterC (doP, p);
      mcPretty_noSpace (doP);
      if (i < h)
        {
          mcPretty_print (doP, (const char *) ",", 1);
          mcPretty_setNeedSpace (doP);
        }
      i += 1;
    }
  if (h == 0)
    {
      outText (doP, (const char *) "void", 4);
    }
  mcPretty_print (doP, (const char *) ")", 1);
  if ((n->procedureF.noreturn && prototype) && (! (mcOptions_getSuppressNoReturn ())))
    {
      mcPretty_setNeedSpace (doP);
      outText (doP, (const char *) "__attribute__ ((noreturn))", 26);
    }
}


/*
   checkDeclareUnboundedParamCopyC -
*/

static bool checkDeclareUnboundedParamCopyC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;
  unsigned int i;
  unsigned int c;
  wlists_wlist l;
  bool seen;

  seen = false;
  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  l = n->paramF.namelist->identlistF.names;
  if (((decl_isArray (static_cast<decl_node> (t))) && (decl_isUnbounded (static_cast<decl_node> (t)))) && (l != NULL))
    {
      t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (t)));
      c = wlists_noOfItemsInList (l);
      i = 1;
      while (i <= c)
        {
          doTypeNameC (p, t);
          mcPretty_setNeedSpace (p);
          doNamesC (p, wlists_getItemFromList (l, i));
          outText (p, (const char *) "[_", 2);
          doNamesC (p, wlists_getItemFromList (l, i));
          outText (p, (const char *) "_high+1];\\n", 11);
          seen = true;
          i += 1;
        }
    }
  return seen;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   checkUnboundedParamCopyC -
*/

static void checkUnboundedParamCopyC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;
  decl_node__opaque s;
  unsigned int i;
  unsigned int c;
  wlists_wlist l;

  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  l = n->paramF.namelist->identlistF.names;
  if (((decl_isArray (static_cast<decl_node> (t))) && (decl_isUnbounded (static_cast<decl_node> (t)))) && (l != NULL))
    {
      c = wlists_noOfItemsInList (l);
      i = 1;
      t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (t)));
      s = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (t)));
      while (i <= c)
        {
          keyc_useMemcpy ();
          outText (p, (const char *) "memcpy (", 8);
          doNamesC (p, wlists_getItemFromList (l, i));
          outText (p, (const char *) ",", 1);
          mcPretty_setNeedSpace (p);
          doNamesC (p, wlists_getItemFromList (l, i));
          outText (p, (const char *) "_, ", 3);
          if (((s == charN) || (s == byteN)) || (s == locN))
            {
              outText (p, (const char *) "_", 1);
              doNamesC (p, wlists_getItemFromList (l, i));
              outText (p, (const char *) "_high+1);\\n", 11);
            }
          else
            {
              outText (p, (const char *) "(_", 2);
              doNamesC (p, wlists_getItemFromList (l, i));
              outText (p, (const char *) "_high+1)", 8);
              mcPretty_setNeedSpace (p);
              doMultiplyBySize (p, t);
              outText (p, (const char *) ");\\n", 4);
            }
          i += 1;
        }
    }
}


/*
   doUnboundedParamCopyC -
*/

static void doUnboundedParamCopyC (mcPretty_pretty p, decl_node__opaque n)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque q;
  bool seen;

  mcDebug_assert (decl_isProcedure (static_cast<decl_node> (n)));
  i = Indexing_LowIndice (n->procedureF.parameters);
  h = Indexing_HighIndice (n->procedureF.parameters);
  seen = false;
  while (i <= h)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->procedureF.parameters, i));
      if (decl_isParam (static_cast<decl_node> (q)))
        {
          seen = (checkDeclareUnboundedParamCopyC (p, q)) || seen;
        }
      i += 1;
    }
  if (seen)
    {
      outText (p, (const char *) "\\n", 2);
      outText (p, (const char *) "/* make a local copy of each unbounded array.  */\\n", 51);
      i = Indexing_LowIndice (n->procedureF.parameters);
      while (i <= h)
        {
          q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->procedureF.parameters, i));
          if (decl_isParam (static_cast<decl_node> (q)))
            {
              checkUnboundedParamCopyC (p, q);
            }
          i += 1;
        }
    }
}


/*
   doPrototypeC -
*/

static void doPrototypeC (decl_node__opaque n)
{
  if (! (decl_isExported (static_cast<decl_node> (n))))
    {
      keyc_enterScope (static_cast<decl_node> (n));
      doProcedureHeadingC (n, true);
      mcPretty_print (doP, (const char *) ";\\n", 3);
      keyc_leaveScope (static_cast<decl_node> (n));
    }
}


/*
   addTodo - adds, n, to the todo list.
*/

static void addTodo (decl_node__opaque n)
{
  if (((n != NULL) && (! (alists_isItemInList (globalGroup->partialQ, reinterpret_cast <void *> (n))))) && (! (alists_isItemInList (globalGroup->doneQ, reinterpret_cast <void *> (n)))))
    {
      mcDebug_assert (! (decl_isVarient (static_cast<decl_node> (n))));
      mcDebug_assert (! (decl_isVarientField (static_cast<decl_node> (n))));
      mcDebug_assert (! (decl_isDef (static_cast<decl_node> (n))));
      alists_includeItemIntoList (globalGroup->todoQ, reinterpret_cast <void *> (n));
    }
}


/*
   addVariablesTodo -
*/

static void addVariablesTodo (decl_node__opaque n)
{
  if (decl_isVar (static_cast<decl_node> (n)))
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if (n->varF.isParameter || n->varF.isVarParameter)
        {
          addDone (n);
          addTodo (static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
        }
      else
        {
          addTodo (n);
        }
    }
}


/*
   addTypesTodo -
*/

static void addTypesTodo (decl_node__opaque n)
{
  if (decl_isUnbounded (static_cast<decl_node> (n)))
    {
      addDone (n);
    }
  else
    {
      addTodo (n);
    }
}


/*
   tempName -
*/

static DynamicStrings_String tempName (void)
{
  tempCount += 1;
  return FormatStrings_Sprintf1 (DynamicStrings_InitString ((const char *) "_T%d", 4), (const unsigned char *) &tempCount, (sizeof (tempCount)-1));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeIntermediateType -
*/

static decl_node__opaque makeIntermediateType (DynamicStrings_String s, decl_node__opaque p)
{
  nameKey_Name n;
  decl_node__opaque o;

  n = nameKey_makekey (DynamicStrings_string (s));
  decl_enterScope (decl_getScope (static_cast<decl_node> (p)));
  o = p;
  p = static_cast<decl_node__opaque> (decl_makeType (nameKey_makekey (DynamicStrings_string (s))));
  decl_putType (static_cast<decl_node> (p), static_cast<decl_node> (o));
  putTypeInternal (p);
  decl_leaveScope ();
  return p;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   simplifyType -
*/

static void simplifyType (alists_alist l, decl_node__opaque *p)
{
  DynamicStrings_String s;

  if ((((*p) != NULL) && (((decl_isRecord (static_cast<decl_node> ((*p)))) || (decl_isArray (static_cast<decl_node> ((*p))))) || (decl_isProcType (static_cast<decl_node> ((*p)))))) && (! (decl_isUnbounded (static_cast<decl_node> ((*p))))))
    {
      s = tempName ();
      (*p) = makeIntermediateType (s, (*p));
      s = DynamicStrings_KillString (s);
      simplified = false;
    }
  simplifyNode (l, (*p));
}


/*
   simplifyVar -
*/

static void simplifyVar (alists_alist l, decl_node__opaque n)
{
  unsigned int i;
  unsigned int t;
  decl_node__opaque v;
  decl_node__opaque d;
  decl_node__opaque o;

  mcDebug_assert (decl_isVar (static_cast<decl_node> (n)));
  o = n->varF.type;
  simplifyType (l, &n->varF.type);
  if (o != n->varF.type)
    {
      /* simplification has occurred, make sure that all other variables of this type
         use the new type.  */
      d = n->varF.decl;
      mcDebug_assert (isVarDecl (d));
      t = wlists_noOfItemsInList (d->vardeclF.names);
      i = 1;
      while (i <= t)
        {
          v = static_cast<decl_node__opaque> (decl_lookupInScope (static_cast<decl_node> (n->varF.scope), wlists_getItemFromList (d->vardeclF.names, i)));
          mcDebug_assert (decl_isVar (static_cast<decl_node> (v)));
          v->varF.type = n->varF.type;
          i += 1;
        }
    }
}


/*
   simplifyRecord -
*/

static void simplifyRecord (alists_alist l, decl_node__opaque n)
{
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  i = Indexing_LowIndice (n->recordF.listOfSons);
  t = Indexing_HighIndice (n->recordF.listOfSons);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->recordF.listOfSons, i));
      simplifyNode (l, q);
      i += 1;
    }
}


/*
   simplifyVarient -
*/

static void simplifyVarient (alists_alist l, decl_node__opaque n)
{
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  simplifyNode (l, n->varientF.tag);
  i = Indexing_LowIndice (n->varientF.listOfSons);
  t = Indexing_HighIndice (n->varientF.listOfSons);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->varientF.listOfSons, i));
      simplifyNode (l, q);
      i += 1;
    }
}


/*
   simplifyVarientField -
*/

static void simplifyVarientField (alists_alist l, decl_node__opaque n)
{
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  i = Indexing_LowIndice (n->varientfieldF.listOfSons);
  t = Indexing_HighIndice (n->varientfieldF.listOfSons);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->varientfieldF.listOfSons, i));
      simplifyNode (l, q);
      i += 1;
    }
}


/*
   doSimplifyNode -
*/

static void doSimplifyNode (alists_alist l, decl_node__opaque n)
{
  if (n == NULL)
    {}  /* empty.  */
  else if (decl_isType (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      /* no need to simplify a type.  */
      simplifyNode (l, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
    }
  else if (decl_isVar (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      simplifyVar (l, n);
    }
  else if (decl_isRecord (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      simplifyRecord (l, n);
    }
  else if (decl_isRecordField (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      simplifyType (l, &n->recordfieldF.type);
    }
  else if (decl_isArray (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      simplifyType (l, &n->arrayF.type);
    }
  else if (decl_isVarient (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      simplifyVarient (l, n);
    }
  else if (decl_isVarientField (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      simplifyVarientField (l, n);
    }
  else if (decl_isPointer (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      simplifyType (l, &n->pointerF.type);
    }
}


/*
   simplifyNode -
*/

static void simplifyNode (alists_alist l, decl_node__opaque n)
{
  if (! (alists_isItemInList (l, reinterpret_cast <void *> (n))))
    {
      alists_includeItemIntoList (l, reinterpret_cast <void *> (n));
      doSimplifyNode (l, n);
    }
}


/*
   doSimplify -
*/

static void doSimplify (decl_node__opaque n)
{
  alists_alist l;

  l = alists_initList ();
  simplifyNode (l, n);
  alists_killList (&l);
}


/*
   simplifyTypes -
*/

static void simplifyTypes (decl_scopeT s)
{
  do {
    simplified = true;
    Indexing_ForeachIndiceInIndexDo (s.types, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doSimplify});
    Indexing_ForeachIndiceInIndexDo (s.variables, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doSimplify});
  } while (! (simplified));
}


/*
   outDeclsDefC -
*/

static void outDeclsDefC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_scopeT s;

  s = n->defF.decls;
  simplifyTypes (s);
  includeConstType (s);
  doP = p;
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartial}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doCompletePartialC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone});
  /* try and output types, constants before variables and procedures.  */
  includeDefVarProcedure (n);
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartial}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doCompletePartialC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone});
  Indexing_ForeachIndiceInIndexDo (s.procedures, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doPrototypeC});
}


/*
   includeConstType -
*/

static void includeConstType (decl_scopeT s)
{
  Indexing_ForeachIndiceInIndexDo (s.constants, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) addTodo});
  Indexing_ForeachIndiceInIndexDo (s.types, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) addTypesTodo});
}


/*
   includeVarProcedure -
*/

static void includeVarProcedure (decl_scopeT s)
{
  Indexing_ForeachIndiceInIndexDo (s.procedures, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) addTodo});
  Indexing_ForeachIndiceInIndexDo (s.variables, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) addVariablesTodo});
}


/*
   includeVar -
*/

static void includeVar (decl_scopeT s)
{
  Indexing_ForeachIndiceInIndexDo (s.variables, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) addTodo});
}


/*
   includeExternals -
*/

static void includeExternals (decl_node__opaque n)
{
  alists_alist l;

  l = alists_initList ();
  visitNode (l, n, (decl_nodeProcedure) {(decl_nodeProcedure_t) addExported});
  alists_killList (&l);
}


/*
   checkSystemInclude -
*/

static void checkSystemInclude (decl_node__opaque n)
{
}


/*
   addExported -
*/

static void addExported (decl_node__opaque n)
{
  decl_node__opaque s;

  s = static_cast<decl_node__opaque> (decl_getScope (static_cast<decl_node> (n)));
  if (((s != NULL) && (decl_isDef (static_cast<decl_node> (s)))) && (s != defModule))
    {
      if (((decl_isType (static_cast<decl_node> (n))) || (decl_isVar (static_cast<decl_node> (n)))) || (decl_isConst (static_cast<decl_node> (n))))
        {
          addTodo (n);
        }
    }
}


/*
   addExternal - only adds, n, if this symbol is external to the
                 implementation module and is not a hidden type.
*/

static void addExternal (decl_node__opaque n)
{
  if (((((decl_getScope (static_cast<decl_node> (n))) == defModule) && (decl_isType (static_cast<decl_node> (n)))) && (decl_isTypeHidden (static_cast<decl_node> (n)))) && (! (mcOptions_getExtendedOpaque ())))
    {}  /* empty.  */
  /* do nothing.  */
  else if (! (decl_isDef (static_cast<decl_node> (n))))
    {
      /* avoid dangling else.  */
      addTodo (n);
    }
}


/*
   includeDefConstType -
*/

static void includeDefConstType (decl_node__opaque n)
{
  decl_node__opaque d;

  if (decl_isImp (static_cast<decl_node> (n)))
    {
      defModule = static_cast<decl_node__opaque> (decl_lookupDef (decl_getSymName (static_cast<decl_node> (n))));
      if (defModule != NULL)
        {
          simplifyTypes (defModule->defF.decls);
          includeConstType (defModule->defF.decls);
          symbolKey_foreachNodeDo (defModule->defF.decls.symbols, (symbolKey_performOperation) {(symbolKey_performOperation_t) addExternal});
        }
    }
}


/*
   runIncludeDefConstType -
*/

static void runIncludeDefConstType (decl_node__opaque n)
{
  decl_node__opaque d;

  if (decl_isDef (static_cast<decl_node> (n)))
    {
      simplifyTypes (n->defF.decls);
      includeConstType (n->defF.decls);
      symbolKey_foreachNodeDo (n->defF.decls.symbols, (symbolKey_performOperation) {(symbolKey_performOperation_t) addExternal});
    }
}


/*
   joinProcedures - copies procedures from definition module,
                    d, into implementation module, i.
*/

static void joinProcedures (decl_node__opaque i, decl_node__opaque d)
{
  unsigned int h;
  unsigned int j;

  mcDebug_assert (decl_isDef (static_cast<decl_node> (d)));
  mcDebug_assert (decl_isImp (static_cast<decl_node> (i)));
  j = 1;
  h = Indexing_HighIndice (d->defF.decls.procedures);
  while (j <= h)
    {
      Indexing_IncludeIndiceIntoIndex (i->impF.decls.procedures, Indexing_GetIndice (d->defF.decls.procedures, j));
      j += 1;
    }
}


/*
   includeDefVarProcedure -
*/

static void includeDefVarProcedure (decl_node__opaque n)
{
  decl_node__opaque d;

  if (decl_isImp (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      defModule = static_cast<decl_node__opaque> (decl_lookupDef (decl_getSymName (static_cast<decl_node> (n))));
      if (defModule != NULL)
        {
          /*
         includeVar (defModule^.defF.decls) ;
         simplifyTypes (defModule^.defF.decls) ;
  */
          joinProcedures (n, defModule);
        }
    }
  else if (decl_isDef (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      includeVar (n->defF.decls);
      simplifyTypes (n->defF.decls);
    }
}


/*
   foreachModuleDo -
*/

static void foreachModuleDo (decl_node__opaque n, symbolKey_performOperation p)
{
  decl_foreachDefModuleDo (p);
  decl_foreachModModuleDo (p);
}


/*
   outDeclsImpC -
*/

static void outDeclsImpC (mcPretty_pretty p, decl_scopeT s)
{
  simplifyTypes (s);
  includeConstType (s);
  doP = p;
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartial}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doCompletePartialC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone});
  /* try and output types, constants before variables and procedures.  */
  includeVarProcedure (s);
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartial}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doCompletePartialC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone});
}


/*
   doStatementSequenceC -
*/

static void doStatementSequenceC (mcPretty_pretty p, decl_node__opaque s)
{
  unsigned int i;
  unsigned int h;

  mcDebug_assert (decl_isStatementSequence (static_cast<decl_node> (s)));
  h = Indexing_HighIndice (s->stmtF.statements);
  i = 1;
  while (i <= h)
    {
      doStatementsC (p, static_cast<decl_node__opaque> (Indexing_GetIndice (s->stmtF.statements, i)));
      i += 1;
    }
}


/*
   isStatementSequenceEmpty -
*/

static bool isStatementSequenceEmpty (decl_node__opaque s)
{
  mcDebug_assert (decl_isStatementSequence (static_cast<decl_node> (s)));
  return (Indexing_HighIndice (s->stmtF.statements)) == 0;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isSingleStatement - returns TRUE if the statement sequence, s, has
                       only one statement.
*/

static bool isSingleStatement (decl_node__opaque s)
{
  unsigned int h;

  mcDebug_assert (decl_isStatementSequence (static_cast<decl_node> (s)));
  h = Indexing_HighIndice (s->stmtF.statements);
  if ((h == 0) || (h > 1))
    {
      return false;
    }
  s = static_cast<decl_node__opaque> (Indexing_GetIndice (s->stmtF.statements, 1));
  return (! (decl_isStatementSequence (static_cast<decl_node> (s)))) || (isSingleStatement (s));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doCommentC -
*/

static void doCommentC (mcPretty_pretty p, decl_node__opaque s)
{
  DynamicStrings_String c;

  if (s != NULL)
    {
      mcDebug_assert (isComment (s));
      if (! (mcComment_isProcedureComment (s->commentF.content)))
        {
          if (mcComment_isAfterComment (s->commentF.content))
            {
              mcPretty_setNeedSpace (p);
              outText (p, (const char *) " /* ", 4);
            }
          else
            {
              outText (p, (const char *) "/* ", 3);
            }
          c = mcComment_getContent (s->commentF.content);
          c = DynamicStrings_RemoveWhitePrefix (DynamicStrings_RemoveWhitePostfix (c));
          outTextS (p, c);
          outText (p, (const char *) "  */\\n", 6);
        }
    }
}


/*
   doAfterCommentC - emit an after comment, c, or a newline if, c, is empty.
*/

static void doAfterCommentC (mcPretty_pretty p, decl_node__opaque c)
{
  if (c == NULL)
    {
      outText (p, (const char *) "\\n", 2);
    }
  else
    {
      doCommentC (p, c);
    }
}


/*
   doReturnC - issue a return statement and also place in an after comment if one exists.
*/

static void doReturnC (mcPretty_pretty p, decl_node__opaque s)
{
  decl_node__opaque type;

  mcDebug_assert (decl_isReturn (static_cast<decl_node> (s)));
  doCommentC (p, s->returnF.returnComment.body);
  outText (p, (const char *) "return", 6);
  if ((s->returnF.scope != NULL) && (s->returnF.exp != NULL))
    {
      mcPretty_setNeedSpace (p);
      if ((! (decl_isProcedure (static_cast<decl_node> (s->returnF.scope)))) || ((decl_getType (static_cast<decl_node> (s->returnF.scope))) == NULL))
        {
          mcMetaError_metaError1 ((const char *) "{%1DMad} has no return type", 27, (const unsigned char *) &s->returnF.scope, (sizeof (s->returnF.scope)-1));
        }
      else
        {
          if ((decl_isProcedure (static_cast<decl_node> (s->returnF.scope))) && (nodeUsesOpaque (s->returnF.scope)))
            {
              forceCastOpaque (p, s->returnF.scope, s->returnF.exp, getNodeOpaqueVoidStar (s->returnF.scope));
            }
          else
            {
              doExprCastC (p, s->returnF.exp, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (s->returnF.scope))));
            }
        }
    }
  outText (p, (const char *) ";", 1);
  doAfterCommentC (p, s->returnF.returnComment.after);
}


/*
   isZtypeEquivalent -
*/

static bool isZtypeEquivalent (decl_node__opaque type)
{
  switch (type->kind)
    {
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_ztype:
        return true;
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isEquivalentType - returns TRUE if type1 and type2 are equivalent.
*/

static bool isEquivalentType (decl_node__opaque type1, decl_node__opaque type2)
{
  type1 = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (type1)));
  type2 = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (type2)));
  return (type1 == type2) || ((isZtypeEquivalent (type1)) && (isZtypeEquivalent (type2)));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doExprCastC - build a cast if necessary.
*/

static void doExprCastC (mcPretty_pretty p, decl_node__opaque e, decl_node__opaque type)
{
  decl_node__opaque stype;

  stype = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (type)));
  if ((! (isEquivalentType (type, getExprType (e)))) && (! ((e->kind == decl_nil) && ((decl_isPointer (static_cast<decl_node> (stype))) || (stype->kind == decl_address)))))
    {
      if (lang == decl_ansiCP)
        {
          /* avoid gcc warning by using compound statement even if not strictly necessary.  */
          /* potentially a cast is required.  */
          if ((decl_isPointer (static_cast<decl_node> (type))) || (type == addressN))
            {
              outText (p, (const char *) "static_cast<", 12);
              doTypeNameC (p, type);
              mcPretty_noSpace (p);
              outText (p, (const char *) "> (", 3);
              doExprC (p, e);
              outText (p, (const char *) ")", 1);
              return;
            }
          else
            {
              outText (p, (const char *) "static_cast<", 12);
              if (decl_isProcType (decl_skipType (static_cast<decl_node> (type))))
                {
                  doTypeNameC (p, type);
                  outText (p, (const char *) "_t", 2);
                }
              else
                {
                  doTypeNameC (p, type);
                }
              mcPretty_noSpace (p);
              outText (p, (const char *) "> (", 3);
              doExprC (p, e);
              outText (p, (const char *) ")", 1);
              return;
            }
        }
    }
  doExprC (p, e);
}


/*
   requiresUnpackProc - returns TRUE if either the expr is a procedure or the proctypes differ.
*/

static bool requiresUnpackProc (decl_node__opaque s)
{
  mcDebug_assert (isAssignment (s));
  return (decl_isProcedure (static_cast<decl_node> (s->assignmentF.expr))) || ((decl_skipType (decl_getType (static_cast<decl_node> (s->assignmentF.des)))) != (decl_skipType (decl_getType (static_cast<decl_node> (s->assignmentF.expr)))));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   forceCastOpaque -
*/

static void forceCastOpaque (mcPretty_pretty p, decl_node__opaque des, decl_node__opaque expr, bool toVoidStar)
{
  if (nodeUsesOpaque (expr))
    {
      flushOpaque (p, expr, getNodeOpaqueVoidStar (des));
    }
  else
    {
      forceReintCastOpaque (p, des, expr, toVoidStar);
    }
}


/*
   forceReintCastOpaque -
*/

static void forceReintCastOpaque (mcPretty_pretty p, decl_node__opaque des, decl_node__opaque expr, bool toVoidStar)
{
  decl_node__opaque type;

  type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (des)));
  if (toVoidStar)
    {
      /* next is true cast to void * opaque type.  */
      outText (p, (const char *) "static_cast<", 12);
      doTypeNameC (p, type);
      mcPretty_noSpace (p);
      outText (p, (const char *) "> (", 3);
      doExprC (p, expr);
      outText (p, (const char *) ")", 1);
    }
  else
    {
      /* next is false cast to __opaque opaque type.  */
      outText (p, (const char *) "static_cast<", 12);
      doTypeNameC (p, type);
      outText (p, (const char *) "__opaque", 8);
      mcPretty_noSpace (p);
      outText (p, (const char *) "> (", 3);
      doExprC (p, expr);
      outText (p, (const char *) ")", 1);
    }
}


/*
   doUnConstCastUnbounded - if node n type is an unbounded array then
                            use const_cast to remove the const parameter
                            to allow the unbounded array to be modified.
*/

static void doUnConstCastUnbounded (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque type;
  decl_node__opaque v;

  if (isArrayRef (n))
    {
      if (decl_isVar (static_cast<decl_node> (n->arrayrefF.array)))
        {
          v = n->arrayrefF.array;
          if ((v->varF.isParameter || v->varF.isVarParameter) && (decl_isUnbounded (decl_getType (static_cast<decl_node> (v)))))
            {
              type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (v)));
              outText (p, (const char *) " /* const_cast<", 15);
              doTypeNameC (p, type);
              outText (p, (const char *) "> is needed */ ", 15);
            }
        }
    }
}


/*
   doAssignmentC -
*/

static void doAssignmentC (mcPretty_pretty p, decl_node__opaque s)
{
  mcDebug_assert (isAssignment (s));
  doCommentC (p, s->assignmentF.assignComment.body);
  if (debugOpaque)
    {
      outText (p, (const char *) " /* des: */ ", 12);
      dumpOpaqueState (s->assignmentF.des);
      outText (p, (const char *) " /* expr: */ ", 13);
      dumpOpaqueState (s->assignmentF.expr);
    }
  s->assignmentF.des = doExprCup (p, s->assignmentF.des, requiresUnpackProc (s), true);
  if (debugOpaque)
    {
      outText (p, (const char *) "\\n /* after doExprCup des: */ ", 30);
      dumpOpaqueState (s->assignmentF.des);
      outText (p, (const char *) "\\n", 2);
    }
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "=", 1);
  mcPretty_setNeedSpace (p);
  if (nodeUsesOpaque (s->assignmentF.des))
    {
      forceCastOpaque (p, s->assignmentF.des, s->assignmentF.expr, getNodeOpaqueVoidStar (s->assignmentF.des));
    }
  else
    {
      if (debugOpaque)
        {
          outText (p, (const char *) " /* no opaque des seen */ ", 26);
        }
      doExprCastC (p, s->assignmentF.expr, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (s->assignmentF.des))));
    }
  outText (p, (const char *) ";", 1);
  doAfterCommentC (p, s->assignmentF.assignComment.after);
}


/*
   containsStatement -
*/

static bool containsStatement (decl_node__opaque s)
{
  return ((s != NULL) && (decl_isStatementSequence (static_cast<decl_node> (s)))) && (! (isStatementSequenceEmpty (s)));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doCompoundStmt -
*/

static void doCompoundStmt (mcPretty_pretty p, decl_node__opaque s)
{
  if ((s == NULL) || ((decl_isStatementSequence (static_cast<decl_node> (s))) && (isStatementSequenceEmpty (s))))
    {
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      outText (p, (const char *) "{}  /* empty.  */\\n", 19);
      p = mcPretty_popPretty (p);
    }
  else if (((decl_isStatementSequence (static_cast<decl_node> (s))) && (isSingleStatement (s))) && ! forceCompoundStatement)
    {
      /* avoid dangling else.  */
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      doStatementSequenceC (p, s);
      p = mcPretty_popPretty (p);
    }
  else
    {
      /* avoid dangling else.  */
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      outText (p, (const char *) "{\\n", 3);
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      doStatementSequenceC (p, s);
      p = mcPretty_popPretty (p);
      outText (p, (const char *) "}\\n", 3);
      p = mcPretty_popPretty (p);
    }
}


/*
   doElsifC -
*/

static void doElsifC (mcPretty_pretty p, decl_node__opaque s)
{
  mcDebug_assert (decl_isElsif (static_cast<decl_node> (s)));
  outText (p, (const char *) "else if", 7);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, s->elsifF.expr);
  outText (p, (const char *) ")\\n", 3);
  mcDebug_assert ((s->elsifF.else_ == NULL) || (s->elsifF.elsif == NULL));
  if (forceCompoundStatement || ((hasIfAndNoElse (s->elsifF.then)) && ((s->elsifF.else_ != NULL) || (s->elsifF.elsif != NULL))))
    {
      /* avoid dangling else.  */
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      outText (p, (const char *) "{\\n", 3);
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      outText (p, (const char *) "/* avoid dangling else.  */\\n", 29);
      doStatementSequenceC (p, s->elsifF.then);
      p = mcPretty_popPretty (p);
      outText (p, (const char *) "}\\n", 3);
      p = mcPretty_popPretty (p);
    }
  else
    {
      doCompoundStmt (p, s->elsifF.then);
    }
  if (containsStatement (s->elsifF.else_))
    {
      outText (p, (const char *) "else\\n", 6);
      if (forceCompoundStatement)
        {
          /* avoid dangling else.  */
          p = mcPretty_pushPretty (p);
          mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
          outText (p, (const char *) "{\\n", 3);
          p = mcPretty_pushPretty (p);
          mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
          outText (p, (const char *) "/* avoid dangling else.  */\\n", 29);
          doStatementSequenceC (p, s->elsifF.else_);
          p = mcPretty_popPretty (p);
          outText (p, (const char *) "}\\n", 3);
          p = mcPretty_popPretty (p);
        }
      else
        {
          doCompoundStmt (p, s->elsifF.else_);
        }
    }
  else if ((s->elsifF.elsif != NULL) && (decl_isElsif (static_cast<decl_node> (s->elsifF.elsif))))
    {
      /* avoid dangling else.  */
      doElsifC (p, s->elsifF.elsif);
    }
}


/*
   noIfElse -
*/

static bool noIfElse (decl_node__opaque n)
{
  return (((n != NULL) && (decl_isIf (static_cast<decl_node> (n)))) && (n->ifF.else_ == NULL)) && (n->ifF.elsif == NULL);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   noIfElseChained - returns TRUE if, n, is an IF statement which
                     has no associated ELSE statement.  An IF with an
                     ELSIF is also checked for no ELSE and will result
                     in a return value of TRUE.
*/

static bool noIfElseChained (decl_node__opaque n)
{
  decl_node__opaque e;

  if (n != NULL)
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if (decl_isIf (static_cast<decl_node> (n)))
        {
          if (n->ifF.else_ != NULL)
            {
              /* we do have an else, continue to check this statement.  */
              return hasIfAndNoElse (n->ifF.else_);
            }
          else if (n->ifF.elsif == NULL)
            {
              /* avoid dangling else.  */
              /* neither else or elsif.  */
              return true;
            }
          else
            {
              /* avoid dangling else.  */
              /* test elsif for lack of else.  */
              e = n->ifF.elsif;
              mcDebug_assert (decl_isElsif (static_cast<decl_node> (e)));
              return noIfElseChained (e);
            }
        }
      else if (decl_isElsif (static_cast<decl_node> (n)))
        {
          /* avoid dangling else.  */
          if (n->elsifF.else_ != NULL)
            {
              /* we do have an else, continue to check this statement.  */
              return hasIfAndNoElse (n->elsifF.else_);
            }
          else if (n->elsifF.elsif == NULL)
            {
              /* avoid dangling else.  */
              /* neither else or elsif.  */
              return true;
            }
          else
            {
              /* avoid dangling else.  */
              /* test elsif for lack of else.  */
              e = n->elsifF.elsif;
              mcDebug_assert (decl_isElsif (static_cast<decl_node> (e)));
              return noIfElseChained (e);
            }
        }
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   hasIfElse -
*/

static bool hasIfElse (decl_node__opaque n)
{
  if (n != NULL)
    {
      if (decl_isStatementSequence (static_cast<decl_node> (n)))
        {
          /* avoid gcc warning by using compound statement even if not strictly necessary.  */
          if (isStatementSequenceEmpty (n))
            {
              return false;
            }
          else if (isSingleStatement (n))
            {
              /* avoid dangling else.  */
              n = static_cast<decl_node__opaque> (Indexing_GetIndice (n->stmtF.statements, 1));
              return isIfElse (n);
            }
        }
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isIfElse -
*/

static bool isIfElse (decl_node__opaque n)
{
  return ((n != NULL) && (decl_isIf (static_cast<decl_node> (n)))) && ((n->ifF.else_ != NULL) || (n->ifF.elsif != NULL));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   hasIfAndNoElse - returns TRUE if statement, n, is a single statement
                    which is an IF and it has no else statement.
*/

static bool hasIfAndNoElse (decl_node__opaque n)
{
  if (n != NULL)
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if (decl_isStatementSequence (static_cast<decl_node> (n)))
        {
          if (isStatementSequenceEmpty (n))
            {
              return false;
            }
          else if (isSingleStatement (n))
            {
              /* avoid dangling else.  */
              n = static_cast<decl_node__opaque> (Indexing_GetIndice (n->stmtF.statements, 1));
              return hasIfAndNoElse (n);
            }
          else
            {
              /* avoid dangling else.  */
              n = static_cast<decl_node__opaque> (Indexing_GetIndice (n->stmtF.statements, Indexing_HighIndice (n->stmtF.statements)));
              return hasIfAndNoElse (n);
            }
        }
      else if ((decl_isElsif (static_cast<decl_node> (n))) || (decl_isIf (static_cast<decl_node> (n))))
        {
          /* avoid dangling else.  */
          return noIfElseChained (n);
        }
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doIfC - issue an if statement and also place in an after comment if one exists.
           The if statement might contain an else or elsif which are also handled.
*/

static void doIfC (mcPretty_pretty p, decl_node__opaque s)
{
  mcDebug_assert (decl_isIf (static_cast<decl_node> (s)));
  doCommentC (p, s->ifF.ifComment.body);
  outText (p, (const char *) "if", 2);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, s->ifF.expr);
  outText (p, (const char *) ")", 1);
  doAfterCommentC (p, s->ifF.ifComment.after);
  if ((hasIfAndNoElse (s->ifF.then)) && ((s->ifF.else_ != NULL) || (s->ifF.elsif != NULL)))
    {
      /* avoid dangling else.  */
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      outText (p, (const char *) "{\\n", 3);
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      outText (p, (const char *) "/* avoid dangling else.  */\\n", 29);
      doStatementSequenceC (p, s->ifF.then);
      p = mcPretty_popPretty (p);
      outText (p, (const char *) "}\\n", 3);
      p = mcPretty_popPretty (p);
    }
  else if ((noIfElse (s)) && (hasIfElse (s->ifF.then)))
    {
      /* avoid dangling else.  */
      /* gcc does not like legal non dangling else, as it is poor style.
         So we will avoid getting a warning.  */
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      outText (p, (const char *) "{\\n", 3);
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      outText (p, (const char *) "/* avoid gcc warning by using compound statement even if not strictly necessary.  */\\n", 86);
      doStatementSequenceC (p, s->ifF.then);
      p = mcPretty_popPretty (p);
      outText (p, (const char *) "}\\n", 3);
      p = mcPretty_popPretty (p);
    }
  else
    {
      /* avoid dangling else.  */
      doCompoundStmt (p, s->ifF.then);
    }
  mcDebug_assert ((s->ifF.else_ == NULL) || (s->ifF.elsif == NULL));
  if (containsStatement (s->ifF.else_))
    {
      doCommentC (p, s->ifF.elseComment.body);
      outText (p, (const char *) "else", 4);
      doAfterCommentC (p, s->ifF.elseComment.after);
      doCompoundStmt (p, s->ifF.else_);
    }
  else if ((s->ifF.elsif != NULL) && (decl_isElsif (static_cast<decl_node> (s->ifF.elsif))))
    {
      /* avoid dangling else.  */
      doCommentC (p, s->ifF.elseComment.body);
      doCommentC (p, s->ifF.elseComment.after);
      doElsifC (p, s->ifF.elsif);
    }
  doCommentC (p, s->ifF.endComment.after);
  doCommentC (p, s->ifF.endComment.body);
}


/*
   doForIncCP -
*/

static void doForIncCP (mcPretty_pretty p, decl_node__opaque s)
{
  decl_node__opaque t;

  mcDebug_assert (decl_isFor (static_cast<decl_node> (s)));
  t = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (s->forF.des))));
  if (decl_isEnumeration (static_cast<decl_node> (t)))
    {
      if (s->forF.increment == NULL)
        {
          doExprC (p, s->forF.des);
          outText (p, (const char *) "= static_cast<", 14);
          doTypeNameC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (s->forF.des))));
          mcPretty_noSpace (p);
          outText (p, (const char *) ">(static_cast<int>(", 19);
          doExprC (p, s->forF.des);
          outText (p, (const char *) "+1))", 4);
        }
      else
        {
          doExprC (p, s->forF.des);
          outText (p, (const char *) "= static_cast<", 14);
          doTypeNameC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (s->forF.des))));
          mcPretty_noSpace (p);
          outText (p, (const char *) ">(static_cast<int>(", 19);
          doExprC (p, s->forF.des);
          outText (p, (const char *) "+", 1);
          doExprC (p, s->forF.increment);
          outText (p, (const char *) "))", 2);
        }
    }
  else
    {
      doForIncC (p, s);
    }
}


/*
   doForIncC -
*/

static void doForIncC (mcPretty_pretty p, decl_node__opaque s)
{
  if (s->forF.increment == NULL)
    {
      doExprC (p, s->forF.des);
      outText (p, (const char *) "++", 2);
    }
  else
    {
      doExprC (p, s->forF.des);
      outText (p, (const char *) "=", 1);
      doExprC (p, s->forF.des);
      outText (p, (const char *) "+", 1);
      doExprC (p, s->forF.increment);
    }
}


/*
   doForInc -
*/

static void doForInc (mcPretty_pretty p, decl_node__opaque s)
{
  if (lang == decl_ansiCP)
    {
      doForIncCP (p, s);
    }
  else
    {
      doForIncC (p, s);
    }
}


/*
   doForC -
*/

static void doForC (mcPretty_pretty p, decl_node__opaque s)
{
  mcDebug_assert (decl_isFor (static_cast<decl_node> (s)));
  outText (p, (const char *) "for (", 5);
  doExprC (p, s->forF.des);
  outText (p, (const char *) "=", 1);
  doExprC (p, s->forF.start);
  outText (p, (const char *) ";", 1);
  mcPretty_setNeedSpace (p);
  doExprC (p, s->forF.des);
  outText (p, (const char *) "<=", 2);
  doExprC (p, s->forF.end);
  outText (p, (const char *) ";", 1);
  mcPretty_setNeedSpace (p);
  doForInc (p, s);
  outText (p, (const char *) ")\\n", 3);
  doCompoundStmt (p, s->forF.statements);
}


/*
   doRepeatC -
*/

static void doRepeatC (mcPretty_pretty p, decl_node__opaque s)
{
  mcDebug_assert (decl_isRepeat (static_cast<decl_node> (s)));
  doCommentC (p, s->repeatF.repeatComment.body);
  outText (p, (const char *) "do {", 4);
  doAfterCommentC (p, s->repeatF.repeatComment.after);
  p = mcPretty_pushPretty (p);
  mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
  doStatementSequenceC (p, s->repeatF.statements);
  doCommentC (p, s->repeatF.untilComment.body);
  p = mcPretty_popPretty (p);
  outText (p, (const char *) "} while (! (", 12);
  doExprC (p, s->repeatF.expr);
  outText (p, (const char *) "));", 3);
  doAfterCommentC (p, s->repeatF.untilComment.after);
}


/*
   doWhileC -
*/

static void doWhileC (mcPretty_pretty p, decl_node__opaque s)
{
  mcDebug_assert (decl_isWhile (static_cast<decl_node> (s)));
  doCommentC (p, s->whileF.doComment.body);
  outText (p, (const char *) "while (", 7);
  doExprC (p, s->whileF.expr);
  outText (p, (const char *) ")", 1);
  doAfterCommentC (p, s->whileF.doComment.after);
  doCompoundStmt (p, s->whileF.statements);
  doCommentC (p, s->whileF.endComment.body);
  doCommentC (p, s->whileF.endComment.after);
}


/*
   doFuncHighC -
*/

static void doFuncHighC (mcPretty_pretty p, decl_node__opaque a)
{
  decl_node__opaque s;
  decl_node__opaque n;

  if ((decl_isLiteral (static_cast<decl_node> (a))) && ((decl_getType (static_cast<decl_node> (a))) == charN))
    {
      outCard (p, 0);
    }
  else if (isString (a))
    {
      /* avoid dangling else.  */
      outCard (p, a->stringF.length-2);
    }
  else if ((decl_isConst (static_cast<decl_node> (a))) && (isString (a->constF.value)))
    {
      /* avoid dangling else.  */
      doFuncHighC (p, a->constF.value);
    }
  else if (decl_isUnbounded (decl_getType (static_cast<decl_node> (a))))
    {
      /* avoid dangling else.  */
      outText (p, (const char *) "_", 1);
      outTextN (p, decl_getSymName (static_cast<decl_node> (a)));
      outText (p, (const char *) "_high", 5);
    }
  else if (decl_isArray (decl_skipType (decl_getType (static_cast<decl_node> (a)))))
    {
      /* avoid dangling else.  */
      n = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (a))));
      s = n->arrayF.subr;
      if (isZero (getMin (s)))
        {
          doExprC (p, getMax (s));
        }
      else
        {
          outText (p, (const char *) "(", 1);
          doExprC (p, getMax (s));
          doSubtractC (p, getMin (s));
          outText (p, (const char *) ")", 1);
        }
    }
  else
    {
      /* avoid dangling else.  */
      /* output sizeof (a) in bytes for the high.  */
      outText (p, (const char *) "(sizeof", 7);
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "(", 1);
      doExprC (p, a);
      outText (p, (const char *) ")-1)", 4);
    }
}


/*
   doMultiplyBySize -
*/

static void doMultiplyBySize (mcPretty_pretty p, decl_node__opaque a)
{
  if (((a != charN) && (a != byteN)) && (a != locN))
    {
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "* sizeof (", 10);
      doTypeNameC (p, a);
      mcPretty_noSpace (p);
      outText (p, (const char *) ")", 1);
    }
}


/*
   doTotype -
*/

static void doTotype (mcPretty_pretty p, decl_node__opaque a, decl_node__opaque t)
{
  if ((! (isString (a))) && (! (decl_isLiteral (static_cast<decl_node> (a)))))
    {
      if (decl_isVar (static_cast<decl_node> (a)))
        {
          if (((a->varF.isParameter || a->varF.isVarParameter) && (decl_isUnbounded (decl_getType (static_cast<decl_node> (a))))) && ((decl_skipType (decl_getType (decl_getType (static_cast<decl_node> (a))))) == (decl_skipType (decl_getType (static_cast<decl_node> (t))))))
            {
              /* do not multiply by size as the existing high value is correct.  */
              return;
            }
          a = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (a)));
          if (decl_isArray (static_cast<decl_node> (a)))
            {
              doMultiplyBySize (p, static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (a)))));
            }
        }
    }
  if (t == wordN)
    {
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "/ sizeof (", 10);
      doTypeNameC (p, wordN);
      mcPretty_noSpace (p);
      outText (p, (const char *) ")", 1);
    }
}


/*
   doFuncUnbounded -
*/

static void doFuncUnbounded (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formalParam, decl_node__opaque formal, decl_node__opaque func)
{
  decl_node__opaque h;
  DynamicStrings_String s;

  mcDebug_assert (decl_isUnbounded (static_cast<decl_node> (formal)));
  outText (p, (const char *) "(", 1);
  if ((lang == decl_ansiCP) && (decl_isParam (static_cast<decl_node> (formalParam))))
    {
      outText (p, (const char *) "const", 5);
      mcPretty_setNeedSpace (p);
    }
  doTypeC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (formal))), &formal);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "*)", 2);
  mcPretty_setNeedSpace (p);
  if ((decl_isLiteral (static_cast<decl_node> (actual))) && ((decl_getType (static_cast<decl_node> (actual))) == charN))
    {
      outText (p, (const char *) "\"\\0", 3);
      s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (actual->literalF.name));
      s = DynamicStrings_Slice (DynamicStrings_Mark (s), 0, -1);
      outTextS (p, s);
      outText (p, (const char *) "\"", 1);
      s = DynamicStrings_KillString (s);
    }
  else if (isString (actual))
    {
      /* avoid dangling else.  */
      outCstring (p, actual, true);
    }
  else if (decl_isConst (static_cast<decl_node> (actual)))
    {
      /* avoid dangling else.  */
      actual = resolveString (actual);
      mcDebug_assert (isString (actual));
      outCstring (p, actual, true);
    }
  else if (isFuncCall (actual))
    {
      /* avoid dangling else.  */
      if ((getExprType (actual)) == NULL)
        {
          mcMetaError_metaError3 ((const char *) "there is no return type to the procedure function {%3ad} which is being passed as the parameter {%1ad} to {%2ad}", 112, (const unsigned char *) &formal, (sizeof (formal)-1), (const unsigned char *) &func, (sizeof (func)-1), (const unsigned char *) &actual, (sizeof (actual)-1));
        }
      else
        {
          outText (p, (const char *) "&", 1);
          doExprC (p, actual);
        }
    }
  else if (decl_isUnbounded (decl_getType (static_cast<decl_node> (actual))))
    {
      /* avoid dangling else.  */
      /* doExprC (p, actual).  */
      doFQNameC (p, actual);
    }
  else
    {
      /* avoid dangling else.  */
      outText (p, (const char *) "&", 1);
      doExprC (p, actual);
      if (decl_isArray (decl_skipType (decl_getType (static_cast<decl_node> (actual)))))
        {
          outText (p, (const char *) ".array[0]", 9);
        }
    }
  if (! (enableDefForCStrings && (isDefForC (static_cast<decl_node__opaque> (decl_getScope (static_cast<decl_node> (func)))))))
    {
      outText (p, (const char *) ",", 1);
      mcPretty_setNeedSpace (p);
      doFuncHighC (p, actual);
      doTotype (p, actual, formal);
    }
}


/*
   doProcedureParamC -
*/

static void doProcedureParamC (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formal)
{
  if (isForC (formal))
    {
      outText (p, (const char *) "(", 1);
      doFQNameC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (formal))));
      outText (p, (const char *) "_C", 2);
      outText (p, (const char *) ")", 1);
      mcPretty_setNeedSpace (p);
      doExprC (p, actual);
    }
  else
    {
      outText (p, (const char *) "(", 1);
      doTypeNameC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (formal))));
      outText (p, (const char *) ")", 1);
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "{", 1);
      outText (p, (const char *) "(", 1);
      doFQNameC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (formal))));
      outText (p, (const char *) "_t)", 3);
      mcPretty_setNeedSpace (p);
      doExprC (p, actual);
      outText (p, (const char *) "}", 1);
    }
}


/*
   doAdrExprC -
*/

static void doAdrExprC (mcPretty_pretty p, decl_node__opaque n)
{
  if (isDeref (n))
    {
      /* No point in issuing & ( * n ).  */
      doExprC (p, n->unaryF.arg);
    }
  else if ((decl_isVar (static_cast<decl_node> (n))) && n->varF.isVarParameter)
    {
      /* avoid dangling else.  */
      /* No point in issuing & ( * n ).  */
      doFQNameC (p, n);
    }
  else
    {
      /* avoid dangling else.  */
      outText (p, (const char *) "&", 1);
      doExprC (p, n);
    }
}


/*
   typePair -
*/

static bool typePair (decl_node__opaque a, decl_node__opaque b, decl_node__opaque x, decl_node__opaque y)
{
  return ((a == x) && (b == y)) || ((a == y) && (b == x));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   needsCast - return TRUE if the actual type parameter needs to be cast to
               the formal type.
*/

static bool needsCast (decl_node__opaque at, decl_node__opaque ft)
{
  at = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (at)));
  ft = static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (ft)));
  if (((((((((((((at == nilN) || (at->kind == decl_nil)) || (at == ft)) || (typePair (at, ft, cardinalN, wordN))) || (typePair (at, ft, cardinalN, ztypeN))) || (typePair (at, ft, integerN, ztypeN))) || (typePair (at, ft, longcardN, ztypeN))) || (typePair (at, ft, shortcardN, ztypeN))) || (typePair (at, ft, longintN, ztypeN))) || (typePair (at, ft, shortintN, ztypeN))) || (typePair (at, ft, realN, rtypeN))) || (typePair (at, ft, longrealN, rtypeN))) || (typePair (at, ft, shortrealN, rtypeN)))
    {
      return false;
    }
  else
    {
      return true;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   castDestType - emit the destination type ft
*/

static void castDestType (mcPretty_pretty p, decl_node__opaque formal, decl_node__opaque ft)
{
  doTypeNameC (p, ft);
  if (decl_isVarParam (static_cast<decl_node> (formal)))
    {
      outText (p, (const char *) "*", 1);
    }
}


/*
   identifyPointer -
*/

static decl_node__opaque identifyPointer (decl_node__opaque type)
{
  if (decl_isPointer (static_cast<decl_node> (type)))
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if ((decl_skipType (decl_getType (static_cast<decl_node> (type)))) == charN)
        {
          return charStarN;
        }
      else if (((decl_skipType (decl_getType (static_cast<decl_node> (type)))) == byteN) || ((decl_skipType (decl_getType (static_cast<decl_node> (type)))) == locN))
        {
          /* avoid dangling else.  */
          return addressN;
        }
    }
  return type;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   castPointer - provides a six way cast between ADDRESS (ie void * ),
                 char * and const char *.
*/

static unsigned int castPointer (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formal, decl_node__opaque at, decl_node__opaque ft)
{
  decl_node__opaque sat;
  decl_node__opaque sft;
  unsigned int parenth;

  parenth = 0;
  if (at != ft)
    {
      sat = identifyPointer (static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (at))));
      sft = identifyPointer (static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (ft))));
      if (sat == addressN)
        {
          if (sft == charStarN)
            {
              outText (p, (const char *) "reinterpret_cast <", 18);
              castDestType (p, formal, ft);
              outText (p, (const char *) ">", 1);
            }
          else if (sft == constCharStarN)
            {
              /* avoid dangling else.  */
              outText (p, (const char *) "const_cast <", 12);
              castDestType (p, formal, ft);
              outText (p, (const char *) "> (static_cast <", 16);
              doTypeNameC (p, charStarN);
              outText (p, (const char *) ">", 1);
              parenth += 1;
            }
          else
            {
              /* avoid dangling else.  */
              outText (p, (const char *) "reinterpret_cast <", 18);
              castDestType (p, formal, ft);
              outText (p, (const char *) ">", 1);
            }
        }
      else if (sat == charStarN)
        {
          /* avoid dangling else.  */
          if (sft == addressN)
            {
              outText (p, (const char *) "reinterpret_cast <", 18);
              castDestType (p, formal, ft);
              outText (p, (const char *) ">", 1);
            }
          else if (sft == constCharStarN)
            {
              /* avoid dangling else.  */
              outText (p, (const char *) "const_cast <", 12);
              castDestType (p, formal, ft);
              outText (p, (const char *) ">", 1);
            }
          else
            {
              /* avoid dangling else.  */
              outText (p, (const char *) "reinterpret_cast <", 18);
              castDestType (p, formal, ft);
              outText (p, (const char *) ">", 1);
            }
        }
      else if (sat == constCharStarN)
        {
          /* avoid dangling else.  */
          if (sft == addressN)
            {
              outText (p, (const char *) "static_cast <", 13);
              castDestType (p, formal, ft);
              outText (p, (const char *) "> (const_cast <", 15);
              doTypeNameC (p, charStarN);
              outText (p, (const char *) ">", 1);
              parenth += 1;
            }
          else if (sft == charStarN)
            {
              /* avoid dangling else.  */
              outText (p, (const char *) "const_cast <", 12);
              castDestType (p, formal, ft);
              outText (p, (const char *) ">", 1);
            }
          else
            {
              /* avoid dangling else.  */
              outText (p, (const char *) "reinterpret_cast <", 18);
              castDestType (p, formal, ft);
              outText (p, (const char *) ">", 1);
            }
        }
      else
        {
          /* avoid dangling else.  */
          outText (p, (const char *) "reinterpret_cast <", 18);
          castDestType (p, formal, ft);
          outText (p, (const char *) ">", 1);
        }
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "(", 1);
      parenth += 1;
    }
  return parenth;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   checkSystemCast - checks to see if we are passing to/from
                     a system generic type (WORD, BYTE, ADDRESS)
                     and if so emit a cast.  It returns the number of
                     open parenthesis.
*/

static unsigned int checkSystemCast (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formal)
{
  decl_node__opaque at;
  decl_node__opaque ft;

  at = getExprType (actual);
  ft = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (formal)));
  if (needsCast (at, ft))
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if (lang == decl_ansiCP)
        {
          if ((isString (actual)) && (isCDataType (static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (ft))))))
            {
              /* Nothing to do.  */
              return 0;
            }
          else if ((isString (actual)) && ((decl_skipType (static_cast<decl_node> (ft))) == addressN))
            {
              /* avoid dangling else.  */
              outText (p, (const char *) "const_cast<void*> (static_cast<const void*> (", 45);
              return 2;
            }
          else if (((decl_isPointer (decl_skipType (static_cast<decl_node> (ft)))) || ((decl_skipType (static_cast<decl_node> (ft))) == addressN)) || (isCDataType (static_cast<decl_node__opaque> (decl_skipType (static_cast<decl_node> (ft))))))
            {
              /* avoid dangling else.  */
              if (actual == nilN)
                {
                  if (decl_isVarParam (static_cast<decl_node> (formal)))
                    {
                      mcMetaError_metaError1 ((const char *) "NIL is being passed to a VAR parameter {%1DMad}", 47, (const unsigned char *) &formal, (sizeof (formal)-1));
                    }
                  /* NULL is compatible with pointers/address.  */
                  return 0;
                }
              else
                {
                  return castPointer (p, actual, formal, at, ft);
                }
            }
          else
            {
              /* avoid dangling else.  */
              outText (p, (const char *) "static_cast<", 12);
              doTypeNameC (p, ft);
              if (decl_isVarParam (static_cast<decl_node> (formal)))
                {
                  outText (p, (const char *) "*", 1);
                }
              mcPretty_noSpace (p);
              outText (p, (const char *) "> (", 3);
            }
          return 1;
        }
      else
        {
          outText (p, (const char *) "(", 1);
          doTypeNameC (p, ft);
          if (decl_isVarParam (static_cast<decl_node> (formal)))
            {
              outText (p, (const char *) "*", 1);
            }
          mcPretty_noSpace (p);
          outText (p, (const char *) ")", 1);
          mcPretty_setNeedSpace (p);
        }
    }
  return 0;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   emitN -
*/

static void emitN (mcPretty_pretty p, const char *a_, unsigned int _a_high, unsigned int n)
{
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  while (n > 0)
    {
      outText (p, (const char *) a, _a_high);
      n -= 1;
    }
}


/*
   isForC - return true if node n is a varparam, param or procedure
            which was declared inside a definition module for "C".
*/

static bool isForC (decl_node__opaque n)
{
  if (decl_isVarParam (static_cast<decl_node> (n)))
    {
      return n->varparamF.isForC;
    }
  else if (decl_isParam (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      return n->paramF.isForC;
    }
  else if (decl_isProcedure (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      return n->procedureF.isForC;
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isDefForCNode - return TRUE if node n was declared inside a definition module for "C".
*/

static bool isDefForCNode (decl_node__opaque n)
{
  nameKey_Name name;

  while ((n != NULL) && (! (((decl_isImp (static_cast<decl_node> (n))) || (decl_isDef (static_cast<decl_node> (n)))) || (decl_isModule (static_cast<decl_node> (n))))))
    {
      n = static_cast<decl_node__opaque> (decl_getScope (static_cast<decl_node> (n)));
    }
  if ((n != NULL) && (decl_isImp (static_cast<decl_node> (n))))
    {
      name = decl_getSymName (static_cast<decl_node> (n));
      n = static_cast<decl_node__opaque> (decl_lookupDef (name));
    }
  return ((n != NULL) && (decl_isDef (static_cast<decl_node> (n)))) && (isDefForC (n));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doFuncVarParam - detect whether the formal uses an opaque and ensure that the address of
                    the actual parameter is cast to the formal type.
*/

static void doFuncVarParam (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formal)
{
  decl_node__opaque type;

  if ((nodeUsesOpaque (formal)) && (getNodeOpaqueFlushNecessary (actual, getNodeOpaqueVoidStar (formal))))
    {
      type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (formal)));
      outText (p, (const char *) "reinterpret_cast<", 17);
      if (getNodeOpaqueVoidStar (formal))
        {
          doTypeNameC (p, type);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "*> (&", 5);
          doExprC (p, actual);
          outText (p, (const char *) ")", 1);
          actual = makeOpaqueCast (actual, true);
        }
      else
        {
          doTypeNameC (p, type);
          mcPretty_noSpace (p);
          outText (p, (const char *) "__opaque *> (&", 14);
          doExprC (p, actual);
          outText (p, (const char *) ")", 1);
          actual = makeOpaqueCast (actual, false);
        }
    }
  else
    {
      doAdrExprC (p, actual);
    }
}


/*
   doFuncParamC -
*/

static void doFuncParamC (mcPretty_pretty p, decl_node__opaque actual, decl_node__opaque formal, decl_node__opaque func)
{
  decl_node__opaque ft;
  decl_node__opaque at;
  unsigned int lbr;

  if (formal == NULL)
    {
      doExprC (p, actual);
    }
  else
    {
      ft = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (formal))));
      if (decl_isUnbounded (static_cast<decl_node> (ft)))
        {
          doFuncUnbounded (p, actual, formal, ft, func);
        }
      else
        {
          if ((isAProcType (ft)) && (decl_isProcedure (static_cast<decl_node> (actual))))
            {
              if (decl_isVarParam (static_cast<decl_node> (formal)))
                {
                  mcMetaError_metaError1 ((const char *) "{%1MDad} cannot be passed as a VAR parameter", 44, (const unsigned char *) &actual, (sizeof (actual)-1));
                }
              else
                {
                  doProcedureParamC (p, actual, formal);
                }
            }
          else if (((((decl_getType (static_cast<decl_node> (actual))) != NULL) && (decl_isProcType (decl_skipType (decl_getType (static_cast<decl_node> (actual)))))) && (isAProcType (ft))) && (isForC (formal)))
            {
              /* avoid dangling else.  */
              if (decl_isVarParam (static_cast<decl_node> (formal)))
                {
                  mcMetaError_metaError2 ((const char *) "{%1MDad} cannot be passed as a VAR parameter to the definition for C module as the parameter requires a cast to the formal type {%2MDtad}", 137, (const unsigned char *) &actual, (sizeof (actual)-1), (const unsigned char *) &formal, (sizeof (formal)-1));
                }
              else
                {
                  outText (p, (const char *) "(", 1);
                  doFQNameC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (formal))));
                  outText (p, (const char *) "_C", 2);
                  outText (p, (const char *) ")", 1);
                  mcPretty_setNeedSpace (p);
                  doExprC (p, actual);
                  outText (p, (const char *) ".proc", 5);
                }
            }
          else if ((((decl_getType (static_cast<decl_node> (actual))) != NULL) && (decl_isProcType (decl_skipType (decl_getType (static_cast<decl_node> (actual)))))) && ((decl_getType (static_cast<decl_node> (actual))) != (decl_getType (static_cast<decl_node> (formal)))))
            {
              /* avoid dangling else.  */
              if (decl_isVarParam (static_cast<decl_node> (formal)))
                {
                  mcMetaError_metaError2 ((const char *) "{%1MDad} cannot be passed as a VAR parameter as the parameter requires a cast to the formal type {%2MDtad}", 106, (const unsigned char *) &actual, (sizeof (actual)-1), (const unsigned char *) &formal, (sizeof (formal)-1));
                }
              else
                {
                  doCastC (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (formal))), actual);
                }
            }
          else
            {
              /* avoid dangling else.  */
              if (decl_isVarParam (static_cast<decl_node> (formal)))
                {
                  lbr = checkSystemCast (p, actual, formal);
                  doFuncVarParam (p, actual, formal);
                  emitN (p, (const char *) ")", 1, lbr);
                }
              else
                {
                  if (nodeUsesOpaque (formal))
                    {
                      forceCastOpaque (p, formal, actual, getNodeOpaqueVoidStar (formal));
                    }
                  else
                    {
                      lbr = checkSystemCast (p, actual, formal);
                      doExprC (p, actual);
                      emitN (p, (const char *) ")", 1, lbr);
                    }
                }
            }
        }
    }
}


/*
   getNthParamType - return the type of parameter, i, in list, l.
                     If the parameter is a vararg NIL is returned.
*/

static decl_node__opaque getNthParamType (Indexing_Index l, unsigned int i)
{
  decl_node__opaque p;

  p = getNthParam (l, i);
  if (p != NULL)
    {
      return static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (p)));
    }
  return static_cast<decl_node__opaque> (NULL);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getNthParam - return the parameter, i, in list, l.
                 If the parameter is a vararg NIL is returned.
*/

static decl_node__opaque getNthParam (Indexing_Index l, unsigned int i)
{
  decl_node__opaque p;
  unsigned int j;
  unsigned int k;
  unsigned int h;

  if (l != NULL)
    {
      j = Indexing_LowIndice (l);
      h = Indexing_HighIndice (l);
      while (j <= h)
        {
          p = static_cast<decl_node__opaque> (Indexing_GetIndice (l, j));
          if (decl_isParam (static_cast<decl_node> (p)))
            {
              k = identListLen (p->paramF.namelist);
            }
          else if (decl_isVarParam (static_cast<decl_node> (p)))
            {
              /* avoid dangling else.  */
              k = identListLen (p->varparamF.namelist);
            }
          else
            {
              /* avoid dangling else.  */
              mcDebug_assert (decl_isVarargs (static_cast<decl_node> (p)));
              return static_cast<decl_node__opaque> (NULL);
            }
          if (i <= k)
            {
              return p;
            }
          else
            {
              i -= k;
              j += 1;
            }
        }
    }
  return static_cast<decl_node__opaque> (NULL);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doFuncArgsC -
*/

static void doFuncArgsC (mcPretty_pretty p, decl_node__opaque s, Indexing_Index l, bool needParen)
{
  decl_node__opaque actual;
  decl_node__opaque formal;
  unsigned int i;
  unsigned int n;

  if (needParen)
    {
      outText (p, (const char *) "(", 1);
    }
  if (s->funccallF.args != NULL)
    {
      i = 1;
      n = expListLen (s->funccallF.args);
      while (i <= n)
        {
          actual = getExpList (s->funccallF.args, i);
          formal = getNthParam (l, i);
          doFuncParamC (p, actual, formal, s->funccallF.function);
          if (i < n)
            {
              outText (p, (const char *) ",", 1);
              mcPretty_setNeedSpace (p);
            }
          i += 1;
        }
    }
  if (needParen)
    {
      mcPretty_noSpace (p);
      outText (p, (const char *) ")", 1);
    }
}


/*
   doProcTypeArgsC -
*/

static void doProcTypeArgsC (mcPretty_pretty p, decl_node__opaque s, Indexing_Index args, bool needParen)
{
  decl_node__opaque a;
  decl_node__opaque b;
  unsigned int i;
  unsigned int n;

  if (needParen)
    {
      outText (p, (const char *) "(", 1);
    }
  if (s->funccallF.args != NULL)
    {
      i = 1;
      n = expListLen (s->funccallF.args);
      while (i <= n)
        {
          a = getExpList (s->funccallF.args, i);
          b = static_cast<decl_node__opaque> (Indexing_GetIndice (args, i));
          doFuncParamC (p, a, b, s->funccallF.function);
          if (i < n)
            {
              outText (p, (const char *) ",", 1);
              mcPretty_setNeedSpace (p);
            }
          i += 1;
        }
    }
  if (needParen)
    {
      mcPretty_noSpace (p);
      outText (p, (const char *) ")", 1);
    }
}


/*
   doAdrArgC -
*/

static void doAdrArgC (mcPretty_pretty p, decl_node__opaque n)
{
  if (isDeref (n))
    {
      /* & and * cancel each other out.  */
      doExprC (p, n->unaryF.arg);
    }
  else if ((decl_isVar (static_cast<decl_node> (n))) && n->varF.isVarParameter)
    {
      /* avoid dangling else.  */
      outTextN (p, decl_getSymName (static_cast<decl_node> (n)));  /* --fixme-- does the caller need to cast it?  */
    }
  else if ((isString (n)) || ((decl_isArray (decl_getType (static_cast<decl_node> (n)))) && (decl_isUnbounded (decl_getType (static_cast<decl_node> (n))))))
    {
      /* avoid dangling else.  */
      if (lang == decl_ansiCP)
        {
          outText (p, (const char *) "const_cast<void*> (static_cast<const void*>", 43);
          outText (p, (const char *) "(", 1);
          doExprC (p, n);
          outText (p, (const char *) "))", 2);
        }
      else
        {
          doExprC (p, n);
        }
    }
  else
    {
      /* avoid dangling else.  */
      outText (p, (const char *) "&", 1);
      doExprC (p, n);
    }
}


/*
   doAdrC -
*/

static void doAdrC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isUnary (n));
  doAdrArgC (p, n->unaryF.arg);
}


/*
   doInc -
*/

static void doInc (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isIntrinsic (n));
  if (lang == decl_ansiCP)
    {
      doIncDecCP (p, n, (const char *) "+", 1);
    }
  else
    {
      doIncDecC (p, n, (const char *) "+=", 2);
    }
}


/*
   doDec -
*/

static void doDec (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isIntrinsic (n));
  if (lang == decl_ansiCP)
    {
      doIncDecCP (p, n, (const char *) "-", 1);
    }
  else
    {
      doIncDecC (p, n, (const char *) "-=", 2);
    }
}


/*
   doIncDecC -
*/

static void doIncDecC (mcPretty_pretty p, decl_node__opaque n, const char *op_, unsigned int _op_high)
{
  char op[_op_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (op, op_, _op_high+1);

  mcDebug_assert (isIntrinsic (n));
  if (n->intrinsicF.args != NULL)
    {
      doExprC (p, getExpList (n->intrinsicF.args, 1));
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) op, _op_high);
      mcPretty_setNeedSpace (p);
      if ((expListLen (n->intrinsicF.args)) == 1)
        {
          outText (p, (const char *) "1", 1);
        }
      else
        {
          doExprC (p, getExpList (n->intrinsicF.args, 2));
        }
    }
}


/*
   doIncDecCP -
*/

static void doIncDecCP (mcPretty_pretty p, decl_node__opaque n, const char *op_, unsigned int _op_high)
{
  decl_node__opaque lhs;
  decl_node__opaque type;
  char op[_op_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (op, op_, _op_high+1);

  mcDebug_assert (isIntrinsic (n));
  if (n->intrinsicF.args != NULL)
    {
      lhs = getExpList (n->intrinsicF.args, 1);
      doExprC (p, lhs);
      mcPretty_setNeedSpace (p);
      type = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (lhs)));
      if ((decl_isPointer (static_cast<decl_node> (type))) || (type == addressN))
        {
          /* cast to (char * ) and then back again after the arithmetic is complete.  */
          outText (p, (const char *) "=", 1);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "reinterpret_cast<", 17);
          doTypeNameC (p, type);
          mcPretty_noSpace (p);
          outText (p, (const char *) "> (reinterpret_cast<char *> (", 29);
          doExprC (p, lhs);
          mcPretty_noSpace (p);
          outText (p, (const char *) ")", 1);
          outText (p, (const char *) op, _op_high);
          if ((expListLen (n->intrinsicF.args)) == 1)
            {
              outText (p, (const char *) "1", 1);
            }
          else
            {
              doExprC (p, getExpList (n->intrinsicF.args, 2));
            }
          outText (p, (const char *) ")", 1);
        }
      else if (decl_isEnumeration (decl_skipType (static_cast<decl_node> (type))))
        {
          /* avoid dangling else.  */
          outText (p, (const char *) "= static_cast<", 14);
          doTypeNameC (p, type);
          mcPretty_noSpace (p);
          outText (p, (const char *) ">(static_cast<int>(", 19);
          doExprC (p, lhs);
          outText (p, (const char *) ")", 1);
          outText (p, (const char *) op, _op_high);
          if ((expListLen (n->intrinsicF.args)) == 1)
            {
              outText (p, (const char *) "1", 1);
            }
          else
            {
              doExprC (p, getExpList (n->intrinsicF.args, 2));
            }
          outText (p, (const char *) ")", 1);
        }
      else
        {
          /* avoid dangling else.  */
          outText (p, (const char *) op, _op_high);
          outText (p, (const char *) "=", 1);
          mcPretty_setNeedSpace (p);
          if ((expListLen (n->intrinsicF.args)) == 1)
            {
              outText (p, (const char *) "1", 1);
            }
          else
            {
              doExprC (p, getExpList (n->intrinsicF.args, 2));
            }
        }
    }
}


/*
   doInclC -
*/

static void doInclC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque lo;

  mcDebug_assert (isIntrinsic (n));
  if (n->intrinsicF.args != NULL)
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if ((expListLen (n->intrinsicF.args)) == 2)
        {
          doExprC (p, getExpList (n->intrinsicF.args, 1));
          lo = getSetLow (getExpList (n->intrinsicF.args, 1));
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "|=", 2);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "(1", 2);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "<<", 2);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "(", 1);
          doExprC (p, getExpList (n->intrinsicF.args, 2));
          doSubtractC (p, lo);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "))", 2);
        }
      else
        {
          M2RTS_HALT (-1);  /* metaError0 ('expecting two parameters to INCL')  */
          __builtin_unreachable ();
        }
    }
}


/*
   doExclC -
*/

static void doExclC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque lo;

  mcDebug_assert (isIntrinsic (n));
  if (n->intrinsicF.args != NULL)
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if ((expListLen (n->intrinsicF.args)) == 2)
        {
          doExprC (p, getExpList (n->intrinsicF.args, 1));
          lo = getSetLow (getExpList (n->intrinsicF.args, 1));
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "&=", 2);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "(~(1", 4);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "<<", 2);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "(", 1);
          doExprC (p, getExpList (n->intrinsicF.args, 2));
          doSubtractC (p, lo);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) ")))", 3);
        }
      else
        {
          M2RTS_HALT (-1);  /* metaError0 ('expecting two parameters to EXCL')  */
          __builtin_unreachable ();
        }
    }
}


/*
   doNewC -
*/

static void doNewC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;

  mcDebug_assert (isIntrinsic (n));
  if (n->intrinsicF.args == NULL)
    {
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  else
    {
      if ((expListLen (n->intrinsicF.args)) == 1)
        {
          keyc_useStorage ();
          outText (p, (const char *) "Storage_ALLOCATE", 16);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "((void **)", 10);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "&", 1);
          doExprC (p, getExpList (n->intrinsicF.args, 1));
          outText (p, (const char *) ",", 1);
          mcPretty_setNeedSpace (p);
          t = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (getExpList (n->intrinsicF.args, 1)))));
          if (decl_isPointer (static_cast<decl_node> (t)))
            {
              t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (t)));
              outText (p, (const char *) "sizeof", 6);
              mcPretty_setNeedSpace (p);
              outText (p, (const char *) "(", 1);
              doTypeNameC (p, t);
              mcPretty_noSpace (p);
              outText (p, (const char *) "))", 2);
            }
          else
            {
              mcMetaError_metaError1 ((const char *) "expecting a pointer type variable as the argument to NEW, rather than {%1ad}", 76, (const unsigned char *) &t, (sizeof (t)-1));
            }
        }
    }
}


/*
   doDisposeC -
*/

static void doDisposeC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;

  mcDebug_assert (isIntrinsic (n));
  if (n->intrinsicF.args == NULL)
    {
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  else
    {
      if ((expListLen (n->intrinsicF.args)) == 1)
        {
          keyc_useStorage ();
          outText (p, (const char *) "Storage_DEALLOCATE", 18);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "((void **)", 10);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "&", 1);
          doExprC (p, getExpList (n->intrinsicF.args, 1));
          outText (p, (const char *) ",", 1);
          mcPretty_setNeedSpace (p);
          t = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (getExpList (n->intrinsicF.args, 1)))));
          if (decl_isPointer (static_cast<decl_node> (t)))
            {
              t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (t)));
              outText (p, (const char *) "sizeof", 6);
              mcPretty_setNeedSpace (p);
              outText (p, (const char *) "(", 1);
              doTypeNameC (p, t);
              mcPretty_noSpace (p);
              outText (p, (const char *) "))", 2);
            }
          else
            {
              mcMetaError_metaError1 ((const char *) "expecting a pointer type variable as the argument to DISPOSE, rather than {%1ad}", 80, (const unsigned char *) &t, (sizeof (t)-1));
            }
        }
      else
        {
          M2RTS_HALT (-1);  /* metaError0 ('expecting a single parameter to DISPOSE')  */
          __builtin_unreachable ();
        }
    }
}


/*
   doCapC -
*/

static void doCapC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isUnary (n));
  if (n->unaryF.arg == NULL)
    {
      M2RTS_HALT (-1);  /* metaError0 ('expecting a single parameter to CAP')  */
      __builtin_unreachable ();
    }
  else
    {
      keyc_useCtype ();
      if (mcOptions_getGccConfigSystem ())
        {
          outText (p, (const char *) "TOUPPER", 7);
        }
      else
        {
          outText (p, (const char *) "toupper", 7);
        }
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "(", 1);
      doExprC (p, n->unaryF.arg);
      outText (p, (const char *) ")", 1);
    }
}


/*
   doLengthC -
*/

static void doLengthC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isUnary (n));
  if (n->unaryF.arg == NULL)
    {
      M2RTS_HALT (-1);  /* metaError0 ('expecting a single parameter to LENGTH')  */
      __builtin_unreachable ();
    }
  else
    {
      keyc_useM2RTS ();
      outText (p, (const char *) "M2RTS_Length", 12);
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "(", 1);
      doExprC (p, n->unaryF.arg);
      outText (p, (const char *) ",", 1);
      mcPretty_setNeedSpace (p);
      doFuncHighC (p, n->unaryF.arg);
      outText (p, (const char *) ")", 1);
    }
}


/*
   doAbsC -
*/

static void doAbsC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;

  mcDebug_assert (isUnary (n));
  if (n->unaryF.arg == NULL)
    {
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  else
    {
      t = getExprType (n);
    }
  if (t == longintN)
    {
      keyc_useLabs ();
      outText (p, (const char *) "labs", 4);
    }
  else if (t == integerN)
    {
      /* avoid dangling else.  */
      keyc_useAbs ();
      outText (p, (const char *) "abs", 3);
    }
  else if (t == realN)
    {
      /* avoid dangling else.  */
      keyc_useFabs ();
      outText (p, (const char *) "fabs", 4);
    }
  else if (t == longrealN)
    {
      /* avoid dangling else.  */
      keyc_useFabsl ();
      outText (p, (const char *) "fabsl", 5);
    }
  else if (t == cardinalN)
    {
      /* avoid dangling else.  */
    }
  else
    {
      /* avoid dangling else.  */
      /* do nothing.  */
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, n->unaryF.arg);
  outText (p, (const char *) ")", 1);
}


/*
   doValC -
*/

static void doValC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isBinary (n));
  outText (p, (const char *) "(", 1);
  doTypeNameC (p, n->binaryF.left);
  outText (p, (const char *) ")", 1);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, n->binaryF.right);
  outText (p, (const char *) ")", 1);
}


/*
   doMinC -
*/

static void doMinC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;

  mcDebug_assert (isUnary (n));
  t = getExprType (n->unaryF.arg);
  doExprC (p, getMin (t));
}


/*
   doMaxC -
*/

static void doMaxC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;

  mcDebug_assert (isUnary (n));
  t = getExprType (n->unaryF.arg);
  doExprC (p, getMax (t));
}


/*
   isIntrinsic - returns if, n, is an intrinsic procedure.
                 The intrinsic functions are represented as unary and binary nodes.
*/

static bool isIntrinsic (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_unreachable:
      case decl_throw:
      case decl_inc:
      case decl_dec:
      case decl_incl:
      case decl_excl:
      case decl_new:
      case decl_dispose:
      case decl_halt:
        return true;
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doHalt -
*/

static void doHalt (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (n->kind == decl_halt);
  if ((n->intrinsicF.args == NULL) || ((expListLen (n->intrinsicF.args)) == 0))
    {
      outText (p, (const char *) "M2RTS_HALT", 10);
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "(-1)", 4);
    }
  else if ((expListLen (n->intrinsicF.args)) == 1)
    {
      /* avoid dangling else.  */
      outText (p, (const char *) "M2RTS_HALT", 10);
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "(", 1);
      doExprC (p, getExpList (n->intrinsicF.args, 1));
      outText (p, (const char *) ")", 1);
    }
}


/*
   doCreal - emit the appropriate creal function.
*/

static void doCreal (mcPretty_pretty p, decl_node__opaque t)
{
  switch (t->kind)
    {
      case decl_complex:
        keyc_useComplex ();
        outText (p, (const char *) "creal", 5);
        break;

      case decl_longcomplex:
        keyc_useComplex ();
        outText (p, (const char *) "creall", 6);
        break;

      case decl_shortcomplex:
        keyc_useComplex ();
        outText (p, (const char *) "crealf", 6);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   doCimag - emit the appropriate cimag function.
*/

static void doCimag (mcPretty_pretty p, decl_node__opaque t)
{
  switch (t->kind)
    {
      case decl_complex:
        keyc_useComplex ();
        outText (p, (const char *) "cimag", 5);
        break;

      case decl_longcomplex:
        keyc_useComplex ();
        outText (p, (const char *) "cimagl", 6);
        break;

      case decl_shortcomplex:
        keyc_useComplex ();
        outText (p, (const char *) "cimagf", 6);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   doReC -
*/

static void doReC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;

  mcDebug_assert (n->kind == decl_re);
  if (n->unaryF.arg != NULL)
    {
      t = getExprType (n->unaryF.arg);
    }
  else
    {
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  doCreal (p, t);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, n->unaryF.arg);
  outText (p, (const char *) ")", 1);
}


/*
   doImC -
*/

static void doImC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;

  mcDebug_assert (n->kind == decl_im);
  if (n->unaryF.arg != NULL)
    {
      t = getExprType (n->unaryF.arg);
    }
  else
    {
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  doCimag (p, t);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, n->unaryF.arg);
  outText (p, (const char *) ")", 1);
}


/*
   doCmplx -
*/

static void doCmplx (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isBinary (n));
  keyc_useComplex ();
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, n->binaryF.left);
  outText (p, (const char *) ")", 1);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "+", 1);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, n->binaryF.right);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "*", 1);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "I", 1);
  outText (p, (const char *) ")", 1);
}


/*
   doIntrinsicC -
*/

static void doIntrinsicC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isIntrinsic (n));
  doCommentC (p, n->intrinsicF.intrinsicComment.body);
  switch (n->kind)
    {
      case decl_unreachable:
        doUnreachableC (p, n);
        break;

      case decl_throw:
        doThrowC (p, n);
        break;

      case decl_halt:
        doHalt (p, n);
        break;

      case decl_inc:
        doInc (p, n);
        break;

      case decl_dec:
        doDec (p, n);
        break;

      case decl_incl:
        doInclC (p, n);
        break;

      case decl_excl:
        doExclC (p, n);
        break;

      case decl_new:
        doNewC (p, n);
        break;

      case decl_dispose:
        doDisposeC (p, n);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  outText (p, (const char *) ";", 1);
  doAfterCommentC (p, n->intrinsicF.intrinsicComment.after);
}


/*
   isIntrinsicFunction - returns true if, n, is an instrinsic function.
*/

static bool isIntrinsicFunction (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_val:
      case decl_adr:
      case decl_size:
      case decl_tsize:
      case decl_float:
      case decl_trunc:
      case decl_ord:
      case decl_chr:
      case decl_cap:
      case decl_abs:
      case decl_high:
      case decl_length:
      case decl_min:
      case decl_max:
      case decl_re:
      case decl_im:
      case decl_cmplx:
        return true;
        break;


      default:
        return false;
        break;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doSizeC -
*/

static void doSizeC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (isUnary (n));
  outText (p, (const char *) "sizeof (", 8);
  doExprC (p, n->unaryF.arg);
  outText (p, (const char *) ")", 1);
}


/*
   doConvertC -
*/

static void doConvertC (mcPretty_pretty p, decl_node__opaque n, const char *conversion_, unsigned int _conversion_high)
{
  DynamicStrings_String s;
  char conversion[_conversion_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (conversion, conversion_, _conversion_high+1);

  s = DynamicStrings_InitString ((const char *) conversion, _conversion_high);
  doConvertSC (p, n, s);
  s = DynamicStrings_KillString (s);
}


/*
   doConvertSC -
*/

static void doConvertSC (mcPretty_pretty p, decl_node__opaque n, DynamicStrings_String conversion)
{
  mcDebug_assert (isUnary (n));
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "((", 2);
  outTextS (p, conversion);
  outText (p, (const char *) ")", 1);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doExprC (p, n->unaryF.arg);
  outText (p, (const char *) "))", 2);
}


/*
   getFunction - return the function associate with funccall node n.
*/

static decl_node__opaque getFunction (decl_node__opaque n)
{
  mcDebug_assert (isFuncCall (n));
  switch (n->kind)
    {
      case decl_funccall:
        return n->funccallF.function;
        break;


      default:
        M2RTS_HALT (-1);
        __builtin_unreachable ();
        break;
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   getFuncFromExpr -
*/

static decl_node__opaque getFuncFromExpr (decl_node__opaque n)
{
  n = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (n))));
  while ((n != procN) && (! (decl_isProcType (static_cast<decl_node> (n)))))
    {
      n = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (n))));
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doFuncExprC -
*/

static void doFuncExprC (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque t;

  mcDebug_assert (isFuncCall (n));
  if (decl_isProcedure (static_cast<decl_node> (n->funccallF.function)))
    {
      doFQDNameC (p, n->funccallF.function, true);
      mcPretty_setNeedSpace (p);
      doFuncArgsC (p, n, n->funccallF.function->procedureF.parameters, true);
    }
  else
    {
      outText (p, (const char *) "(*", 2);
      doExprC (p, n->funccallF.function);
      outText (p, (const char *) ".proc", 5);
      outText (p, (const char *) ")", 1);
      t = getFuncFromExpr (n->funccallF.function);
      mcPretty_setNeedSpace (p);
      if (t == procN)
        {
          doProcTypeArgsC (p, n, static_cast<Indexing_Index> (NULL), true);
        }
      else
        {
          mcDebug_assert (decl_isProcType (static_cast<decl_node> (t)));
          doProcTypeArgsC (p, n, t->proctypeF.parameters, true);
        }
    }
}


/*
   doFuncCallC -
*/

static void doFuncCallC (mcPretty_pretty p, decl_node__opaque n)
{
  doCommentC (p, n->funccallF.funccallComment.body);
  doFuncExprC (p, n);
  outText (p, (const char *) ";", 1);
  doAfterCommentC (p, n->funccallF.funccallComment.after);
}


/*
   doCaseStatementC -
*/

static void doCaseStatementC (mcPretty_pretty p, decl_node__opaque n, bool needBreak)
{
  p = mcPretty_pushPretty (p);
  mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
  doStatementSequenceC (p, n);
  if (needBreak)
    {
      outText (p, (const char *) "break;\\n", 8);
    }
  p = mcPretty_popPretty (p);
}


/*
   doExceptionC -
*/

static void doExceptionC (mcPretty_pretty p, const char *a_, unsigned int _a_high, decl_node__opaque n)
{
  unsigned int w;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  w = decl_getDeclaredMod (static_cast<decl_node> (n));
  outText (p, (const char *) a, _a_high);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(\"", 2);
  outTextS (p, mcLexBuf_findFileNameFromToken (w, 0));
  outText (p, (const char *) "\",", 2);
  mcPretty_setNeedSpace (p);
  outCard (p, mcLexBuf_tokenToLineNo (w, 0));
  outText (p, (const char *) ",", 1);
  mcPretty_setNeedSpace (p);
  outCard (p, mcLexBuf_tokenToColumnNo (w, 0));
  outText (p, (const char *) ");\\n", 4);
  outText (p, (const char *) "__builtin_unreachable ();\\n", 27);
}


/*
   doExceptionCP -
*/

static void doExceptionCP (mcPretty_pretty p, const char *a_, unsigned int _a_high, decl_node__opaque n)
{
  unsigned int w;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  w = decl_getDeclaredMod (static_cast<decl_node> (n));
  outText (p, (const char *) a, _a_high);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(\"", 2);
  outTextS (p, mcLexBuf_findFileNameFromToken (w, 0));
  outText (p, (const char *) "\",", 2);
  mcPretty_setNeedSpace (p);
  outCard (p, mcLexBuf_tokenToLineNo (w, 0));
  outText (p, (const char *) ",", 1);
  mcPretty_setNeedSpace (p);
  outCard (p, mcLexBuf_tokenToColumnNo (w, 0));
  outText (p, (const char *) ");\\n", 4);
  outText (p, (const char *) "__builtin_unreachable ();\\n", 27);
}


/*
   doException -
*/

static void doException (mcPretty_pretty p, const char *a_, unsigned int _a_high, decl_node__opaque n)
{
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  keyc_useException ();
  if (lang == decl_ansiCP)
    {
      doExceptionCP (p, (const char *) a, _a_high, n);
    }
  else
    {
      doExceptionC (p, (const char *) a, _a_high, n);
    }
}


/*
   doRangeListC -
*/

static void doRangeListC (mcPretty_pretty p, decl_node__opaque c)
{
  decl_node__opaque r;
  unsigned int i;
  unsigned int h;

  mcDebug_assert (decl_isCaseList (static_cast<decl_node> (c)));
  i = 1;
  h = Indexing_HighIndice (c->caselistF.rangePairs);
  while (i <= h)
    {
      r = static_cast<decl_node__opaque> (Indexing_GetIndice (c->caselistF.rangePairs, i));
      mcDebug_assert ((r->rangeF.hi == NULL) || (r->rangeF.lo == r->rangeF.hi));
      outText (p, (const char *) "case", 4);
      mcPretty_setNeedSpace (p);
      doExprC (p, r->rangeF.lo);
      outText (p, (const char *) ":\\n", 3);
      i += 1;
    }
}


/*
   doRangeIfListC -
*/

static void doRangeIfListC (mcPretty_pretty p, decl_node__opaque e, decl_node__opaque c)
{
  decl_node__opaque r;
  unsigned int i;
  unsigned int h;

  mcDebug_assert (decl_isCaseList (static_cast<decl_node> (c)));
  i = 1;
  h = Indexing_HighIndice (c->caselistF.rangePairs);
  while (i <= h)
    {
      r = static_cast<decl_node__opaque> (Indexing_GetIndice (c->caselistF.rangePairs, i));
      if ((r->rangeF.lo != r->rangeF.hi) && (r->rangeF.hi != NULL))
        {
          outText (p, (const char *) "((", 2);
          doExprC (p, e);
          outText (p, (const char *) ")", 1);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) ">=", 2);
          mcPretty_setNeedSpace (p);
          doExprC (p, r->rangeF.lo);
          outText (p, (const char *) ")", 1);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "&&", 2);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "((", 2);
          doExprC (p, e);
          outText (p, (const char *) ")", 1);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "<=", 2);
          mcPretty_setNeedSpace (p);
          doExprC (p, r->rangeF.hi);
          outText (p, (const char *) ")", 1);
        }
      else
        {
          outText (p, (const char *) "((", 2);
          doExprC (p, e);
          outText (p, (const char *) ")", 1);
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "==", 2);
          mcPretty_setNeedSpace (p);
          doExprC (p, r->rangeF.lo);
          outText (p, (const char *) ")", 1);
        }
      if (i < h)
        {
          mcPretty_setNeedSpace (p);
          outText (p, (const char *) "||", 2);
          mcPretty_setNeedSpace (p);
        }
      i += 1;
    }
}


/*
   doCaseLabels -
*/

static void doCaseLabels (mcPretty_pretty p, decl_node__opaque n, bool needBreak)
{
  mcDebug_assert (decl_isCaseLabelList (static_cast<decl_node> (n)));
  doRangeListC (p, n->caselabellistF.caseList);
  p = mcPretty_pushPretty (p);
  mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
  doStatementSequenceC (p, n->caselabellistF.statements);
  if (needBreak)
    {
      outText (p, (const char *) "break;\\n\\n", 10);
    }
  p = mcPretty_popPretty (p);
}


/*
   doCaseLabelListC -
*/

static void doCaseLabelListC (mcPretty_pretty p, decl_node__opaque n, bool haveElse)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque c;

  mcDebug_assert (decl_isCase (static_cast<decl_node> (n)));
  i = 1;
  h = Indexing_HighIndice (n->caseF.caseLabelList);
  while (i <= h)
    {
      c = static_cast<decl_node__opaque> (Indexing_GetIndice (n->caseF.caseLabelList, i));
      doCaseLabels (p, c, ((i < h) || haveElse) || caseException);
      i += 1;
    }
}


/*
   doCaseIfLabels -
*/

static void doCaseIfLabels (mcPretty_pretty p, decl_node__opaque e, decl_node__opaque n, unsigned int i, unsigned int h)
{
  mcDebug_assert (decl_isCaseLabelList (static_cast<decl_node> (n)));
  if (i > 1)
    {
      outText (p, (const char *) "else", 4);
      mcPretty_setNeedSpace (p);
    }
  outText (p, (const char *) "if", 2);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(", 1);
  doRangeIfListC (p, e, n->caselabellistF.caseList);
  outText (p, (const char *) ")\\n", 3);
  if (h == 1)
    {
      doCompoundStmt (p, n->caselabellistF.statements);
    }
  else
    {
      outText (p, (const char *) "{\\n", 3);
      doStatementSequenceC (p, n->caselabellistF.statements);
      outText (p, (const char *) "}\\n", 3);
    }
}


/*
   doCaseIfLabelListC -
*/

static void doCaseIfLabelListC (mcPretty_pretty p, decl_node__opaque n)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque c;

  mcDebug_assert (decl_isCase (static_cast<decl_node> (n)));
  i = 1;
  h = Indexing_HighIndice (n->caseF.caseLabelList);
  while (i <= h)
    {
      c = static_cast<decl_node__opaque> (Indexing_GetIndice (n->caseF.caseLabelList, i));
      doCaseIfLabels (p, n->caseF.expression, c, i, h);
      i += 1;
    }
}


/*
   doCaseElseC -
*/

static void doCaseElseC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (decl_isCase (static_cast<decl_node> (n)));
  if (n->caseF.else_ == NULL)
    {
      /* avoid dangling else.  */
      if (caseException)
        {
          outText (p, (const char *) "\\ndefault:\\n", 12);
          p = mcPretty_pushPretty (p);
          mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
          doException (p, (const char *) "CaseException", 13, n);
          p = mcPretty_popPretty (p);
        }
    }
  else
    {
      outText (p, (const char *) "\\ndefault:\\n", 12);
      doCaseStatementC (p, n->caseF.else_, true);
    }
}


/*
   doCaseIfElseC -
*/

static void doCaseIfElseC (mcPretty_pretty p, decl_node__opaque n)
{
  mcDebug_assert (decl_isCase (static_cast<decl_node> (n)));
  if (n->caseF.else_ == NULL)
    {
      /* avoid dangling else.  */
      if (true)
        {
          outText (p, (const char *) "\\n", 2);
          outText (p, (const char *) "else {\\n", 8);
          p = mcPretty_pushPretty (p);
          mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
          doException (p, (const char *) "CaseException", 13, n);
          p = mcPretty_popPretty (p);
          outText (p, (const char *) "}\\n", 3);
        }
    }
  else
    {
      outText (p, (const char *) "\\n", 2);
      outText (p, (const char *) "else {\\n", 8);
      doCaseStatementC (p, n->caseF.else_, false);
      outText (p, (const char *) "}\\n", 3);
    }
}


/*
   canUseSwitchCaseLabels - returns TRUE if all the case labels are
                            single values and not ranges.
*/

static bool canUseSwitchCaseLabels (decl_node__opaque n)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque r;
  decl_node__opaque l;

  mcDebug_assert (decl_isCaseLabelList (static_cast<decl_node> (n)));
  l = n->caselabellistF.caseList;
  i = 1;
  h = Indexing_HighIndice (l->caselistF.rangePairs);
  while (i <= h)
    {
      r = static_cast<decl_node__opaque> (Indexing_GetIndice (l->caselistF.rangePairs, i));
      if ((r->rangeF.hi != NULL) && (r->rangeF.lo != r->rangeF.hi))
        {
          return false;
        }
      i += 1;
    }
  return true;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   canUseSwitch - returns TRUE if the case statement can be implement
                  by a switch statement.  This will be TRUE if all case
                  selectors are single values rather than ranges.
*/

static bool canUseSwitch (decl_node__opaque n)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque c;

  mcDebug_assert (decl_isCase (static_cast<decl_node> (n)));
  i = 1;
  h = Indexing_HighIndice (n->caseF.caseLabelList);
  while (i <= h)
    {
      c = static_cast<decl_node__opaque> (Indexing_GetIndice (n->caseF.caseLabelList, i));
      if (! (canUseSwitchCaseLabels (c)))
        {
          return false;
        }
      i += 1;
    }
  return true;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doCaseC -
*/

static void doCaseC (mcPretty_pretty p, decl_node__opaque n)
{
  unsigned int i;

  mcDebug_assert (decl_isCase (static_cast<decl_node> (n)));
  if (canUseSwitch (n))
    {
      i = mcPretty_getindent (p);
      outText (p, (const char *) "switch", 6);
      mcPretty_setNeedSpace (p);
      outText (p, (const char *) "(", 1);
      doExprC (p, n->caseF.expression);
      p = mcPretty_pushPretty (p);
      outText (p, (const char *) ")", 1);
      mcPretty_setindent (p, i+indentationC);
      outText (p, (const char *) "\\n{\\n", 5);
      p = mcPretty_pushPretty (p);
      mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
      doCaseLabelListC (p, n, n->caseF.else_ != NULL);
      doCaseElseC (p, n);
      p = mcPretty_popPretty (p);
      outText (p, (const char *) "}\\n", 3);
      p = mcPretty_popPretty (p);
    }
  else
    {
      doCaseIfLabelListC (p, n);
      doCaseIfElseC (p, n);
    }
}


/*
   doLoopC -
*/

static void doLoopC (mcPretty_pretty p, decl_node__opaque s)
{
  mcDebug_assert (decl_isLoop (static_cast<decl_node> (s)));
  outText (p, (const char *) "for (;;)\\n", 10);
  outText (p, (const char *) "{\\n", 3);
  p = mcPretty_pushPretty (p);
  mcPretty_setindent (p, (mcPretty_getindent (p))+indentationC);
  doStatementSequenceC (p, s->loopF.statements);
  p = mcPretty_popPretty (p);
  outText (p, (const char *) "}\\n", 3);
}


/*
   doExitC -
*/

static void doExitC (mcPretty_pretty p, decl_node__opaque s)
{
  mcDebug_assert (decl_isExit (static_cast<decl_node> (s)));
  outText (p, (const char *) "/* exit.  */\\n", 14);
}


/*
   doStatementsC -
*/

static void doStatementsC (mcPretty_pretty p, decl_node__opaque s)
{
  if (s == NULL)
    {}  /* empty.  */
  else if (decl_isStatementSequence (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      doStatementSequenceC (p, s);
    }
  else if (isComment (s))
    {
      /* avoid dangling else.  */
      doCommentC (p, s);
    }
  else if (decl_isExit (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      doExitC (p, s);
    }
  else if (decl_isReturn (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      doReturnC (p, s);
    }
  else if (isAssignment (s))
    {
      /* avoid dangling else.  */
      doAssignmentC (p, s);
    }
  else if (decl_isIf (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      doIfC (p, s);
    }
  else if (decl_isFor (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      doForC (p, s);
    }
  else if (decl_isRepeat (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      doRepeatC (p, s);
    }
  else if (decl_isWhile (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      doWhileC (p, s);
    }
  else if (isIntrinsic (s))
    {
      /* avoid dangling else.  */
      doIntrinsicC (p, s);
    }
  else if (isFuncCall (s))
    {
      /* avoid dangling else.  */
      doFuncCallC (p, s);
    }
  else if (decl_isCase (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      doCaseC (p, s);
    }
  else if (decl_isLoop (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      doLoopC (p, s);
    }
  else if (decl_isExit (static_cast<decl_node> (s)))
    {
      /* avoid dangling else.  */
      doExitC (p, s);
    }
  else
    {
      /* avoid dangling else.  */
      M2RTS_HALT (-1);  /* need to handle another s^.kind.  */
      __builtin_unreachable ();
    }
}

static void localstop (void)
{
}


/*
   doLocalVarC -
*/

static void doLocalVarC (mcPretty_pretty p, decl_scopeT s)
{
  includeVarProcedure (s);
  debugLists ();
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartial}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doCompletePartialC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone});
}


/*
   doLocalConstTypesC -
*/

static void doLocalConstTypesC (mcPretty_pretty p, decl_scopeT s)
{
  simplifyTypes (s);
  includeConstType (s);
  doP = p;
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartial}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doCompletePartialC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone});
}


/*
   addParamDone -
*/

static void addParamDone (decl_node__opaque n)
{
  if ((decl_isVar (static_cast<decl_node> (n))) && n->varF.isParameter)
    {
      addDone (n);
      addDone (static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
    }
}


/*
   includeParameters -
*/

static void includeParameters (decl_node__opaque n)
{
  mcDebug_assert (decl_isProcedure (static_cast<decl_node> (n)));
  Indexing_ForeachIndiceInIndexDo (n->procedureF.decls.variables, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) addParamDone});
}


/*
   isHalt -
*/

static bool isHalt (decl_node__opaque n)
{
  return n->kind == decl_halt;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isReturnOrHalt -
*/

static bool isReturnOrHalt (decl_node__opaque n)
{
  return (isHalt (n)) || (decl_isReturn (static_cast<decl_node> (n)));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLastStatementReturn -
*/

static bool isLastStatementReturn (decl_node__opaque n)
{
  return isLastStatement (n, (decl_isNodeF) {(decl_isNodeF_t) isReturnOrHalt});
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLastStatementSequence -
*/

static bool isLastStatementSequence (decl_node__opaque n, decl_isNodeF q)
{
  unsigned int h;

  mcDebug_assert (decl_isStatementSequence (static_cast<decl_node> (n)));
  h = Indexing_HighIndice (n->stmtF.statements);
  if (h > 0)
    {
      return isLastStatement (static_cast<decl_node__opaque> (Indexing_GetIndice (n->stmtF.statements, h)), q);
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLastStatementIf -
*/

static bool isLastStatementIf (decl_node__opaque n, decl_isNodeF q)
{
  bool ret;

  mcDebug_assert (decl_isIf (static_cast<decl_node> (n)));
  ret = true;
  if ((n->ifF.elsif != NULL) && ret)
    {
      ret = isLastStatement (n->ifF.elsif, q);
    }
  if ((n->ifF.then != NULL) && ret)
    {
      ret = isLastStatement (n->ifF.then, q);
    }
  if ((n->ifF.else_ != NULL) && ret)
    {
      ret = isLastStatement (n->ifF.else_, q);
    }
  return ret;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLastStatementElsif -
*/

static bool isLastStatementElsif (decl_node__opaque n, decl_isNodeF q)
{
  bool ret;

  mcDebug_assert (decl_isElsif (static_cast<decl_node> (n)));
  ret = true;
  if ((n->elsifF.elsif != NULL) && ret)
    {
      ret = isLastStatement (n->elsifF.elsif, q);
    }
  if ((n->elsifF.then != NULL) && ret)
    {
      ret = isLastStatement (n->elsifF.then, q);
    }
  if ((n->elsifF.else_ != NULL) && ret)
    {
      ret = isLastStatement (n->elsifF.else_, q);
    }
  return ret;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLastStatementCase -
*/

static bool isLastStatementCase (decl_node__opaque n, decl_isNodeF q)
{
  bool ret;
  unsigned int i;
  unsigned int h;
  decl_node__opaque c;

  ret = true;
  mcDebug_assert (decl_isCase (static_cast<decl_node> (n)));
  i = 1;
  h = Indexing_HighIndice (n->caseF.caseLabelList);
  while (i <= h)
    {
      c = static_cast<decl_node__opaque> (Indexing_GetIndice (n->caseF.caseLabelList, i));
      mcDebug_assert (decl_isCaseLabelList (static_cast<decl_node> (c)));
      ret = ret && (isLastStatement (c->caselabellistF.statements, q));
      i += 1;
    }
  if (n->caseF.else_ != NULL)
    {
      ret = ret && (isLastStatement (n->caseF.else_, q));
    }
  return ret;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLastStatement - returns TRUE if the last statement in, n, is, q.
*/

static bool isLastStatement (decl_node__opaque n, decl_isNodeF q)
{
  bool ret;

  if (n == NULL)
    {
      return false;
    }
  else if (decl_isStatementSequence (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      return isLastStatementSequence (n, q);
    }
  else if (decl_isProcedure (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      mcDebug_assert (decl_isProcedure (static_cast<decl_node> (n)));
      return isLastStatement (n->procedureF.beginStatements, q);
    }
  else if (decl_isIf (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      return isLastStatementIf (n, q);
    }
  else if (decl_isElsif (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      return isLastStatementElsif (n, q);
    }
  else if (decl_isCase (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      return isLastStatementCase (n, q);
    }
  else if ((*q.proc) (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      return true;
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doProcedureC -
*/

static void doProcedureC (decl_node__opaque n)
{
  unsigned int s;

  outText (doP, (const char *) "\\n", 2);
  includeParameters (n);
  keyc_enterScope (static_cast<decl_node> (n));
  doProcedureHeadingC (n, false);
  outText (doP, (const char *) "\\n", 2);
  doP = outKc (doP, (const char *) "{\\n", 3);
  s = mcPretty_getcurline (doP);
  doLocalConstTypesC (doP, n->procedureF.decls);
  doLocalVarC (doP, n->procedureF.decls);
  doUnboundedParamCopyC (doP, n);
  if (s != (mcPretty_getcurline (doP)))
    {
      outText (doP, (const char *) "\\n", 2);
    }
  doStatementsC (doP, n->procedureF.beginStatements);
  if (n->procedureF.returnType != NULL)
    {
      if (returnException)
        {
          /* avoid gcc warning by using compound statement even if not strictly necessary.  */
          if (isLastStatementReturn (n))
            {
              outText (doP, (const char *) "/* static analysis guarentees a RETURN statement will be used before here.  */\\n", 80);
              outText (doP, (const char *) "__builtin_unreachable ();\\n", 27);
            }
          else
            {
              doException (doP, (const char *) "ReturnException", 15, n);
            }
        }
    }
  doP = outKc (doP, (const char *) "}\\n", 3);
  keyc_leaveScope (static_cast<decl_node> (n));
}


/*
   outProceduresC -
*/

static void outProceduresC (mcPretty_pretty p, decl_scopeT s)
{
  doP = p;
  if (debugDecl)
    {
      libc_printf ((const char *) "seen %d procedures\\n", 20, Indexing_HighIndice (s.procedures));
    }
  Indexing_ForeachIndiceInIndexDo (s.procedures, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doProcedureC});
}


/*
   output -
*/

static void output (decl_node__opaque n, decl_nodeProcedure c, decl_nodeProcedure t, decl_nodeProcedure v)
{
  if (decl_isConst (static_cast<decl_node> (n)))
    {
      (*c.proc) (n);
    }
  else if (decl_isVar (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      (*v.proc) (n);
    }
  else
    {
      /* avoid dangling else.  */
      (*t.proc) (n);
    }
}


/*
   allDependants -
*/

static decl_dependentState allDependants (decl_node__opaque n)
{
  alists_alist l;
  decl_dependentState s;

  l = alists_initList ();
  s = walkDependants (l, n);
  alists_killList (&l);
  return s;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkDependants -
*/

static decl_dependentState walkDependants (alists_alist l, decl_node__opaque n)
{
  if ((n == NULL) || (alists_isItemInList (globalGroup->doneQ, reinterpret_cast <void *> (n))))
    {
      return decl_completed;
    }
  else if (alists_isItemInList (l, reinterpret_cast <void *> (n)))
    {
      /* avoid dangling else.  */
      return decl_recursive;
    }
  else
    {
      /* avoid dangling else.  */
      alists_includeItemIntoList (l, reinterpret_cast <void *> (n));
      return doDependants (l, n);
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkType -
*/

static decl_dependentState walkType (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;

  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (alists_isItemInList (globalGroup->doneQ, reinterpret_cast <void *> (t)))
    {
      return decl_completed;
    }
  else if (alists_isItemInList (globalGroup->partialQ, reinterpret_cast <void *> (t)))
    {
      /* avoid dangling else.  */
      return decl_blocked;
    }
  else
    {
      /* avoid dangling else.  */
      queueBlocked (t);
      return decl_blocked;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   db -
*/

static void db (const char *a_, unsigned int _a_high, decl_node__opaque n)
{
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  if (mcOptions_getDebugTopological ())
    {
      outText (doP, (const char *) a, _a_high);
      if (n != NULL)
        {
          outTextS (doP, gen (n));
        }
    }
}


/*
   dbt -
*/

static void dbt (const char *a_, unsigned int _a_high)
{
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  if (mcOptions_getDebugTopological ())
    {
      outText (doP, (const char *) a, _a_high);
    }
}


/*
   dbs -
*/

static void dbs (decl_dependentState s, decl_node__opaque n)
{
  if (mcOptions_getDebugTopological ())
    {
      switch (s)
        {
          case decl_completed:
            outText (doP, (const char *) "{completed ", 11);
            break;

          case decl_blocked:
            outText (doP, (const char *) "{blocked ", 9);
            break;

          case decl_partial:
            outText (doP, (const char *) "{partial ", 9);
            break;

          case decl_recursive:
            outText (doP, (const char *) "{recursive ", 11);
            break;


          default:
            CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
            __builtin_unreachable ();
        }
      if (n != NULL)
        {
          outTextS (doP, gen (n));
        }
      outText (doP, (const char *) "}\\n", 3);
    }
}


/*
   dbq -
*/

static void dbq (decl_node__opaque n)
{
  if (mcOptions_getDebugTopological ())
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if (alists_isItemInList (globalGroup->todoQ, reinterpret_cast <void *> (n)))
        {
          db ((const char *) "{T", 2, n);
          outText (doP, (const char *) "}", 1);
        }
      else if (alists_isItemInList (globalGroup->partialQ, reinterpret_cast <void *> (n)))
        {
          /* avoid dangling else.  */
          db ((const char *) "{P", 2, n);
          outText (doP, (const char *) "}", 1);
        }
      else if (alists_isItemInList (globalGroup->doneQ, reinterpret_cast <void *> (n)))
        {
          /* avoid dangling else.  */
          db ((const char *) "{D", 2, n);
          outText (doP, (const char *) "}", 1);
        }
    }
}


/*
   walkRecord -
*/

static decl_dependentState walkRecord (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;
  unsigned int o;
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  i = Indexing_LowIndice (n->recordF.listOfSons);
  t = Indexing_HighIndice (n->recordF.listOfSons);
  db ((const char *) "\\nwalking ", 10, n);
  o = mcPretty_getindent (doP);
  mcPretty_setindent (doP, (mcPretty_getcurpos (doP))+3);
  dbq (n);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->recordF.listOfSons, i));
      db ((const char *) "", 0, q);
      if ((decl_isRecordField (static_cast<decl_node> (q))) && q->recordfieldF.tag)
        {}  /* empty.  */
      else
        {
          /* do nothing as it is a tag selector processed in the varient.  */
          s = walkDependants (l, q);
          if (s != decl_completed)
            {
              dbs (s, q);
              addTodo (n);
              dbq (n);
              db ((const char *) "\\n", 2, static_cast<decl_node__opaque> (NULL));
              mcPretty_setindent (doP, o);
              return s;
            }
        }
      i += 1;
    }
  db ((const char *) "{completed", 10, n);
  dbt ((const char *) "}\\n", 3);
  mcPretty_setindent (doP, o);
  return decl_completed;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkVarient -
*/

static decl_dependentState walkVarient (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  db ((const char *) "\\nwalking", 9, n);
  s = walkDependants (l, n->varientF.tag);
  if (s != decl_completed)
    {
      dbs (s, n->varientF.tag);
      dbq (n->varientF.tag);
      db ((const char *) "\\n", 2, static_cast<decl_node__opaque> (NULL));
      return s;
    }
  i = Indexing_LowIndice (n->varientF.listOfSons);
  t = Indexing_HighIndice (n->varientF.listOfSons);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->varientF.listOfSons, i));
      db ((const char *) "", 0, q);
      s = walkDependants (l, q);
      if (s != decl_completed)
        {
          dbs (s, q);
          db ((const char *) "\\n", 2, static_cast<decl_node__opaque> (NULL));
          return s;
        }
      i += 1;
    }
  db ((const char *) "{completed", 10, n);
  dbt ((const char *) "}\\n", 3);
  return decl_completed;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   queueBlocked -
*/

static void queueBlocked (decl_node__opaque n)
{
  if (! ((alists_isItemInList (globalGroup->doneQ, reinterpret_cast <void *> (n))) || (alists_isItemInList (globalGroup->partialQ, reinterpret_cast <void *> (n)))))
    {
      addTodo (n);
    }
}


/*
   walkVar -
*/

static decl_dependentState walkVar (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;

  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (alists_isItemInList (globalGroup->doneQ, reinterpret_cast <void *> (t)))
    {
      return decl_completed;
    }
  else
    {
      queueBlocked (t);
      return decl_blocked;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkEnumeration -
*/

static decl_dependentState walkEnumeration (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  i = Indexing_LowIndice (n->enumerationF.listOfSons);
  t = Indexing_HighIndice (n->enumerationF.listOfSons);
  s = decl_completed;
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->enumerationF.listOfSons, i));
      s = walkDependants (l, q);
      if (s != decl_completed)
        {
          return s;
        }
      i += 1;
    }
  return s;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkSubrange -
*/

static decl_dependentState walkSubrange (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;

  s = walkDependants (l, n->subrangeF.low);
  if (s != decl_completed)
    {
      return s;
    }
  s = walkDependants (l, n->subrangeF.high);
  if (s != decl_completed)
    {
      return s;
    }
  s = walkDependants (l, n->subrangeF.type);
  if (s != decl_completed)
    {
      return s;
    }
  return decl_completed;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkSubscript -
*/

static decl_dependentState walkSubscript (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;

  s = walkDependants (l, n->subscriptF.expr);
  if (s != decl_completed)
    {
      return s;
    }
  s = walkDependants (l, n->subscriptF.type);
  if (s != decl_completed)
    {
      return s;
    }
  return decl_completed;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkPointer -
*/

static decl_dependentState walkPointer (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;

  /* if the type of, n, is done or partial then we can output pointer.  */
  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if ((alists_isItemInList (globalGroup->partialQ, reinterpret_cast <void *> (t))) || (alists_isItemInList (globalGroup->doneQ, reinterpret_cast <void *> (t))))
    {
      /* pointer to partial can always generate a complete type.  */
      return decl_completed;
    }
  return walkType (l, n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkArray -
*/

static decl_dependentState walkArray (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;

  /* an array can only be declared if its data type has already been emitted.  */
  if (! (alists_isItemInList (globalGroup->doneQ, reinterpret_cast <void *> (n->arrayF.type))))
    {
      s = walkDependants (l, n->arrayF.type);
      queueBlocked (n->arrayF.type);
      if (s == decl_completed)
        {
          /* downgrade the completed to partial as it has not yet been written.  */
          return decl_partial;
        }
      else
        {
          return s;
        }
    }
  return walkDependants (l, n->arrayF.subr);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkConst -
*/

static decl_dependentState walkConst (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;

  s = walkDependants (l, n->constF.type);
  if (s != decl_completed)
    {
      return s;
    }
  s = walkDependants (l, n->constF.value);
  if (s != decl_completed)
    {
      return s;
    }
  return decl_completed;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkVarParam -
*/

static decl_dependentState walkVarParam (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;

  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (alists_isItemInList (globalGroup->partialQ, reinterpret_cast <void *> (t)))
    {
      /* parameter can be issued from a partial.  */
      return decl_completed;
    }
  return walkDependants (l, t);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkParam -
*/

static decl_dependentState walkParam (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;

  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (alists_isItemInList (globalGroup->partialQ, reinterpret_cast <void *> (t)))
    {
      /* parameter can be issued from a partial.  */
      return decl_completed;
    }
  return walkDependants (l, t);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkOptarg -
*/

static decl_dependentState walkOptarg (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;

  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (alists_isItemInList (globalGroup->partialQ, reinterpret_cast <void *> (t)))
    {
      /* parameter can be issued from a partial.  */
      return decl_completed;
    }
  return walkDependants (l, t);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkRecordField -
*/

static decl_dependentState walkRecordField (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;
  decl_dependentState s;

  mcDebug_assert (decl_isRecordField (static_cast<decl_node> (n)));
  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (alists_isItemInList (globalGroup->partialQ, reinterpret_cast <void *> (t)))
    {
      dbs (decl_partial, n);
      return decl_partial;
    }
  else if (alists_isItemInList (globalGroup->doneQ, reinterpret_cast <void *> (t)))
    {
      /* avoid dangling else.  */
      dbs (decl_completed, n);
      return decl_completed;
    }
  else
    {
      /* avoid dangling else.  */
      addTodo (t);
      dbs (decl_blocked, n);
      dbq (n);
      dbq (t);
      /* s := walkDependants (l, t)  */
      return decl_blocked;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkVarientField -
*/

static decl_dependentState walkVarientField (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  i = Indexing_LowIndice (n->varientfieldF.listOfSons);
  t = Indexing_HighIndice (n->varientfieldF.listOfSons);
  s = decl_completed;
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->varientfieldF.listOfSons, i));
      s = walkDependants (l, q);
      if (s != decl_completed)
        {
          dbs (s, n);
          return s;
        }
      i += 1;
    }
  n->varientfieldF.simple = t <= 1;
  dbs (s, n);
  return s;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkEnumerationField -
*/

static decl_dependentState walkEnumerationField (alists_alist l, decl_node__opaque n)
{
  return decl_completed;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkSet -
*/

static decl_dependentState walkSet (alists_alist l, decl_node__opaque n)
{
  return walkDependants (l, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkProcType -
*/

static decl_dependentState walkProcType (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;
  decl_node__opaque t;

  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (alists_isItemInList (globalGroup->partialQ, reinterpret_cast <void *> (t)))
    {}  /* empty.  */
  else
    {
      /* proctype can be generated from partial types.  */
      s = walkDependants (l, t);
      if (s != decl_completed)
        {
          return s;
        }
    }
  return walkParameters (l, n->proctypeF.parameters);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkProcedure -
*/

static decl_dependentState walkProcedure (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;

  s = walkDependants (l, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  if (s != decl_completed)
    {
      return s;
    }
  return walkParameters (l, n->procedureF.parameters);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkParameters -
*/

static decl_dependentState walkParameters (alists_alist l, Indexing_Index p)
{
  decl_dependentState s;
  unsigned int i;
  unsigned int h;
  decl_node__opaque q;

  i = Indexing_LowIndice (p);
  h = Indexing_HighIndice (p);
  while (i <= h)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (p, i));
      s = walkDependants (l, q);
      if (s != decl_completed)
        {
          return s;
        }
      i += 1;
    }
  return decl_completed;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkFuncCall -
*/

static decl_dependentState walkFuncCall (alists_alist l, decl_node__opaque n)
{
  return decl_completed;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkUnary -
*/

static decl_dependentState walkUnary (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;

  s = walkDependants (l, n->unaryF.arg);
  if (s != decl_completed)
    {
      return s;
    }
  return walkDependants (l, n->unaryF.resultType);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkBinary -
*/

static decl_dependentState walkBinary (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;

  s = walkDependants (l, n->binaryF.left);
  if (s != decl_completed)
    {
      return s;
    }
  s = walkDependants (l, n->binaryF.right);
  if (s != decl_completed)
    {
      return s;
    }
  return walkDependants (l, n->binaryF.resultType);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkComponentRef -
*/

static decl_dependentState walkComponentRef (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;

  s = walkDependants (l, n->componentrefF.rec);
  if (s != decl_completed)
    {
      return s;
    }
  s = walkDependants (l, n->componentrefF.field);
  if (s != decl_completed)
    {
      return s;
    }
  return walkDependants (l, n->componentrefF.resultType);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkPointerRef -
*/

static decl_dependentState walkPointerRef (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;

  s = walkDependants (l, n->pointerrefF.ptr);
  if (s != decl_completed)
    {
      return s;
    }
  s = walkDependants (l, n->pointerrefF.field);
  if (s != decl_completed)
    {
      return s;
    }
  return walkDependants (l, n->pointerrefF.resultType);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   walkSetValue -
*/

static decl_dependentState walkSetValue (alists_alist l, decl_node__opaque n)
{
  decl_dependentState s;
  unsigned int i;
  unsigned int j;

  mcDebug_assert (decl_isSetValue (static_cast<decl_node> (n)));
  s = walkDependants (l, n->setvalueF.type);
  if (s != decl_completed)
    {
      return s;
    }
  i = Indexing_LowIndice (n->setvalueF.values);
  j = Indexing_HighIndice (n->setvalueF.values);
  while (i <= j)
    {
      s = walkDependants (l, static_cast<decl_node__opaque> (Indexing_GetIndice (n->setvalueF.values, i)));
      if (s != decl_completed)
        {
          return s;
        }
      i += 1;
    }
  return decl_completed;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doDependants - return the dependentState depending upon whether
                  all dependants have been declared.
*/

static decl_dependentState doDependants (alists_alist l, decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_throw:
      case decl_varargs:
      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_csizet:
      case decl_cssizet:
      case decl_cofft:
      case decl_cardinal64:
      case decl_boolean:
      case decl_char:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_real:
      case decl_longreal:
      case decl_shortreal:
      case decl_bitset:
      case decl_ztype:
      case decl_rtype:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
      case decl_proc:
        /* base types.  */
        return decl_completed;
        break;

      case decl_type:
        /* language features and compound type attributes.  */
        return walkType (l, n);
        break;

      case decl_record:
        return walkRecord (l, n);
        break;

      case decl_varient:
        return walkVarient (l, n);
        break;

      case decl_var:
        return walkVar (l, n);
        break;

      case decl_enumeration:
        return walkEnumeration (l, n);
        break;

      case decl_subrange:
        return walkSubrange (l, n);
        break;

      case decl_pointer:
        return walkPointer (l, n);
        break;

      case decl_array:
        return walkArray (l, n);
        break;

      case decl_string:
        return decl_completed;
        break;

      case decl_const:
        return walkConst (l, n);
        break;

      case decl_literal:
        return decl_completed;
        break;

      case decl_varparam:
        return walkVarParam (l, n);
        break;

      case decl_param:
        return walkParam (l, n);
        break;

      case decl_optarg:
        return walkOptarg (l, n);
        break;

      case decl_recordfield:
        return walkRecordField (l, n);
        break;

      case decl_varientfield:
        return walkVarientField (l, n);
        break;

      case decl_enumerationfield:
        return walkEnumerationField (l, n);
        break;

      case decl_set:
        return walkSet (l, n);
        break;

      case decl_proctype:
        return walkProcType (l, n);
        break;

      case decl_subscript:
        return walkSubscript (l, n);
        break;

      case decl_procedure:
        /* blocks.  */
        return walkProcedure (l, n);
        break;

      case decl_def:
      case decl_imp:
      case decl_module:
      case decl_loop:
      case decl_while:
      case decl_for:
      case decl_repeat:
      case decl_if:
      case decl_elsif:
      case decl_assignment:
        /* statements.  */
        M2RTS_HALT (-1);
        __builtin_unreachable ();
        break;

      case decl_componentref:
        /* expressions.  */
        return walkComponentRef (l, n);
        break;

      case decl_pointerref:
        return walkPointerRef (l, n);
        break;

      case decl_not:
      case decl_abs:
      case decl_min:
      case decl_max:
      case decl_chr:
      case decl_cap:
      case decl_ord:
      case decl_float:
      case decl_trunc:
      case decl_high:
        return walkUnary (l, n);
        break;

      case decl_cast:
      case decl_val:
      case decl_plus:
      case decl_sub:
      case decl_div:
      case decl_mod:
      case decl_mult:
      case decl_divide:
        return walkBinary (l, n);
        break;

      case decl_constexp:
      case decl_neg:
      case decl_adr:
      case decl_size:
      case decl_tsize:
      case decl_deref:
        return walkUnary (l, n);
        break;

      case decl_equal:
      case decl_notequal:
      case decl_less:
      case decl_greater:
      case decl_greequal:
      case decl_lessequal:
        return walkBinary (l, n);
        break;

      case decl_funccall:
        return walkFuncCall (l, n);
        break;

      case decl_setvalue:
        return walkSetValue (l, n);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   tryComplete - returns TRUE if node, n, can be and was completed.
*/

static bool tryComplete (decl_node__opaque n, decl_nodeProcedure c, decl_nodeProcedure t, decl_nodeProcedure v)
{
  if (decl_isEnumeration (static_cast<decl_node> (n)))
    {
      /* can always emit enumerated types.  */
      output (n, c, t, v);
      return true;
    }
  else if (((decl_isType (static_cast<decl_node> (n))) && (decl_isTypeHidden (static_cast<decl_node> (n)))) && ((decl_getType (static_cast<decl_node> (n))) == NULL))
    {
      /* avoid dangling else.  */
      /* can always emit hidden types.  */
      outputHidden (n);
      return true;
    }
  else if ((allDependants (n)) == decl_completed)
    {
      /* avoid dangling else.  */
      output (n, c, t, v);
      return true;
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   tryCompleteFromPartial -
*/

static bool tryCompleteFromPartial (decl_node__opaque n, decl_nodeProcedure t)
{
  if ((((decl_isType (static_cast<decl_node> (n))) && ((decl_getType (static_cast<decl_node> (n))) != NULL)) && (decl_isPointer (decl_getType (static_cast<decl_node> (n))))) && ((allDependants (static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))))) == decl_completed))
    {
      /* alists.includeItemIntoList (globalGroup^.partialQ, getType (n)) ;  */
      outputHiddenComplete (n);
      return true;
    }
  else if ((allDependants (n)) == decl_completed)
    {
      /* avoid dangling else.  */
      (*t.proc) (n);
      return true;
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   visitIntrinsicFunction -
*/

static void visitIntrinsicFunction (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (isIntrinsicFunction (n));
  switch (n->kind)
    {
      case decl_val:
      case decl_cmplx:
        visitNode (v, n->binaryF.left, p);
        visitNode (v, n->binaryF.right, p);
        visitNode (v, n->binaryF.resultType, p);
        break;

      case decl_length:
      case decl_adr:
      case decl_size:
      case decl_tsize:
      case decl_float:
      case decl_trunc:
      case decl_ord:
      case decl_chr:
      case decl_cap:
      case decl_abs:
      case decl_high:
      case decl_min:
      case decl_max:
      case decl_re:
      case decl_im:
        visitNode (v, n->unaryF.arg, p);
        visitNode (v, n->unaryF.resultType, p);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   visitUnary -
*/

static void visitUnary (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (isUnary (n));
  visitNode (v, n->unaryF.arg, p);
  visitNode (v, n->unaryF.resultType, p);
}


/*
   visitBinary -
*/

static void visitBinary (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  visitNode (v, n->binaryF.left, p);
  visitNode (v, n->binaryF.right, p);
  visitNode (v, n->binaryF.resultType, p);
}


/*
   visitBoolean -
*/

static void visitBoolean (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  visitNode (v, falseN, p);
  visitNode (v, trueN, p);
}


/*
   visitScope -
*/

static void visitScope (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  if (mustVisitScope)
    {
      visitNode (v, n, p);
    }
}


/*
   visitType -
*/

static void visitType (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isType (static_cast<decl_node> (n)));
  visitNode (v, n->typeF.type, p);
  visitScope (v, n->typeF.scope, p);
}


/*
   visitIndex -
*/

static void visitIndex (alists_alist v, Indexing_Index i, decl_nodeProcedure p)
{
  unsigned int j;
  unsigned int h;

  j = 1;
  h = Indexing_HighIndice (i);
  while (j <= h)
    {
      visitNode (v, static_cast<decl_node__opaque> (Indexing_GetIndice (i, j)), p);
      j += 1;
    }
}


/*
   visitRecord -
*/

static void visitRecord (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isRecord (static_cast<decl_node> (n)));
  visitScope (v, n->recordF.scope, p);
  visitIndex (v, n->recordF.listOfSons, p);
}


/*
   visitVarient -
*/

static void visitVarient (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isVarient (static_cast<decl_node> (n)));
  visitIndex (v, n->varientF.listOfSons, p);
  visitNode (v, n->varientF.varient, p);
  visitNode (v, n->varientF.tag, p);
  visitScope (v, n->varientF.scope, p);
}


/*
   visitVar -
*/

static void visitVar (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isVar (static_cast<decl_node> (n)));
  visitNode (v, n->varF.type, p);
  visitNode (v, n->varF.decl, p);
  visitScope (v, n->varF.scope, p);
}


/*
   visitEnumeration -
*/

static void visitEnumeration (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isEnumeration (static_cast<decl_node> (n)));
  visitIndex (v, n->enumerationF.listOfSons, p);
  visitScope (v, n->enumerationF.scope, p);
}


/*
   visitSubrange -
*/

static void visitSubrange (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isSubrange (static_cast<decl_node> (n)));
  visitNode (v, n->subrangeF.low, p);
  visitNode (v, n->subrangeF.high, p);
  visitNode (v, n->subrangeF.type, p);
  visitScope (v, n->subrangeF.scope, p);
}


/*
   visitPointer -
*/

static void visitPointer (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isPointer (static_cast<decl_node> (n)));
  visitNode (v, n->pointerF.type, p);
  visitScope (v, n->pointerF.scope, p);
}


/*
   visitArray -
*/

static void visitArray (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isArray (static_cast<decl_node> (n)));
  visitNode (v, n->arrayF.subr, p);
  visitNode (v, n->arrayF.type, p);
  visitScope (v, n->arrayF.scope, p);
}


/*
   visitConst -
*/

static void visitConst (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isConst (static_cast<decl_node> (n)));
  visitNode (v, n->constF.type, p);
  visitNode (v, n->constF.value, p);
  visitScope (v, n->constF.scope, p);
}


/*
   visitVarParam -
*/

static void visitVarParam (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isVarParam (static_cast<decl_node> (n)));
  visitNode (v, n->varparamF.namelist, p);
  visitNode (v, n->varparamF.type, p);
  visitScope (v, n->varparamF.scope, p);
}


/*
   visitParam -
*/

static void visitParam (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isParam (static_cast<decl_node> (n)));
  visitNode (v, n->paramF.namelist, p);
  visitNode (v, n->paramF.type, p);
  visitScope (v, n->paramF.scope, p);
}


/*
   visitOptarg -
*/

static void visitOptarg (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isOptarg (static_cast<decl_node> (n)));
  visitNode (v, n->optargF.namelist, p);
  visitNode (v, n->optargF.type, p);
  visitNode (v, n->optargF.init, p);
  visitScope (v, n->optargF.scope, p);
}


/*
   visitRecordField -
*/

static void visitRecordField (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isRecordField (static_cast<decl_node> (n)));
  visitNode (v, n->recordfieldF.type, p);
  visitNode (v, n->recordfieldF.parent, p);
  visitNode (v, n->recordfieldF.varient, p);
  visitScope (v, n->recordfieldF.scope, p);
}


/*
   visitVarientField -
*/

static void visitVarientField (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isVarientField (static_cast<decl_node> (n)));
  visitNode (v, n->varientfieldF.parent, p);
  visitNode (v, n->varientfieldF.varient, p);
  visitIndex (v, n->varientfieldF.listOfSons, p);
  visitScope (v, n->varientfieldF.scope, p);
}


/*
   visitEnumerationField -
*/

static void visitEnumerationField (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isEnumerationField (static_cast<decl_node> (n)));
  visitNode (v, n->enumerationfieldF.type, p);
  visitScope (v, n->enumerationfieldF.scope, p);
}


/*
   visitSet -
*/

static void visitSet (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isSet (static_cast<decl_node> (n)));
  visitNode (v, n->setF.type, p);
  visitScope (v, n->setF.scope, p);
}


/*
   visitProcType -
*/

static void visitProcType (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isProcType (static_cast<decl_node> (n)));
  visitIndex (v, n->proctypeF.parameters, p);
  visitNode (v, n->proctypeF.optarg_, p);
  visitNode (v, n->proctypeF.returnType, p);
  visitScope (v, n->proctypeF.scope, p);
}


/*
   visitSubscript -
*/

static void visitSubscript (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
}


/*
   visitDecls -
*/

static void visitDecls (alists_alist v, decl_scopeT s, decl_nodeProcedure p)
{
  visitIndex (v, s.constants, p);
  visitIndex (v, s.types, p);
  visitIndex (v, s.procedures, p);
  visitIndex (v, s.variables, p);
}


/*
   visitProcedure -
*/

static void visitProcedure (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isProcedure (static_cast<decl_node> (n)));
  visitDecls (v, n->procedureF.decls, p);
  visitScope (v, n->procedureF.scope, p);
  visitIndex (v, n->procedureF.parameters, p);
  visitNode (v, n->procedureF.optarg_, p);
  visitNode (v, n->procedureF.returnType, p);
  visitNode (v, n->procedureF.beginStatements, p);
}


/*
   visitDef -
*/

static void visitDef (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isDef (static_cast<decl_node> (n)));
  visitDecls (v, n->defF.decls, p);
}


/*
   visitImp -
*/

static void visitImp (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isImp (static_cast<decl_node> (n)));
  visitDecls (v, n->impF.decls, p);
  visitNode (v, n->impF.beginStatements, p);
  /* --fixme-- do we need to visit definitionModule?  */
  visitNode (v, n->impF.finallyStatements, p);
}


/*
   visitModule -
*/

static void visitModule (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isModule (static_cast<decl_node> (n)));
  visitDecls (v, n->moduleF.decls, p);
  visitNode (v, n->moduleF.beginStatements, p);
  visitNode (v, n->moduleF.finallyStatements, p);
}


/*
   visitLoop -
*/

static void visitLoop (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isLoop (static_cast<decl_node> (n)));
  visitNode (v, n->loopF.statements, p);
}


/*
   visitWhile -
*/

static void visitWhile (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isWhile (static_cast<decl_node> (n)));
  visitNode (v, n->whileF.expr, p);
  visitNode (v, n->whileF.statements, p);
}


/*
   visitRepeat -
*/

static void visitRepeat (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isRepeat (static_cast<decl_node> (n)));
  visitNode (v, n->repeatF.expr, p);
  visitNode (v, n->repeatF.statements, p);
}


/*
   visitCase -
*/

static void visitCase (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isCase (static_cast<decl_node> (n)));
  visitNode (v, n->caseF.expression, p);
  visitIndex (v, n->caseF.caseLabelList, p);
  visitNode (v, n->caseF.else_, p);
}


/*
   visitCaseLabelList -
*/

static void visitCaseLabelList (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isCaseLabelList (static_cast<decl_node> (n)));
  visitNode (v, n->caselabellistF.caseList, p);
  visitNode (v, n->caselabellistF.statements, p);
}


/*
   visitCaseList -
*/

static void visitCaseList (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isCaseList (static_cast<decl_node> (n)));
  visitIndex (v, n->caselistF.rangePairs, p);
}


/*
   visitRange -
*/

static void visitRange (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isRange (static_cast<decl_node> (n)));
  visitNode (v, n->rangeF.lo, p);
  visitNode (v, n->rangeF.hi, p);
}


/*
   visitIf -
*/

static void visitIf (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isIf (static_cast<decl_node> (n)));
  visitNode (v, n->ifF.expr, p);
  visitNode (v, n->ifF.elsif, p);
  visitNode (v, n->ifF.then, p);
  visitNode (v, n->ifF.else_, p);
}


/*
   visitElsif -
*/

static void visitElsif (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isElsif (static_cast<decl_node> (n)));
  visitNode (v, n->elsifF.expr, p);
  visitNode (v, n->elsifF.elsif, p);
  visitNode (v, n->elsifF.then, p);
  visitNode (v, n->elsifF.else_, p);
}


/*
   visitFor -
*/

static void visitFor (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isFor (static_cast<decl_node> (n)));
  visitNode (v, n->forF.des, p);
  visitNode (v, n->forF.start, p);
  visitNode (v, n->forF.end, p);
  visitNode (v, n->forF.increment, p);
  visitNode (v, n->forF.statements, p);
}


/*
   visitAssignment -
*/

static void visitAssignment (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (isAssignment (n));
  visitNode (v, n->assignmentF.des, p);
  visitNode (v, n->assignmentF.expr, p);
}


/*
   visitComponentRef -
*/

static void visitComponentRef (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (isComponentRef (n));
  visitNode (v, n->componentrefF.rec, p);
  visitNode (v, n->componentrefF.field, p);
  visitNode (v, n->componentrefF.resultType, p);
}


/*
   visitPointerRef -
*/

static void visitPointerRef (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isPointerRef (static_cast<decl_node> (n)));
  visitNode (v, n->pointerrefF.ptr, p);
  visitNode (v, n->pointerrefF.field, p);
  visitNode (v, n->pointerrefF.resultType, p);
}


/*
   visitArrayRef -
*/

static void visitArrayRef (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (isArrayRef (n));
  visitNode (v, n->arrayrefF.array, p);
  visitNode (v, n->arrayrefF.index, p);
  visitNode (v, n->arrayrefF.resultType, p);
}


/*
   visitFunccall -
*/

static void visitFunccall (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (isFuncCall (n));
  visitNode (v, n->funccallF.function, p);
  visitNode (v, n->funccallF.args, p);
  visitNode (v, n->funccallF.type, p);
}


/*
   visitVarDecl -
*/

static void visitVarDecl (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (isVarDecl (n));
  visitNode (v, n->vardeclF.type, p);
  visitScope (v, n->vardeclF.scope, p);
}


/*
   visitExplist -
*/

static void visitExplist (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isExpList (static_cast<decl_node> (n)));
  visitIndex (v, n->explistF.exp, p);
}


/*
   visitExit -
*/

static void visitExit (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isExit (static_cast<decl_node> (n)));
  visitNode (v, n->exitF.loop, p);
}


/*
   visitReturn -
*/

static void visitReturn (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isReturn (static_cast<decl_node> (n)));
  visitNode (v, n->returnF.exp, p);
}


/*
   visitStmtSeq -
*/

static void visitStmtSeq (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isStatementSequence (static_cast<decl_node> (n)));
  visitIndex (v, n->stmtF.statements, p);
}


/*
   visitVarargs -
*/

static void visitVarargs (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isVarargs (static_cast<decl_node> (n)));
  visitScope (v, n->varargsF.scope, p);
}


/*
   visitSetValue -
*/

static void visitSetValue (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (decl_isSetValue (static_cast<decl_node> (n)));
  visitNode (v, n->setvalueF.type, p);
  visitIndex (v, n->setvalueF.values, p);
}


/*
   visitIntrinsic -
*/

static void visitIntrinsic (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (isIntrinsic (n));
  visitNode (v, n->intrinsicF.args, p);
}


/*
   visitDependants - helper procedure function called from visitNode.
                     node n has just been visited, this procedure will
                     visit node, n, dependants.
*/

static void visitDependants (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  mcDebug_assert (n != NULL);
  mcDebug_assert (alists_isItemInList (v, reinterpret_cast <void *> (n)));
  switch (n->kind)
    {
      case decl_explist:
        visitExplist (v, n, p);
        break;

      case decl_funccall:
        visitFunccall (v, n, p);
        break;

      case decl_exit:
        visitExit (v, n, p);
        break;

      case decl_return:
        visitReturn (v, n, p);
        break;

      case decl_stmtseq:
        visitStmtSeq (v, n, p);
        break;

      case decl_comment:
        break;

      case decl_length:
        visitIntrinsicFunction (v, n, p);
        break;

      case decl_unreachable:
      case decl_throw:
      case decl_halt:
      case decl_new:
      case decl_dispose:
      case decl_inc:
      case decl_dec:
      case decl_incl:
      case decl_excl:
        visitIntrinsic (v, n, p);
        break;

      case decl_boolean:
        visitBoolean (v, n, p);
        break;

      case decl_nil:
      case decl_false:
      case decl_true:
        break;

      case decl_varargs:
        visitVarargs (v, n, p);
        break;

      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_csizet:
      case decl_cssizet:
      case decl_cofft:
      case decl_cardinal64:
      case decl_char:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_real:
      case decl_longreal:
      case decl_shortreal:
      case decl_bitset:
      case decl_ztype:
      case decl_rtype:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
      case decl_proc:
        break;

      case decl_type:
        /* language features and compound type attributes.  */
        visitType (v, n, p);
        break;

      case decl_record:
        visitRecord (v, n, p);
        break;

      case decl_varient:
        visitVarient (v, n, p);
        break;

      case decl_var:
        visitVar (v, n, p);
        break;

      case decl_enumeration:
        visitEnumeration (v, n, p);
        break;

      case decl_subrange:
        visitSubrange (v, n, p);
        break;

      case decl_pointer:
        visitPointer (v, n, p);
        break;

      case decl_array:
        visitArray (v, n, p);
        break;

      case decl_string:
        break;

      case decl_const:
        visitConst (v, n, p);
        break;

      case decl_literal:
        break;

      case decl_varparam:
        visitVarParam (v, n, p);
        break;

      case decl_param:
        visitParam (v, n, p);
        break;

      case decl_optarg:
        visitOptarg (v, n, p);
        break;

      case decl_recordfield:
        visitRecordField (v, n, p);
        break;

      case decl_varientfield:
        visitVarientField (v, n, p);
        break;

      case decl_enumerationfield:
        visitEnumerationField (v, n, p);
        break;

      case decl_set:
        visitSet (v, n, p);
        break;

      case decl_proctype:
        visitProcType (v, n, p);
        break;

      case decl_subscript:
        visitSubscript (v, n, p);
        break;

      case decl_procedure:
        /* blocks.  */
        visitProcedure (v, n, p);
        break;

      case decl_def:
        visitDef (v, n, p);
        break;

      case decl_imp:
        visitImp (v, n, p);
        break;

      case decl_module:
        visitModule (v, n, p);
        break;

      case decl_loop:
        /* statements.  */
        visitLoop (v, n, p);
        break;

      case decl_while:
        visitWhile (v, n, p);
        break;

      case decl_for:
        visitFor (v, n, p);
        break;

      case decl_repeat:
        visitRepeat (v, n, p);
        break;

      case decl_case:
        visitCase (v, n, p);
        break;

      case decl_caselabellist:
        visitCaseLabelList (v, n, p);
        break;

      case decl_caselist:
        visitCaseList (v, n, p);
        break;

      case decl_range:
        visitRange (v, n, p);
        break;

      case decl_if:
        visitIf (v, n, p);
        break;

      case decl_elsif:
        visitElsif (v, n, p);
        break;

      case decl_assignment:
        visitAssignment (v, n, p);
        break;

      case decl_componentref:
        /* expressions.  */
        visitComponentRef (v, n, p);
        break;

      case decl_pointerref:
        visitPointerRef (v, n, p);
        break;

      case decl_arrayref:
        visitArrayRef (v, n, p);
        break;

      case decl_cmplx:
      case decl_equal:
      case decl_notequal:
      case decl_less:
      case decl_greater:
      case decl_greequal:
      case decl_lessequal:
      case decl_and:
      case decl_or:
      case decl_in:
      case decl_cast:
      case decl_val:
      case decl_plus:
      case decl_sub:
      case decl_div:
      case decl_mod:
      case decl_mult:
      case decl_divide:
        visitBinary (v, n, p);
        break;

      case decl_re:
        visitUnary (v, n, p);
        break;

      case decl_im:
        visitUnary (v, n, p);
        break;

      case decl_abs:
        visitUnary (v, n, p);
        break;

      case decl_chr:
        visitUnary (v, n, p);
        break;

      case decl_cap:
        visitUnary (v, n, p);
        break;

      case decl_high:
        visitUnary (v, n, p);
        break;

      case decl_ord:
        visitUnary (v, n, p);
        break;

      case decl_float:
        visitUnary (v, n, p);
        break;

      case decl_trunc:
        visitUnary (v, n, p);
        break;

      case decl_not:
        visitUnary (v, n, p);
        break;

      case decl_neg:
        visitUnary (v, n, p);
        break;

      case decl_adr:
        visitUnary (v, n, p);
        break;

      case decl_size:
        visitUnary (v, n, p);
        break;

      case decl_tsize:
        visitUnary (v, n, p);
        break;

      case decl_min:
        visitUnary (v, n, p);
        break;

      case decl_max:
        visitUnary (v, n, p);
        break;

      case decl_constexp:
        visitUnary (v, n, p);
        break;

      case decl_deref:
        visitUnary (v, n, p);
        break;

      case decl_identlist:
        break;

      case decl_vardecl:
        visitVarDecl (v, n, p);
        break;

      case decl_setvalue:
        visitSetValue (v, n, p);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   visitNode - visits node, n, if it is not already in the alist, v.
               It calls p(n) if the node is unvisited.
*/

static void visitNode (alists_alist v, decl_node__opaque n, decl_nodeProcedure p)
{
  if ((n != NULL) && (! (alists_isItemInList (v, reinterpret_cast <void *> (n)))))
    {
      alists_includeItemIntoList (v, reinterpret_cast <void *> (n));
      (*p.proc) (n);
      visitDependants (v, n, p);
    }
}


/*
   genKind - returns a string depending upon the kind of node, n.
*/

static DynamicStrings_String genKind (decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_nil:
      case decl_true:
      case decl_false:
      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_csizet:
      case decl_cssizet:
      case decl_cofft:
      case decl_cardinal64:
      case decl_char:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_real:
      case decl_longreal:
      case decl_shortreal:
      case decl_bitset:
      case decl_boolean:
      case decl_proc:
      case decl_ztype:
      case decl_rtype:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
        /* types, no need to generate a kind string as it it contained in the name.  */
        return static_cast<DynamicStrings_String> (NULL);
        break;

      case decl_type:
        /* language features and compound type attributes.  */
        return DynamicStrings_InitString ((const char *) "type", 4);
        break;

      case decl_record:
        return DynamicStrings_InitString ((const char *) "record", 6);
        break;

      case decl_varient:
        return DynamicStrings_InitString ((const char *) "varient", 7);
        break;

      case decl_var:
        return DynamicStrings_InitString ((const char *) "var", 3);
        break;

      case decl_enumeration:
        return DynamicStrings_InitString ((const char *) "enumeration", 11);
        break;

      case decl_subrange:
        return DynamicStrings_InitString ((const char *) "subrange", 8);
        break;

      case decl_array:
        return DynamicStrings_InitString ((const char *) "array", 5);
        break;

      case decl_subscript:
        return DynamicStrings_InitString ((const char *) "subscript", 9);
        break;

      case decl_string:
        return DynamicStrings_InitString ((const char *) "string", 6);
        break;

      case decl_const:
        return DynamicStrings_InitString ((const char *) "const", 5);
        break;

      case decl_literal:
        return DynamicStrings_InitString ((const char *) "literal", 7);
        break;

      case decl_varparam:
        return DynamicStrings_InitString ((const char *) "varparam", 8);
        break;

      case decl_param:
        return DynamicStrings_InitString ((const char *) "param", 5);
        break;

      case decl_varargs:
        return DynamicStrings_InitString ((const char *) "varargs", 7);
        break;

      case decl_pointer:
        return DynamicStrings_InitString ((const char *) "pointer", 7);
        break;

      case decl_recordfield:
        return DynamicStrings_InitString ((const char *) "recordfield", 11);
        break;

      case decl_varientfield:
        return DynamicStrings_InitString ((const char *) "varientfield", 12);
        break;

      case decl_enumerationfield:
        return DynamicStrings_InitString ((const char *) "enumerationfield", 16);
        break;

      case decl_set:
        return DynamicStrings_InitString ((const char *) "set", 3);
        break;

      case decl_proctype:
        return DynamicStrings_InitString ((const char *) "proctype", 8);
        break;

      case decl_procedure:
        /* blocks.  */
        return DynamicStrings_InitString ((const char *) "procedure", 9);
        break;

      case decl_def:
        return DynamicStrings_InitString ((const char *) "def", 3);
        break;

      case decl_imp:
        return DynamicStrings_InitString ((const char *) "imp", 3);
        break;

      case decl_module:
        return DynamicStrings_InitString ((const char *) "module", 6);
        break;

      case decl_loop:
        /* statements.  */
        return DynamicStrings_InitString ((const char *) "loop", 4);
        break;

      case decl_while:
        return DynamicStrings_InitString ((const char *) "while", 5);
        break;

      case decl_for:
        return DynamicStrings_InitString ((const char *) "for", 3);
        break;

      case decl_repeat:
        return DynamicStrings_InitString ((const char *) "repeat", 6);
        break;

      case decl_assignment:
        return DynamicStrings_InitString ((const char *) "assignment", 10);
        break;

      case decl_if:
        return DynamicStrings_InitString ((const char *) "if", 2);
        break;

      case decl_elsif:
        return DynamicStrings_InitString ((const char *) "elsif", 5);
        break;

      case decl_constexp:
        /* expressions.  */
        return DynamicStrings_InitString ((const char *) "constexp", 8);
        break;

      case decl_neg:
        return DynamicStrings_InitString ((const char *) "neg", 3);
        break;

      case decl_cast:
        return DynamicStrings_InitString ((const char *) "cast", 4);
        break;

      case decl_val:
        return DynamicStrings_InitString ((const char *) "val", 3);
        break;

      case decl_plus:
        return DynamicStrings_InitString ((const char *) "plus", 4);
        break;

      case decl_sub:
        return DynamicStrings_InitString ((const char *) "sub", 3);
        break;

      case decl_div:
        return DynamicStrings_InitString ((const char *) "div", 3);
        break;

      case decl_mod:
        return DynamicStrings_InitString ((const char *) "mod", 3);
        break;

      case decl_mult:
        return DynamicStrings_InitString ((const char *) "mult", 4);
        break;

      case decl_divide:
        return DynamicStrings_InitString ((const char *) "divide", 6);
        break;

      case decl_adr:
        return DynamicStrings_InitString ((const char *) "adr", 3);
        break;

      case decl_size:
        return DynamicStrings_InitString ((const char *) "size", 4);
        break;

      case decl_tsize:
        return DynamicStrings_InitString ((const char *) "tsize", 5);
        break;

      case decl_chr:
        return DynamicStrings_InitString ((const char *) "chr", 3);
        break;

      case decl_ord:
        return DynamicStrings_InitString ((const char *) "ord", 3);
        break;

      case decl_float:
        return DynamicStrings_InitString ((const char *) "float", 5);
        break;

      case decl_trunc:
        return DynamicStrings_InitString ((const char *) "trunc", 5);
        break;

      case decl_high:
        return DynamicStrings_InitString ((const char *) "high", 4);
        break;

      case decl_componentref:
        return DynamicStrings_InitString ((const char *) "componentref", 12);
        break;

      case decl_pointerref:
        return DynamicStrings_InitString ((const char *) "pointerref", 10);
        break;

      case decl_arrayref:
        return DynamicStrings_InitString ((const char *) "arrayref", 8);
        break;

      case decl_deref:
        return DynamicStrings_InitString ((const char *) "deref", 5);
        break;

      case decl_equal:
        return DynamicStrings_InitString ((const char *) "equal", 5);
        break;

      case decl_notequal:
        return DynamicStrings_InitString ((const char *) "notequal", 8);
        break;

      case decl_less:
        return DynamicStrings_InitString ((const char *) "less", 4);
        break;

      case decl_greater:
        return DynamicStrings_InitString ((const char *) "greater", 7);
        break;

      case decl_greequal:
        return DynamicStrings_InitString ((const char *) "greequal", 8);
        break;

      case decl_lessequal:
        return DynamicStrings_InitString ((const char *) "lessequal", 9);
        break;

      case decl_lsl:
        return DynamicStrings_InitString ((const char *) "lsl", 3);
        break;

      case decl_lsr:
        return DynamicStrings_InitString ((const char *) "lsr", 3);
        break;

      case decl_lor:
        return DynamicStrings_InitString ((const char *) "lor", 3);
        break;

      case decl_land:
        return DynamicStrings_InitString ((const char *) "land", 4);
        break;

      case decl_lnot:
        return DynamicStrings_InitString ((const char *) "lnot", 4);
        break;

      case decl_lxor:
        return DynamicStrings_InitString ((const char *) "lxor", 4);
        break;

      case decl_and:
        return DynamicStrings_InitString ((const char *) "and", 3);
        break;

      case decl_or:
        return DynamicStrings_InitString ((const char *) "or", 2);
        break;

      case decl_not:
        return DynamicStrings_InitString ((const char *) "not", 3);
        break;

      case decl_identlist:
        return DynamicStrings_InitString ((const char *) "identlist", 9);
        break;

      case decl_vardecl:
        return DynamicStrings_InitString ((const char *) "vardecl", 7);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  M2RTS_HALT (-1);
  __builtin_unreachable ();
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   gen - generate a small string describing node, n.
*/

static DynamicStrings_String gen (decl_node__opaque n)
{
  DynamicStrings_String s;
  unsigned int d;

  d = (unsigned int ) ((long unsigned int ) (n));
  s = FormatStrings_Sprintf1 (DynamicStrings_InitString ((const char *) "< %d ", 5), (const unsigned char *) &d, (sizeof (d)-1));  /* use 0x%x once FormatStrings has been released.  */
  s = DynamicStrings_ConCat (s, genKind (n));  /* use 0x%x once FormatStrings has been released.  */
  s = DynamicStrings_ConCat (s, DynamicStrings_InitString ((const char *) " ", 1));
  s = DynamicStrings_ConCat (s, getFQstring (n));
  s = DynamicStrings_ConCat (s, DynamicStrings_InitString ((const char *) " >", 2));
  return s;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dumpQ -
*/

static void dumpQ (const char *q_, unsigned int _q_high, alists_alist l)
{
  DynamicStrings_String m;
  decl_node__opaque n;
  unsigned int d;
  unsigned int h;
  unsigned int i;
  char q[_q_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (q, q_, _q_high+1);

  m = FormatStrings_Sprintf0 (DynamicStrings_InitString ((const char *) "Queue ", 6));
  m = DynamicStrings_KillString (SFIO_WriteS (FIO_StdOut, m));
  m = FormatStrings_Sprintf0 (DynamicStrings_InitString ((const char *) q, _q_high));
  m = DynamicStrings_KillString (SFIO_WriteS (FIO_StdOut, m));
  m = FormatStrings_Sprintf0 (DynamicStrings_InitString ((const char *) "\\n", 2));
  m = DynamicStrings_KillString (SFIO_WriteS (FIO_StdOut, m));
  i = 1;
  h = alists_noOfItemsInList (l);
  while (i <= h)
    {
      n = static_cast<decl_node__opaque> (alists_getItemFromList (l, i));
      m = DynamicStrings_KillString (SFIO_WriteS (FIO_StdOut, gen (n)));
      i += 1;
    }
  m = FormatStrings_Sprintf0 (DynamicStrings_InitString ((const char *) "\\n", 2));
  m = DynamicStrings_KillString (SFIO_WriteS (FIO_StdOut, m));
}


/*
   dumpLists -
*/

static void dumpLists (void)
{
  if ((mcOptions_getDebugTopological ()) && false)
    {
      dumpQ ((const char *) "todo", 4, globalGroup->todoQ);
      dumpQ ((const char *) "partial", 7, globalGroup->partialQ);
      dumpQ ((const char *) "done", 4, globalGroup->doneQ);
    }
}


/*
   outputHidden -
*/

static void outputHidden (decl_node__opaque n)
{
  outText (doP, (const char *) "#if !defined (", 14);
  doFQNameC (doP, n);
  outText (doP, (const char *) "_D)\\n", 5);
  outText (doP, (const char *) "#  define ", 10);
  doFQNameC (doP, n);
  outText (doP, (const char *) "_D\\n", 4);
  outText (doP, (const char *) "   typedef void *", 17);
  doFQNameC (doP, n);
  outText (doP, (const char *) ";\\n", 3);
  outText (doP, (const char *) "#endif\\n\\n", 10);
}


/*
   outputHiddenComplete -
*/

static void outputHiddenComplete (decl_node__opaque n)
{
  decl_node__opaque t;

  mcDebug_assert (decl_isType (static_cast<decl_node> (n)));
  t = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  mcDebug_assert (decl_isPointer (static_cast<decl_node> (t)));
  outText (doP, (const char *) "#define ", 8);
  doFQNameC (doP, n);
  outText (doP, (const char *) "_D\\n", 4);
  outText (doP, (const char *) "typedef ", 8);
  doTypeNameC (doP, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (t))));
  mcPretty_setNeedSpace (doP);
  outText (doP, (const char *) "*", 1);
  doFQNameC (doP, n);
  outText (doP, (const char *) ";\\n", 3);
}


/*
   tryPartial -
*/

static bool tryPartial (decl_node__opaque n, decl_nodeProcedure pt)
{
  decl_node__opaque q;

  if ((n != NULL) && (decl_isType (static_cast<decl_node> (n))))
    {
      q = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
      while (decl_isPointer (static_cast<decl_node> (q)))
        {
          q = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (q)));
        }
      if (q != NULL)
        {
          /* avoid gcc warning by using compound statement even if not strictly necessary.  */
          if ((decl_isRecord (static_cast<decl_node> (q))) || (decl_isProcType (static_cast<decl_node> (q))))
            {
              (*pt.proc) (n);
              addTodo (q);
              return true;
            }
          else if (decl_isArray (static_cast<decl_node> (q)))
            {
              /* avoid dangling else.  */
              (*pt.proc) (n);
              addTodo (q);
              return true;
            }
        }
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   outputPartialRecordArrayProcType -
*/

static void outputPartialRecordArrayProcType (decl_node__opaque n, decl_node__opaque q, unsigned int indirection)
{
  DynamicStrings_String s;

  outText (doP, (const char *) "typedef struct", 14);
  mcPretty_setNeedSpace (doP);
  s = getFQstring (n);
  if (decl_isRecord (static_cast<decl_node> (q)))
    {
      s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "_r", 2)));
    }
  else if (decl_isArray (static_cast<decl_node> (q)))
    {
      /* avoid dangling else.  */
      s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "_a", 2)));
    }
  else if (decl_isProcType (static_cast<decl_node> (q)))
    {
      /* avoid dangling else.  */
      s = DynamicStrings_ConCat (s, DynamicStrings_Mark (DynamicStrings_InitString ((const char *) "_p", 2)));
    }
  outTextS (doP, s);
  mcPretty_setNeedSpace (doP);
  s = DynamicStrings_KillString (s);
  while (indirection > 0)
    {
      outText (doP, (const char *) "*", 1);
      indirection -= 1;
    }
  doFQNameC (doP, n);
  outText (doP, (const char *) ";\\n\\n", 5);
}


/*
   outputPartial -
*/

static void outputPartial (decl_node__opaque n)
{
  decl_node__opaque q;
  unsigned int indirection;

  q = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  indirection = 0;
  while (decl_isPointer (static_cast<decl_node> (q)))
    {
      q = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (q)));
      indirection += 1;
    }
  outputPartialRecordArrayProcType (n, q, indirection);
}


/*
   tryOutputTodo -
*/

static void tryOutputTodo (decl_nodeProcedure c, decl_nodeProcedure t, decl_nodeProcedure v, decl_nodeProcedure pt)
{
  unsigned int i;
  unsigned int n;
  decl_node__opaque d;

  i = 1;
  n = alists_noOfItemsInList (globalGroup->todoQ);
  while (i <= n)
    {
      d = static_cast<decl_node__opaque> (alists_getItemFromList (globalGroup->todoQ, i));
      if (tryComplete (d, c, t, v))
        {
          alists_removeItemFromList (globalGroup->todoQ, reinterpret_cast <void *> (d));
          addDone (d);
          i = 1;
        }
      else if (tryPartial (d, pt))
        {
          /* avoid dangling else.  */
          alists_removeItemFromList (globalGroup->todoQ, reinterpret_cast <void *> (d));
          alists_includeItemIntoList (globalGroup->partialQ, reinterpret_cast <void *> (d));
          i = 1;
        }
      else
        {
          /* avoid dangling else.  */
          i += 1;
        }
      n = alists_noOfItemsInList (globalGroup->todoQ);
    }
}


/*
   tryOutputPartial -
*/

static void tryOutputPartial (decl_nodeProcedure t)
{
  unsigned int i;
  unsigned int n;
  decl_node__opaque d;

  i = 1;
  n = alists_noOfItemsInList (globalGroup->partialQ);
  while (i <= n)
    {
      d = static_cast<decl_node__opaque> (alists_getItemFromList (globalGroup->partialQ, i));
      if (tryCompleteFromPartial (d, t))
        {
          alists_removeItemFromList (globalGroup->partialQ, reinterpret_cast <void *> (d));
          addDone (d);
          i = 1;
          n -= 1;
        }
      else
        {
          i += 1;
        }
    }
}


/*
   debugList -
*/

static void debugList (const char *listName_, unsigned int _listName_high, const char *symName_, unsigned int _symName_high, alists_alist l)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque n;
  char listName[_listName_high+1];
  char symName[_symName_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (listName, listName_, _listName_high+1);
  memcpy (symName, symName_, _symName_high+1);

  h = alists_noOfItemsInList (l);
  if (h > 0)
    {
      i = 1;
      do {
        n = static_cast<decl_node__opaque> (alists_getItemFromList (l, i));
        dbg ((const char *) listName, _listName_high, (const char *) symName, _symName_high, n);
        i += 1;
      } while (! (i > h));
    }
}


/*
   debugLists -
*/

static void debugLists (void)
{
  if (mcOptions_getDebugTopological ())
    {
      debugList ((const char *) "todo", 4, (const char *) "decl_node", 9, globalGroup->todoQ);
      debugList ((const char *) "partial", 7, (const char *) "decl_node", 9, globalGroup->partialQ);
      debugList ((const char *) "done", 4, (const char *) "decl_node", 9, globalGroup->doneQ);
    }
}


/*
   addEnumConst -
*/

static void addEnumConst (decl_node__opaque n)
{
  DynamicStrings_String s;

  if ((decl_isConst (static_cast<decl_node> (n))) || (decl_isEnumeration (static_cast<decl_node> (n))))
    {
      addTodo (n);
    }
}


/*
   populateTodo -
*/

static void populateTodo (decl_nodeProcedure p)
{
  decl_node__opaque n;
  unsigned int i;
  unsigned int h;
  alists_alist l;

  h = alists_noOfItemsInList (globalGroup->todoQ);
  i = 1;
  while (i <= h)
    {
      n = static_cast<decl_node__opaque> (alists_getItemFromList (globalGroup->todoQ, i));
      l = alists_initList ();
      visitNode (l, n, p);
      alists_killList (&l);
      h = alists_noOfItemsInList (globalGroup->todoQ);
      i += 1;
    }
}


/*
   topologicallyOut - keep trying to resolve the todoQ and partialQ
                      until there is no change from the global group.
*/

static void topologicallyOut (decl_nodeProcedure c, decl_nodeProcedure t, decl_nodeProcedure v, decl_nodeProcedure tp, decl_nodeProcedure pc, decl_nodeProcedure pt, decl_nodeProcedure pv)
{
  decl_group before;

  populateTodo ((decl_nodeProcedure) {(decl_nodeProcedure_t) addEnumConst});
  before = NULL;
  do {
    before = dupGroup (before);  /* Get a copy of the globalGroup and free before.  */
    dumpLists ();  /* Get a copy of the globalGroup and free before.  */
    tryOutputTodo (c, t, v, tp);
    dumpLists ();
    tryOutputPartial (pt);
  } while (! (equalGroup (before, globalGroup)));
  killGroup (&before);
  dumpLists ();
  debugLists ();
}


/*
   scaffoldStatic -
*/

static void scaffoldStatic (mcPretty_pretty p, decl_node__opaque n)
{
  outText (p, (const char *) "\\n", 2);
  doExternCP (p);
  outText (p, (const char *) "void", 4);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "_M2_", 4);
  doFQNameC (p, n);
  outText (p, (const char *) "_init", 5);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(__attribute__((unused)) int argc,", 34);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "__attribute__((unused)) char *argv[],", 37);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "__attribute__((unused)) char *envp[])\\n", 39);
  p = outKc (p, (const char *) "{\\n", 3);
  doStatementsC (p, n->impF.beginStatements);
  p = outKc (p, (const char *) "}\\n", 3);
  outText (p, (const char *) "\\n", 2);
  doExternCP (p);
  outText (p, (const char *) "void", 4);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "_M2_", 4);
  doFQNameC (p, n);
  outText (p, (const char *) "_fini", 5);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(__attribute__((unused)) int argc,", 34);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "__attribute__((unused)) char *argv[],", 37);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "__attribute__((unused)) char *envp[])\\n", 39);
  p = outKc (p, (const char *) "{\\n", 3);
  doStatementsC (p, n->impF.finallyStatements);
  p = outKc (p, (const char *) "}\\n", 3);
}


/*
   emitCtor -
*/

static void emitCtor (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  outText (p, (const char *) "\\n", 2);
  outText (p, (const char *) "static void", 11);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "ctorFunction ()\\n", 17);
  doFQNameC (p, n);
  p = outKc (p, (const char *) "{\\n", 3);
  outText (p, (const char *) "M2RTS_RegisterModule (\"", 23);
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
  mcPretty_prints (p, s);
  outText (p, (const char *) "\",\\n", 4);
  outText (p, (const char *) "init, fini, dependencies);\\n", 28);
  p = outKc (p, (const char *) "}\\n\\n", 5);
  p = outKc (p, (const char *) "struct ", 7);
  mcPretty_prints (p, s);
  p = outKc (p, (const char *) "_module_m2 { ", 13);
  mcPretty_prints (p, s);
  p = outKc (p, (const char *) "_module_m2 (); ~", 16);
  mcPretty_prints (p, s);
  p = outKc (p, (const char *) "_module_m2 (); } global_module_", 31);
  mcPretty_prints (p, s);
  outText (p, (const char *) ";\\n\\n", 5);
  mcPretty_prints (p, s);
  p = outKc (p, (const char *) "_module_m2::", 12);
  mcPretty_prints (p, s);
  p = outKc (p, (const char *) "_module_m2 ()\\n", 15);
  p = outKc (p, (const char *) "{\\n", 3);
  outText (p, (const char *) "M2RTS_RegisterModule (\"", 23);
  mcPretty_prints (p, s);
  outText (p, (const char *) "\", init, fini, dependencies);", 29);
  p = outKc (p, (const char *) "}\\n", 3);
  mcPretty_prints (p, s);
  p = outKc (p, (const char *) "_module_m2::~", 13);
  mcPretty_prints (p, s);
  p = outKc (p, (const char *) "_module_m2 ()\\n", 15);
  p = outKc (p, (const char *) "{\\n", 3);
  p = outKc (p, (const char *) "}\\n", 3);
  s = DynamicStrings_KillString (s);
}


/*
   scaffoldDynamic -
*/

static void scaffoldDynamic (mcPretty_pretty p, decl_node__opaque n)
{
  outText (p, (const char *) "\\n", 2);
  doExternCP (p);
  outText (p, (const char *) "void", 4);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "_M2_", 4);
  doFQNameC (p, n);
  outText (p, (const char *) "_init", 5);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(__attribute__((unused)) int argc,", 34);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "__attribute__((unused)) char *argv[],", 37);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "__attribute__((unused)) char *envp[])\\n", 39);
  p = outKc (p, (const char *) "{\\n", 3);
  doStatementsC (p, n->impF.beginStatements);
  p = outKc (p, (const char *) "}\\n", 3);
  outText (p, (const char *) "\\n", 2);
  doExternCP (p);
  outText (p, (const char *) "void", 4);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "_M2_", 4);
  doFQNameC (p, n);
  outText (p, (const char *) "_fini", 5);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(__attribute__((unused)) int argc,", 34);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "__attribute__((unused)) char *argv[],", 37);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "__attribute__((unused)) char *envp[])\\n", 39);
  p = outKc (p, (const char *) "{\\n", 3);
  doStatementsC (p, n->impF.finallyStatements);
  p = outKc (p, (const char *) "}\\n", 3);
  emitCtor (p, n);
}


/*
   scaffoldMain -
*/

static void scaffoldMain (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  outText (p, (const char *) "int\\n", 5);
  outText (p, (const char *) "main", 4);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(int argc, char *argv[], char *envp[])\\n", 40);
  p = outKc (p, (const char *) "{\\n", 3);
  outText (p, (const char *) "M2RTS_ConstructModules (", 24);
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
  mcPretty_prints (p, s);
  outText (p, (const char *) ", argc, argv, envp);\\n", 22);
  outText (p, (const char *) "M2RTS_DeconstructModules (", 26);
  mcPretty_prints (p, s);
  outText (p, (const char *) ", argc, argv, envp);\\n", 22);
  outText (p, (const char *) "return 0;", 9);
  p = outKc (p, (const char *) "}\\n", 3);
  s = DynamicStrings_KillString (s);
}


/*
   outImpInitC - emit the init/fini functions and main function if required.
*/

static void outImpInitC (mcPretty_pretty p, decl_node__opaque n)
{
  if (mcOptions_getScaffoldDynamic ())
    {
      scaffoldDynamic (p, n);
    }
  else
    {
      scaffoldStatic (p, n);
    }
  if (mcOptions_getScaffoldMain ())
    {
      scaffoldMain (p, n);
    }
}


/*
   runSimplifyTypes -
*/

static void runSimplifyTypes (decl_node__opaque n)
{
  if (decl_isImp (static_cast<decl_node> (n)))
    {
      simplifyTypes (n->impF.decls);
    }
  else if (decl_isModule (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      simplifyTypes (n->moduleF.decls);
    }
  else if (decl_isDef (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      simplifyTypes (n->defF.decls);
    }
}


/*
   outDefC -
*/

static void outDefC (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  mcDebug_assert (decl_isDef (static_cast<decl_node> (n)));
  outputFile = mcStream_openFrag (1);  /* first fragment.  */
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));  /* first fragment.  */
  mcPretty_print (p, (const char *) "/* do not edit automatically generated by mc from ", 50);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) ".  */\\n", 7);
  mcOptions_writeGPLheader (outputFile);
  doCommentC (p, n->defF.com.body);
  mcPretty_print (p, (const char *) "\\n\\n#if !defined (_", 19);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) "_H)\\n", 5);
  mcPretty_print (p, (const char *) "#   define _", 12);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) "_H\\n\\n", 6);
  keyc_genConfigSystem (p);
  mcPretty_print (p, (const char *) "#   ifdef __cplusplus\\n", 23);
  mcPretty_print (p, (const char *) "extern \"C\" {\\n", 14);
  mcPretty_print (p, (const char *) "#   endif\\n", 11);
  outputFile = mcStream_openFrag (3);  /* third fragment.  */
  doP = p;  /* third fragment.  */
  Indexing_ForeachIndiceInIndexDo (n->defF.importedModules, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doIncludeC});
  mcPretty_print (p, (const char *) "\\n", 2);
  mcPretty_print (p, (const char *) "#   if defined (_", 17);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) "_C)\\n", 5);
  mcPretty_print (p, (const char *) "#      define EXTERN\\n", 22);
  mcPretty_print (p, (const char *) "#   else\\n", 10);
  mcPretty_print (p, (const char *) "#      define EXTERN extern\\n", 29);
  mcPretty_print (p, (const char *) "#   endif\\n\\n", 13);
  outDeclsDefC (p, n);
  runPrototypeDefC (n);
  mcPretty_print (p, (const char *) "#   ifdef __cplusplus\\n", 23);
  mcPretty_print (p, (const char *) "}\\n", 3);
  mcPretty_print (p, (const char *) "#   endif\\n", 11);
  mcPretty_print (p, (const char *) "\\n", 2);
  mcPretty_print (p, (const char *) "#   undef EXTERN\\n", 18);
  mcPretty_print (p, (const char *) "#endif\\n", 8);
  outputFile = mcStream_openFrag (2);  /* second fragment.  */
  keyc_genDefs (p);  /* second fragment.  */
  s = DynamicStrings_KillString (s);
}


/*
   runPrototypeExported -
*/

static void runPrototypeExported (decl_node__opaque n)
{
  if (decl_isExported (static_cast<decl_node> (n)))
    {
      keyc_enterScope (static_cast<decl_node> (n));
      doProcedureHeadingC (n, true);
      mcPretty_print (doP, (const char *) ";\\n", 3);
      keyc_leaveScope (static_cast<decl_node> (n));
    }
}


/*
   runPrototypeDefC -
*/

static void runPrototypeDefC (decl_node__opaque n)
{
  if (decl_isDef (static_cast<decl_node> (n)))
    {
      Indexing_ForeachIndiceInIndexDo (n->defF.decls.procedures, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) runPrototypeExported});
    }
}


/*
   outImpC -
*/

static void outImpC (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;
  decl_node__opaque defModule;

  mcDebug_assert (decl_isImp (static_cast<decl_node> (n)));
  outputFile = mcStream_openFrag (1);  /* first fragment.  */
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));  /* first fragment.  */
  mcPretty_print (p, (const char *) "/* do not edit automatically generated by mc from ", 50);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) ".  */\\n", 7);
  mcOptions_writeGPLheader (outputFile);
  doCommentC (p, n->impF.com.body);
  outText (p, (const char *) "\\n", 2);
  outputFile = mcStream_openFrag (3);  /* third fragment.  */
  if (mcOptions_getExtendedOpaque ())  /* third fragment.  */
    {
      doP = p;
      /* ForeachIndiceInIndexDo (n^.impF.importedModules, doIncludeC) ;  */
      includeExternals (n);
      foreachModuleDo (n, (symbolKey_performOperation) {(symbolKey_performOperation_t) runSimplifyTypes});
      libc_printf ((const char *) "/*  --extended-opaque seen therefore no #include will be used and everything will be declared in full.  */\\n", 108);
      decl_foreachDefModuleDo ((symbolKey_performOperation) {(symbolKey_performOperation_t) runIncludeDefConstType});
      includeDefVarProcedure (n);
      outDeclsImpC (p, n->impF.decls);
      decl_foreachDefModuleDo ((symbolKey_performOperation) {(symbolKey_performOperation_t) runPrototypeDefC});
    }
  else
    {
      s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
      /* Inform the source that this code belongs to the implementation module.  */
      mcPretty_print (p, (const char *) "#define _", 9);
      mcPretty_prints (p, s);
      mcPretty_print (p, (const char *) "_C\\n\\n", 6);
      /* Include the definition module for any opaque types.  */
      mcPretty_print (doP, (const char *) "#include \"", 10);
      mcPretty_prints (p, mcOptions_getHPrefix ());
      mcPretty_prints (p, s);
      mcPretty_print (p, (const char *) ".h\"\\n", 5);
      s = DynamicStrings_KillString (s);
      doP = p;
      Indexing_ForeachIndiceInIndexDo (n->impF.importedModules, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doIncludeC});
      mcPretty_print (p, (const char *) "\\n", 2);
      includeDefConstType (n);
      includeDefVarProcedure (n);
      outDeclsImpC (p, n->impF.decls);
      defModule = static_cast<decl_node__opaque> (decl_lookupDef (decl_getSymName (static_cast<decl_node> (n))));
      if (defModule != NULL)
        {
          runPrototypeDefC (defModule);
        }
    }
  Indexing_ForeachIndiceInIndexDo (n->impF.decls.procedures, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doPrototypeC});
  outProceduresC (p, n->impF.decls);
  outImpInitC (p, n);
  outputFile = mcStream_openFrag (2);  /* second fragment.  */
  keyc_genConfigSystem (p);  /* second fragment.  */
  keyc_genDefs (p);
}


/*
   outDeclsModuleC -
*/

static void outDeclsModuleC (mcPretty_pretty p, decl_scopeT s)
{
  simplifyTypes (s);
  includeConstType (s);
  doP = p;
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartial}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doCompletePartialC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone});
  /* try and output types, constants before variables and procedures.  */
  includeVarProcedure (s);
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartial}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doCompletePartialC}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNone});
  Indexing_ForeachIndiceInIndexDo (s.procedures, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doPrototypeC});
}


/*
   outModuleInitC -
*/

static void outModuleInitC (mcPretty_pretty p, decl_node__opaque n)
{
  outText (p, (const char *) "\\n", 2);
  doExternCP (p);
  outText (p, (const char *) "void", 4);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "_M2_", 4);
  doFQNameC (p, n);
  outText (p, (const char *) "_init", 5);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(__attribute__((unused)) int argc", 33);
  outText (p, (const char *) ",__attribute__((unused)) char *argv[]", 37);
  outText (p, (const char *) ",__attribute__((unused)) char *envp[])\\n", 40);
  p = outKc (p, (const char *) "{\\n", 3);
  doStatementsC (p, n->moduleF.beginStatements);
  p = outKc (p, (const char *) "}\\n", 3);
  outText (p, (const char *) "\\n", 2);
  doExternCP (p);
  outText (p, (const char *) "void", 4);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "_M2_", 4);
  doFQNameC (p, n);
  outText (p, (const char *) "_fini", 5);
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "(__attribute__((unused)) int argc", 33);
  outText (p, (const char *) ",__attribute__((unused)) char *argv[]", 37);
  outText (p, (const char *) ",__attribute__((unused)) char *envp[])\\n", 40);
  p = outKc (p, (const char *) "{\\n", 3);
  doStatementsC (p, n->moduleF.finallyStatements);
  p = outKc (p, (const char *) "}\\n", 3);
}


/*
   outModuleC -
*/

static void outModuleC (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  mcDebug_assert (decl_isModule (static_cast<decl_node> (n)));
  outputFile = mcStream_openFrag (1);  /* first fragment.  */
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));  /* first fragment.  */
  mcPretty_print (p, (const char *) "/* do not edit automatically generated by mc from ", 50);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) ".  */\\n", 7);
  mcOptions_writeGPLheader (outputFile);
  doCommentC (p, n->moduleF.com.body);
  outText (p, (const char *) "\\n", 2);
  outputFile = mcStream_openFrag (3);  /* third fragment.  */
  if (mcOptions_getExtendedOpaque ())  /* third fragment.  */
    {
      doP = p;
      includeExternals (n);
      foreachModuleDo (n, (symbolKey_performOperation) {(symbolKey_performOperation_t) runSimplifyTypes});
      libc_printf ((const char *) "/*  --extended-opaque seen therefore no #include will be used and everything will be declared in full.  */\\n", 108);
      decl_foreachDefModuleDo ((symbolKey_performOperation) {(symbolKey_performOperation_t) runIncludeDefConstType});
      outDeclsModuleC (p, n->moduleF.decls);
      decl_foreachDefModuleDo ((symbolKey_performOperation) {(symbolKey_performOperation_t) runPrototypeDefC});
    }
  else
    {
      doP = p;
      Indexing_ForeachIndiceInIndexDo (n->moduleF.importedModules, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doIncludeC});
      mcPretty_print (p, (const char *) "\\n", 2);
      outDeclsModuleC (p, n->moduleF.decls);
    }
  Indexing_ForeachIndiceInIndexDo (n->moduleF.decls.procedures, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doPrototypeC});
  outProceduresC (p, n->moduleF.decls);
  outModuleInitC (p, n);
  outputFile = mcStream_openFrag (2);  /* second fragment.  */
  keyc_genConfigSystem (p);  /* second fragment.  */
  keyc_genDefs (p);
}


/*
   outC -
*/

static void outC (mcPretty_pretty p, decl_node__opaque n)
{
  keyc_enterScope (static_cast<decl_node> (n));
  if (decl_isDef (static_cast<decl_node> (n)))
    {
      outDefC (p, n);
    }
  else if (decl_isImp (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      outImpC (p, n);
    }
  else if (decl_isModule (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      outModuleC (p, n);
    }
  else
    {
      /* avoid dangling else.  */
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  keyc_leaveScope (static_cast<decl_node> (n));
}


/*
   doIncludeM2 - include modules in module, n.
*/

static void doIncludeM2 (decl_node__opaque n)
{
  DynamicStrings_String s;

  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
  mcPretty_print (doP, (const char *) "IMPORT ", 7);
  mcPretty_prints (doP, s);
  mcPretty_print (doP, (const char *) " ;\\n", 4);
  s = DynamicStrings_KillString (s);
  if (decl_isDef (static_cast<decl_node> (n)))
    {
      symbolKey_foreachNodeDo (n->defF.decls.symbols, (symbolKey_performOperation) {(symbolKey_performOperation_t) addDone});
    }
  else if (decl_isImp (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      symbolKey_foreachNodeDo (n->impF.decls.symbols, (symbolKey_performOperation) {(symbolKey_performOperation_t) addDone});
    }
  else if (decl_isModule (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      symbolKey_foreachNodeDo (n->moduleF.decls.symbols, (symbolKey_performOperation) {(symbolKey_performOperation_t) addDone});
    }
}


/*
   doConstM2 -
*/

static void doConstM2 (decl_node__opaque n)
{
  mcPretty_print (doP, (const char *) "CONST\\n", 7);
  doFQNameC (doP, n);
  mcPretty_setNeedSpace (doP);
  doExprC (doP, n->constF.value);
  mcPretty_print (doP, (const char *) "\\n", 2);
}


/*
   doProcTypeM2 -
*/

static void doProcTypeM2 (mcPretty_pretty p, decl_node__opaque n)
{
  outText (p, (const char *) "proc type to do..", 17);
}


/*
   doRecordFieldM2 -
*/

static void doRecordFieldM2 (mcPretty_pretty p, decl_node__opaque f)
{
  doNameM2 (p, f);
  outText (p, (const char *) ":", 1);
  mcPretty_setNeedSpace (p);
  doTypeM2 (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (f))));
  mcPretty_setNeedSpace (p);
}


/*
   doVarientFieldM2 -
*/

static void doVarientFieldM2 (mcPretty_pretty p, decl_node__opaque n)
{
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  mcDebug_assert (decl_isVarientField (static_cast<decl_node> (n)));
  doNameM2 (p, n);
  outText (p, (const char *) ":", 1);
  mcPretty_setNeedSpace (p);
  i = Indexing_LowIndice (n->varientfieldF.listOfSons);
  t = Indexing_HighIndice (n->varientfieldF.listOfSons);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->varientfieldF.listOfSons, i));
      if (decl_isRecordField (static_cast<decl_node> (q)))
        {
          doRecordFieldM2 (p, q);
          outText (p, (const char *) ";\\n", 3);
        }
      else if (decl_isVarient (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          doVarientM2 (p, q);
          outText (p, (const char *) ";\\n", 3);
        }
      else
        {
          /* avoid dangling else.  */
          M2RTS_HALT (-1);
          __builtin_unreachable ();
        }
      i += 1;
    }
}


/*
   doVarientM2 -
*/

static void doVarientM2 (mcPretty_pretty p, decl_node__opaque n)
{
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  mcDebug_assert (decl_isVarient (static_cast<decl_node> (n)));
  outText (p, (const char *) "CASE", 4);
  mcPretty_setNeedSpace (p);
  if (n->varientF.tag != NULL)
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if (decl_isRecordField (static_cast<decl_node> (n->varientF.tag)))
        {
          doRecordFieldM2 (p, n->varientF.tag);
        }
      else if (decl_isVarientField (static_cast<decl_node> (n->varientF.tag)))
        {
          /* avoid dangling else.  */
          doVarientFieldM2 (p, n->varientF.tag);
        }
      else
        {
          /* avoid dangling else.  */
          M2RTS_HALT (-1);
          __builtin_unreachable ();
        }
    }
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "OF\\n", 4);
  i = Indexing_LowIndice (n->varientF.listOfSons);
  t = Indexing_HighIndice (n->varientF.listOfSons);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->varientF.listOfSons, i));
      if (decl_isRecordField (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          if (! q->recordfieldF.tag)
            {
              doRecordFieldM2 (p, q);
              outText (p, (const char *) ";\\n", 3);
            }
        }
      else if (decl_isVarientField (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          doVarientFieldM2 (p, q);
        }
      else
        {
          /* avoid dangling else.  */
          M2RTS_HALT (-1);
          __builtin_unreachable ();
        }
      i += 1;
    }
  outText (p, (const char *) "END", 3);
  mcPretty_setNeedSpace (p);
}


/*
   doRecordM2 -
*/

static void doRecordM2 (mcPretty_pretty p, decl_node__opaque n)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque f;

  mcDebug_assert (decl_isRecord (static_cast<decl_node> (n)));
  p = outKm2 (p, (const char *) "RECORD", 6);
  i = Indexing_LowIndice (n->recordF.listOfSons);
  h = Indexing_HighIndice (n->recordF.listOfSons);
  outText (p, (const char *) "\\n", 2);
  while (i <= h)
    {
      f = static_cast<decl_node__opaque> (Indexing_GetIndice (n->recordF.listOfSons, i));
      if (decl_isRecordField (static_cast<decl_node> (f)))
        {
          /* avoid dangling else.  */
          if (! f->recordfieldF.tag)
            {
              doRecordFieldM2 (p, f);
              outText (p, (const char *) ";\\n", 3);
            }
        }
      else if (decl_isVarient (static_cast<decl_node> (f)))
        {
          /* avoid dangling else.  */
          doVarientM2 (p, f);
          outText (p, (const char *) ";\\n", 3);
        }
      else if (decl_isVarientField (static_cast<decl_node> (f)))
        {
          /* avoid dangling else.  */
          doVarientFieldM2 (p, f);
        }
      i += 1;
    }
  p = outKm2 (p, (const char *) "END", 3);
  mcPretty_setNeedSpace (p);
}


/*
   doPointerM2 -
*/

static void doPointerM2 (mcPretty_pretty p, decl_node__opaque n)
{
  outText (p, (const char *) "POINTER TO", 10);
  mcPretty_setNeedSpace (doP);
  doTypeM2 (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) ";\\n", 3);
}


/*
   doTypeAliasM2 -
*/

static void doTypeAliasM2 (mcPretty_pretty p, decl_node__opaque n)
{
  doTypeNameC (p, n);
  mcPretty_setNeedSpace (p);
  outText (doP, (const char *) "=", 1);
  mcPretty_setNeedSpace (p);
  doTypeM2 (p, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  mcPretty_setNeedSpace (p);
  outText (p, (const char *) "\\n", 2);
}


/*
   doEnumerationM2 -
*/

static void doEnumerationM2 (mcPretty_pretty p, decl_node__opaque n)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque s;
  DynamicStrings_String t;

  outText (p, (const char *) "(", 1);
  i = Indexing_LowIndice (n->enumerationF.listOfSons);
  h = Indexing_HighIndice (n->enumerationF.listOfSons);
  while (i <= h)
    {
      s = static_cast<decl_node__opaque> (Indexing_GetIndice (n->enumerationF.listOfSons, i));
      doFQNameC (p, s);
      if (i < h)
        {
          outText (p, (const char *) ",", 1);
          mcPretty_setNeedSpace (p);
        }
      i += 1;
    }
  outText (p, (const char *) ")", 1);
}


/*
   doBaseM2 -
*/

static void doBaseM2 (mcPretty_pretty p, decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_char:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
      case decl_real:
      case decl_longreal:
      case decl_shortreal:
      case decl_bitset:
      case decl_boolean:
      case decl_proc:
        doNameM2 (p, n);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  mcPretty_setNeedSpace (p);
}


/*
   doSystemM2 -
*/

static void doSystemM2 (mcPretty_pretty p, decl_node__opaque n)
{
  switch (n->kind)
    {
      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_csizet:
      case decl_cssizet:
      case decl_cofft:
      case decl_cardinal64:
        doNameM2 (p, n);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   doTypeM2 -
*/

static void doTypeM2 (mcPretty_pretty p, decl_node__opaque n)
{
  if (isBase (n))
    {
      doBaseM2 (p, n);
    }
  else if (isSystem (n))
    {
      /* avoid dangling else.  */
      doSystemM2 (p, n);
    }
  else if (decl_isType (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doTypeAliasM2 (p, n);
    }
  else if (decl_isProcType (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doProcTypeM2 (p, n);
    }
  else if (decl_isPointer (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doPointerM2 (p, n);
    }
  else if (decl_isEnumeration (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doEnumerationM2 (p, n);
    }
  else if (decl_isRecord (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doRecordM2 (p, n);
    }
}


/*
   doTypesM2 -
*/

static void doTypesM2 (decl_node__opaque n)
{
  decl_node__opaque m;

  outText (doP, (const char *) "TYPE\\n", 6);
  doTypeM2 (doP, n);
}


/*
   doVarM2 -
*/

static void doVarM2 (decl_node__opaque n)
{
  mcDebug_assert (decl_isVar (static_cast<decl_node> (n)));
  doNameC (doP, n);
  outText (doP, (const char *) ":", 1);
  mcPretty_setNeedSpace (doP);
  doTypeM2 (doP, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  mcPretty_setNeedSpace (doP);
  outText (doP, (const char *) ";\\n", 3);
}


/*
   doVarsM2 -
*/

static void doVarsM2 (decl_node__opaque n)
{
  decl_node__opaque m;

  outText (doP, (const char *) "VAR\\n", 5);
  doVarM2 (n);
}


/*
   doTypeNameM2 -
*/

static void doTypeNameM2 (mcPretty_pretty p, decl_node__opaque n)
{
  doNameM2 (p, n);
}


/*
   doParamM2 -
*/

static void doParamM2 (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque ptype;
  nameKey_Name i;
  unsigned int c;
  unsigned int t;
  wlists_wlist l;

  mcDebug_assert (decl_isParam (static_cast<decl_node> (n)));
  ptype = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (n->paramF.namelist == NULL)
    {
      doTypeNameM2 (p, ptype);
    }
  else
    {
      mcDebug_assert (isIdentList (n->paramF.namelist));
      l = n->paramF.namelist->identlistF.names;
      if (l == NULL)
        {
          doTypeNameM2 (p, ptype);
        }
      else
        {
          t = wlists_noOfItemsInList (l);
          c = 1;
          while (c <= t)
            {
              i = static_cast<nameKey_Name> (wlists_getItemFromList (l, c));
              mcPretty_setNeedSpace (p);
              doNamesC (p, i);
              if (c < t)
                {
                  outText (p, (const char *) ",", 1);
                  mcPretty_setNeedSpace (p);
                }
              c += 1;
            }
          outText (p, (const char *) ":", 1);
          mcPretty_setNeedSpace (p);
          doTypeNameM2 (p, ptype);
        }
    }
}


/*
   doVarParamM2 -
*/

static void doVarParamM2 (mcPretty_pretty p, decl_node__opaque n)
{
  decl_node__opaque ptype;
  nameKey_Name i;
  unsigned int c;
  unsigned int t;
  wlists_wlist l;

  mcDebug_assert (decl_isVarParam (static_cast<decl_node> (n)));
  outText (p, (const char *) "VAR", 3);
  mcPretty_setNeedSpace (p);
  ptype = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (n->varparamF.namelist == NULL)
    {
      doTypeNameM2 (p, ptype);
    }
  else
    {
      mcDebug_assert (isIdentList (n->varparamF.namelist));
      l = n->varparamF.namelist->identlistF.names;
      if (l == NULL)
        {
          doTypeNameM2 (p, ptype);
        }
      else
        {
          t = wlists_noOfItemsInList (l);
          c = 1;
          while (c <= t)
            {
              i = static_cast<nameKey_Name> (wlists_getItemFromList (l, c));
              mcPretty_setNeedSpace (p);
              doNamesC (p, i);
              if (c < t)
                {
                  outText (p, (const char *) ",", 1);
                  mcPretty_setNeedSpace (p);
                }
              c += 1;
            }
          outText (p, (const char *) ":", 1);
          mcPretty_setNeedSpace (p);
          doTypeNameM2 (p, ptype);
        }
    }
}


/*
   doParameterM2 -
*/

static void doParameterM2 (mcPretty_pretty p, decl_node__opaque n)
{
  if (decl_isParam (static_cast<decl_node> (n)))
    {
      doParamM2 (p, n);
    }
  else if (decl_isVarParam (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      doVarParamM2 (p, n);
    }
  else if (decl_isVarargs (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      mcPretty_print (p, (const char *) "...", 3);
    }
}


/*
   doPrototypeM2 -
*/

static void doPrototypeM2 (decl_node__opaque n)
{
  unsigned int i;
  unsigned int h;
  decl_node__opaque p;

  mcDebug_assert (decl_isProcedure (static_cast<decl_node> (n)));
  mcPretty_noSpace (doP);
  doNameM2 (doP, n);
  mcPretty_setNeedSpace (doP);
  outText (doP, (const char *) "(", 1);
  i = Indexing_LowIndice (n->procedureF.parameters);
  h = Indexing_HighIndice (n->procedureF.parameters);
  while (i <= h)
    {
      p = static_cast<decl_node__opaque> (Indexing_GetIndice (n->procedureF.parameters, i));
      doParameterM2 (doP, p);
      mcPretty_noSpace (doP);
      if (i < h)
        {
          mcPretty_print (doP, (const char *) ";", 1);
          mcPretty_setNeedSpace (doP);
        }
      i += 1;
    }
  outText (doP, (const char *) ")", 1);
  if (n->procedureF.returnType != NULL)
    {
      mcPretty_setNeedSpace (doP);
      outText (doP, (const char *) ":", 1);
      doTypeM2 (doP, n->procedureF.returnType);
      mcPretty_setNeedSpace (doP);
    }
  outText (doP, (const char *) ";\\n", 3);
}


/*
   outputPartialM2 - just writes out record, array, and proctypes.
                     No need for forward declarations in Modula-2
                     but we need to keep topological sort happy.
                     So when asked to output partial we emit the
                     full type for these types and then do nothing
                     when trying to complete partial to full.
*/

static void outputPartialM2 (decl_node__opaque n)
{
  decl_node__opaque q;

  q = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n)));
  if (decl_isRecord (static_cast<decl_node> (q)))
    {
      doTypeM2 (doP, n);
    }
  else if (decl_isArray (static_cast<decl_node> (q)))
    {
      /* avoid dangling else.  */
      doTypeM2 (doP, n);
    }
  else if (decl_isProcType (static_cast<decl_node> (q)))
    {
      /* avoid dangling else.  */
      doTypeM2 (doP, n);
    }
}


/*
   outDeclsDefM2 -
*/

static void outDeclsDefM2 (mcPretty_pretty p, decl_scopeT s)
{
  simplifyTypes (s);
  includeConstType (s);
  doP = p;
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarsM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartialM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing});
  includeVarProcedure (s);
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarsM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartialM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing});
  Indexing_ForeachIndiceInIndexDo (s.procedures, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doPrototypeM2});
}


/*
   outDefM2 -
*/

static void outDefM2 (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSource (static_cast<decl_node> (n))));
  mcPretty_print (p, (const char *) "(* automatically created by mc from ", 36);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) ".  *)\\n\\n", 9);
  s = DynamicStrings_KillString (s);
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSymName (static_cast<decl_node> (n))));
  mcPretty_print (p, (const char *) "DEFINITION MODULE ", 18);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) " ;\\n\\n", 6);
  doP = p;
  Indexing_ForeachIndiceInIndexDo (n->defF.importedModules, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doIncludeM2});
  mcPretty_print (p, (const char *) "\\n", 2);
  outDeclsDefM2 (p, n->defF.decls);
  mcPretty_print (p, (const char *) "\\n", 2);
  mcPretty_print (p, (const char *) "END ", 4);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) ".\\n", 3);
  s = DynamicStrings_KillString (s);
}


/*
   outDeclsImpM2 -
*/

static void outDeclsImpM2 (mcPretty_pretty p, decl_scopeT s)
{
  simplifyTypes (s);
  includeConstType (s);
  doP = p;
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartialM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing});
  includeVarProcedure (s);
  topologicallyOut ((decl_nodeProcedure) {(decl_nodeProcedure_t) doConstM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doTypesM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doVarsM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) outputPartialM2}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing}, (decl_nodeProcedure) {(decl_nodeProcedure_t) doNothing});
  outText (p, (const char *) "\\n", 2);
  Indexing_ForeachIndiceInIndexDo (s.procedures, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doPrototypeC});
}


/*
   outImpM2 -
*/

static void outImpM2 (mcPretty_pretty p, decl_node__opaque n)
{
  DynamicStrings_String s;

  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (decl_getSource (static_cast<decl_node> (n))));
  mcPretty_print (p, (const char *) "(* automatically created by mc from ", 36);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) ".  *)\\n\\n", 9);
  mcPretty_print (p, (const char *) "IMPLEMENTATION MODULE ", 22);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) " ;\\n\\n", 6);
  doP = p;
  Indexing_ForeachIndiceInIndexDo (n->impF.importedModules, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) doIncludeM2});
  mcPretty_print (p, (const char *) "\\n", 2);
  includeDefConstType (n);
  outDeclsImpM2 (p, n->impF.decls);
  mcPretty_print (p, (const char *) "\\n", 2);
  mcPretty_print (p, (const char *) "END ", 4);
  mcPretty_prints (p, s);
  mcPretty_print (p, (const char *) ".\\n", 3);
  s = DynamicStrings_KillString (s);
}


/*
   outModuleM2 -
*/

static void outModuleM2 (mcPretty_pretty p, decl_node__opaque n)
{
}


/*
   outM2 -
*/

static void outM2 (mcPretty_pretty p, decl_node__opaque n)
{
  if (decl_isDef (static_cast<decl_node> (n)))
    {
      outDefM2 (p, n);
    }
  else if (decl_isImp (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      outImpM2 (p, n);
    }
  else if (decl_isModule (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      outModuleM2 (p, n);
    }
  else
    {
      /* avoid dangling else.  */
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
}


/*
   addDone - adds node, n, to the doneQ.
*/

static void addDone (decl_node__opaque n)
{
  DynamicStrings_String s;

  alists_includeItemIntoList (globalGroup->doneQ, reinterpret_cast <void *> (n));
  if ((decl_isVar (static_cast<decl_node> (n))) || (decl_isParameter (static_cast<decl_node> (n))))
    {
      initNodeOpaqueState (n);
    }
  debugLists ();
}


/*
   addDoneDef - adds node, n, to the doneQ providing
                it is not an opaque of the main module we are compiling.
*/

static void addDoneDef (decl_node__opaque n)
{
  if (decl_isDef (static_cast<decl_node> (n)))
    {
      addDone (n);
      return;
    }
  if (false && ((decl_lookupImp (decl_getSymName (decl_getScope (static_cast<decl_node> (n))))) == (decl_getMainModule ())))
    {
      mcMetaError_metaError1 ((const char *) "cyclic dependancy found between another module using {%1ad} from the definition module of the implementation main being compiled, use the --extended-opaque option to compile", 173, (const unsigned char *) &n, (sizeof (n)-1));
      mcError_flushErrors ();
      mcError_errorAbort0 ((const char *) "terminating compilation", 23);
    }
  else if ((decl_isType (static_cast<decl_node> (n))) && (isDeclInImp (n)))
    {
      /* avoid dangling else.  */
    }
  else
    {
      /* avoid dangling else.  */
      /* Ignore an opaque type which is declared in this implementation module as it
         will be fully declared in C/C++ with the __opaque postfix.  Whereas the
         void * non prefixed typedef will be declared in the .h file.  */
      addDone (n);
    }
}


/*
   dbgAdd -
*/

static decl_node__opaque dbgAdd (alists_alist l, decl_node__opaque n)
{
  if (n != NULL)
    {
      alists_includeItemIntoList (l, reinterpret_cast <void *> (n));
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dbgType -
*/

static void dbgType (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;

  t = dbgAdd (l, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  out1 ((const char *) "<%s type", 8, n);
  if (t == NULL)
    {
      out0 ((const char *) ", type = NIL\\n", 14);
    }
  else
    {
      out1 ((const char *) ", type = %s>\\n", 14, t);
    }
}


/*
   dbgPointer -
*/

static void dbgPointer (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;

  t = dbgAdd (l, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  out1 ((const char *) "<%s pointer", 11, n);
  out1 ((const char *) " to %s>\\n", 9, t);
}


/*
   dbgRecord -
*/

static void dbgRecord (alists_alist l, decl_node__opaque n)
{
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  out1 ((const char *) "<%s record:\\n", 13, n);
  i = Indexing_LowIndice (n->recordF.listOfSons);
  t = Indexing_HighIndice (n->recordF.listOfSons);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->recordF.listOfSons, i));
      if (decl_isRecordField (static_cast<decl_node> (q)))
        {
          out1 ((const char *) " <recordfield %s", 16, q);
        }
      else if (decl_isVarientField (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          out1 ((const char *) " <varientfield %s", 17, q);
        }
      else if (decl_isVarient (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          out1 ((const char *) " <varient %s", 12, q);
        }
      else
        {
          /* avoid dangling else.  */
          M2RTS_HALT (-1);
          __builtin_unreachable ();
        }
      q = dbgAdd (l, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (q))));
      out1 ((const char *) ": %s>\\n", 7, q);
      i += 1;
    }
  outText (doP, (const char *) ">\\n", 3);
}


/*
   dbgVarient -
*/

static void dbgVarient (alists_alist l, decl_node__opaque n)
{
  unsigned int i;
  unsigned int t;
  decl_node__opaque q;

  out1 ((const char *) "<%s varient: ", 13, n);
  out1 ((const char *) "tag %s", 6, n->varientF.tag);
  q = static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n->varientF.tag)));
  if (q == NULL)
    {
      outText (doP, (const char *) "\\n", 2);
    }
  else
    {
      out1 ((const char *) ": %s\\n", 6, q);
      q = dbgAdd (l, q);
    }
  i = Indexing_LowIndice (n->varientF.listOfSons);
  t = Indexing_HighIndice (n->varientF.listOfSons);
  while (i <= t)
    {
      q = static_cast<decl_node__opaque> (Indexing_GetIndice (n->varientF.listOfSons, i));
      if (decl_isRecordField (static_cast<decl_node> (q)))
        {
          out1 ((const char *) " <recordfield %s", 16, q);
        }
      else if (decl_isVarientField (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          out1 ((const char *) " <varientfield %s", 17, q);
        }
      else if (decl_isVarient (static_cast<decl_node> (q)))
        {
          /* avoid dangling else.  */
          out1 ((const char *) " <varient %s", 12, q);
        }
      else
        {
          /* avoid dangling else.  */
          M2RTS_HALT (-1);
          __builtin_unreachable ();
        }
      q = dbgAdd (l, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (q))));
      out1 ((const char *) ": %s>\\n", 7, q);
      i += 1;
    }
  outText (doP, (const char *) ">\\n", 3);
}


/*
   dbgEnumeration -
*/

static void dbgEnumeration (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque e;
  unsigned int i;
  unsigned int h;

  outText (doP, (const char *) "< enumeration ", 14);
  i = Indexing_LowIndice (n->enumerationF.listOfSons);
  h = Indexing_HighIndice (n->enumerationF.listOfSons);
  while (i <= h)
    {
      e = static_cast<decl_node__opaque> (Indexing_GetIndice (n->enumerationF.listOfSons, i));
      out1 ((const char *) "%s, ", 4, e);
      i += 1;
    }
  outText (doP, (const char *) ">\\n", 3);
}


/*
   dbgVar -
*/

static void dbgVar (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;

  t = dbgAdd (l, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  out1 ((const char *) "<%s var", 7, n);
  out1 ((const char *) ", type = %s>\\n", 14, t);
}


/*
   dbgSubrange -
*/

static void dbgSubrange (alists_alist l, decl_node__opaque n)
{
  if (n->subrangeF.low == NULL)
    {
      out1 ((const char *) "%s", 2, n->subrangeF.type);
    }
  else
    {
      out1 ((const char *) "[%s", 3, n->subrangeF.low);
      out1 ((const char *) "..%s]", 5, n->subrangeF.high);
    }
}


/*
   dbgArray -
*/

static void dbgArray (alists_alist l, decl_node__opaque n)
{
  decl_node__opaque t;

  t = dbgAdd (l, static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (n))));
  out1 ((const char *) "<%s array ", 10, n);
  if (n->arrayF.subr != NULL)
    {
      dbgSubrange (l, n->arrayF.subr);
    }
  out1 ((const char *) " of %s>\\n", 9, t);
}


/*
   doDbg -
*/

static void doDbg (alists_alist l, decl_node__opaque n)
{
  if (n == NULL)
    {}  /* empty.  */
  else if (decl_isSubrange (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      dbgSubrange (l, n);
    }
  else if (decl_isType (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      dbgType (l, n);
    }
  else if (decl_isRecord (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      dbgRecord (l, n);
    }
  else if (decl_isVarient (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      dbgVarient (l, n);
    }
  else if (decl_isEnumeration (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      dbgEnumeration (l, n);
    }
  else if (decl_isPointer (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      dbgPointer (l, n);
    }
  else if (decl_isArray (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      dbgArray (l, n);
    }
  else if (decl_isVar (static_cast<decl_node> (n)))
    {
      /* avoid dangling else.  */
      dbgVar (l, n);
    }
}


/*
   dbg -
*/

static void dbg (const char *listName_, unsigned int _listName_high, const char *symName_, unsigned int _symName_high, decl_node__opaque n)
{
  alists_alist l;
  mcPretty_pretty o;
  FIO_File f;
  DynamicStrings_String s;
  unsigned int i;
  char listName[_listName_high+1];
  char symName[_symName_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (listName, listName_, _listName_high+1);
  memcpy (symName, symName_, _symName_high+1);

  o = doP;
  f = outputFile;
  outputFile = FIO_StdOut;
  doP = mcPretty_initPretty ((mcPretty_writeProc) {(mcPretty_writeProc_t) write_}, (mcPretty_writeLnProc) {(mcPretty_writeLnProc_t) writeln});
  l = alists_initList ();
  alists_includeItemIntoList (l, reinterpret_cast <void *> (n));
  i = 1;
  do {
    n = static_cast<decl_node__opaque> (alists_getItemFromList (l, i));
    if (decl_isType (static_cast<decl_node> (n)))
      {
        s = getFQstring (n);
        if (DynamicStrings_EqualArray (s, (const char *) symName, _symName_high))
          {
            out0 ((const char *) "list ", 5);
            out0 ((const char *) listName, _listName_high);
            out0 ((const char *) ": ", 2);
            doDbg (l, n);
          }
        s = DynamicStrings_KillString (s);
      }
    i += 1;
  } while (! (i > (alists_noOfItemsInList (l))));
  doP = o;
  outputFile = f;
}


/*
   addGenericBody - adds comment node to funccall, return, assignment
                    nodes.
*/

static void addGenericBody (decl_node__opaque n, decl_node__opaque c)
{
  switch (n->kind)
    {
      case decl_unreachable:
      case decl_throw:
      case decl_halt:
      case decl_new:
      case decl_dispose:
      case decl_inc:
      case decl_dec:
      case decl_incl:
      case decl_excl:
        n->intrinsicF.intrinsicComment.body = c;
        break;

      case decl_funccall:
        n->funccallF.funccallComment.body = c;
        break;

      case decl_return:
        n->returnF.returnComment.body = c;
        break;

      case decl_assignment:
        n->assignmentF.assignComment.body = c;
        break;

      case decl_module:
        n->moduleF.com.body = c;
        break;

      case decl_def:
        n->defF.com.body = c;
        break;

      case decl_imp:
        n->impF.com.body = c;
        break;


      default:
        break;
    }
}


/*
   addGenericAfter - adds comment node to funccall, return, assignment
                     nodes.
*/

static void addGenericAfter (decl_node__opaque n, decl_node__opaque c)
{
  switch (n->kind)
    {
      case decl_unreachable:
      case decl_throw:
      case decl_halt:
      case decl_new:
      case decl_dispose:
      case decl_inc:
      case decl_dec:
      case decl_incl:
      case decl_excl:
        n->intrinsicF.intrinsicComment.after = c;
        break;

      case decl_funccall:
        n->funccallF.funccallComment.after = c;
        break;

      case decl_return:
        n->returnF.returnComment.after = c;
        break;

      case decl_assignment:
        n->assignmentF.assignComment.after = c;
        break;

      case decl_module:
        n->moduleF.com.after = c;
        break;

      case decl_def:
        n->defF.com.after = c;
        break;

      case decl_imp:
        n->impF.com.after = c;
        break;


      default:
        break;
    }
}


/*
   isAssignment -
*/

static bool isAssignment (decl_node__opaque n)
{
  return n->kind == decl_assignment;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isComment - returns TRUE if node, n, is a comment.
*/

static bool isComment (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  return n->kind == decl_comment;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   initPair - initialise the commentPair, c.
*/

static void initPair (decl_commentPair *c)
{
  (*c).after = static_cast<decl_node__opaque> (NULL);
  (*c).body = static_cast<decl_node__opaque> (NULL);
}


/*
   dupExplist -
*/

static decl_node__opaque dupExplist (decl_node__opaque n)
{
  decl_node__opaque m;
  unsigned int i;

  mcDebug_assert (decl_isExpList (static_cast<decl_node> (n)));
  m = static_cast<decl_node__opaque> (decl_makeExpList ());
  i = Indexing_LowIndice (n->explistF.exp);
  while (i <= (Indexing_HighIndice (n->explistF.exp)))
    {
      decl_putExpList (static_cast<decl_node> (m), decl_dupExpr (static_cast<decl_node> (Indexing_GetIndice (n->explistF.exp, i))));
      i += 1;
    }
  return m;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dupArrayref -
*/

static decl_node__opaque dupArrayref (decl_node__opaque n)
{
  mcDebug_assert (isArrayRef (n));
  return static_cast<decl_node__opaque> (decl_makeArrayRef (decl_dupExpr (static_cast<decl_node> (n->arrayrefF.array)), decl_dupExpr (static_cast<decl_node> (n->arrayrefF.index))));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dupPointerref -
*/

static decl_node__opaque dupPointerref (decl_node__opaque n)
{
  mcDebug_assert (decl_isPointerRef (static_cast<decl_node> (n)));
  return static_cast<decl_node__opaque> (decl_makePointerRef (decl_dupExpr (static_cast<decl_node> (n->pointerrefF.ptr)), decl_dupExpr (static_cast<decl_node> (n->pointerrefF.field))));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dupComponentref -
*/

static decl_node__opaque dupComponentref (decl_node__opaque n)
{
  mcDebug_assert (isComponentRef (n));
  return doMakeComponentRef (static_cast<decl_node__opaque> (decl_dupExpr (static_cast<decl_node> (n->componentrefF.rec))), static_cast<decl_node__opaque> (decl_dupExpr (static_cast<decl_node> (n->componentrefF.field))));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dupBinary -
*/

static decl_node__opaque dupBinary (decl_node__opaque n)
{
  /* assert (isBinary (n)) ;  */
  return makeBinary (n->kind, static_cast<decl_node__opaque> (decl_dupExpr (static_cast<decl_node> (n->binaryF.left))), static_cast<decl_node__opaque> (decl_dupExpr (static_cast<decl_node> (n->binaryF.right))), n->binaryF.resultType);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dupUnary -
*/

static decl_node__opaque dupUnary (decl_node__opaque n)
{
  /* assert (isUnary (n)) ;  */
  return makeUnary (n->kind, static_cast<decl_node__opaque> (decl_dupExpr (static_cast<decl_node> (n->unaryF.arg))), n->unaryF.resultType);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dupFunccall -
*/

static decl_node__opaque dupFunccall (decl_node__opaque n)
{
  decl_node__opaque m;

  mcDebug_assert (isFuncCall (n));
  m = static_cast<decl_node__opaque> (decl_makeFuncCall (decl_dupExpr (static_cast<decl_node> (n->funccallF.function)), decl_dupExpr (static_cast<decl_node> (n->funccallF.args))));
  m->funccallF.type = n->funccallF.type;
  assignNodeOpaqueCastState (m, n);
  return m;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   dupSetValue -
*/

static decl_node__opaque dupSetValue (decl_node__opaque n)
{
  decl_node__opaque m;
  unsigned int i;

  m = newNode (decl_setvalue);
  m->setvalueF.type = n->setvalueF.type;
  i = Indexing_LowIndice (n->setvalueF.values);
  while (i <= (Indexing_HighIndice (n->setvalueF.values)))
    {
      m = static_cast<decl_node__opaque> (decl_putSetValue (static_cast<decl_node> (m), decl_dupExpr (static_cast<decl_node> (Indexing_GetIndice (n->setvalueF.values, i)))));
      i += 1;
    }
  return m;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   doDupExpr -
*/

static decl_node__opaque doDupExpr (decl_node__opaque n)
{
  mcDebug_assert (n != NULL);
  switch (n->kind)
    {
      case decl_explist:
        return dupExplist (n);
        break;

      case decl_exit:
      case decl_return:
      case decl_stmtseq:
      case decl_comment:
        M2RTS_HALT (-1);  /* should not be duplicating code.  */
        __builtin_unreachable ();
        break;

      case decl_length:
        M2RTS_HALT (-1);
        __builtin_unreachable ();
        break;

      case decl_nil:
      case decl_true:
      case decl_false:
      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_csizet:
      case decl_cssizet:
      case decl_cofft:
      case decl_cardinal64:
      case decl_boolean:
      case decl_proc:
      case decl_char:
      case decl_integer:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_longint:
      case decl_shortint:
      case decl_real:
      case decl_longreal:
      case decl_shortreal:
      case decl_bitset:
      case decl_ztype:
      case decl_rtype:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
        /* base types.  */
        return n;
        break;

      case decl_type:
      case decl_record:
      case decl_varient:
      case decl_var:
      case decl_enumeration:
      case decl_subrange:
      case decl_subscript:
      case decl_array:
      case decl_string:
      case decl_const:
      case decl_literal:
      case decl_varparam:
      case decl_param:
      case decl_varargs:
      case decl_optarg:
      case decl_pointer:
      case decl_recordfield:
      case decl_varientfield:
      case decl_enumerationfield:
      case decl_set:
      case decl_proctype:
        /* language features and compound type attributes.  */
        return n;
        break;

      case decl_procedure:
      case decl_def:
      case decl_imp:
      case decl_module:
        /* blocks.  */
        return n;
        break;

      case decl_loop:
      case decl_while:
      case decl_for:
      case decl_repeat:
      case decl_case:
      case decl_caselabellist:
      case decl_caselist:
      case decl_range:
      case decl_if:
      case decl_elsif:
      case decl_assignment:
        /* statements.  */
        return n;
        break;

      case decl_arrayref:
        /* expressions.  */
        return dupArrayref (n);
        break;

      case decl_pointerref:
        return dupPointerref (n);
        break;

      case decl_componentref:
        return dupComponentref (n);
        break;

      case decl_cmplx:
      case decl_and:
      case decl_or:
      case decl_equal:
      case decl_notequal:
      case decl_less:
      case decl_greater:
      case decl_greequal:
      case decl_lessequal:
      case decl_cast:
      case decl_val:
      case decl_plus:
      case decl_sub:
      case decl_div:
      case decl_mod:
      case decl_mult:
      case decl_divide:
      case decl_in:
        return dupBinary (n);
        break;

      case decl_re:
      case decl_im:
      case decl_constexp:
      case decl_deref:
      case decl_abs:
      case decl_chr:
      case decl_cap:
      case decl_high:
      case decl_float:
      case decl_trunc:
      case decl_ord:
      case decl_not:
      case decl_neg:
      case decl_adr:
      case decl_size:
      case decl_tsize:
      case decl_min:
      case decl_max:
        return dupUnary (n);
        break;

      case decl_identlist:
        return n;
        break;

      case decl_vardecl:
        return n;
        break;

      case decl_funccall:
        return dupFunccall (n);
        break;

      case decl_setvalue:
        return dupSetValue (n);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   makeSystem -
*/

static void makeSystem (void)
{
  systemN = static_cast<decl_node__opaque> (decl_lookupDef (nameKey_makeKey ((const char *) "SYSTEM", 6)));
  addressN = makeBase (decl_address);
  locN = makeBase (decl_loc);
  byteN = makeBase (decl_byte);
  wordN = makeBase (decl_word);
  csizetN = makeBase (decl_csizet);
  cssizetN = makeBase (decl_cssizet);
  cofftN = makeBase (decl_cofft);
  cardinal64N = makeBase (decl_cardinal64);
  adrN = makeBase (decl_adr);
  tsizeN = makeBase (decl_tsize);
  throwN = makeBase (decl_throw);
  decl_enterScope (static_cast<decl_node> (systemN));
  addressN = addToScope (addressN);
  locN = addToScope (locN);
  byteN = addToScope (byteN);
  wordN = addToScope (wordN);
  csizetN = addToScope (csizetN);
  cssizetN = addToScope (cssizetN);
  cofftN = addToScope (cofftN);
  cardinal64N = addToScope (cardinal64N);
  adrN = addToScope (adrN);
  tsizeN = addToScope (tsizeN);
  throwN = addToScope (throwN);
  mcDebug_assert (sizeN != NULL);  /* assumed to be built already.  */
  sizeN = addToScope (sizeN);  /* also export size from system.  */
  decl_leaveScope ();  /* also export size from system.  */
  addDone (addressN);
  addDone (locN);
  addDone (byteN);
  addDone (wordN);
  addDone (csizetN);
  addDone (cssizetN);
  addDone (cofftN);
  addDone (cardinal64N);
}


/*
   makeM2rts -
*/

static void makeM2rts (void)
{
  m2rtsN = static_cast<decl_node__opaque> (decl_lookupDef (nameKey_makeKey ((const char *) "M2RTS", 5)));
}


/*
   makeBitnum -
*/

static decl_node__opaque makeBitnum (void)
{
  decl_node__opaque b;

  b = newNode (decl_subrange);
  b->subrangeF.type = static_cast<decl_node__opaque> (NULL);
  b->subrangeF.scope = static_cast<decl_node__opaque> (NULL);
  b->subrangeF.low = lookupConst (b, nameKey_makeKey ((const char *) "0", 1));
  b->subrangeF.high = lookupConst (b, nameKey_makeKey ((const char *) "31", 2));
  return b;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeBaseSymbols -
*/

static void makeBaseSymbols (void)
{
  baseSymbols = symbolKey_initTree ();
  booleanN = makeBase (decl_boolean);
  charN = makeBase (decl_char);
  procN = makeBase (decl_proc);
  cardinalN = makeBase (decl_cardinal);
  longcardN = makeBase (decl_longcard);
  shortcardN = makeBase (decl_shortcard);
  integerN = makeBase (decl_integer);
  longintN = makeBase (decl_longint);
  shortintN = makeBase (decl_shortint);
  bitsetN = makeBase (decl_bitset);
  bitnumN = makeBitnum ();
  ztypeN = makeBase (decl_ztype);
  rtypeN = makeBase (decl_rtype);
  complexN = makeBase (decl_complex);
  longcomplexN = makeBase (decl_longcomplex);
  shortcomplexN = makeBase (decl_shortcomplex);
  realN = makeBase (decl_real);
  longrealN = makeBase (decl_longreal);
  shortrealN = makeBase (decl_shortreal);
  nilN = makeBase (decl_nil);
  trueN = makeBase (decl_true);
  falseN = makeBase (decl_false);
  sizeN = makeBase (decl_size);
  minN = makeBase (decl_min);
  maxN = makeBase (decl_max);
  floatN = makeBase (decl_float);
  truncN = makeBase (decl_trunc);
  ordN = makeBase (decl_ord);
  valN = makeBase (decl_val);
  chrN = makeBase (decl_chr);
  capN = makeBase (decl_cap);
  absN = makeBase (decl_abs);
  newN = makeBase (decl_new);
  disposeN = makeBase (decl_dispose);
  lengthN = makeBase (decl_length);
  incN = makeBase (decl_inc);
  decN = makeBase (decl_dec);
  inclN = makeBase (decl_incl);
  exclN = makeBase (decl_excl);
  highN = makeBase (decl_high);
  imN = makeBase (decl_im);
  reN = makeBase (decl_re);
  cmplxN = makeBase (decl_cmplx);
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "BOOLEAN", 7), reinterpret_cast <void *> (booleanN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "PROC", 4), reinterpret_cast <void *> (procN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "CHAR", 4), reinterpret_cast <void *> (charN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "CARDINAL", 8), reinterpret_cast <void *> (cardinalN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "SHORTCARD", 9), reinterpret_cast <void *> (shortcardN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "LONGCARD", 8), reinterpret_cast <void *> (longcardN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "INTEGER", 7), reinterpret_cast <void *> (integerN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "LONGINT", 7), reinterpret_cast <void *> (longintN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "SHORTINT", 8), reinterpret_cast <void *> (shortintN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "BITSET", 6), reinterpret_cast <void *> (bitsetN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "REAL", 4), reinterpret_cast <void *> (realN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "SHORTREAL", 9), reinterpret_cast <void *> (shortrealN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "LONGREAL", 8), reinterpret_cast <void *> (longrealN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "COMPLEX", 7), reinterpret_cast <void *> (complexN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "LONGCOMPLEX", 11), reinterpret_cast <void *> (longcomplexN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "SHORTCOMPLEX", 12), reinterpret_cast <void *> (shortcomplexN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "NIL", 3), reinterpret_cast <void *> (nilN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "TRUE", 4), reinterpret_cast <void *> (trueN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "FALSE", 5), reinterpret_cast <void *> (falseN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "SIZE", 4), reinterpret_cast <void *> (sizeN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "MIN", 3), reinterpret_cast <void *> (minN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "MAX", 3), reinterpret_cast <void *> (maxN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "FLOAT", 5), reinterpret_cast <void *> (floatN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "TRUNC", 5), reinterpret_cast <void *> (truncN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "ORD", 3), reinterpret_cast <void *> (ordN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "VAL", 3), reinterpret_cast <void *> (valN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "CHR", 3), reinterpret_cast <void *> (chrN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "CAP", 3), reinterpret_cast <void *> (capN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "ABS", 3), reinterpret_cast <void *> (absN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "NEW", 3), reinterpret_cast <void *> (newN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "DISPOSE", 7), reinterpret_cast <void *> (disposeN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "LENGTH", 6), reinterpret_cast <void *> (lengthN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "INC", 3), reinterpret_cast <void *> (incN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "DEC", 3), reinterpret_cast <void *> (decN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "INCL", 4), reinterpret_cast <void *> (inclN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "EXCL", 4), reinterpret_cast <void *> (exclN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "HIGH", 4), reinterpret_cast <void *> (highN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "CMPLX", 5), reinterpret_cast <void *> (cmplxN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "RE", 2), reinterpret_cast <void *> (reN));
  symbolKey_putSymKey (baseSymbols, nameKey_makeKey ((const char *) "IM", 2), reinterpret_cast <void *> (imN));
  addDone (booleanN);
  addDone (charN);
  addDone (cardinalN);
  addDone (longcardN);
  addDone (shortcardN);
  addDone (integerN);
  addDone (longintN);
  addDone (shortintN);
  addDone (bitsetN);
  addDone (bitnumN);
  addDone (ztypeN);
  addDone (rtypeN);
  addDone (realN);
  addDone (longrealN);
  addDone (shortrealN);
  addDone (complexN);
  addDone (longcomplexN);
  addDone (shortcomplexN);
  addDone (procN);
  addDone (nilN);
  addDone (trueN);
  addDone (falseN);
}


/*
   makeBuiltins -
*/

static void makeBuiltins (void)
{
  bitsperunitN = static_cast<decl_node__opaque> (decl_makeLiteralInt (nameKey_makeKey ((const char *) "8", 1)));
  bitsperwordN = static_cast<decl_node__opaque> (decl_makeLiteralInt (nameKey_makeKey ((const char *) "32", 2)));
  bitspercharN = static_cast<decl_node__opaque> (decl_makeLiteralInt (nameKey_makeKey ((const char *) "8", 1)));
  unitsperwordN = static_cast<decl_node__opaque> (decl_makeLiteralInt (nameKey_makeKey ((const char *) "4", 1)));
  addDone (bitsperunitN);
  addDone (bitsperwordN);
  addDone (bitspercharN);
  addDone (unitsperwordN);
}


/*
   makeCDataTypes - assign the charStarN and constCharStarN to NIL.
*/

static void makeCDataTypes (void)
{
  decl_node__opaque CdatatypesN;

  CdatatypesN = static_cast<decl_node__opaque> (decl_lookupDef (nameKey_makeKey ((const char *) "CDataTypes", 10)));
  decl_enterScope (static_cast<decl_node> (CdatatypesN));
  charStarN = static_cast<decl_node__opaque> (decl_makePointer (static_cast<decl_node> (charN)));
  constCharStarN = static_cast<decl_node__opaque> (decl_makePointer (static_cast<decl_node> (charN)));
  decl_leaveScope ();
}


/*
   init -
*/

static void init (void)
{
  lang = decl_ansiC;
  outputFile = FIO_StdOut;
  doP = mcPretty_initPretty ((mcPretty_writeProc) {(mcPretty_writeProc_t) write_}, (mcPretty_writeLnProc) {(mcPretty_writeLnProc_t) writeln});
  freeGroup = NULL;
  globalGroup = initGroup ();
  modUniverse = symbolKey_initTree ();
  defUniverse = symbolKey_initTree ();
  modUniverseI = Indexing_InitIndex (1);
  defUniverseI = Indexing_InitIndex (1);
  scopeStack = Indexing_InitIndex (1);
  makeBaseSymbols ();
  makeSystem ();
  makeBuiltins ();
  makeM2rts ();
  outputState = decl_punct;
  tempCount = 0;
  mustVisitScope = false;
  makeCDataTypes ();
}


/*
   getDeclaredMod - returns the token number associated with the nodes declaration
                    in the implementation or program module.
*/

extern "C" unsigned int decl_getDeclaredMod (decl_node n)
{
  return static_cast<decl_node__opaque> (n)->at.modDeclared;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getDeclaredDef - returns the token number associated with the nodes declaration
                    in the definition module.
*/

extern "C" unsigned int decl_getDeclaredDef (decl_node n)
{
  return static_cast<decl_node__opaque> (n)->at.defDeclared;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getFirstUsed - returns the token number associated with the first use of
                  node, n.
*/

extern "C" unsigned int decl_getFirstUsed (decl_node n)
{
  return static_cast<decl_node__opaque> (n)->at.firstUsed;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isDef - return TRUE if node, n, is a definition module.
*/

extern "C" bool decl_isDef (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_def;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isImp - return TRUE if node, n, is an implementation module.
*/

extern "C" bool decl_isImp (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_imp;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isImpOrModule - returns TRUE if, n, is a program module or implementation module.
*/

extern "C" bool decl_isImpOrModule (decl_node n)
{
  return (decl_isImp (n)) || (decl_isModule (n));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isVisited - returns TRUE if the node was visited.
*/

extern "C" bool decl_isVisited (decl_node n)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_def:
        return static_cast<decl_node__opaque> (n)->defF.visited;
        break;

      case decl_imp:
        return static_cast<decl_node__opaque> (n)->impF.visited;
        break;

      case decl_module:
        return static_cast<decl_node__opaque> (n)->moduleF.visited;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   unsetVisited - unset the visited flag on a def/imp/module node.
*/

extern "C" void decl_unsetVisited (decl_node n)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_def:
        static_cast<decl_node__opaque> (n)->defF.visited = false;
        break;

      case decl_imp:
        static_cast<decl_node__opaque> (n)->impF.visited = false;
        break;

      case decl_module:
        static_cast<decl_node__opaque> (n)->moduleF.visited = false;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   setVisited - set the visited flag on a def/imp/module node.
*/

extern "C" void decl_setVisited (decl_node n)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_def:
        static_cast<decl_node__opaque> (n)->defF.visited = true;
        break;

      case decl_imp:
        static_cast<decl_node__opaque> (n)->impF.visited = true;
        break;

      case decl_module:
        static_cast<decl_node__opaque> (n)->moduleF.visited = true;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   setEnumsComplete - sets the field inside the def or imp or module, n.
*/

extern "C" void decl_setEnumsComplete (decl_node n)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_def:
        static_cast<decl_node__opaque> (n)->defF.enumsComplete = true;
        break;

      case decl_imp:
        static_cast<decl_node__opaque> (n)->impF.enumsComplete = true;
        break;

      case decl_module:
        static_cast<decl_node__opaque> (n)->moduleF.enumsComplete = true;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   getEnumsComplete - gets the field from the def or imp or module, n.
*/

extern "C" bool decl_getEnumsComplete (decl_node n)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_def:
        return static_cast<decl_node__opaque> (n)->defF.enumsComplete;
        break;

      case decl_imp:
        return static_cast<decl_node__opaque> (n)->impF.enumsComplete;
        break;

      case decl_module:
        return static_cast<decl_node__opaque> (n)->moduleF.enumsComplete;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   resetEnumPos - resets the index into the saved list of enums inside
                  module, n.
*/

extern "C" void decl_resetEnumPos (decl_node n)
{
  mcDebug_assert (((decl_isDef (n)) || (decl_isImp (n))) || (decl_isModule (n)));
  if (decl_isDef (n))
    {
      static_cast<decl_node__opaque> (n)->defF.enumFixup.count = 0;
    }
  else if (decl_isImp (n))
    {
      /* avoid dangling else.  */
      static_cast<decl_node__opaque> (n)->impF.enumFixup.count = 0;
    }
  else if (decl_isModule (n))
    {
      /* avoid dangling else.  */
      static_cast<decl_node__opaque> (n)->moduleF.enumFixup.count = 0;
    }
}


/*
   getNextEnum - returns the next enumeration node.
*/

extern "C" decl_node decl_getNextEnum (void)
{
  decl_node__opaque n;

  n = static_cast<decl_node__opaque> (NULL);
  mcDebug_assert (((decl_isDef (static_cast<decl_node> (currentModule))) || (decl_isImp (static_cast<decl_node> (currentModule)))) || (decl_isModule (static_cast<decl_node> (currentModule))));
  if (decl_isDef (static_cast<decl_node> (currentModule)))
    {
      n = getNextFixup (&currentModule->defF.enumFixup);
    }
  else if (decl_isImp (static_cast<decl_node> (currentModule)))
    {
      /* avoid dangling else.  */
      n = getNextFixup (&currentModule->impF.enumFixup);
    }
  else if (decl_isModule (static_cast<decl_node> (currentModule)))
    {
      /* avoid dangling else.  */
      n = getNextFixup (&currentModule->moduleF.enumFixup);
    }
  mcDebug_assert (n != NULL);
  mcDebug_assert ((decl_isEnumeration (static_cast<decl_node> (n))) || (decl_isEnumerationField (static_cast<decl_node> (n))));
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isModule - return TRUE if node, n, is a program module.
*/

extern "C" bool decl_isModule (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_module;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isMainModule - return TRUE if node, n, is the main module specified
                  by the source file.  This might be a definition,
                  implementation or program module.
*/

extern "C" bool decl_isMainModule (decl_node n)
{
  mcDebug_assert (n != NULL);
  return n == mainModule;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   setMainModule - sets node, n, as the main module to be compiled.
*/

extern "C" void decl_setMainModule (decl_node n)
{
  mcDebug_assert (n != NULL);
  mainModule = static_cast<decl_node__opaque> (n);
}


/*
   setCurrentModule - sets node, n, as the current module being compiled.
*/

extern "C" void decl_setCurrentModule (decl_node n)
{
  mcDebug_assert (n != NULL);
  currentModule = static_cast<decl_node__opaque> (n);
}


/*
   lookupDef - returns a definition module node named, n.
*/

extern "C" decl_node decl_lookupDef (nameKey_Name n)
{
  decl_node__opaque d;

  d = static_cast<decl_node__opaque> (symbolKey_getSymKey (defUniverse, n));
  if (d == NULL)
    {
      d = makeDef (n);
      symbolKey_putSymKey (defUniverse, n, reinterpret_cast <void *> (d));
      Indexing_IncludeIndiceIntoIndex (defUniverseI, reinterpret_cast <void *> (d));
    }
  return static_cast<decl_node> (d);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   lookupImp - returns an implementation module node named, n.
*/

extern "C" decl_node decl_lookupImp (nameKey_Name n)
{
  decl_node__opaque m;

  m = static_cast<decl_node__opaque> (symbolKey_getSymKey (modUniverse, n));
  if (m == NULL)
    {
      m = makeImp (n);
      symbolKey_putSymKey (modUniverse, n, reinterpret_cast <void *> (m));
      Indexing_IncludeIndiceIntoIndex (modUniverseI, reinterpret_cast <void *> (m));
    }
  mcDebug_assert (! (decl_isModule (static_cast<decl_node> (m))));
  return static_cast<decl_node> (m);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   lookupModule - returns a module node named, n.
*/

extern "C" decl_node decl_lookupModule (nameKey_Name n)
{
  decl_node__opaque m;

  m = static_cast<decl_node__opaque> (symbolKey_getSymKey (modUniverse, n));
  if (m == NULL)
    {
      m = makeModule (n);
      symbolKey_putSymKey (modUniverse, n, reinterpret_cast <void *> (m));
      Indexing_IncludeIndiceIntoIndex (modUniverseI, reinterpret_cast <void *> (m));
    }
  mcDebug_assert (! (decl_isImp (static_cast<decl_node> (m))));
  return static_cast<decl_node> (m);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putDefForC - the definition module was defined FOR "C".
*/

extern "C" void decl_putDefForC (decl_node n)
{
  mcDebug_assert (decl_isDef (n));
  static_cast<decl_node__opaque> (n)->defF.forC = true;
}


/*
   putDefUnqualified - the definition module uses unqualified.
*/

extern "C" void decl_putDefUnqualified (decl_node n)
{
  mcDebug_assert (decl_isDef (n));
  /* Currently (and this is a temporary development restriction to
      reduce any search space for bugs) the only module which can be
      export unqualified is gcctypes.  */
  if (static_cast<decl_node__opaque> (n)->defF.name == (nameKey_makeKey ((const char *) "gcctypes", 8)))
    {
      static_cast<decl_node__opaque> (n)->defF.unqualified = true;
    }
}


/*
   isDefUnqualified - returns TRUE if the definition module uses unqualified.
*/

extern "C" bool decl_isDefUnqualified (decl_node n)
{
  return (decl_isDef (n)) && static_cast<decl_node__opaque> (n)->defF.unqualified;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   lookupInScope - looks up a symbol named, n, from, scope.
*/

extern "C" decl_node decl_lookupInScope (decl_node scope, nameKey_Name n)
{
  switch (static_cast<decl_node__opaque> (scope)->kind)
    {
      case decl_def:
        return static_cast<decl_node> (symbolKey_getSymKey (static_cast<decl_node__opaque> (scope)->defF.decls.symbols, n));
        break;

      case decl_module:
        return static_cast<decl_node> (symbolKey_getSymKey (static_cast<decl_node__opaque> (scope)->moduleF.decls.symbols, n));
        break;

      case decl_imp:
        return static_cast<decl_node> (symbolKey_getSymKey (static_cast<decl_node__opaque> (scope)->impF.decls.symbols, n));
        break;

      case decl_procedure:
        return static_cast<decl_node> (symbolKey_getSymKey (static_cast<decl_node__opaque> (scope)->procedureF.decls.symbols, n));
        break;

      case decl_record:
        return static_cast<decl_node> (symbolKey_getSymKey (static_cast<decl_node__opaque> (scope)->recordF.localSymbols, n));
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isConst - returns TRUE if node, n, is a const.
*/

extern "C" bool decl_isConst (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_const;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isType - returns TRUE if node, n, is a type.
*/

extern "C" bool decl_isType (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_type;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putType - places, exp, as the type alias to des.
             TYPE des = exp ;
*/

extern "C" void decl_putType (decl_node des, decl_node exp)
{
  mcDebug_assert (des != NULL);
  mcDebug_assert (decl_isType (des));
  static_cast<decl_node__opaque> (des)->typeF.type = static_cast<decl_node__opaque> (exp);
}


/*
   getType - returns the type associated with node, n.
*/

extern "C" decl_node decl_getType (decl_node n)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_new:
      case decl_dispose:
        return static_cast<decl_node> (NULL);
        break;

      case decl_length:
        return static_cast<decl_node> (cardinalN);
        break;

      case decl_inc:
      case decl_dec:
      case decl_incl:
      case decl_excl:
        return static_cast<decl_node> (NULL);
        break;

      case decl_nil:
        return static_cast<decl_node> (addressN);
        break;

      case decl_true:
      case decl_false:
        return static_cast<decl_node> (booleanN);
        break;

      case decl_address:
        return n;
        break;

      case decl_loc:
        return n;
        break;

      case decl_byte:
        return n;
        break;

      case decl_word:
        return n;
        break;

      case decl_csizet:
        return n;
        break;

      case decl_cssizet:
        return n;
        break;

      case decl_cofft:
        return n;
        break;

      case decl_cardinal64:
        return n;
        break;

      case decl_boolean:
        /* base types.  */
        return n;
        break;

      case decl_proc:
        return n;
        break;

      case decl_char:
        return n;
        break;

      case decl_cardinal:
        return n;
        break;

      case decl_longcard:
        return n;
        break;

      case decl_shortcard:
        return n;
        break;

      case decl_integer:
        return n;
        break;

      case decl_longint:
        return n;
        break;

      case decl_shortint:
        return n;
        break;

      case decl_real:
        return n;
        break;

      case decl_longreal:
        return n;
        break;

      case decl_shortreal:
        return n;
        break;

      case decl_bitset:
        return n;
        break;

      case decl_ztype:
        return n;
        break;

      case decl_rtype:
        return n;
        break;

      case decl_complex:
        return n;
        break;

      case decl_longcomplex:
        return n;
        break;

      case decl_shortcomplex:
        return n;
        break;

      case decl_type:
        /* language features and compound type attributes.  */
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->typeF.type);
        break;

      case decl_record:
        return n;
        break;

      case decl_varient:
        return n;
        break;

      case decl_var:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->varF.type);
        break;

      case decl_enumeration:
        return n;
        break;

      case decl_subrange:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->subrangeF.type);
        break;

      case decl_array:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->arrayF.type);
        break;

      case decl_string:
        return static_cast<decl_node> (charN);
        break;

      case decl_const:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->constF.type);
        break;

      case decl_literal:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->literalF.type);
        break;

      case decl_varparam:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->varparamF.type);
        break;

      case decl_param:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->paramF.type);
        break;

      case decl_optarg:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->optargF.type);
        break;

      case decl_pointer:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->pointerF.type);
        break;

      case decl_recordfield:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->recordfieldF.type);
        break;

      case decl_varientfield:
        return n;
        break;

      case decl_enumerationfield:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->enumerationfieldF.type);
        break;

      case decl_set:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->setF.type);
        break;

      case decl_proctype:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->proctypeF.returnType);
        break;

      case decl_subscript:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->subscriptF.type);
        break;

      case decl_procedure:
        /* blocks.  */
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->procedureF.returnType);
        break;

      case decl_throw:
        return static_cast<decl_node> (NULL);
        break;

      case decl_unreachable:
        return static_cast<decl_node> (NULL);
        break;

      case decl_def:
      case decl_imp:
      case decl_module:
      case decl_loop:
      case decl_while:
      case decl_for:
      case decl_repeat:
      case decl_if:
      case decl_elsif:
      case decl_assignment:
        /* statements.  */
        M2RTS_HALT (-1);
        __builtin_unreachable ();
        break;

      case decl_cmplx:
      case decl_cast:
      case decl_val:
      case decl_plus:
      case decl_sub:
      case decl_div:
      case decl_mod:
      case decl_mult:
      case decl_divide:
        /* expressions.  */
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->binaryF.resultType);
        break;

      case decl_in:
        return static_cast<decl_node> (booleanN);
        break;

      case decl_max:
      case decl_min:
      case decl_re:
      case decl_im:
      case decl_abs:
      case decl_constexp:
      case decl_deref:
      case decl_neg:
      case decl_adr:
      case decl_size:
      case decl_tsize:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->unaryF.resultType);
        break;

      case decl_and:
      case decl_or:
      case decl_not:
      case decl_equal:
      case decl_notequal:
      case decl_less:
      case decl_greater:
      case decl_greequal:
      case decl_lessequal:
        return static_cast<decl_node> (booleanN);
        break;

      case decl_trunc:
        return static_cast<decl_node> (integerN);
        break;

      case decl_float:
        return static_cast<decl_node> (realN);
        break;

      case decl_high:
        return static_cast<decl_node> (cardinalN);
        break;

      case decl_ord:
        return static_cast<decl_node> (cardinalN);
        break;

      case decl_chr:
        return static_cast<decl_node> (charN);
        break;

      case decl_cap:
        return static_cast<decl_node> (charN);
        break;

      case decl_arrayref:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->arrayrefF.resultType);
        break;

      case decl_componentref:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->componentrefF.resultType);
        break;

      case decl_pointerref:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->pointerrefF.resultType);
        break;

      case decl_funccall:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->funccallF.type);
        break;

      case decl_setvalue:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->setvalueF.type);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  M2RTS_HALT (-1);
  __builtin_unreachable ();
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   skipType - skips over type aliases.
*/

extern "C" decl_node decl_skipType (decl_node n)
{
  while (((n != NULL) && (decl_isType (n))) && (! (isCDataType (static_cast<decl_node__opaque> (n)))))
    {
      if ((decl_getType (n)) == NULL)
        {
          /* this will occur if, n, is an opaque type.  */
          return n;
        }
      n = decl_getType (n);
    }
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putTypeHidden - marks type, des, as being a hidden type.
                   TYPE des ;
*/

extern "C" void decl_putTypeHidden (decl_node des)
{
  decl_node__opaque s;

  mcDebug_assert (des != NULL);
  mcDebug_assert (decl_isType (des));
  static_cast<decl_node__opaque> (des)->typeF.isHidden = true;
  s = static_cast<decl_node__opaque> (decl_getScope (des));
  mcDebug_assert (decl_isDef (static_cast<decl_node> (s)));
  s->defF.hasHidden = true;
}


/*
   isTypeHidden - returns TRUE if type, n, is hidden.
*/

extern "C" bool decl_isTypeHidden (decl_node n)
{
  mcDebug_assert (n != NULL);
  mcDebug_assert (decl_isType (n));
  return static_cast<decl_node__opaque> (n)->typeF.isHidden;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   hasHidden - returns TRUE if module, n, has a hidden type.
*/

extern "C" bool decl_hasHidden (decl_node n)
{
  mcDebug_assert (decl_isDef (n));
  return static_cast<decl_node__opaque> (n)->defF.hasHidden;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putTypeOpaque - marks type, des, as being an opaque type.
                   TYPE des ;
*/

extern "C" void decl_putTypeOpaque (decl_node des)
{
  decl_node__opaque s;

  mcDebug_assert (des != NULL);
  mcDebug_assert (decl_isType (des));
  static_cast<decl_node__opaque> (des)->typeF.isOpaque = true;
}


/*
   isTypeOpaque - returns TRUE if type, n, is an opaque type.
*/

extern "C" bool decl_isTypeOpaque (decl_node n)
{
  mcDebug_assert (n != NULL);
  mcDebug_assert (decl_isType (n));
  return static_cast<decl_node__opaque> (n)->typeF.isOpaque;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isVar - returns TRUE if node, n, is a type.
*/

extern "C" bool decl_isVar (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_var;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isTemporary - returns TRUE if node, n, is a variable and temporary.
*/

extern "C" bool decl_isTemporary (decl_node n)
{
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isExported - returns TRUE if symbol, n, is exported from
                the definition module.
*/

extern "C" bool decl_isExported (decl_node n)
{
  decl_node__opaque s;

  s = static_cast<decl_node__opaque> (decl_getScope (n));
  if (s != NULL)
    {
      switch (s->kind)
        {
          case decl_def:
            return Indexing_IsIndiceInIndex (s->defF.exported, reinterpret_cast <void *> (n));
            break;


          default:
            return false;
            break;
        }
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getDeclScope - returns the node representing the
                  current declaration scope.
*/

extern "C" decl_node decl_getDeclScope (void)
{
  unsigned int i;

  i = Indexing_HighIndice (scopeStack);
  return static_cast<decl_node> (Indexing_GetIndice (scopeStack, i));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getScope - returns the scope associated with node, n.
*/

extern "C" decl_node decl_getScope (decl_node n)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_stmtseq:
      case decl_exit:
      case decl_return:
      case decl_comment:
      case decl_identlist:
      case decl_setvalue:
      case decl_halt:
      case decl_new:
      case decl_dispose:
      case decl_length:
      case decl_inc:
      case decl_dec:
      case decl_incl:
      case decl_excl:
      case decl_nil:
      case decl_true:
      case decl_false:
        return static_cast<decl_node> (NULL);
        break;

      case decl_address:
      case decl_loc:
      case decl_byte:
      case decl_word:
      case decl_csizet:
      case decl_cssizet:
      case decl_cofft:
      case decl_cardinal64:
        return static_cast<decl_node> (systemN);
        break;

      case decl_boolean:
      case decl_proc:
      case decl_char:
      case decl_cardinal:
      case decl_longcard:
      case decl_shortcard:
      case decl_integer:
      case decl_longint:
      case decl_shortint:
      case decl_real:
      case decl_longreal:
      case decl_shortreal:
      case decl_bitset:
      case decl_ztype:
      case decl_rtype:
      case decl_complex:
      case decl_longcomplex:
      case decl_shortcomplex:
        /* base types.  */
        return static_cast<decl_node> (NULL);
        break;

      case decl_type:
        /* language features and compound type attributes.  */
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->typeF.scope);
        break;

      case decl_record:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->recordF.scope);
        break;

      case decl_varient:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->varientF.scope);
        break;

      case decl_var:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->varF.scope);
        break;

      case decl_enumeration:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->enumerationF.scope);
        break;

      case decl_subrange:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->subrangeF.scope);
        break;

      case decl_array:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->arrayF.scope);
        break;

      case decl_string:
        return static_cast<decl_node> (NULL);
        break;

      case decl_const:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->constF.scope);
        break;

      case decl_literal:
        return static_cast<decl_node> (NULL);
        break;

      case decl_varparam:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->varparamF.scope);
        break;

      case decl_param:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->paramF.scope);
        break;

      case decl_optarg:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->optargF.scope);
        break;

      case decl_pointer:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->pointerF.scope);
        break;

      case decl_recordfield:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->recordfieldF.scope);
        break;

      case decl_varientfield:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->varientfieldF.scope);
        break;

      case decl_enumerationfield:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->enumerationfieldF.scope);
        break;

      case decl_set:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->setF.scope);
        break;

      case decl_proctype:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->proctypeF.scope);
        break;

      case decl_subscript:
        return static_cast<decl_node> (NULL);
        break;

      case decl_procedure:
        /* blocks.  */
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->procedureF.scope);
        break;

      case decl_def:
      case decl_imp:
      case decl_module:
      case decl_case:
      case decl_loop:
      case decl_while:
      case decl_for:
      case decl_repeat:
      case decl_if:
      case decl_elsif:
      case decl_assignment:
        /* statements.  */
        return static_cast<decl_node> (NULL);
        break;

      case decl_componentref:
      case decl_pointerref:
      case decl_arrayref:
      case decl_chr:
      case decl_cap:
      case decl_ord:
      case decl_float:
      case decl_trunc:
      case decl_high:
      case decl_cast:
      case decl_val:
      case decl_plus:
      case decl_sub:
      case decl_div:
      case decl_mod:
      case decl_mult:
      case decl_divide:
      case decl_in:
        /* expressions.  */
        return static_cast<decl_node> (NULL);
        break;

      case decl_neg:
        return static_cast<decl_node> (NULL);
        break;

      case decl_lsl:
      case decl_lsr:
      case decl_lor:
      case decl_land:
      case decl_lnot:
      case decl_lxor:
      case decl_and:
      case decl_or:
      case decl_not:
      case decl_constexp:
      case decl_deref:
      case decl_equal:
      case decl_notequal:
      case decl_less:
      case decl_greater:
      case decl_greequal:
      case decl_lessequal:
        return static_cast<decl_node> (NULL);
        break;

      case decl_adr:
      case decl_size:
      case decl_tsize:
      case decl_throw:
        return static_cast<decl_node> (systemN);
        break;

      case decl_unreachable:
      case decl_cmplx:
      case decl_re:
      case decl_im:
      case decl_min:
      case decl_max:
        return static_cast<decl_node> (NULL);
        break;

      case decl_vardecl:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->vardeclF.scope);
        break;

      case decl_funccall:
        return static_cast<decl_node> (NULL);
        break;

      case decl_explist:
        return static_cast<decl_node> (NULL);
        break;

      case decl_caselabellist:
        return static_cast<decl_node> (NULL);
        break;

      case decl_caselist:
        return static_cast<decl_node> (NULL);
        break;

      case decl_range:
        return static_cast<decl_node> (NULL);
        break;

      case decl_varargs:
        return static_cast<decl_node> (static_cast<decl_node__opaque> (n)->varargsF.scope);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLiteral - returns TRUE if, n, is a literal.
*/

extern "C" bool decl_isLiteral (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_literal;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isConstSet - returns TRUE if, n, is a constant set.
*/

extern "C" bool decl_isConstSet (decl_node n)
{
  mcDebug_assert (n != NULL);
  if ((decl_isLiteral (n)) || (decl_isConst (n)))
    {
      return decl_isSet (decl_skipType (decl_getType (n)));
    }
  return false;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isEnumerationField - returns TRUE if, n, is an enumeration field.
*/

extern "C" bool decl_isEnumerationField (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_enumerationfield;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isEnumeration - returns TRUE if node, n, is an enumeration type.
*/

extern "C" bool decl_isEnumeration (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_enumeration;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isUnbounded - returns TRUE if, n, is an unbounded array.
*/

extern "C" bool decl_isUnbounded (decl_node n)
{
  mcDebug_assert (n != NULL);
  return (static_cast<decl_node__opaque> (n)->kind == decl_array) && static_cast<decl_node__opaque> (n)->arrayF.isUnbounded;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isParameter - returns TRUE if, n, is a parameter.
*/

extern "C" bool decl_isParameter (decl_node n)
{
  mcDebug_assert (n != NULL);
  return (static_cast<decl_node__opaque> (n)->kind == decl_param) || (static_cast<decl_node__opaque> (n)->kind == decl_varparam);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isVarParam - returns TRUE if, n, is a var parameter.
*/

extern "C" bool decl_isVarParam (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_varparam;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isParam - returns TRUE if, n, is a non var parameter.
*/

extern "C" bool decl_isParam (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_param;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isNonVarParam - is an alias to isParam.
*/

extern "C" bool decl_isNonVarParam (decl_node n)
{
  return decl_isParam (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   addOptParameter - returns an optarg which has been created and added to
                     procedure node, proc.  It has a name, id, and, type,
                     and an initial value, init.
*/

extern "C" decl_node decl_addOptParameter (decl_node proc, nameKey_Name id, decl_node type, decl_node init)
{
  decl_node__opaque p;
  decl_node__opaque l;

  mcDebug_assert (decl_isProcedure (proc));
  l = static_cast<decl_node__opaque> (decl_makeIdentList ());
  mcDebug_assert (decl_putIdent (static_cast<decl_node> (l), id));
  checkMakeVariables (static_cast<decl_node__opaque> (proc), l, static_cast<decl_node__opaque> (type), false, true);
  if (! static_cast<decl_node__opaque> (proc)->procedureF.checking)
    {
      p = makeOptParameter (l, static_cast<decl_node__opaque> (type), static_cast<decl_node__opaque> (init));
      decl_addParameter (proc, static_cast<decl_node> (p));
    }
  return static_cast<decl_node> (p);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isOptarg - returns TRUE if, n, is an optarg.
*/

extern "C" bool decl_isOptarg (decl_node n)
{
  return static_cast<decl_node__opaque> (n)->kind == decl_optarg;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isRecord - returns TRUE if, n, is a record.
*/

extern "C" bool decl_isRecord (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_record;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isRecordField - returns TRUE if, n, is a record field.
*/

extern "C" bool decl_isRecordField (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_recordfield;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isVarientField - returns TRUE if, n, is a varient field.
*/

extern "C" bool decl_isVarientField (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_varientfield;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isArray - returns TRUE if, n, is an array.
*/

extern "C" bool decl_isArray (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_array;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isProcType - returns TRUE if, n, is a procedure type.
*/

extern "C" bool decl_isProcType (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_proctype;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isPointer - returns TRUE if, n, is a pointer.
*/

extern "C" bool decl_isPointer (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_pointer;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isProcedure - returns TRUE if node, n, is a procedure.
*/

extern "C" bool decl_isProcedure (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_procedure;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isVarient - returns TRUE if, n, is a varient record.
*/

extern "C" bool decl_isVarient (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_varient;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isSet - returns TRUE if, n, is a set type.
*/

extern "C" bool decl_isSet (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_set;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isSubrange - returns TRUE if, n, is a subrange type.
*/

extern "C" bool decl_isSubrange (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_subrange;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isZtype - returns TRUE if, n, is the Z type.
*/

extern "C" bool decl_isZtype (decl_node n)
{
  return n == ztypeN;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isRtype - returns TRUE if, n, is the R type.
*/

extern "C" bool decl_isRtype (decl_node n)
{
  return n == rtypeN;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeConst - create, initialise and return a const node.
*/

extern "C" decl_node decl_makeConst (nameKey_Name n)
{
  decl_node__opaque d;

  d = newNode (decl_const);
  d->constF.name = n;
  d->constF.type = static_cast<decl_node__opaque> (NULL);
  d->constF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  d->constF.value = static_cast<decl_node__opaque> (NULL);
  return static_cast<decl_node> (addToScope (d));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putConst - places value, v, into node, n.
*/

extern "C" void decl_putConst (decl_node n, decl_node v)
{
  mcDebug_assert (decl_isConst (n));
  static_cast<decl_node__opaque> (n)->constF.value = static_cast<decl_node__opaque> (v);
}


/*
   makeType - create, initialise and return a type node.
*/

extern "C" decl_node decl_makeType (nameKey_Name n)
{
  decl_node__opaque d;

  d = newNode (decl_type);
  d->typeF.name = n;
  d->typeF.type = static_cast<decl_node__opaque> (NULL);
  d->typeF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  d->typeF.isOpaque = false;
  d->typeF.isHidden = false;
  d->typeF.isInternal = false;
  return static_cast<decl_node> (addToScope (d));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeTypeImp - lookup a type in the definition module
                 and return it.  Otherwise create a new type.
*/

extern "C" decl_node decl_makeTypeImp (nameKey_Name n)
{
  decl_node__opaque d;

  d = static_cast<decl_node__opaque> (decl_lookupSym (n));
  if (d != NULL)
    {
      d->typeF.isHidden = false;
      return static_cast<decl_node> (addToScope (d));
    }
  else
    {
      d = newNode (decl_type);
      d->typeF.name = n;
      d->typeF.type = static_cast<decl_node__opaque> (NULL);
      d->typeF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
      d->typeF.isOpaque = false;
      d->typeF.isHidden = false;
      return static_cast<decl_node> (addToScope (d));
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeVar - create, initialise and return a var node.
*/

extern "C" decl_node decl_makeVar (nameKey_Name n)
{
  decl_node__opaque d;

  d = newNode (decl_var);
  d->varF.name = n;
  d->varF.type = static_cast<decl_node__opaque> (NULL);
  d->varF.decl = static_cast<decl_node__opaque> (NULL);
  d->varF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  d->varF.isInitialised = false;
  d->varF.isParameter = false;
  d->varF.isVarParameter = false;
  initCname (&d->varF.cname);
  return static_cast<decl_node> (addToScope (d));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putVar - places, type, as the type for var.
*/

extern "C" void decl_putVar (decl_node var, decl_node type, decl_node decl)
{
  mcDebug_assert (var != NULL);
  mcDebug_assert (decl_isVar (var));
  static_cast<decl_node__opaque> (var)->varF.type = static_cast<decl_node__opaque> (type);
  static_cast<decl_node__opaque> (var)->varF.decl = static_cast<decl_node__opaque> (decl);
  initNodeOpaqueState (static_cast<decl_node__opaque> (var));
}


/*
   makeVarDecl - create a vardecl node and create a shadow variable in the
                 current scope.
*/

extern "C" decl_node decl_makeVarDecl (decl_node i, decl_node type)
{
  decl_node__opaque d;
  decl_node__opaque v;
  unsigned int j;
  unsigned int n;

  type = static_cast<decl_node> (checkPtr (static_cast<decl_node__opaque> (type)));
  d = newNode (decl_vardecl);
  d->vardeclF.names = static_cast<decl_node__opaque> (i)->identlistF.names;
  d->vardeclF.type = static_cast<decl_node__opaque> (type);
  d->vardeclF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  n = wlists_noOfItemsInList (d->vardeclF.names);
  j = 1;
  while (j <= n)
    {
      v = static_cast<decl_node__opaque> (decl_lookupSym (wlists_getItemFromList (d->vardeclF.names, j)));
      mcDebug_assert (decl_isVar (static_cast<decl_node> (v)));
      decl_putVar (static_cast<decl_node> (v), type, static_cast<decl_node> (d));
      j += 1;
    }
  return static_cast<decl_node> (d);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeEnum - creates an enumerated type and returns the node.
*/

extern "C" decl_node decl_makeEnum (void)
{
  if ((currentModule != NULL) && (decl_getEnumsComplete (static_cast<decl_node> (currentModule))))
    {
      return decl_getNextEnum ();
    }
  else
    {
      return static_cast<decl_node> (doMakeEnum ());
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeEnumField - returns an enumeration field, named, n.
*/

extern "C" decl_node decl_makeEnumField (decl_node e, nameKey_Name n)
{
  if ((currentModule != NULL) && (decl_getEnumsComplete (static_cast<decl_node> (currentModule))))
    {
      return decl_getNextEnum ();
    }
  else
    {
      return static_cast<decl_node> (doMakeEnumField (static_cast<decl_node__opaque> (e), n));
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeSubrange - returns a subrange node, built from range: low..high.
*/

extern "C" decl_node decl_makeSubrange (decl_node low, decl_node high)
{
  decl_node__opaque n;

  n = newNode (decl_subrange);
  n->subrangeF.low = static_cast<decl_node__opaque> (low);
  n->subrangeF.high = static_cast<decl_node__opaque> (high);
  n->subrangeF.type = static_cast<decl_node__opaque> (NULL);
  n->subrangeF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putSubrangeType - assigns, type, to the subrange type, sub.
*/

extern "C" void decl_putSubrangeType (decl_node sub, decl_node type)
{
  mcDebug_assert (decl_isSubrange (sub));
  static_cast<decl_node__opaque> (sub)->subrangeF.type = static_cast<decl_node__opaque> (type);
}


/*
   makePointer - returns a pointer of, type, node.
*/

extern "C" decl_node decl_makePointer (decl_node type)
{
  decl_node__opaque n;

  n = newNode (decl_pointer);
  n->pointerF.type = static_cast<decl_node__opaque> (type);
  n->pointerF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeSet - returns a set of, type, node.
*/

extern "C" decl_node decl_makeSet (decl_node type)
{
  decl_node__opaque n;

  n = newNode (decl_set);
  n->setF.type = static_cast<decl_node__opaque> (type);
  n->setF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeArray - returns a node representing ARRAY subr OF type.
*/

extern "C" decl_node decl_makeArray (decl_node subr, decl_node type)
{
  decl_node__opaque n;
  decl_node__opaque s;

  s = static_cast<decl_node__opaque> (decl_skipType (subr));
  mcDebug_assert (((decl_isSubrange (static_cast<decl_node> (s))) || (isOrdinal (s))) || (decl_isEnumeration (static_cast<decl_node> (s))));
  n = newNode (decl_array);
  n->arrayF.subr = static_cast<decl_node__opaque> (subr);
  n->arrayF.type = static_cast<decl_node__opaque> (type);
  n->arrayF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  n->arrayF.isUnbounded = false;
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putUnbounded - sets array, n, as unbounded.
*/

extern "C" void decl_putUnbounded (decl_node n)
{
  mcDebug_assert (static_cast<decl_node__opaque> (n)->kind == decl_array);
  static_cast<decl_node__opaque> (n)->arrayF.isUnbounded = true;
}


/*
   makeRecord - creates and returns a record node.
*/

extern "C" decl_node decl_makeRecord (void)
{
  decl_node__opaque n;

  n = newNode (decl_record);
  n->recordF.localSymbols = symbolKey_initTree ();
  n->recordF.listOfSons = Indexing_InitIndex (1);
  n->recordF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeVarient - creates a new symbol, a varient symbol for record or varient field
                 symbol, r.
*/

extern "C" decl_node decl_makeVarient (decl_node r)
{
  decl_node__opaque n;

  n = newNode (decl_varient);
  n->varientF.listOfSons = Indexing_InitIndex (1);
  /* if so use this   n^.varientF.parent := r  */
  if (decl_isRecord (r))
    {
      n->varientF.varient = static_cast<decl_node__opaque> (NULL);
    }
  else
    {
      n->varientF.varient = static_cast<decl_node__opaque> (r);
    }
  n->varientF.tag = static_cast<decl_node__opaque> (NULL);
  n->varientF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  switch (static_cast<decl_node__opaque> (r)->kind)
    {
      case decl_record:
        /* now add, n, to the record/varient, r, field list  */
        Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (r)->recordF.listOfSons, reinterpret_cast <void *> (n));
        break;

      case decl_varientfield:
        Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (r)->varientfieldF.listOfSons, reinterpret_cast <void *> (n));
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   addFieldsToRecord - adds fields, i, of type, t, into a record, r.
                       It returns, r.
*/

extern "C" decl_node decl_addFieldsToRecord (decl_node r, decl_node v, decl_node i, decl_node t)
{
  decl_node__opaque p;
  decl_node__opaque fj;
  unsigned int j;
  unsigned int n;
  nameKey_Name fn;

  if (decl_isRecord (r))
    {
      p = static_cast<decl_node__opaque> (r);
      v = static_cast<decl_node> (NULL);
    }
  else
    {
      p = getRecord (getParent (static_cast<decl_node__opaque> (r)));
      mcDebug_assert (decl_isVarientField (r));
      mcDebug_assert (decl_isVarient (v));
      putFieldVarient (static_cast<decl_node__opaque> (r), static_cast<decl_node__opaque> (v));
    }
  n = wlists_noOfItemsInList (static_cast<decl_node__opaque> (i)->identlistF.names);
  j = 1;
  while (j <= n)
    {
      fn = static_cast<nameKey_Name> (wlists_getItemFromList (static_cast<decl_node__opaque> (i)->identlistF.names, j));
      fj = static_cast<decl_node__opaque> (symbolKey_getSymKey (p->recordF.localSymbols, n));
      if (fj == NULL)
        {
          fj = putFieldRecord (static_cast<decl_node__opaque> (r), fn, static_cast<decl_node__opaque> (t), static_cast<decl_node__opaque> (v));
        }
      else
        {
          mcMetaError_metaErrors2 ((const char *) "record field {%1ad} has already been declared inside a {%2Dd} {%2a}", 67, (const char *) "attempting to declare a duplicate record field", 46, (const unsigned char *) &fj, (sizeof (fj)-1), (const unsigned char *) &p, (sizeof (p)-1));
        }
      j += 1;
    }
  return r;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   buildVarientSelector - builds a field of name, tag, of, type onto:
                          record or varient field, r.
                          varient, v.
*/

extern "C" void decl_buildVarientSelector (decl_node r, decl_node v, nameKey_Name tag, decl_node type)
{
  decl_node__opaque f;

  mcDebug_assert ((decl_isRecord (r)) || (decl_isVarientField (r)));
  if ((decl_isRecord (r)) || (decl_isVarientField (r)))
    {
      /* avoid gcc warning by using compound statement even if not strictly necessary.  */
      if ((type == NULL) && (tag == nameKey_NulName))
        {
          mcMetaError_metaError1 ((const char *) "expecting a tag field in the declaration of a varient record {%1Ua}", 67, (const unsigned char *) &r, (sizeof (r)-1));
        }
      else if (type == NULL)
        {
          /* avoid dangling else.  */
          f = static_cast<decl_node__opaque> (decl_lookupSym (tag));
          putVarientTag (static_cast<decl_node__opaque> (v), f);
        }
      else
        {
          /* avoid dangling else.  */
          f = putFieldRecord (static_cast<decl_node__opaque> (r), tag, static_cast<decl_node__opaque> (type), static_cast<decl_node__opaque> (v));
          mcDebug_assert (decl_isRecordField (static_cast<decl_node> (f)));
          f->recordfieldF.tag = true;
          putVarientTag (static_cast<decl_node__opaque> (v), f);
        }
    }
}


/*
   buildVarientFieldRecord - builds a varient field into a varient symbol, v.
                             The varient field is returned.
*/

extern "C" decl_node decl_buildVarientFieldRecord (decl_node v, decl_node p)
{
  decl_node__opaque f;

  mcDebug_assert (decl_isVarient (v));
  f = makeVarientField (static_cast<decl_node__opaque> (v), static_cast<decl_node__opaque> (p));
  mcDebug_assert (decl_isVarientField (static_cast<decl_node> (f)));
  putFieldVarient (f, static_cast<decl_node__opaque> (v));
  return static_cast<decl_node> (f);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getSymName - returns the name of symbol, n.
*/

extern "C" nameKey_Name decl_getSymName (decl_node n)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_new:
        return nameKey_makeKey ((const char *) "NEW", 3);
        break;

      case decl_dispose:
        return nameKey_makeKey ((const char *) "DISPOSE", 7);
        break;

      case decl_length:
        return nameKey_makeKey ((const char *) "LENGTH", 6);
        break;

      case decl_inc:
        return nameKey_makeKey ((const char *) "INC", 3);
        break;

      case decl_dec:
        return nameKey_makeKey ((const char *) "DEC", 3);
        break;

      case decl_incl:
        return nameKey_makeKey ((const char *) "INCL", 4);
        break;

      case decl_excl:
        return nameKey_makeKey ((const char *) "EXCL", 4);
        break;

      case decl_nil:
        return nameKey_makeKey ((const char *) "NIL", 3);
        break;

      case decl_true:
        return nameKey_makeKey ((const char *) "TRUE", 4);
        break;

      case decl_false:
        return nameKey_makeKey ((const char *) "FALSE", 5);
        break;

      case decl_address:
        return nameKey_makeKey ((const char *) "ADDRESS", 7);
        break;

      case decl_loc:
        return nameKey_makeKey ((const char *) "LOC", 3);
        break;

      case decl_byte:
        return nameKey_makeKey ((const char *) "BYTE", 4);
        break;

      case decl_word:
        return nameKey_makeKey ((const char *) "WORD", 4);
        break;

      case decl_csizet:
        return nameKey_makeKey ((const char *) "CSIZE_T", 7);
        break;

      case decl_cssizet:
        return nameKey_makeKey ((const char *) "CSSIZE_T", 8);
        break;

      case decl_cofft:
        return nameKey_makeKey ((const char *) "COFF_T", 6);
        break;

      case decl_cardinal64:
        return nameKey_makeKey ((const char *) "CARDINAL64", 10);
        break;

      case decl_boolean:
        /* base types.  */
        return nameKey_makeKey ((const char *) "BOOLEAN", 7);
        break;

      case decl_proc:
        return nameKey_makeKey ((const char *) "PROC", 4);
        break;

      case decl_char:
        return nameKey_makeKey ((const char *) "CHAR", 4);
        break;

      case decl_cardinal:
        return nameKey_makeKey ((const char *) "CARDINAL", 8);
        break;

      case decl_longcard:
        return nameKey_makeKey ((const char *) "LONGCARD", 8);
        break;

      case decl_shortcard:
        return nameKey_makeKey ((const char *) "SHORTCARD", 9);
        break;

      case decl_integer:
        return nameKey_makeKey ((const char *) "INTEGER", 7);
        break;

      case decl_longint:
        return nameKey_makeKey ((const char *) "LONGINT", 7);
        break;

      case decl_shortint:
        return nameKey_makeKey ((const char *) "SHORTINT", 8);
        break;

      case decl_real:
        return nameKey_makeKey ((const char *) "REAL", 4);
        break;

      case decl_longreal:
        return nameKey_makeKey ((const char *) "LONGREAL", 8);
        break;

      case decl_shortreal:
        return nameKey_makeKey ((const char *) "SHORTREAL", 9);
        break;

      case decl_bitset:
        return nameKey_makeKey ((const char *) "BITSET", 6);
        break;

      case decl_ztype:
        return nameKey_makeKey ((const char *) "_ZTYPE", 6);
        break;

      case decl_rtype:
        return nameKey_makeKey ((const char *) "_RTYPE", 6);
        break;

      case decl_complex:
        return nameKey_makeKey ((const char *) "COMPLEX", 7);
        break;

      case decl_longcomplex:
        return nameKey_makeKey ((const char *) "LONGCOMPLEX", 11);
        break;

      case decl_shortcomplex:
        return nameKey_makeKey ((const char *) "SHORTCOMPLEX", 12);
        break;

      case decl_type:
        /* language features and compound type attributes.  */
        return static_cast<decl_node__opaque> (n)->typeF.name;
        break;

      case decl_record:
        return nameKey_NulName;
        break;

      case decl_varient:
        return nameKey_NulName;
        break;

      case decl_var:
        return static_cast<decl_node__opaque> (n)->varF.name;
        break;

      case decl_enumeration:
        return nameKey_NulName;
        break;

      case decl_subrange:
        return nameKey_NulName;
        break;

      case decl_pointer:
        return nameKey_NulName;
        break;

      case decl_array:
        return nameKey_NulName;
        break;

      case decl_string:
        return static_cast<decl_node__opaque> (n)->stringF.name;
        break;

      case decl_const:
        return static_cast<decl_node__opaque> (n)->constF.name;
        break;

      case decl_literal:
        return static_cast<decl_node__opaque> (n)->literalF.name;
        break;

      case decl_varparam:
        return nameKey_NulName;
        break;

      case decl_param:
        return nameKey_NulName;
        break;

      case decl_optarg:
        return nameKey_NulName;
        break;

      case decl_recordfield:
        return static_cast<decl_node__opaque> (n)->recordfieldF.name;
        break;

      case decl_varientfield:
        return static_cast<decl_node__opaque> (n)->varientfieldF.name;
        break;

      case decl_enumerationfield:
        return static_cast<decl_node__opaque> (n)->enumerationfieldF.name;
        break;

      case decl_set:
        return nameKey_NulName;
        break;

      case decl_proctype:
        return nameKey_NulName;
        break;

      case decl_subscript:
        return nameKey_NulName;
        break;

      case decl_procedure:
        /* blocks.  */
        return static_cast<decl_node__opaque> (n)->procedureF.name;
        break;

      case decl_def:
        return static_cast<decl_node__opaque> (n)->defF.name;
        break;

      case decl_imp:
        return static_cast<decl_node__opaque> (n)->impF.name;
        break;

      case decl_module:
        return static_cast<decl_node__opaque> (n)->moduleF.name;
        break;

      case decl_loop:
      case decl_while:
      case decl_for:
      case decl_repeat:
      case decl_if:
      case decl_elsif:
      case decl_assignment:
        /* statements.  */
        return nameKey_NulName;
        break;

      case decl_constexp:
      case decl_deref:
      case decl_arrayref:
      case decl_componentref:
      case decl_cast:
      case decl_val:
      case decl_plus:
      case decl_sub:
      case decl_div:
      case decl_mod:
      case decl_mult:
      case decl_divide:
      case decl_in:
      case decl_neg:
      case decl_equal:
      case decl_notequal:
      case decl_less:
      case decl_greater:
      case decl_greequal:
      case decl_lessequal:
        /* expressions.  */
        return nameKey_NulName;
        break;

      case decl_adr:
        return nameKey_makeKey ((const char *) "ADR", 3);
        break;

      case decl_size:
        return nameKey_makeKey ((const char *) "SIZE", 4);
        break;

      case decl_tsize:
        return nameKey_makeKey ((const char *) "TSIZE", 5);
        break;

      case decl_chr:
        return nameKey_makeKey ((const char *) "CHR", 3);
        break;

      case decl_abs:
        return nameKey_makeKey ((const char *) "ABS", 3);
        break;

      case decl_ord:
        return nameKey_makeKey ((const char *) "ORD", 3);
        break;

      case decl_float:
        return nameKey_makeKey ((const char *) "FLOAT", 5);
        break;

      case decl_trunc:
        return nameKey_makeKey ((const char *) "TRUNC", 5);
        break;

      case decl_high:
        return nameKey_makeKey ((const char *) "HIGH", 4);
        break;

      case decl_throw:
        return nameKey_makeKey ((const char *) "THROW", 5);
        break;

      case decl_unreachable:
        return nameKey_makeKey ((const char *) "builtin_unreachable", 19);
        break;

      case decl_cmplx:
        return nameKey_makeKey ((const char *) "CMPLX", 5);
        break;

      case decl_re:
        return nameKey_makeKey ((const char *) "RE", 2);
        break;

      case decl_im:
        return nameKey_makeKey ((const char *) "IM", 2);
        break;

      case decl_max:
        return nameKey_makeKey ((const char *) "MAX", 3);
        break;

      case decl_min:
        return nameKey_makeKey ((const char *) "MIN", 3);
        break;

      case decl_pointerref:
        return nameKey_NulName;
        break;

      case decl_funccall:
        return nameKey_NulName;
        break;

      case decl_identlist:
        return nameKey_NulName;
        break;


      default:
        M2RTS_HALT (-1);
        __builtin_unreachable ();
        break;
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   import - attempts to add node, n, into the scope of module, m.
            It might fail due to a name clash in which case the
            previous named symbol is returned.  On success, n,
            is returned.
*/

extern "C" decl_node decl_import (decl_node m, decl_node n)
{
  nameKey_Name name;
  decl_node__opaque r;

  mcDebug_assert (((decl_isDef (m)) || (decl_isModule (m))) || (decl_isImp (m)));
  name = decl_getSymName (n);
  checkGccType (static_cast<decl_node__opaque> (n));
  checkCDataTypes (static_cast<decl_node__opaque> (n));
  r = static_cast<decl_node__opaque> (decl_lookupInScope (m, name));
  if (r == NULL)
    {
      switch (static_cast<decl_node__opaque> (m)->kind)
        {
          case decl_def:
            symbolKey_putSymKey (static_cast<decl_node__opaque> (m)->defF.decls.symbols, name, reinterpret_cast <void *> (n));
            break;

          case decl_imp:
            symbolKey_putSymKey (static_cast<decl_node__opaque> (m)->impF.decls.symbols, name, reinterpret_cast <void *> (n));
            break;

          case decl_module:
            symbolKey_putSymKey (static_cast<decl_node__opaque> (m)->moduleF.decls.symbols, name, reinterpret_cast <void *> (n));
            break;


          default:
            CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
            __builtin_unreachable ();
        }
      importEnumFields (static_cast<decl_node__opaque> (m), static_cast<decl_node__opaque> (n));
      return n;
    }
  return static_cast<decl_node> (r);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   lookupExported - attempts to lookup a node named, i, from definition
                    module, n.  The node is returned if found.
                    NIL is returned if not found.
*/

extern "C" decl_node decl_lookupExported (decl_node n, nameKey_Name i)
{
  decl_node__opaque r;

  mcDebug_assert (decl_isDef (n));
  r = static_cast<decl_node__opaque> (symbolKey_getSymKey (static_cast<decl_node__opaque> (n)->defF.decls.symbols, i));
  if ((r != NULL) && (decl_isExported (static_cast<decl_node> (r))))
    {
      return static_cast<decl_node> (r);
    }
  return static_cast<decl_node> (NULL);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   lookupSym - returns the symbol named, n, from the scope stack.
*/

extern "C" decl_node decl_lookupSym (nameKey_Name n)
{
  decl_node__opaque s;
  decl_node__opaque m;
  unsigned int l;
  unsigned int h;

  l = Indexing_LowIndice (scopeStack);
  h = Indexing_HighIndice (scopeStack);
  while (h >= l)
    {
      s = static_cast<decl_node__opaque> (Indexing_GetIndice (scopeStack, h));
      m = static_cast<decl_node__opaque> (decl_lookupInScope (static_cast<decl_node> (s), n));
      if (debugScopes && (m == NULL))
        {
          out3 ((const char *) " [%d] search for symbol name %s in scope %s\\n", 45, h, n, s);
        }
      if (m != NULL)
        {
          if (debugScopes)
            {
              out3 ((const char *) " [%d] search for symbol name %s in scope %s (found)\\n", 53, h, n, s);
            }
          return static_cast<decl_node> (m);
        }
      h -= 1;
    }
  return static_cast<decl_node> (lookupBase (n));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   addImportedModule - add module, i, to be imported by, m.
                       If scoped then module, i, is added to the
                       module, m, scope.
*/

extern "C" void decl_addImportedModule (decl_node m, decl_node i, bool scoped)
{
  mcDebug_assert ((decl_isDef (i)) || (decl_isModule (i)));
  if (decl_isDef (m))
    {
      Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (m)->defF.importedModules, reinterpret_cast <void *> (i));
    }
  else if (decl_isImp (m))
    {
      /* avoid dangling else.  */
      Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (m)->impF.importedModules, reinterpret_cast <void *> (i));
    }
  else if (decl_isModule (m))
    {
      /* avoid dangling else.  */
      Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (m)->moduleF.importedModules, reinterpret_cast <void *> (i));
    }
  else
    {
      /* avoid dangling else.  */
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  if (scoped)
    {
      addModuleToScope (static_cast<decl_node__opaque> (m), static_cast<decl_node__opaque> (i));
    }
}


/*
   setSource - sets the source filename for module, n, to s.
*/

extern "C" void decl_setSource (decl_node n, nameKey_Name s)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_def:
        static_cast<decl_node__opaque> (n)->defF.source = s;
        break;

      case decl_module:
        static_cast<decl_node__opaque> (n)->moduleF.source = s;
        break;

      case decl_imp:
        static_cast<decl_node__opaque> (n)->impF.source = s;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   getSource - returns the source filename for module, n.
*/

extern "C" nameKey_Name decl_getSource (decl_node n)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_def:
        return static_cast<decl_node__opaque> (n)->defF.source;
        break;

      case decl_module:
        return static_cast<decl_node__opaque> (n)->moduleF.source;
        break;

      case decl_imp:
        return static_cast<decl_node__opaque> (n)->impF.source;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getMainModule - returns the main module node.
*/

extern "C" decl_node decl_getMainModule (void)
{
  return static_cast<decl_node> (mainModule);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getCurrentModule - returns the current module being compiled.
*/

extern "C" decl_node decl_getCurrentModule (void)
{
  return static_cast<decl_node> (currentModule);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   foreachDefModuleDo - foreach definition node, n, in the module universe,
                        call p (n).
*/

extern "C" void decl_foreachDefModuleDo (symbolKey_performOperation p)
{
  Indexing_ForeachIndiceInIndexDo (defUniverseI, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) p.proc});
}


/*
   foreachModModuleDo - foreach implementation or module node, n, in the module universe,
                        call p (n).
*/

extern "C" void decl_foreachModModuleDo (symbolKey_performOperation p)
{
  Indexing_ForeachIndiceInIndexDo (modUniverseI, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) p.proc});
}


/*
   enterScope - pushes symbol, n, to the scope stack.
*/

extern "C" void decl_enterScope (decl_node n)
{
  if (Indexing_IsIndiceInIndex (scopeStack, reinterpret_cast <void *> (n)))
    {
      M2RTS_HALT (-1);
      __builtin_unreachable ();
    }
  else
    {
      Indexing_IncludeIndiceIntoIndex (scopeStack, reinterpret_cast <void *> (n));
    }
  if (debugScopes)
    {
      libc_printf ((const char *) "enter scope\\n", 13);
      dumpScopes ();
    }
}


/*
   leaveScope - removes the top level scope.
*/

extern "C" void decl_leaveScope (void)
{
  unsigned int i;
  decl_node__opaque n;

  i = Indexing_HighIndice (scopeStack);
  n = static_cast<decl_node__opaque> (Indexing_GetIndice (scopeStack, i));
  Indexing_RemoveIndiceFromIndex (scopeStack, reinterpret_cast <void *> (n));
  if (debugScopes)
    {
      libc_printf ((const char *) "leave scope\\n", 13);
      dumpScopes ();
    }
}


/*
   makeProcedure - create, initialise and return a procedure node.
*/

extern "C" decl_node decl_makeProcedure (nameKey_Name n)
{
  decl_node__opaque d;

  d = static_cast<decl_node__opaque> (decl_lookupSym (n));
  if (d == NULL)
    {
      d = newNode (decl_procedure);
      d->procedureF.name = n;
      initDecls (&d->procedureF.decls);
      d->procedureF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
      d->procedureF.parameters = Indexing_InitIndex (1);
      d->procedureF.isForC = isDefForCNode (static_cast<decl_node__opaque> (decl_getDeclScope ()));
      d->procedureF.built = false;
      d->procedureF.returnopt = false;
      d->procedureF.optarg_ = static_cast<decl_node__opaque> (NULL);
      d->procedureF.noreturnused = false;
      d->procedureF.noreturn = false;
      d->procedureF.vararg = false;
      d->procedureF.checking = false;
      d->procedureF.paramcount = 0;
      d->procedureF.returnType = static_cast<decl_node__opaque> (NULL);
      d->procedureF.beginStatements = static_cast<decl_node__opaque> (NULL);
      initCname (&d->procedureF.cname);
      d->procedureF.defComment = static_cast<mcComment_commentDesc> (NULL);
      d->procedureF.modComment = static_cast<mcComment_commentDesc> (NULL);
    }
  return static_cast<decl_node> (addProcedureToScope (d, n));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putCommentDefProcedure - remembers the procedure comment (if it exists) as a
                            definition module procedure heading.  NIL is placed
                            if there is no procedure comment available.
*/

extern "C" void decl_putCommentDefProcedure (decl_node n)
{
  mcDebug_assert (decl_isProcedure (n));
  if (mcComment_isProcedureComment (mcLexBuf_lastcomment))
    {
      static_cast<decl_node__opaque> (n)->procedureF.defComment = mcLexBuf_lastcomment;
    }
}


/*
   putCommentModProcedure - remembers the procedure comment (if it exists) as an
                            implementation/program module procedure heading.  NIL is placed
                            if there is no procedure comment available.
*/

extern "C" void decl_putCommentModProcedure (decl_node n)
{
  mcDebug_assert (decl_isProcedure (n));
  if (mcComment_isProcedureComment (mcLexBuf_lastcomment))
    {
      static_cast<decl_node__opaque> (n)->procedureF.modComment = mcLexBuf_lastcomment;
    }
}


/*
   makeProcType - returns a proctype node.
*/

extern "C" decl_node decl_makeProcType (void)
{
  decl_node__opaque d;

  d = newNode (decl_proctype);
  d->proctypeF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
  d->proctypeF.parameters = Indexing_InitIndex (1);
  d->proctypeF.returnopt = false;
  d->proctypeF.optarg_ = static_cast<decl_node__opaque> (NULL);
  d->proctypeF.vararg = false;
  d->proctypeF.returnType = static_cast<decl_node__opaque> (NULL);
  initNodeOpaqueState (d);
  return static_cast<decl_node> (d);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putReturnType - sets the return type of procedure or proctype proc to type.
*/

extern "C" void decl_putReturnType (decl_node proc, decl_node type)
{
  mcDebug_assert ((decl_isProcedure (proc)) || (decl_isProcType (proc)));
  if (decl_isProcedure (proc))
    {
      static_cast<decl_node__opaque> (proc)->procedureF.returnType = static_cast<decl_node__opaque> (type);
    }
  else
    {
      static_cast<decl_node__opaque> (proc)->proctypeF.returnType = static_cast<decl_node__opaque> (type);
    }
  initNodeOpaqueState (static_cast<decl_node__opaque> (proc));
}


/*
   putOptReturn - sets, proctype or procedure, proc, to have an optional return type.
*/

extern "C" void decl_putOptReturn (decl_node proc)
{
  mcDebug_assert ((decl_isProcedure (proc)) || (decl_isProcType (proc)));
  if (decl_isProcedure (proc))
    {
      static_cast<decl_node__opaque> (proc)->procedureF.returnopt = true;
    }
  else
    {
      static_cast<decl_node__opaque> (proc)->proctypeF.returnopt = true;
    }
}


/*
   makeVarParameter - returns a var parameter node with, name: type.
*/

extern "C" decl_node decl_makeVarParameter (decl_node l, decl_node type, decl_node proc, bool isused)
{
  decl_node__opaque d;

  mcDebug_assert ((l == NULL) || (isIdentList (static_cast<decl_node__opaque> (l))));
  d = newNode (decl_varparam);
  d->varparamF.namelist = static_cast<decl_node__opaque> (l);
  d->varparamF.type = static_cast<decl_node__opaque> (type);
  d->varparamF.scope = static_cast<decl_node__opaque> (proc);
  d->varparamF.isUnbounded = false;
  d->varparamF.isForC = isDefForCNode (static_cast<decl_node__opaque> (proc));
  d->varparamF.isUsed = isused;
  initNodeOpaqueState (d);
  return static_cast<decl_node> (d);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeNonVarParameter - returns a non var parameter node with, name: type.
*/

extern "C" decl_node decl_makeNonVarParameter (decl_node l, decl_node type, decl_node proc, bool isused)
{
  decl_node__opaque d;

  mcDebug_assert ((l == NULL) || (isIdentList (static_cast<decl_node__opaque> (l))));
  d = newNode (decl_param);
  d->paramF.namelist = static_cast<decl_node__opaque> (l);
  d->paramF.type = static_cast<decl_node__opaque> (type);
  d->paramF.scope = static_cast<decl_node__opaque> (proc);
  d->paramF.isUnbounded = false;
  d->paramF.isForC = isDefForCNode (static_cast<decl_node__opaque> (proc));
  d->paramF.isUsed = isused;
  initNodeOpaqueState (d);
  return static_cast<decl_node> (d);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   paramEnter - reset the parameter count.
*/

extern "C" void decl_paramEnter (decl_node n)
{
  mcDebug_assert (decl_isProcedure (n));
  static_cast<decl_node__opaque> (n)->procedureF.paramcount = 0;
}


/*
   paramLeave - set paramater checking to TRUE from now onwards.
*/

extern "C" void decl_paramLeave (decl_node n)
{
  mcDebug_assert (decl_isProcedure (n));
  static_cast<decl_node__opaque> (n)->procedureF.checking = true;
  if ((decl_isImp (static_cast<decl_node> (currentModule))) || (decl_isModule (static_cast<decl_node> (currentModule))))
    {
      static_cast<decl_node__opaque> (n)->procedureF.built = true;
    }
}


/*
   makeIdentList - returns a node which will be used to maintain an ident list.
*/

extern "C" decl_node decl_makeIdentList (void)
{
  decl_node__opaque n;

  n = newNode (decl_identlist);
  n->identlistF.names = wlists_initList ();
  n->identlistF.cnamed = false;
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putIdent - places ident, i, into identlist, n.  It returns TRUE if
              ident, i, is unique.
*/

extern "C" bool decl_putIdent (decl_node n, nameKey_Name i)
{
  mcDebug_assert (isIdentList (static_cast<decl_node__opaque> (n)));
  if (wlists_isItemInList (static_cast<decl_node__opaque> (n)->identlistF.names, i))
    {
      return false;
    }
  else
    {
      wlists_putItemIntoList (static_cast<decl_node__opaque> (n)->identlistF.names, i);
      return true;
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   addVarParameters - adds the identlist, i, of, type, to be VAR parameters
                      in procedure, n.
*/

extern "C" void decl_addVarParameters (decl_node n, decl_node i, decl_node type, bool isused)
{
  decl_node__opaque p;

  mcDebug_assert (isIdentList (static_cast<decl_node__opaque> (i)));
  mcDebug_assert (decl_isProcedure (n));
  checkMakeVariables (static_cast<decl_node__opaque> (n), static_cast<decl_node__opaque> (i), static_cast<decl_node__opaque> (type), true, isused);
  if (static_cast<decl_node__opaque> (n)->procedureF.checking)
    {
      checkParameters (static_cast<decl_node__opaque> (n), static_cast<decl_node__opaque> (i), static_cast<decl_node__opaque> (type), true, isused);  /* will destroy, i.  */
    }
  else
    {
      p = static_cast<decl_node__opaque> (decl_makeVarParameter (i, type, n, isused));
      Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (n)->procedureF.parameters, reinterpret_cast <void *> (p));
    }
}


/*
   addNonVarParameters - adds the identlist, i, of, type, to be parameters
                         in procedure, n.
*/

extern "C" void decl_addNonVarParameters (decl_node n, decl_node i, decl_node type, bool isused)
{
  decl_node__opaque p;

  mcDebug_assert (isIdentList (static_cast<decl_node__opaque> (i)));
  mcDebug_assert (decl_isProcedure (n));
  checkMakeVariables (static_cast<decl_node__opaque> (n), static_cast<decl_node__opaque> (i), static_cast<decl_node__opaque> (type), false, isused);
  if (static_cast<decl_node__opaque> (n)->procedureF.checking)
    {
      checkParameters (static_cast<decl_node__opaque> (n), static_cast<decl_node__opaque> (i), static_cast<decl_node__opaque> (type), false, isused);  /* will destroy, i.  */
    }
  else
    {
      p = static_cast<decl_node__opaque> (decl_makeNonVarParameter (i, type, n, isused));
      Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (n)->procedureF.parameters, reinterpret_cast <void *> (p));
    }
}


/*
   makeVarargs - returns a varargs node.
*/

extern "C" decl_node decl_makeVarargs (void)
{
  decl_node__opaque d;

  d = newNode (decl_varargs);
  d->varargsF.scope = static_cast<decl_node__opaque> (NULL);
  return static_cast<decl_node> (d);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isVarargs - returns TRUE if, n, is a varargs node.
*/

extern "C" bool decl_isVarargs (decl_node n)
{
  return static_cast<decl_node__opaque> (n)->kind == decl_varargs;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   addParameter - adds a parameter, param, to procedure or proctype, proc.
*/

extern "C" void decl_addParameter (decl_node proc, decl_node param)
{
  mcDebug_assert ((((decl_isVarargs (param)) || (decl_isParam (param))) || (decl_isVarParam (param))) || (decl_isOptarg (param)));
  switch (static_cast<decl_node__opaque> (proc)->kind)
    {
      case decl_procedure:
        Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (proc)->procedureF.parameters, reinterpret_cast <void *> (param));
        if (decl_isVarargs (param))
          {
            static_cast<decl_node__opaque> (proc)->procedureF.vararg = true;
          }
        if (decl_isOptarg (param))
          {
            static_cast<decl_node__opaque> (proc)->procedureF.optarg_ = static_cast<decl_node__opaque> (param);
          }
        break;

      case decl_proctype:
        Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (proc)->proctypeF.parameters, reinterpret_cast <void *> (param));
        if (decl_isVarargs (param))
          {
            static_cast<decl_node__opaque> (proc)->proctypeF.vararg = true;
          }
        if (decl_isOptarg (param))
          {
            static_cast<decl_node__opaque> (proc)->proctypeF.optarg_ = static_cast<decl_node__opaque> (param);
          }
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   makeBinaryTok - creates and returns a boolean type node with,
                   l, and, r, nodes.
*/

extern "C" decl_node decl_makeBinaryTok (mcReserved_toktype op, decl_node l, decl_node r)
{
  if (op == mcReserved_equaltok)
    {
      return static_cast<decl_node> (makeBinary (decl_equal, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), booleanN));
    }
  else if ((op == mcReserved_hashtok) || (op == mcReserved_lessgreatertok))
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_notequal, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), booleanN));
    }
  else if (op == mcReserved_lesstok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_less, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), booleanN));
    }
  else if (op == mcReserved_greatertok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_greater, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), booleanN));
    }
  else if (op == mcReserved_greaterequaltok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_greequal, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), booleanN));
    }
  else if (op == mcReserved_lessequaltok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_lessequal, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), booleanN));
    }
  else if (op == mcReserved_andtok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_and, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), booleanN));
    }
  else if (op == mcReserved_ortok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_or, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), booleanN));
    }
  else if (op == mcReserved_plustok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_plus, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), static_cast<decl_node__opaque> (NULL)));
    }
  else if (op == mcReserved_minustok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_sub, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), static_cast<decl_node__opaque> (NULL)));
    }
  else if (op == mcReserved_divtok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_div, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), static_cast<decl_node__opaque> (NULL)));
    }
  else if (op == mcReserved_timestok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_mult, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), static_cast<decl_node__opaque> (NULL)));
    }
  else if (op == mcReserved_modtok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_mod, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), static_cast<decl_node__opaque> (NULL)));
    }
  else if (op == mcReserved_intok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_in, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), static_cast<decl_node__opaque> (NULL)));
    }
  else if (op == mcReserved_dividetok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeBinary (decl_divide, static_cast<decl_node__opaque> (l), static_cast<decl_node__opaque> (r), static_cast<decl_node__opaque> (NULL)));
    }
  else
    {
      /* avoid dangling else.  */
      M2RTS_HALT (-1);  /* most likely op needs a clause as above.  */
      __builtin_unreachable ();
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   makeUnaryTok - creates and returns a boolean type node with,
                  e, node.
*/

extern "C" decl_node decl_makeUnaryTok (mcReserved_toktype op, decl_node e)
{
  if (op == mcReserved_nottok)
    {
      return static_cast<decl_node> (makeUnary (decl_not, static_cast<decl_node__opaque> (e), booleanN));
    }
  else if (op == mcReserved_plustok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeUnary (decl_plus, static_cast<decl_node__opaque> (e), static_cast<decl_node__opaque> (NULL)));
    }
  else if (op == mcReserved_minustok)
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (makeUnary (decl_neg, static_cast<decl_node__opaque> (e), static_cast<decl_node__opaque> (NULL)));
    }
  else
    {
      /* avoid dangling else.  */
      M2RTS_HALT (-1);  /* most likely op needs a clause as above.  */
      __builtin_unreachable ();
    }
  ReturnException ("../../gcc/m2/mc/decl.def", 20, 1);
  __builtin_unreachable ();
}


/*
   makeComponentRef - build a componentref node which accesses, field,
                      within, record, rec.
*/

extern "C" decl_node decl_makeComponentRef (decl_node rec, decl_node field)
{
  decl_node__opaque n;
  decl_node__opaque a;

  /*
   n := getLastOp (rec) ;
   IF (n#NIL) AND (isDeref (n) OR isPointerRef (n)) AND
      (skipType (getType (rec)) = skipType (getType (n)))
   THEN
      a := n^.unaryF.arg ;
      n^.kind := pointerref ;
      n^.pointerrefF.ptr := a ;
      n^.pointerrefF.field := field ;
      n^.pointerrefF.resultType := getType (field) ;
      RETURN n
   ELSE
      RETURN doMakeComponentRef (rec, field)
   END
  */
  if (isDeref (static_cast<decl_node__opaque> (rec)))
    {
      a = static_cast<decl_node__opaque> (rec)->unaryF.arg;
      static_cast<decl_node__opaque> (rec)->kind = decl_pointerref;
      static_cast<decl_node__opaque> (rec)->pointerrefF.ptr = a;
      static_cast<decl_node__opaque> (rec)->pointerrefF.field = static_cast<decl_node__opaque> (field);
      static_cast<decl_node__opaque> (rec)->pointerrefF.resultType = static_cast<decl_node__opaque> (decl_getType (field));
      initNodeOpaqueState (static_cast<decl_node__opaque> (rec));
      return rec;
    }
  else
    {
      return static_cast<decl_node> (doMakeComponentRef (static_cast<decl_node__opaque> (rec), static_cast<decl_node__opaque> (field)));
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makePointerRef - build a pointerref node which accesses, field,
                    within, pointer to record, ptr.
*/

extern "C" decl_node decl_makePointerRef (decl_node ptr, decl_node field)
{
  decl_node__opaque n;

  n = newNode (decl_pointerref);
  n->pointerrefF.ptr = static_cast<decl_node__opaque> (ptr);
  n->pointerrefF.field = static_cast<decl_node__opaque> (field);
  n->pointerrefF.resultType = static_cast<decl_node__opaque> (decl_getType (field));
  initNodeOpaqueState (n);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isPointerRef - returns TRUE if, n, is a pointerref node.
*/

extern "C" bool decl_isPointerRef (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_pointerref;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeDeRef - dereferences the pointer defined by, n.
*/

extern "C" decl_node decl_makeDeRef (decl_node n)
{
  decl_node__opaque t;

  t = static_cast<decl_node__opaque> (decl_skipType (decl_getType (n)));
  mcDebug_assert (decl_isPointer (static_cast<decl_node> (t)));
  return static_cast<decl_node> (makeUnary (decl_deref, static_cast<decl_node__opaque> (n), static_cast<decl_node__opaque> (decl_getType (static_cast<decl_node> (t)))));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeArrayRef - build an arrayref node which access element,
                  index, in, array.  array is a variable/expression/constant
                  which has a type array.
*/

extern "C" decl_node decl_makeArrayRef (decl_node array, decl_node index)
{
  decl_node__opaque n;
  decl_node__opaque t;
  unsigned int i;
  unsigned int j;

  n = newNode (decl_arrayref);
  n->arrayrefF.array = static_cast<decl_node__opaque> (array);
  n->arrayrefF.index = static_cast<decl_node__opaque> (index);
  t = static_cast<decl_node__opaque> (array);
  j = expListLen (static_cast<decl_node__opaque> (index));
  i = 1;
  t = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (t))));
  do {
    if (decl_isArray (static_cast<decl_node> (t)))
      {
        t = static_cast<decl_node__opaque> (decl_skipType (decl_getType (static_cast<decl_node> (t))));
      }
    else
      {
        mcMetaError_metaError2 ((const char *) "cannot access {%1N} dimension of array {%2a}", 44, (const unsigned char *) &i, (sizeof (i)-1), (const unsigned char *) &t, (sizeof (t)-1));
      }
    i += 1;
  } while (! (i > j));
  n->arrayrefF.resultType = t;
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getLastOp - return the right most non leaf node.
*/

extern "C" decl_node decl_getLastOp (decl_node n)
{
  return static_cast<decl_node> (doGetLastOp (static_cast<decl_node__opaque> (n), static_cast<decl_node__opaque> (n)));
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getCardinal - returns the cardinal type node.
*/

extern "C" decl_node decl_getCardinal (void)
{
  return static_cast<decl_node> (cardinalN);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeLiteralInt - creates and returns a literal node based on an integer type.
*/

extern "C" decl_node decl_makeLiteralInt (nameKey_Name n)
{
  decl_node__opaque m;
  DynamicStrings_String s;

  m = newNode (decl_literal);
  s = DynamicStrings_InitStringCharStar (nameKey_keyToCharStar (n));
  m->literalF.name = n;
  if ((DynamicStrings_char (s, -1)) == 'C')
    {
      m->literalF.type = charN;
    }
  else
    {
      m->literalF.type = ztypeN;
    }
  s = DynamicStrings_KillString (s);
  return static_cast<decl_node> (m);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeLiteralReal - creates and returns a literal node based on a real type.
*/

extern "C" decl_node decl_makeLiteralReal (nameKey_Name n)
{
  decl_node__opaque m;

  m = newNode (decl_literal);
  m->literalF.name = n;
  m->literalF.type = rtypeN;
  return static_cast<decl_node> (m);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeString - creates and returns a node containing string, n.
*/

extern "C" decl_node decl_makeString (nameKey_Name n)
{
  decl_node__opaque m;

  m = newNode (decl_string);
  m->stringF.name = n;
  m->stringF.length = nameKey_lengthKey (n);
  m->stringF.isCharCompatible = m->stringF.length <= 3;
  m->stringF.cstring = toCstring (n);
  m->stringF.clength = lenCstring (m->stringF.cstring);
  if (m->stringF.isCharCompatible)
    {
      m->stringF.cchar = toCchar (n);
    }
  else
    {
      m->stringF.cchar = static_cast<DynamicStrings_String> (NULL);
    }
  return static_cast<decl_node> (m);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeSetValue - creates and returns a setvalue node.
*/

extern "C" decl_node decl_makeSetValue (void)
{
  decl_node__opaque n;

  n = newNode (decl_setvalue);
  n->setvalueF.type = bitsetN;
  n->setvalueF.values = Indexing_InitIndex (1);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isSetValue - returns TRUE if, n, is a setvalue node.
*/

extern "C" bool decl_isSetValue (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_setvalue;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putSetValue - assigns the type, t, to the set value, n.  The
                 node, n, is returned.
*/

extern "C" decl_node decl_putSetValue (decl_node n, decl_node t)
{
  mcDebug_assert (decl_isSetValue (n));
  static_cast<decl_node__opaque> (n)->setvalueF.type = static_cast<decl_node__opaque> (t);
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   includeSetValue - includes the range l..h into the setvalue.
                     h might be NIL indicating that a single element
                       is to be included into the set.
                     n is returned.
*/

extern "C" decl_node decl_includeSetValue (decl_node n, decl_node l, decl_node h)
{
  mcDebug_assert (decl_isSetValue (n));
  Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (n)->setvalueF.values, reinterpret_cast <void *> (l));
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getBuiltinConst - creates and returns a builtin const if available.
*/

extern "C" decl_node decl_getBuiltinConst (nameKey_Name n)
{
  if (n == (nameKey_makeKey ((const char *) "BITS_PER_UNIT", 13)))
    {
      return static_cast<decl_node> (bitsperunitN);
    }
  else if (n == (nameKey_makeKey ((const char *) "BITS_PER_WORD", 13)))
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (bitsperwordN);
    }
  else if (n == (nameKey_makeKey ((const char *) "BITS_PER_CHAR", 13)))
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (bitspercharN);
    }
  else if (n == (nameKey_makeKey ((const char *) "UNITS_PER_WORD", 14)))
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (unitsperwordN);
    }
  else
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (NULL);
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeExpList - creates and returns an expList node.
*/

extern "C" decl_node decl_makeExpList (void)
{
  decl_node__opaque n;

  n = newNode (decl_explist);
  n->explistF.exp = Indexing_InitIndex (1);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isExpList - returns TRUE if, n, is an explist node.
*/

extern "C" bool decl_isExpList (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_explist;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putExpList - places, expression, e, within the explist, n.
*/

extern "C" void decl_putExpList (decl_node n, decl_node e)
{
  mcDebug_assert (n != NULL);
  mcDebug_assert (decl_isExpList (n));
  Indexing_PutIndice (static_cast<decl_node__opaque> (n)->explistF.exp, (Indexing_HighIndice (static_cast<decl_node__opaque> (n)->explistF.exp))+1, reinterpret_cast <void *> (e));
}


/*
   makeConstExp - returns a constexp node.
*/

extern "C" decl_node decl_makeConstExp (void)
{
  if ((currentModule != NULL) && (getConstExpComplete (currentModule)))
    {
      return decl_getNextConstExp ();
    }
  else
    {
      return static_cast<decl_node> (doMakeConstExp ());
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   getNextConstExp - returns the next constexp node.
*/

extern "C" decl_node decl_getNextConstExp (void)
{
  mcDebug_assert (((decl_isDef (static_cast<decl_node> (currentModule))) || (decl_isImp (static_cast<decl_node> (currentModule)))) || (decl_isModule (static_cast<decl_node> (currentModule))));
  if (decl_isDef (static_cast<decl_node> (currentModule)))
    {
      return static_cast<decl_node> (getNextFixup (&currentModule->defF.constFixup));
    }
  else if (decl_isImp (static_cast<decl_node> (currentModule)))
    {
      /* avoid dangling else.  */
      return static_cast<decl_node> (getNextFixup (&currentModule->impF.constFixup));
    }
  else
    {
      /* avoid dangling else.  */
      mcDebug_assert (decl_isModule (static_cast<decl_node> (currentModule)));
      return static_cast<decl_node> (getNextFixup (&currentModule->moduleF.constFixup));
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   setConstExpComplete - sets the field inside the def or imp or module, n.
*/

extern "C" void decl_setConstExpComplete (decl_node n)
{
  switch (static_cast<decl_node__opaque> (n)->kind)
    {
      case decl_def:
        static_cast<decl_node__opaque> (n)->defF.constsComplete = true;
        break;

      case decl_imp:
        static_cast<decl_node__opaque> (n)->impF.constsComplete = true;
        break;

      case decl_module:
        static_cast<decl_node__opaque> (n)->moduleF.constsComplete = true;
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   fixupConstExp - assign fixup expression, e, into the argument of, c.
*/

extern "C" decl_node decl_fixupConstExp (decl_node c, decl_node e)
{
  mcDebug_assert (isConstExp (static_cast<decl_node__opaque> (c)));
  static_cast<decl_node__opaque> (c)->unaryF.arg = static_cast<decl_node__opaque> (e);
  return c;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   resetConstExpPos - resets the index into the saved list of constexps inside
                      module, n.
*/

extern "C" void decl_resetConstExpPos (decl_node n)
{
  mcDebug_assert (((decl_isDef (n)) || (decl_isImp (n))) || (decl_isModule (n)));
  if (decl_isDef (n))
    {
      static_cast<decl_node__opaque> (n)->defF.constFixup.count = 0;
    }
  else if (decl_isImp (n))
    {
      /* avoid dangling else.  */
      static_cast<decl_node__opaque> (n)->impF.constFixup.count = 0;
    }
  else if (decl_isModule (n))
    {
      /* avoid dangling else.  */
      static_cast<decl_node__opaque> (n)->moduleF.constFixup.count = 0;
    }
}


/*
   makeFuncCall - builds a function call to c with param list, n.
*/

extern "C" decl_node decl_makeFuncCall (decl_node c, decl_node n)
{
  decl_node__opaque f;

  mcDebug_assert ((n == NULL) || (decl_isExpList (n)));
  if (((c == haltN) && ((decl_getMainModule ()) != (decl_lookupDef (nameKey_makeKey ((const char *) "M2RTS", 5))))) && ((decl_getMainModule ()) != (decl_lookupImp (nameKey_makeKey ((const char *) "M2RTS", 5)))))
    {
      decl_addImportedModule (decl_getMainModule (), decl_lookupDef (nameKey_makeKey ((const char *) "M2RTS", 5)), false);
    }
  f = checkIntrinsic (static_cast<decl_node__opaque> (c), static_cast<decl_node__opaque> (n));
  checkCHeaders (static_cast<decl_node__opaque> (c));
  if (f == NULL)
    {
      f = newNode (decl_funccall);
      f->funccallF.function = static_cast<decl_node__opaque> (c);
      f->funccallF.args = static_cast<decl_node__opaque> (n);
      f->funccallF.type = static_cast<decl_node__opaque> (decl_getType (c));
      initPair (&f->funccallF.funccallComment);
      initNodeOpaqueState (f);
    }
  return static_cast<decl_node> (f);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeStatementSequence - create and return a statement sequence node.
*/

extern "C" decl_node decl_makeStatementSequence (void)
{
  decl_node__opaque n;

  n = newNode (decl_stmtseq);
  n->stmtF.statements = Indexing_InitIndex (1);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isStatementSequence - returns TRUE if node, n, is a statement sequence.
*/

extern "C" bool decl_isStatementSequence (decl_node n)
{
  return static_cast<decl_node__opaque> (n)->kind == decl_stmtseq;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   addStatement - adds node, n, as a statement to statememt sequence, s.
*/

extern "C" void decl_addStatement (decl_node s, decl_node n)
{
  if (n != NULL)
    {
      mcDebug_assert (decl_isStatementSequence (s));
      Indexing_PutIndice (static_cast<decl_node__opaque> (s)->stmtF.statements, (Indexing_HighIndice (static_cast<decl_node__opaque> (s)->stmtF.statements))+1, reinterpret_cast <void *> (n));
      if ((isIntrinsic (static_cast<decl_node__opaque> (n))) && static_cast<decl_node__opaque> (n)->intrinsicF.postUnreachable)
        {
          static_cast<decl_node__opaque> (n)->intrinsicF.postUnreachable = false;
          decl_addStatement (s, static_cast<decl_node> (makeIntrinsicProc (decl_unreachable, 0, static_cast<decl_node__opaque> (NULL))));
        }
    }
}


/*
   addCommentBody - adds a body comment to a statement sequence node.
*/

extern "C" void decl_addCommentBody (decl_node n)
{
  mcComment_commentDesc b;

  if (n != NULL)
    {
      b = mcLexBuf_getBodyComment ();
      if (b != NULL)
        {
          addGenericBody (static_cast<decl_node__opaque> (n), static_cast<decl_node__opaque> (decl_makeCommentS (b)));
        }
    }
}


/*
   addCommentAfter - adds an after comment to a statement sequence node.
*/

extern "C" void decl_addCommentAfter (decl_node n)
{
  mcComment_commentDesc a;

  if (n != NULL)
    {
      a = mcLexBuf_getAfterComment ();
      if (a != NULL)
        {
          addGenericAfter (static_cast<decl_node__opaque> (n), static_cast<decl_node__opaque> (decl_makeCommentS (a)));
        }
    }
}


/*
   addIfComments - adds the, body, and, after, comments to if node, n.
*/

extern "C" void decl_addIfComments (decl_node n, decl_node body, decl_node after)
{
  mcDebug_assert (decl_isIf (n));
  static_cast<decl_node__opaque> (n)->ifF.ifComment.after = static_cast<decl_node__opaque> (after);
  static_cast<decl_node__opaque> (n)->ifF.ifComment.body = static_cast<decl_node__opaque> (body);
}


/*
   addElseComments - adds the, body, and, after, comments to an, if, or an elsif, node, n.
*/

extern "C" void decl_addElseComments (decl_node n, decl_node body, decl_node after)
{
  mcDebug_assert ((decl_isIf (n)) || (decl_isElsif (n)));
  if (decl_isIf (n))
    {
      static_cast<decl_node__opaque> (n)->ifF.elseComment.after = static_cast<decl_node__opaque> (after);
      static_cast<decl_node__opaque> (n)->ifF.elseComment.body = static_cast<decl_node__opaque> (body);
    }
  else
    {
      static_cast<decl_node__opaque> (n)->elsifF.elseComment.after = static_cast<decl_node__opaque> (after);
      static_cast<decl_node__opaque> (n)->elsifF.elseComment.body = static_cast<decl_node__opaque> (body);
    }
}


/*
   addIfEndComments - adds the, body, and, after, comments to an, if, node, n.
*/

extern "C" void decl_addIfEndComments (decl_node n, decl_node body, decl_node after)
{
  mcDebug_assert (decl_isIf (n));
  static_cast<decl_node__opaque> (n)->ifF.endComment.after = static_cast<decl_node__opaque> (after);
  static_cast<decl_node__opaque> (n)->ifF.endComment.body = static_cast<decl_node__opaque> (body);
}


/*
   makeReturn - creates and returns a return node.
*/

extern "C" decl_node decl_makeReturn (void)
{
  decl_node__opaque type;
  decl_node__opaque n;

  n = newNode (decl_return);
  n->returnF.exp = static_cast<decl_node__opaque> (NULL);
  if (decl_isProcedure (decl_getDeclScope ()))
    {
      n->returnF.scope = static_cast<decl_node__opaque> (decl_getDeclScope ());
    }
  else
    {
      n->returnF.scope = static_cast<decl_node__opaque> (NULL);
    }
  initPair (&n->returnF.returnComment);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isReturn - returns TRUE if node, n, is a return.
*/

extern "C" bool decl_isReturn (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_return;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putReturn - assigns node, e, as the expression on the return node.
*/

extern "C" void decl_putReturn (decl_node n, decl_node e)
{
  mcDebug_assert (decl_isReturn (n));
  static_cast<decl_node__opaque> (n)->returnF.exp = static_cast<decl_node__opaque> (e);
}


/*
   makeWhile - creates and returns a while node.
*/

extern "C" decl_node decl_makeWhile (void)
{
  decl_node__opaque n;

  n = newNode (decl_while);
  n->whileF.expr = static_cast<decl_node__opaque> (NULL);
  n->whileF.statements = static_cast<decl_node__opaque> (NULL);
  initPair (&n->whileF.doComment);
  initPair (&n->whileF.endComment);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putWhile - places an expression, e, and statement sequence, s, into the while
              node, n.
*/

extern "C" void decl_putWhile (decl_node n, decl_node e, decl_node s)
{
  mcDebug_assert (decl_isWhile (n));
  static_cast<decl_node__opaque> (n)->whileF.expr = static_cast<decl_node__opaque> (e);
  static_cast<decl_node__opaque> (n)->whileF.statements = static_cast<decl_node__opaque> (s);
}


/*
   isWhile - returns TRUE if node, n, is a while.
*/

extern "C" bool decl_isWhile (decl_node n)
{
  return static_cast<decl_node__opaque> (n)->kind == decl_while;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   addWhileDoComment - adds body and after comments to while node, w.
*/

extern "C" void decl_addWhileDoComment (decl_node w, decl_node body, decl_node after)
{
  mcDebug_assert (decl_isWhile (w));
  static_cast<decl_node__opaque> (w)->whileF.doComment.after = static_cast<decl_node__opaque> (after);
  static_cast<decl_node__opaque> (w)->whileF.doComment.body = static_cast<decl_node__opaque> (body);
}


/*
   addWhileEndComment - adds body and after comments to the end of a while node, w.
*/

extern "C" void decl_addWhileEndComment (decl_node w, decl_node body, decl_node after)
{
  mcDebug_assert (decl_isWhile (w));
  static_cast<decl_node__opaque> (w)->whileF.endComment.after = static_cast<decl_node__opaque> (after);
  static_cast<decl_node__opaque> (w)->whileF.endComment.body = static_cast<decl_node__opaque> (body);
}


/*
   makeAssignment - creates and returns an assignment node.
                    The designator is, d, and expression, e.
*/

extern "C" decl_node decl_makeAssignment (decl_node d, decl_node e)
{
  decl_node__opaque n;

  n = newNode (decl_assignment);
  n->assignmentF.des = static_cast<decl_node__opaque> (d);
  n->assignmentF.expr = static_cast<decl_node__opaque> (e);
  initPair (&n->assignmentF.assignComment);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putBegin - assigns statements, s, to be the normal part in
              block, b.  The block may be a procedure or module,
              or implementation node.
*/

extern "C" void decl_putBegin (decl_node b, decl_node s)
{
  mcDebug_assert (((decl_isImp (b)) || (decl_isProcedure (b))) || (decl_isModule (b)));
  switch (static_cast<decl_node__opaque> (b)->kind)
    {
      case decl_imp:
        static_cast<decl_node__opaque> (b)->impF.beginStatements = static_cast<decl_node__opaque> (s);
        break;

      case decl_module:
        static_cast<decl_node__opaque> (b)->moduleF.beginStatements = static_cast<decl_node__opaque> (s);
        break;

      case decl_procedure:
        static_cast<decl_node__opaque> (b)->procedureF.beginStatements = static_cast<decl_node__opaque> (s);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   putFinally - assigns statements, s, to be the final part in
                block, b.  The block may be a module
                or implementation node.
*/

extern "C" void decl_putFinally (decl_node b, decl_node s)
{
  mcDebug_assert (((decl_isImp (b)) || (decl_isProcedure (b))) || (decl_isModule (b)));
  switch (static_cast<decl_node__opaque> (b)->kind)
    {
      case decl_imp:
        static_cast<decl_node__opaque> (b)->impF.finallyStatements = static_cast<decl_node__opaque> (s);
        break;

      case decl_module:
        static_cast<decl_node__opaque> (b)->moduleF.finallyStatements = static_cast<decl_node__opaque> (s);
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
}


/*
   makeExit - creates and returns an exit node.
*/

extern "C" decl_node decl_makeExit (decl_node l, unsigned int n)
{
  decl_node__opaque e;

  mcDebug_assert (decl_isLoop (l));
  e = newNode (decl_exit);
  e->exitF.loop = static_cast<decl_node__opaque> (l);
  static_cast<decl_node__opaque> (l)->loopF.labelno = n;
  return static_cast<decl_node> (e);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isExit - returns TRUE if node, n, is an exit.
*/

extern "C" bool decl_isExit (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_exit;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeLoop - creates and returns a loop node.
*/

extern "C" decl_node decl_makeLoop (void)
{
  decl_node__opaque l;

  l = newNode (decl_loop);
  l->loopF.statements = static_cast<decl_node__opaque> (NULL);
  l->loopF.labelno = 0;
  return static_cast<decl_node> (l);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isLoop - returns TRUE if, n, is a loop node.
*/

extern "C" bool decl_isLoop (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_loop;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putLoop - places statement sequence, s, into loop, l.
*/

extern "C" void decl_putLoop (decl_node l, decl_node s)
{
  mcDebug_assert (decl_isLoop (l));
  static_cast<decl_node__opaque> (l)->loopF.statements = static_cast<decl_node__opaque> (s);
}


/*
   makeComment - creates and returns a comment node.
*/

extern "C" decl_node decl_makeComment (const char *a_, unsigned int _a_high)
{
  mcComment_commentDesc c;
  DynamicStrings_String s;
  char a[_a_high+1];

  /* make a local copy of each unbounded array.  */
  memcpy (a, a_, _a_high+1);

  c = mcComment_initComment (true);
  s = DynamicStrings_InitString ((const char *) a, _a_high);
  mcComment_addText (c, DynamicStrings_string (s));
  s = DynamicStrings_KillString (s);
  return decl_makeCommentS (c);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeCommentS - creates and returns a comment node.
*/

extern "C" decl_node decl_makeCommentS (mcComment_commentDesc c)
{
  decl_node__opaque n;

  if (c == NULL)
    {
      return static_cast<decl_node> (NULL);
    }
  else
    {
      n = newNode (decl_comment);
      n->commentF.content = c;
      return static_cast<decl_node> (n);
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeIf - creates and returns an if node.  The if node
            will have expression, e, and statement sequence, s,
            as the then component.
*/

extern "C" decl_node decl_makeIf (decl_node e, decl_node s)
{
  decl_node__opaque n;

  n = newNode (decl_if);
  n->ifF.expr = static_cast<decl_node__opaque> (e);
  n->ifF.then = static_cast<decl_node__opaque> (s);
  n->ifF.else_ = static_cast<decl_node__opaque> (NULL);
  n->ifF.elsif = static_cast<decl_node__opaque> (NULL);
  initPair (&n->ifF.ifComment);
  initPair (&n->ifF.elseComment);
  initPair (&n->ifF.endComment);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isIf - returns TRUE if, n, is an if node.
*/

extern "C" bool decl_isIf (decl_node n)
{
  return static_cast<decl_node__opaque> (n)->kind == decl_if;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeElsif - creates and returns an elsif node.
               This node has an expression, e, and statement
               sequence, s.
*/

extern "C" decl_node decl_makeElsif (decl_node i, decl_node e, decl_node s)
{
  decl_node__opaque n;

  n = newNode (decl_elsif);
  n->elsifF.expr = static_cast<decl_node__opaque> (e);
  n->elsifF.then = static_cast<decl_node__opaque> (s);
  n->elsifF.elsif = static_cast<decl_node__opaque> (NULL);
  n->elsifF.else_ = static_cast<decl_node__opaque> (NULL);
  initPair (&n->elsifF.elseComment);
  mcDebug_assert ((decl_isIf (i)) || (decl_isElsif (i)));
  if (decl_isIf (i))
    {
      static_cast<decl_node__opaque> (i)->ifF.elsif = n;
      mcDebug_assert (static_cast<decl_node__opaque> (i)->ifF.else_ == NULL);
    }
  else
    {
      static_cast<decl_node__opaque> (i)->elsifF.elsif = n;
      mcDebug_assert (static_cast<decl_node__opaque> (i)->elsifF.else_ == NULL);
    }
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isElsif - returns TRUE if node, n, is an elsif node.
*/

extern "C" bool decl_isElsif (decl_node n)
{
  return static_cast<decl_node__opaque> (n)->kind == decl_elsif;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putElse - the else is grafted onto the if/elsif node, i,
             and the statement sequence will be, s.
*/

extern "C" void decl_putElse (decl_node i, decl_node s)
{
  mcDebug_assert ((decl_isIf (i)) || (decl_isElsif (i)));
  if (decl_isIf (i))
    {
      mcDebug_assert (static_cast<decl_node__opaque> (i)->ifF.elsif == NULL);
      mcDebug_assert (static_cast<decl_node__opaque> (i)->ifF.else_ == NULL);
      static_cast<decl_node__opaque> (i)->ifF.else_ = static_cast<decl_node__opaque> (s);
    }
  else
    {
      mcDebug_assert (static_cast<decl_node__opaque> (i)->elsifF.elsif == NULL);
      mcDebug_assert (static_cast<decl_node__opaque> (i)->elsifF.else_ == NULL);
      static_cast<decl_node__opaque> (i)->elsifF.else_ = static_cast<decl_node__opaque> (s);
    }
}


/*
   makeFor - creates and returns a for node.
*/

extern "C" decl_node decl_makeFor (void)
{
  decl_node__opaque n;

  n = newNode (decl_for);
  n->forF.des = static_cast<decl_node__opaque> (NULL);
  n->forF.start = static_cast<decl_node__opaque> (NULL);
  n->forF.end = static_cast<decl_node__opaque> (NULL);
  n->forF.increment = static_cast<decl_node__opaque> (NULL);
  n->forF.statements = static_cast<decl_node__opaque> (NULL);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isFor - returns TRUE if node, n, is a for node.
*/

extern "C" bool decl_isFor (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_for;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putFor - assigns the fields of the for node with
            ident, i,
            start, s,
            end, e,
            increment, i,
            statements, sq.
*/

extern "C" void decl_putFor (decl_node f, decl_node i, decl_node s, decl_node e, decl_node b, decl_node sq)
{
  mcDebug_assert (decl_isFor (f));
  static_cast<decl_node__opaque> (f)->forF.des = static_cast<decl_node__opaque> (i);
  static_cast<decl_node__opaque> (f)->forF.start = static_cast<decl_node__opaque> (s);
  static_cast<decl_node__opaque> (f)->forF.end = static_cast<decl_node__opaque> (e);
  static_cast<decl_node__opaque> (f)->forF.increment = static_cast<decl_node__opaque> (b);
  static_cast<decl_node__opaque> (f)->forF.statements = static_cast<decl_node__opaque> (sq);
}


/*
   makeRepeat - creates and returns a repeat node.
*/

extern "C" decl_node decl_makeRepeat (void)
{
  decl_node__opaque n;

  n = newNode (decl_repeat);
  n->repeatF.expr = static_cast<decl_node__opaque> (NULL);
  n->repeatF.statements = static_cast<decl_node__opaque> (NULL);
  initPair (&n->repeatF.repeatComment);
  initPair (&n->repeatF.untilComment);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isRepeat - returns TRUE if node, n, is a repeat node.
*/

extern "C" bool decl_isRepeat (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_repeat;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putRepeat - places statements, s, and expression, e, into
               repeat statement, n.
*/

extern "C" void decl_putRepeat (decl_node n, decl_node s, decl_node e)
{
  static_cast<decl_node__opaque> (n)->repeatF.expr = static_cast<decl_node__opaque> (e);
  static_cast<decl_node__opaque> (n)->repeatF.statements = static_cast<decl_node__opaque> (s);
}


/*
   addRepeatComment - adds body and after comments to repeat node, r.
*/

extern "C" void decl_addRepeatComment (decl_node r, decl_node body, decl_node after)
{
  mcDebug_assert (decl_isRepeat (r));
  static_cast<decl_node__opaque> (r)->repeatF.repeatComment.after = static_cast<decl_node__opaque> (after);
  static_cast<decl_node__opaque> (r)->repeatF.repeatComment.body = static_cast<decl_node__opaque> (body);
}


/*
   addUntilComment - adds body and after comments to the until section of a repeat node, r.
*/

extern "C" void decl_addUntilComment (decl_node r, decl_node body, decl_node after)
{
  mcDebug_assert (decl_isRepeat (r));
  static_cast<decl_node__opaque> (r)->repeatF.untilComment.after = static_cast<decl_node__opaque> (after);
  static_cast<decl_node__opaque> (r)->repeatF.untilComment.body = static_cast<decl_node__opaque> (body);
}


/*
   makeCase - builds and returns a case statement node.
*/

extern "C" decl_node decl_makeCase (void)
{
  decl_node__opaque n;

  n = newNode (decl_case);
  n->caseF.expression = static_cast<decl_node__opaque> (NULL);
  n->caseF.caseLabelList = Indexing_InitIndex (1);
  n->caseF.else_ = static_cast<decl_node__opaque> (NULL);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isCase - returns TRUE if node, n, is a case statement.
*/

extern "C" bool decl_isCase (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_case;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putCaseExpression - places expression, e, into case statement, n.
                       n is returned.
*/

extern "C" decl_node decl_putCaseExpression (decl_node n, decl_node e)
{
  mcDebug_assert (decl_isCase (n));
  static_cast<decl_node__opaque> (n)->caseF.expression = static_cast<decl_node__opaque> (e);
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putCaseElse - places else statement, e, into case statement, n.
                 n is returned.
*/

extern "C" decl_node decl_putCaseElse (decl_node n, decl_node e)
{
  mcDebug_assert (decl_isCase (n));
  static_cast<decl_node__opaque> (n)->caseF.else_ = static_cast<decl_node__opaque> (e);
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putCaseStatement - places a caselist, l, and associated
                      statement sequence, s, into case statement, n.
                      n is returned.
*/

extern "C" decl_node decl_putCaseStatement (decl_node n, decl_node l, decl_node s)
{
  mcDebug_assert (decl_isCase (n));
  mcDebug_assert (decl_isCaseList (l));
  Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (n)->caseF.caseLabelList, reinterpret_cast <void *> (decl_makeCaseLabelList (l, s)));
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeCaseLabelList - creates and returns a caselabellist node.
*/

extern "C" decl_node decl_makeCaseLabelList (decl_node l, decl_node s)
{
  decl_node__opaque n;

  n = newNode (decl_caselabellist);
  n->caselabellistF.caseList = static_cast<decl_node__opaque> (l);
  n->caselabellistF.statements = static_cast<decl_node__opaque> (s);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isCaseLabelList - returns TRUE if, n, is a caselabellist.
*/

extern "C" bool decl_isCaseLabelList (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_caselabellist;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeCaseList - creates and returns a case statement node.
*/

extern "C" decl_node decl_makeCaseList (void)
{
  decl_node__opaque n;

  n = newNode (decl_caselist);
  n->caselistF.rangePairs = Indexing_InitIndex (1);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isCaseList - returns TRUE if, n, is a case list.
*/

extern "C" bool decl_isCaseList (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_caselist;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   putCaseRange - places the case range lo..hi into caselist, n.
*/

extern "C" decl_node decl_putCaseRange (decl_node n, decl_node lo, decl_node hi)
{
  mcDebug_assert (decl_isCaseList (n));
  Indexing_IncludeIndiceIntoIndex (static_cast<decl_node__opaque> (n)->caselistF.rangePairs, reinterpret_cast <void *> (decl_makeRange (lo, hi)));
  return n;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   makeRange - creates and returns a case range.
*/

extern "C" decl_node decl_makeRange (decl_node lo, decl_node hi)
{
  decl_node__opaque n;

  n = newNode (decl_range);
  n->rangeF.lo = static_cast<decl_node__opaque> (lo);
  n->rangeF.hi = static_cast<decl_node__opaque> (hi);
  return static_cast<decl_node> (n);
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   isRange - returns TRUE if node, n, is a range.
*/

extern "C" bool decl_isRange (decl_node n)
{
  mcDebug_assert (n != NULL);
  return static_cast<decl_node__opaque> (n)->kind == decl_range;
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   setNoReturn - sets noreturn field inside procedure.
*/

extern "C" void decl_setNoReturn (decl_node n, bool value)
{
  mcDebug_assert (n != NULL);
  mcDebug_assert (decl_isProcedure (n));
  if (static_cast<decl_node__opaque> (n)->procedureF.noreturnused && (static_cast<decl_node__opaque> (n)->procedureF.noreturn != value))
    {
      mcMetaError_metaError1 ((const char *) "{%1DMad} definition module and implementation module have different <* noreturn *> attributes", 93, (const unsigned char *) &n, (sizeof (n)-1));
    }
  static_cast<decl_node__opaque> (n)->procedureF.noreturn = value;
  static_cast<decl_node__opaque> (n)->procedureF.noreturnused = true;
}


/*
   dupExpr - duplicate the expression nodes, it does not duplicate
             variables, literals, constants but only the expression
             operators (including function calls and parameter lists).
*/

extern "C" decl_node decl_dupExpr (decl_node n)
{
  if (n == NULL)
    {
      return static_cast<decl_node> (NULL);
    }
  else
    {
      return static_cast<decl_node> (doDupExpr (static_cast<decl_node__opaque> (n)));
    }
  /* static analysis guarentees a RETURN statement will be used before here.  */
  __builtin_unreachable ();
}


/*
   setLangC -
*/

extern "C" void decl_setLangC (void)
{
  lang = decl_ansiC;
}


/*
   setLangCP -
*/

extern "C" void decl_setLangCP (void)
{
  lang = decl_ansiCP;
  keyc_cp ();
}


/*
   setLangM2 -
*/

extern "C" void decl_setLangM2 (void)
{
  lang = decl_pim4;
}


/*
   out - walks the tree of node declarations for the main module
         and writes the output to the outputFile specified in
         mcOptions.  It outputs the declarations in the language
         specified above.
*/

extern "C" void decl_out (void)
{
  mcPretty_pretty p;

  openOutput ();
  p = mcPretty_initPretty ((mcPretty_writeProc) {(mcPretty_writeProc_t) write_}, (mcPretty_writeLnProc) {(mcPretty_writeLnProc_t) writeln});
  switch (lang)
    {
      case decl_ansiC:
        outC (p, static_cast<decl_node__opaque> (decl_getMainModule ()));
        break;

      case decl_ansiCP:
        outC (p, static_cast<decl_node__opaque> (decl_getMainModule ()));
        break;

      case decl_pim4:
        outM2 (p, static_cast<decl_node__opaque> (decl_getMainModule ()));
        break;


      default:
        CaseException ("../../gcc/m2/mc/decl.def", 20, 1);
        __builtin_unreachable ();
    }
  closeOutput ();
}

extern "C" void _M2_decl_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
{
  init ();
}

extern "C" void _M2_decl_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
{
}