/* translation of file "parse.k" */
/* generated by:
 *  @(#)$Author$
 */
#define KC_FUNCTIONS_parse_

#include <stdlib.h>
#include "k.h"
#include "parse.h"
namespace kc { }
using namespace kc;
/* included stuff */
//
// The Termprocessor Kimwitu++
//
// Copyright (C) 1991 University of Twente, Dept TIOS.
// Copyright (C) 1998-2003 Humboldt-University of Berlin, Institute of Informatics
// All rights reserved.
//
// Kimwitu++ 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 2 of the License, or
// (at your option) any later version.
//
// Kimwitu++ 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 Kimwitu++; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

static char parse_kAccesSid[] = "@(#)$Id$";

int pg_lineno = 1;					/* global line # */
int pg_column = 0;					/* global column # */
int pg_charpos = 0;					/* global charpos # */
casestring pg_filename;					/* global file name */
int pg_no_of_arguments;					/* no_of_arguments */
phylumdeclarations Thephylumdeclarations;		/* global phylumdecls */
rwdeclarations Therwdeclarations;			/* global rw-decls */
fndeclarations Thefndeclarations;			/* fn-decls for the file being parsed */
fnfiles Thefnfiles;					/* global fn-decls */
includefiles Theincludefiles;				/* global incl-decls */
unparsedeclarations Theunparsedeclarations;		/* global unp-decls */
argsnumbers Theargsnumbers;				/* global list of argsnumbers */
viewnames Theuviewnames;				/* global list of u-viewnames */
viewnames Therviewnames;				/* global list of r-viewnames */
storageclasses Thestorageclasses;			/* global list of storageclasses */
languagenames Thelanguages;				/* global list of used languages */
baseclass_declarations Thebaseclasses;			/* global list of defined baseclasses */
bool pg_uviewshavebeendefined;				/* global indication */
bool pg_rviewshavebeendefined;				/* global indication */
bool pg_storageclasseshavebeendefined;			/* global indication */
bool pg_languageshavebeendefined;			/* global indication */

static long language_text_nr=0;
static bool language_text_nr_used=false;

#include "util.h"

/* end included stuff */


namespace kc {

#ifndef KC_TRACE_PROVIDED
#define KC_TRACE_PROVIDED(COND,FILE,LINE,NODE) COND
#endif

static  ID f_ID_of_direct_decl (ac_direct_declarator d);
static  int f_stars_of_ac_pointer_option (ac_pointer_option d);
static  int f_stars_of_ac_pointer (ac_pointer d);
static  bool f_is_member_fn (ac_declarator dec);
static  bool f_static_in_ac_decl_spec (ac_declaration_specifier ds);
static  bool f_static_in_ac_stor_class (ac_storage_class_specifier sc);
static  ID f_ID_of_ac_declaration_specifier (ac_declaration_specifier d);
static  ID f_ID_of_ac_type_specifier (ac_type_specifier d);
phylumdeclarations mergephylumdeclarations(phylumdeclaration pd, phylumdeclarations pds)
{{
	phylumdeclaration kc_selvar_0_1 = phylum_cast<phylumdeclaration>(pd);
	if ((kc_selvar_0_1->prod_sel() == sel_PhylumDeclaration)) {
	    const ID pd_id = phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_0_1)->ID_1;
	    const storageoption pd_stopt = phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_0_1)->storageoption_1;
	    const productionblock pd_pb = phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_0_1)->productionblock_1;
	    const Ccode_option pd_ccopt = phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_0_1)->Ccode_option_1;

	    phylumdeclaration fpd = f_lookupuserdecl( pd_id );
	    if (!fpd) {
		v_add( pd_id );
		return Consphylumdeclarations( pd, pds );
	    } else if ( pd == fpd ) {
		if ( f_added( pd_id ) ) {
		    return pds;
		} else {
		    v_add( pd_id );
		    return Consphylumdeclarations( pd, pds );
		}
	    }

	    {
		phylumdeclaration kc_selvar_1_1 = phylum_cast<phylumdeclaration>( fpd );
		if ((kc_selvar_1_1->prod_sel() == sel_PhylumDeclaration)) {
		    const ID fpd_id = phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_1_1)->ID_1;
		    const storageoption fpd_stopt = phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_1_1)->storageoption_1;
		    const productionblock fpd_pb = phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_1_1)->productionblock_1;
		    const Ccode_option fpd_ccopt = phylum_cast<const impl_phylumdeclaration_PhylumDeclaration*>(kc_selvar_1_1)->Ccode_option_1;

		    {
			storageoption kc_selvar_2_1 = phylum_cast<storageoption>( pd_stopt);
			storageoption kc_selvar_2_2 = phylum_cast<storageoption>( fpd_stopt );
			if ((kc_selvar_2_1->prod_sel() == sel_PositiveStorageOption) && (kc_selvar_2_2->prod_sel() == sel_NegativeStorageOption) && (phylum_cast<const impl_storageoption_NegativeStorageOption*>(kc_selvar_2_2)->ID_1->eq(phylum_cast<const impl_storageoption_PositiveStorageOption*>(kc_selvar_2_1)->ID_1))) {
			    const ID id = phylum_cast<const impl_storageoption_PositiveStorageOption*>(kc_selvar_2_1)->ID_1;

			    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1storageoption1S1ID( "storage option mismatch  ( declared as ", fpd_stopt, ")  for phylum", fpd_id )));

			} else
			    if ((kc_selvar_2_1->prod_sel() == sel_NegativeStorageOption) && (kc_selvar_2_2->prod_sel() == sel_PositiveStorageOption) && (phylum_cast<const impl_storageoption_PositiveStorageOption*>(kc_selvar_2_2)->ID_1->eq(phylum_cast<const impl_storageoption_NegativeStorageOption*>(kc_selvar_2_1)->ID_1))) {
			    const ID id = phylum_cast<const impl_storageoption_NegativeStorageOption*>(kc_selvar_2_1)->ID_1;

			    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1storageoption1S1ID( "storage option mismatch  ( declared as ", fpd_stopt, ")  for phylum", fpd_id )));

			} else
			    if ((kc_selvar_2_1->prod_sel() == sel_PositiveStorageOption) && (kc_selvar_2_2->prod_sel() == sel_PositiveStorageOption) && (phylum_cast<const impl_storageoption_PositiveStorageOption*>(kc_selvar_2_2)->ID_1->eq(phylum_cast<const impl_storageoption_PositiveStorageOption*>(kc_selvar_2_1)->ID_1))) {
			    const ID id = phylum_cast<const impl_storageoption_PositiveStorageOption*>(kc_selvar_2_1)->ID_1;

			} else
			    if ((kc_selvar_2_1->prod_sel() == sel_NegativeStorageOption) && (kc_selvar_2_2->prod_sel() == sel_NegativeStorageOption) && (phylum_cast<const impl_storageoption_NegativeStorageOption*>(kc_selvar_2_2)->ID_1->eq(phylum_cast<const impl_storageoption_NegativeStorageOption*>(kc_selvar_2_1)->ID_1))) {
			    const ID id = phylum_cast<const impl_storageoption_NegativeStorageOption*>(kc_selvar_2_1)->ID_1;

			} else
			    if ((kc_selvar_2_1->prod_sel() == sel_NoStorageOption)) {
			    /*EMPTY*/  
			    	} else
			    if ((kc_selvar_2_2->prod_sel() == sel_NoStorageOption)) {
			    static_cast<impl_phylumdeclaration_PhylumDeclaration*>(fpd)->storageoption_1 = pd_stopt; 
			    	} else
			{




			    v_report(NonFatal( FileLine( pd_id->file, pd_id->line ), Problem1S1storageoption1S1ID( "storage option mismatch  ( declared as ", fpd_stopt, ")  for phylum", fpd_id )));

			}
		    }
		    {
			productionblock kc_selvar_2_1 = phylum_cast<productionblock>( pd_pb);
			productionblock kc_selvar_2_2 = phylum_cast<productionblock>( fpd_pb );
			if ((kc_selvar_2_1->prod_sel() == sel_NonlistAlternatives) && (kc_selvar_2_2->prod_sel() == sel_NonlistAlternatives)) {
			    const alternatives pd_pb_a = phylum_cast<const impl_productionblock_NonlistAlternatives*>(kc_selvar_2_1)->alternatives_1;
			    const alternatives fpd_pb_a = phylum_cast<const impl_productionblock_NonlistAlternatives*>(kc_selvar_2_2)->alternatives_1;

			    static_cast<impl_productionblock_NonlistAlternatives*>(fpd_pb)->alternatives_1 = concat(pd_pb_a, fpd_pb_a );

			} else
			    if ((kc_selvar_2_1->prod_sel() == sel_NonlistAlternatives) && (kc_selvar_2_2->prod_sel() == sel_Emptyproductionblock)) {
			    static_cast<impl_phylumdeclaration_PhylumDeclaration*>(fpd)->productionblock_1 = pd_pb; 
			    	} else
			    if ((kc_selvar_2_1->prod_sel() == sel_PredefinedAlternatives) && (kc_selvar_2_2->prod_sel() == sel_Emptyproductionblock)) {
			    static_cast<impl_phylumdeclaration_PhylumDeclaration*>(fpd)->productionblock_1 = pd_pb; 
			    	} else
			    if ((kc_selvar_2_1->prod_sel() == sel_ListAlternatives) && (kc_selvar_2_2->prod_sel() == sel_Emptyproductionblock)) {
			    static_cast<impl_phylumdeclaration_PhylumDeclaration*>(fpd)->productionblock_1 = pd_pb; 
			    	} else
			    if ((kc_selvar_2_1->prod_sel() == sel_Emptyproductionblock) && (kc_selvar_2_2->prod_sel() == sel_Emptyproductionblock)) {
			    /*EMPTY*/  
			    	} else
			    if ((kc_selvar_2_1->prod_sel() == sel_NonlistAlternatives)) {

			    v_report(NonFatal( FileLine( pd_id->file, pd_id->line ), Problem1S1ID( "production block mismatch: trying to extend phylum", pd_id )));

			} else
			    if ((kc_selvar_2_1->prod_sel() == sel_PredefinedAlternatives)) {

			    v_report(NonFatal( FileLine( pd_id->file, pd_id->line ), Problem1S1ID( "production block mismatch: trying to predefine phylum", pd_id )));

			} else
			    if ((kc_selvar_2_1->prod_sel() == sel_ListAlternatives)) {

			    v_report(NonFatal( FileLine( pd_id->file, pd_id->line ), Problem1S1ID( "production block mismatch: trying to redefine list phylum", pd_id )));

			} else
			    if ((kc_selvar_2_1->prod_sel() == sel_Emptyproductionblock)) {
			    /*EMPTY*/  
			    	} else
			{ kc_no_default_in_with( "mergephylumdeclarations", __LINE__, __FILE__ );
			    return static_cast<phylumdeclarations>(0); }
		    }
		    {
			Ccode_option kc_selvar_2_1 = phylum_cast<Ccode_option>( pd_ccopt);
			Ccode_option kc_selvar_2_2 = phylum_cast<Ccode_option>( fpd_ccopt );
			if ((kc_selvar_2_1->prod_sel() == sel_CcodeOption) && (kc_selvar_2_2->prod_sel() == sel_CcodeOption)) {
			    const attributes pd_ccopt_attr = phylum_cast<const impl_Ccode_option_CcodeOption*>(kc_selvar_2_1)->attributes_1;
			    const Ctexts pd_ccopt_ct = phylum_cast<const impl_Ccode_option_CcodeOption*>(kc_selvar_2_1)->Ctexts_1;
			    const attributes fpd_ccopt_attr = phylum_cast<const impl_Ccode_option_CcodeOption*>(kc_selvar_2_2)->attributes_1;
			    const Ctexts fpd_ccopt_ct = phylum_cast<const impl_Ccode_option_CcodeOption*>(kc_selvar_2_2)->Ctexts_1;

			    static_cast<impl_phylumdeclaration_PhylumDeclaration*>(fpd)->Ccode_option_1 = CcodeOption( concat(pd_ccopt_attr, fpd_ccopt_attr), concat(pd_ccopt_ct, fpd_ccopt_ct ));

			} else
			{ kc_no_default_in_with( "mergephylumdeclarations", __LINE__, __FILE__ );
			    return static_cast<phylumdeclarations>(0); }
		    }

		} else
		{ kc_no_default_in_with( "mergephylumdeclarations", __LINE__, __FILE__ );
		    return static_cast<phylumdeclarations>(0); }
	    }
	    return pds;

	} else
	{ kc_no_default_in_with( "mergephylumdeclarations", __LINE__, __FILE__ );
	    return static_cast<phylumdeclarations>(0); }
    }

}

alternatives makeListAlternatives(ID listphylum, ID elementphylum)
{
    ID Nil_id, Cons_id;
    alternative Nil_alternative, Cons_alternative;
    Nil_id = Id( Str( mkcasestring((string("Nil")+f_strofID(listphylum)).c_str())));
    Cons_id = Id( Str( mkcasestring((string("Cons")+f_strofID(listphylum)).c_str())));
    Nil_id->line = elementphylum->line;
    Nil_id->file = elementphylum->file;
    Cons_id->line = elementphylum->line;
    Cons_id->file = elementphylum->file;
    Nil_alternative = Alternative( Nil_id, Nilarguments() );
    Cons_alternative = Alternative( Cons_id, Consarguments( listphylum, Consarguments( elementphylum, Nilarguments() ) ) );
    v_extendoccur( Nil_id, ITUserOperator( Nil_alternative, listphylum ) );
    v_extendoccur( Cons_id, ITUserOperator( Cons_alternative, listphylum ) );
    return Consalternatives( Cons_alternative, Consalternatives( Nil_alternative, Nilalternatives() ) );

}

const char *f_strofID(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id) && (phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1->prod_sel() == sel_Str)) {
	    const casestring cs = phylum_cast<const impl_uniqID_Str*>(phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1)->casestring_1;
	    return cs->name; 
	    	} else
	{ kc_no_default_in_with( "f_strofID", __LINE__, __FILE__ );
	    return static_cast<char*>(0); }
    }

}

phylumdeclaration f_lookupuserdecl(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITUserFunction)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined function:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITUserRView)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined rewrite view:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedRView)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined rewrite view:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITUserUView)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined unparse view:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedUView)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined unparse view:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITStorageClass)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined storage class:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedStorageClass)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined storage class:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITUserOperator)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined operator:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedOperator)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined operator:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITUserPhylum)) {
		    const phylumdeclaration pd = phylum_cast<const impl_IDtype_ITUserPhylum*>(kc_selvar_1_1)->phylumdeclaration_1;
		    return pd; 
		    	} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedPhylum)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined phylum:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITUnknown)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "undefined phylum:", id )));
		    return 0;

		} else
		{ kc_no_default_in_with( "f_lookupuserdecl", __LINE__, __FILE__ );
		    return static_cast<phylumdeclaration>(0); }
	    }

	} else
	{ kc_no_default_in_with( "f_lookupuserdecl", __LINE__, __FILE__ );
	    return static_cast<phylumdeclaration>(0); }
    }

}

phylumdeclaration f_lookupdecl(ID id)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(id);
	if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
	    const uniqID uid = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

	    {
		IDtype kc_selvar_1_1 = phylum_cast<IDtype>( uid->type );
		if ((kc_selvar_1_1->prod_sel() == sel_ITUserFunction)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined function:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITUserRView)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined rewrite view:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedRView)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined rewrite view:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITUserUView)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined unparse view:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedUView)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined unparse view:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITStorageClass)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined storage class:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedStorageClass)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined storage class:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITUserOperator)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of user-defined operator:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedOperator)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "expected user-defined phylum instead of predefined operator:", id )));
		    return 0;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITUserPhylum)) {
		    const phylumdeclaration pd = phylum_cast<const impl_IDtype_ITUserPhylum*>(kc_selvar_1_1)->phylumdeclaration_1;
		    return pd; 
		    	} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITPredefinedPhylum)) {
		    const phylumdeclaration pd = phylum_cast<const impl_IDtype_ITPredefinedPhylum*>(kc_selvar_1_1)->phylumdeclaration_1;
		    return pd; 
		    	} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ITUnknown)) {

		    v_report(NonFatal( FileLine( id->file, id->line ), Problem1S1ID( "undefined phylum:", id )));
		    return 0;

		} else
		{ kc_no_default_in_with( "f_lookupdecl", __LINE__, __FILE__ );
		    return static_cast<phylumdeclaration>(0); }
	    }

	} else
	{ kc_no_default_in_with( "f_lookupdecl", __LINE__, __FILE__ );
	    return static_cast<phylumdeclaration>(0); }
    }

}

argsnumbers insert_in_argsnumbers(int i, argsnumbers a)
{{
	argsnumbers kc_selvar_0_1 = phylum_cast<argsnumbers>(a);
	if ((kc_selvar_0_1->prod_sel() == sel_Consargsnumbers)) {
	    const integer j = (kc_selvar_0_1)->integer_1;
	    const argsnumbers ra = (kc_selvar_0_1)->argsnumbers_1;

	    if ( i < j->value )
	    return Consargsnumbers( mkinteger(i), a );
	    else if ( i == j->value )
	    return a;
	    else
	    return Consargsnumbers( j, insert_in_argsnumbers( i, ra ));

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilargsnumbers)) {
	    return Consargsnumbers( mkinteger(i), a ); 
	    	} else
	{ kc_no_default_in_with( "insert_in_argsnumbers", __LINE__, __FILE__ );
	    return static_cast<argsnumbers>(0); }
    }

}

void set_includefiles(includefiles ifs, includedeclaration i)
{
    {
	includefiles kc_fe_selvar_1 =  ifs ;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Consincludefiles
	    ) {
	    includefile kc_selvar_0_1 = kc_fe_selvar_1->includefile_1;
	    {
		{
		    {
			const includefile pl_includefile = kc_selvar_0_1;

			assertCond((pl_includefile->inc_type == include_file) || (pl_includefile->inc_type == include_header));
			pl_includefile->inc[pl_includefile->inc_type] =
			Consincludedeclarations( i, pl_includefile->inc[pl_includefile->inc_type] );

		    }
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->includefiles_1;

	}
    }

}

languagenames merge_languagenames(languagenames names, languagenames name_list)
{
    languagenames res=name_list;
    {
	languagenames kc_fe_selvar_1 =  names ;

	while(
		kc_fe_selvar_1->prod_sel() == sel_Conslanguagenames
	    ) {
	    ID kc_selvar_0_1 = kc_fe_selvar_1->ID_1;
	    {
		{
		    if ((kc_selvar_0_1->prod_sel() == sel_Id)) {
			const ID id = kc_selvar_0_1;
			const uniqID u_id = phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1;

			if(u_id->type->eq(ITUnknown())) {
			    res=Conslanguagenames(id,res);
			    u_id->type=ITLanguageName(
				mkinteger(res->length()-1));
			}

		    } else
		    {/* EMPTY */ /*skip: no matching pattern in foreach patterns*/}
		}

	    }
	    kc_fe_selvar_1 = kc_fe_selvar_1->languagenames_1;

	}
    }
    return res;

}

long get_text_nr()
{
    language_text_nr_used=true;
    return language_text_nr;

}

void inc_text_nr()
{
    if(language_text_nr_used) {
	language_text_nr++;
	language_text_nr_used=false;
    }

}

long last_text_nr()
{
    if(language_text_nr_used)
    return language_text_nr;
    else
    return language_text_nr-1;

}

ID f_ID_of_declarator(ac_declarator d)
{{
	ac_declarator kc_selvar_0_1 = phylum_cast<ac_declarator>(d);
	if ((kc_selvar_0_1->prod_sel() == sel_AcDeclarator)) {
	    const ac_direct_declarator dd = phylum_cast<const impl_ac_declarator_AcDeclarator*>(kc_selvar_0_1)->ac_direct_declarator_1;

	    return f_ID_of_direct_decl( dd );

	} else
	{ kc_no_default_in_with( "f_ID_of_declarator", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

ID f_ID_of_fn_declarator(ac_declarator d, fnclass fnc)
{{
	ac_declarator kc_selvar_0_1 = phylum_cast<ac_declarator>(d);
	if ((kc_selvar_0_1->prod_sel() == sel_AcDeclarator)) {
	    const ac_direct_declarator dd = phylum_cast<const impl_ac_declarator_AcDeclarator*>(kc_selvar_0_1)->ac_direct_declarator_1;

	    ID id=f_ID_of_direct_decl( dd );
	    {
		fnclass kc_selvar_1_1 = phylum_cast<fnclass>(fnc);
		if ((kc_selvar_1_1->prod_sel() == sel_DestructorFn)) {

		    static int dtor_nr=0;
		    char buf[30];
		    sprintf(buf,"destructor_%d",++dtor_nr);
		    ID new_id=Id(Str(mkcasestring(buf)));
		    new_id->file=id->file;
		    new_id->line=id->line;
		    return new_id;

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_ConstructorFn)) {

		    static int ctor_nr=0;
		    char buf[30];
		    sprintf(buf,"constructor_%d",++ctor_nr);
		    ID new_id=Id(Str(mkcasestring(buf)));
		    new_id->file=id->file;
		    new_id->line=id->line;
		    return new_id;

		} else
		{
		    return id; 
		}
	    }

	} else
	{ kc_no_default_in_with( "f_ID_of_fn_declarator", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

static  ID f_ID_of_direct_decl(ac_direct_declarator d)
{{
	ac_direct_declarator kc_selvar_0_1 = phylum_cast<ac_direct_declarator>(d);
	if ((kc_selvar_0_1->prod_sel() == sel_AcQualifiedDeclProto)) {
	    const ac_direct_declarator a_d = phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(kc_selvar_0_1)->ac_direct_declarator_1;
	    return f_ID_of_direct_decl( a_d ); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcDirectDeclProto)) {
	    const ac_direct_declarator a_d = phylum_cast<const impl_ac_direct_declarator_AcDirectDeclProto*>(kc_selvar_0_1)->ac_direct_declarator_1;
	    return f_ID_of_direct_decl( a_d ); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcDirectDeclArray)) {
	    const ac_direct_declarator a_d = phylum_cast<const impl_ac_direct_declarator_AcDirectDeclArray*>(kc_selvar_0_1)->ac_direct_declarator_1;
	    return f_ID_of_direct_decl( a_d ); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcDirectDeclPack)) {
	    const ac_declarator a_d = phylum_cast<const impl_ac_direct_declarator_AcDirectDeclPack*>(kc_selvar_0_1)->ac_declarator_1;
	    return f_ID_of_declarator( a_d ); 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcDirectDeclId)) {
	    const ID i = phylum_cast<const impl_ac_direct_declarator_AcDirectDeclId*>(kc_selvar_0_1)->ID_1;
	    return i; 
	    	} else
	{
	    return f_emptyId(); 
	}
    }

}

int f_stars_of_declarator(ac_declarator d)
{{
	ac_declarator kc_selvar_0_1 = phylum_cast<ac_declarator>(d);
	if ((kc_selvar_0_1->prod_sel() == sel_AcDeclarator)) {
	    const ac_pointer_option po = phylum_cast<const impl_ac_declarator_AcDeclarator*>(kc_selvar_0_1)->ac_pointer_option_1;
	    return f_stars_of_ac_pointer_option( po ); 
	    	} else
	{
	    return 0; 
	}
    }

}

static  int f_stars_of_ac_pointer_option(ac_pointer_option d)
{{
	ac_pointer_option kc_selvar_0_1 = phylum_cast<ac_pointer_option>(d);
	if ((kc_selvar_0_1->prod_sel() == sel_Yespointer)) {
	    const ac_pointer p = phylum_cast<const impl_ac_pointer_option_Yespointer*>(kc_selvar_0_1)->ac_pointer_1;
	    return f_stars_of_ac_pointer( p ); 
	    	} else
	{
	    return 0; 
	}
    }

}

static  int f_stars_of_ac_pointer(ac_pointer d)
{{
	ac_pointer kc_selvar_0_1 = phylum_cast<ac_pointer>(d);
	if ((kc_selvar_0_1->prod_sel() == sel_AcPointerCons)) {
	    const ac_pointer p = phylum_cast<const impl_ac_pointer_AcPointerCons*>(kc_selvar_0_1)->ac_pointer_1;
	    return 1 + f_stars_of_ac_pointer( p ); 
	    	} else
	{
	    return 1; 
	}
    }

}

static  bool f_is_member_fn(ac_declarator dec)
{{
	ac_declarator kc_selvar_0_1 = phylum_cast<ac_declarator>(dec);
	if ((kc_selvar_0_1->prod_sel() == sel_AcDeclarator) && (phylum_cast<const impl_ac_declarator_AcDeclarator*>(kc_selvar_0_1)->ac_direct_declarator_1->prod_sel() == sel_AcQualifiedDeclProto) && (phylum_cast<const impl_ac_direct_declarator_AcQualifiedDeclProto*>(phylum_cast<const impl_ac_declarator_AcDeclarator*>(kc_selvar_0_1)->ac_direct_declarator_1)->ac_class_qualifier_list_1->prod_sel() == sel_Consac_class_qualifier_list)) {
	    return true; 
	    	} else
	{
	    return false; 
	}
    }

}

fnclass f_fnclass_info(ac_declaration_specifiers ds, casestring fn, ac_declarator dec)
{{
	ac_declaration_specifiers kc_selvar_0_1 = phylum_cast<ac_declaration_specifiers>(ds);
	if ((kc_selvar_0_1->prod_sel() == sel_Consac_declaration_specifiers)) {
	    const ac_declaration_specifier h = (kc_selvar_0_1)->ac_declaration_specifier_1;
	    const ac_declaration_specifiers t = (kc_selvar_0_1)->ac_declaration_specifiers_1;

	    if (f_static_in_ac_decl_spec( h )) {
		return StaticFn( fn );
	    } else {
		return f_is_member_fn(dec)?MemberFn():f_fnclass_info( t, fn , dec);
	    }

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilac_declaration_specifiers)) {

	    assertCond(!f_is_member_fn(dec)); 
	    return

	    GlobalFn(); 
	    	} else
	{ kc_no_default_in_with( "f_fnclass_info", __LINE__, __FILE__ );
	    return static_cast<fnclass>(0); }
    }

}

fnclass f_member_class_info(ac_declaration_specifiers ds, casestring fn)
{{
	ac_declaration_specifiers kc_selvar_0_1 = phylum_cast<ac_declaration_specifiers>(ds);
	if ((kc_selvar_0_1->prod_sel() == sel_Consac_declaration_specifiers)) {
	    const ac_declaration_specifier h = (kc_selvar_0_1)->ac_declaration_specifier_1;
	    const ac_declaration_specifiers t = (kc_selvar_0_1)->ac_declaration_specifiers_1;

	    if (f_static_in_ac_decl_spec( h )) {
		return StaticFn( fn );
	    } else {
		return f_member_class_info( t, fn);
	    }

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilac_declaration_specifiers)) {
	    return MemberFn(); 
	    	} else
	{ kc_no_default_in_with( "f_member_class_info", __LINE__, __FILE__ );
	    return static_cast<fnclass>(0); }
    }

}

bool f_static_in_ac_decl_specs(ac_declaration_specifiers ds)
{{
	ac_declaration_specifiers kc_selvar_0_1 = phylum_cast<ac_declaration_specifiers>(ds);
	if ((kc_selvar_0_1->prod_sel() == sel_Nilac_declaration_specifiers)) {
	    return false; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Consac_declaration_specifiers)) {
	    const ac_declaration_specifier head = (kc_selvar_0_1)->ac_declaration_specifier_1;
	    const ac_declaration_specifiers tail = (kc_selvar_0_1)->ac_declaration_specifiers_1;

	    return f_static_in_ac_decl_spec(head) || f_static_in_ac_decl_specs(tail);

	} else
	{ kc_no_default_in_with( "f_static_in_ac_decl_specs", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

static  bool f_static_in_ac_decl_spec(ac_declaration_specifier ds)
{{
	ac_declaration_specifier kc_selvar_0_1 = phylum_cast<ac_declaration_specifier>(ds);
	if ((kc_selvar_0_1->prod_sel() == sel_AcDeclSpecTypeQual)) {
	    return false; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcDeclSpecTypeSpec)) {
	    return false; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcDeclSpecStorageSpec)) {
	    const ac_storage_class_specifier a_sc = phylum_cast<const impl_ac_declaration_specifier_AcDeclSpecStorageSpec*>(kc_selvar_0_1)->ac_storage_class_specifier_1;
	    return f_static_in_ac_stor_class( a_sc ); 
	    	} else
	{ kc_no_default_in_with( "f_static_in_ac_decl_spec", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

static  bool f_static_in_ac_stor_class(ac_storage_class_specifier sc)
{{
	ac_storage_class_specifier kc_selvar_0_1 = phylum_cast<ac_storage_class_specifier>(sc);
	if ((kc_selvar_0_1->prod_sel() == sel_AcTypedef)) {
	    return false; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcExtern)) {
	    return false; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcStatic)) {
	    return true; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcRegister)) {
	    return false; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcAuto)) {
	    return false; 
	    	} else
	{ kc_no_default_in_with( "f_static_in_ac_stor_class", __LINE__, __FILE__ );
	    return static_cast<bool>(0); }
    }

}

ID f_ID_of_ac_declaration_specifiers(ac_declaration_specifiers d)
{{
	ac_declaration_specifiers kc_selvar_0_1 = phylum_cast<ac_declaration_specifiers>(d);
	if ((kc_selvar_0_1->prod_sel() == sel_Consac_declaration_specifiers)) {
	    const ac_declaration_specifier h = (kc_selvar_0_1)->ac_declaration_specifier_1;
	    const ac_declaration_specifiers t = (kc_selvar_0_1)->ac_declaration_specifiers_1;

	    ID tmp = f_ID_of_ac_declaration_specifier( h );
	    if (tmp)
	    return tmp;
	    else
	    return f_ID_of_ac_declaration_specifiers( t );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilac_declaration_specifiers)) {
	    return 0;	
	    	} else
	{ kc_no_default_in_with( "f_ID_of_ac_declaration_specifiers", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

static  ID f_ID_of_ac_declaration_specifier(ac_declaration_specifier d)
{{
	ac_declaration_specifier kc_selvar_0_1 = phylum_cast<ac_declaration_specifier>(d);
	if ((kc_selvar_0_1->prod_sel() == sel_AcDeclSpecTypeSpec)) {
	    const ac_type_specifier t = phylum_cast<const impl_ac_declaration_specifier_AcDeclSpecTypeSpec*>(kc_selvar_0_1)->ac_type_specifier_1;

	    return f_ID_of_ac_type_specifier( t );

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcDeclSpecTypeQual)) {
	    return 0; 
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_AcDeclSpecStorageSpec)) {
	    return 0; 
	    	} else
	{ kc_no_default_in_with( "f_ID_of_ac_declaration_specifier", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

static  ID f_ID_of_ac_type_specifier(ac_type_specifier d)
{{
	ac_type_specifier kc_selvar_0_1 = phylum_cast<ac_type_specifier>(d);
	if ((kc_selvar_0_1->prod_sel() == sel_AcTypeSpec)) {
	    const ID i = phylum_cast<const impl_ac_type_specifier_AcTypeSpec*>(kc_selvar_0_1)->ID_1;
	    return i; 
	    	} else
	{ kc_no_default_in_with( "f_ID_of_ac_type_specifier", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}

void check_no_patternchaingroup_in_patternchain(casestring f, int l, patternchain a_patternchain, const char *ctxt)
{{
	patternchain kc_selvar_0_1 = phylum_cast<patternchain>(a_patternchain);
	if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternchain)) {
	    /*EMPTY*/
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Conspatternchain)) {
	    const patternchainitem h = (kc_selvar_0_1)->patternchainitem_1;
	    const patternchain t = (kc_selvar_0_1)->patternchain_1;

	    check_no_patternchaingroup_in_patternchain( f, l, t, ctxt );
	    {
		patternchainitem kc_selvar_1_1 = phylum_cast<patternchainitem>( h );
		if ((kc_selvar_1_1->prod_sel() == sel_PatternchainitemGroup)) {

		    v_report(NonFatal( FileLine( f, l ), Problem3S( "no pattern grouping () allowed in", ctxt, "context." )));

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_PatternchainitemDollarid)) {
		    /*EMPTY*/
		    	} else
		    if ((kc_selvar_1_1->prod_sel() == sel_PatternchainitemOutmost)) {
		    /*EMPTY*/
		    	} else
		    kc_no_default_in_with( "check_no_patternchaingroup_in_patternchain", __LINE__, __FILE__ );
	    }

	} else
	    kc_no_default_in_with( "check_no_patternchaingroup_in_patternchain", __LINE__, __FILE__ );
    }

}

void check_no_patternchaingroup_in_patternchains(casestring f, int l, patternchains a_patternchains, const char *ctxt)
{{
	patternchains kc_selvar_0_1 = phylum_cast<patternchains>(a_patternchains);
	if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternchains)) {
	    /*EMPTY*/
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Conspatternchains)) {
	    const patternchain h = (kc_selvar_0_1)->patternchain_1;
	    const patternchains t = (kc_selvar_0_1)->patternchains_1;

	    check_no_patternchaingroup_in_patternchains( f, l, t, ctxt );
	    check_no_patternchaingroup_in_patternchain( f, l, h, ctxt );

	} else
	    kc_no_default_in_with( "check_no_patternchaingroup_in_patternchains", __LINE__, __FILE__ );
    }

}

void check_no_patternchaingroup_or_pattern_in_patternchain(casestring f, int l, patternchain a_patternchain, const char *ctxt)
{{
	patternchain kc_selvar_0_1 = phylum_cast<patternchain>(a_patternchain);
	if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternchain)) {
	    /*EMPTY*/
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Conspatternchain)) {
	    const patternchainitem h = (kc_selvar_0_1)->patternchainitem_1;
	    const patternchain t = (kc_selvar_0_1)->patternchain_1;

	    check_no_patternchaingroup_or_pattern_in_patternchain( f, l, t, ctxt );
	    {
		patternchainitem kc_selvar_1_1 = phylum_cast<patternchainitem>( h );
		if ((kc_selvar_1_1->prod_sel() == sel_PatternchainitemGroup)) {

		    v_report(NonFatal( FileLine( f, l ), Problem3S( "no pattern grouping () allowed in", ctxt, "context." )));

		} else
		    if ((kc_selvar_1_1->prod_sel() == sel_PatternchainitemDollarid)) {
		    /*EMPTY*/
		    	} else
		    if ((kc_selvar_1_1->prod_sel() == sel_PatternchainitemOutmost)) {
		    const outmostpattern op = phylum_cast<const impl_patternchainitem_PatternchainitemOutmost*>(kc_selvar_1_1)->outmostpattern_1;



		} else
		    kc_no_default_in_with( "check_no_patternchaingroup_or_pattern_in_patternchain", __LINE__, __FILE__ );
	    }

	} else
	    kc_no_default_in_with( "check_no_patternchaingroup_or_pattern_in_patternchain", __LINE__, __FILE__ );
    }

}

void check_no_patternchaingroup_or_pattern_in_patternchains(casestring f, int l, patternchains a_patternchains, const char *ctxt)
{{
	patternchains kc_selvar_0_1 = phylum_cast<patternchains>(a_patternchains);
	if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternchains)) {
	    /*EMPTY*/
	    	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Conspatternchains)) {
	    const patternchain h = (kc_selvar_0_1)->patternchain_1;
	    const patternchains t = (kc_selvar_0_1)->patternchains_1;

	    check_no_patternchaingroup_or_pattern_in_patternchains( f, l, t, ctxt );
	    check_no_patternchaingroup_or_pattern_in_patternchain( f, l, h, ctxt );

	} else
	    kc_no_default_in_with( "check_no_patternchaingroup_or_pattern_in_patternchains", __LINE__, __FILE__ );
    }

}

patternchains syn_patternchains_fileline(patternchains a_patternchains, casestring a_file, int a_line)
{{
	patternchains kc_selvar_0_1 = phylum_cast<patternchains>(a_patternchains);
	if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternchains)) {

	    kc_selvar_0_1->file = a_file;
	    kc_selvar_0_1->line = a_line;
	    return a_patternchains;

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Conspatternchains)) {
	    const patternchain h = (kc_selvar_0_1)->patternchain_1;
	    const patternchains t = (kc_selvar_0_1)->patternchains_1;

	    syn_patternchains_fileline( t, a_file, a_line  );
	    syn_patternchain_fileline( h, t->file, t->line );
	    kc_selvar_0_1->file = h->file;
	    kc_selvar_0_1->line = h->line;
	    return a_patternchains;

	} else
	{ kc_no_default_in_with( "syn_patternchains_fileline", __LINE__, __FILE__ );
	    return static_cast<patternchains>(0); }
    }

}

patternchain syn_patternchain_fileline(patternchain a_patternchain, casestring a_file, int a_line)
{{
	patternchain kc_selvar_0_1 = phylum_cast<patternchain>(a_patternchain);
	if ((kc_selvar_0_1->prod_sel() == sel_Nilpatternchain)) {

	    kc_selvar_0_1->file = a_file;
	    kc_selvar_0_1->line = a_line;
	    return a_patternchain;

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Conspatternchain)) {
	    const patternchainitem h = (kc_selvar_0_1)->patternchainitem_1;
	    const patternchain t = (kc_selvar_0_1)->patternchain_1;

	    syn_patternchain_fileline( t, a_file, a_line  );
	    kc_selvar_0_1->file = h->file;
	    kc_selvar_0_1->line = h->line;
	    return a_patternchain;

	} else
	{ kc_no_default_in_with( "syn_patternchain_fileline", __LINE__, __FILE__ );
	    return static_cast<patternchain>(0); }
    }

}

withexpressions pf_gen_foreachwith_vars(idCexpressions a_idCexpressions)
{
    static int nrof_foreach_occ = 0;
    nrof_foreach_occ++;
    return t_pf_gen_foreachwith_vars(a_idCexpressions, nrof_foreach_occ, a_idCexpressions->length(), false);

}

withexpressions pf_gen_foreachwith_listvars(idCexpressions a_idCexpressions)
{
    static int nrof_foreach_occ = 0;
    nrof_foreach_occ++;
    return t_pf_gen_foreachwith_vars(a_idCexpressions, nrof_foreach_occ, a_idCexpressions->length(), true);

}

withexpressions t_pf_gen_foreachwith_vars(idCexpressions a_idCexpressions, int occ, int nr, bool listvars)
{{
	idCexpressions kc_selvar_0_1 = phylum_cast<idCexpressions>(a_idCexpressions);
	if ((kc_selvar_0_1->prod_sel() == sel_ConsidCexpressions) && ((kc_selvar_0_1)->idCexpression_1->prod_sel() == sel_IdCexpression)) {
	    const idCexpression ice = (kc_selvar_0_1)->idCexpression_1;
	    const ID id = phylum_cast<const impl_idCexpression_IdCexpression*>((kc_selvar_0_1)->idCexpression_1)->ID_1;
	    const Cexpression ce = phylum_cast<const impl_idCexpression_IdCexpression*>((kc_selvar_0_1)->idCexpression_1)->Cexpression_1;
	    const idCexpressions t = (kc_selvar_0_1)->idCexpressions_1;

	    char tmp[BUFSIZ];
	    withexpression w;
	    withexpressions ws;
	    ID w_id;
	    if (listvars)
	    sprintf(tmp, "kc_fe_withlistvar_%d_%d", occ, nr);
	    else
	    sprintf(tmp, "kc_fe_withvar_%d_%d", occ, nr);
	    w_id = Id(Str(mkcasestring(tmp)));
	    w = WEVariable(w_id);
	    w->type = (listvars ? id : f_listelementphylum(id));
	    w->file = ce->file;
	    w->line = ce->line;
	    ice->id = w_id;
	    ws =  Conswithexpressions(
		w,
		t_pf_gen_foreachwith_vars( t, occ, nr-1, listvars));
	    ws->file = w->file;
	    ws->line = w->line;
	    return ws;

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_NilidCexpressions)) {
	    return Nilwithexpressions(); 
	    	} else
	{ kc_no_default_in_with( "t_pf_gen_foreachwith_vars", __LINE__, __FILE__ );
	    return static_cast<withexpressions>(0); }
    }

}

ac_class_qualifier_list f_check_build_qualifier_tail(ac_class_qualifier_help_list qh_list)
{{
	ac_class_qualifier_help_list kc_selvar_0_1 = phylum_cast<ac_class_qualifier_help_list>(qh_list);
	if ((kc_selvar_0_1->prod_sel() == sel_Consac_class_qualifier_help_list) && ((kc_selvar_0_1)->ac_direct_declarator_1->prod_sel() == sel_AcOperatorDeclId) && (phylum_cast<const impl_ac_direct_declarator_AcOperatorDeclId*>((kc_selvar_0_1)->ac_direct_declarator_1)->ac_operator_name_1->prod_sel() == sel_AcOperatorName)) {
	    const ac_operator_name op = phylum_cast<const impl_ac_direct_declarator_AcOperatorDeclId*>((kc_selvar_0_1)->ac_direct_declarator_1)->ac_operator_name_1;
	    const casestring str = phylum_cast<const impl_ac_operator_name_AcOperatorName*>(phylum_cast<const impl_ac_direct_declarator_AcOperatorDeclId*>((kc_selvar_0_1)->ac_direct_declarator_1)->ac_operator_name_1)->casestring_1;

	    v_report(NonFatal( FileLine( op->file, op->line ), Problem3S( "operator ",str->name, "is not a type name" )));
	    return Nilac_class_qualifier_list();

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Consac_class_qualifier_help_list) && ((kc_selvar_0_1)->ac_direct_declarator_1->prod_sel() == sel_AcDirectDeclId)) {
	    const ID id = phylum_cast<const impl_ac_direct_declarator_AcDirectDeclId*>((kc_selvar_0_1)->ac_direct_declarator_1)->ID_1;
	    const ac_class_qualifier_help_list tail = (kc_selvar_0_1)->ac_class_qualifier_help_list_1;

	    return Consac_class_qualifier_list(id,f_check_build_qualifier_tail(tail));

	} else
	    if ((kc_selvar_0_1->prod_sel() == sel_Nilac_class_qualifier_help_list)) {
	    return Nilac_class_qualifier_list(); 
	    	} else
	{ kc_no_default_in_with( "f_check_build_qualifier_tail", __LINE__, __FILE__ );
	    return static_cast<ac_class_qualifier_list>(0); }
    }

}

ac_class_qualifier_list f_check_build_qualifier(ac_class_qualifier_help_list qh_list, ac_direct_declarator &decl)
{{
	ac_class_qualifier_help_list kc_selvar_0_1 = phylum_cast<ac_class_qualifier_help_list>(qh_list);
	if ((kc_selvar_0_1->prod_sel() == sel_Consac_class_qualifier_help_list)) {
	    const ac_direct_declarator dd = (kc_selvar_0_1)->ac_direct_declarator_1;
	    const ac_class_qualifier_help_list tail = (kc_selvar_0_1)->ac_class_qualifier_help_list_1;

	    decl=dd;
	    return f_check_build_qualifier_tail(tail);

	} else
	{
	    assertCond(false); return NULL; 
	}
    }

}

ID subst_name(ID n, casestring oldname, casestring newname)
{{
	ID kc_selvar_0_1 = phylum_cast<ID>(n);
	if ((kc_selvar_0_1->prod_sel() == sel_Id) && (phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1->prod_sel() == sel_Str)) {
	    const casestring s = phylum_cast<const impl_uniqID_Str*>(phylum_cast<const impl_ID_Id*>(kc_selvar_0_1)->uniqID_1)->casestring_1;

	    if (s->eq(oldname)) {
		ID tmp = Id(Str(newname));
		tmp->file = n->file;
		tmp->line = n->line;
		return tmp;
	    } else
	    return n;

	} else
	{ kc_no_default_in_with( "subst_name", __LINE__, __FILE__ );
	    return static_cast<ID>(0); }
    }

}


} // namespace kc
