Blame parser.y

Packit 4a5d52
/***************************************************************************
Packit 4a5d52
Packit 4a5d52
    parser.y (IDL yacc parser and tree generation)
Packit 4a5d52
Packit 4a5d52
    Copyright (C) 1998, 1999 Andrew T. Veliath
Packit 4a5d52
Packit 4a5d52
    This library is free software; you can redistribute it and/or
Packit 4a5d52
    modify it under the terms of the GNU Library General Public
Packit 4a5d52
    License as published by the Free Software Foundation; either
Packit 4a5d52
    version 2 of the License, or (at your option) any later version.
Packit 4a5d52
Packit 4a5d52
    This library is distributed in the hope that it will be useful,
Packit 4a5d52
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 4a5d52
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 4a5d52
    Library General Public License for more details.
Packit 4a5d52
Packit 4a5d52
    You should have received a copy of the GNU Library General Public
Packit 4a5d52
    License along with this library; if not, write to the Free
Packit 4a5d52
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Packit 4a5d52
Packit 4a5d52
    $Id: parser.y,v 1.163 2004/11/12 15:37:11 michael Exp $
Packit 4a5d52
Packit 4a5d52
***************************************************************************/
Packit 4a5d52
%{
Packit 4a5d52
#include <assert.h>
Packit 4a5d52
#include <stdarg.h>
Packit 4a5d52
#include <stdio.h>
Packit 4a5d52
#include <stdlib.h>
Packit 4a5d52
#include <ctype.h>
Packit 4a5d52
#include <string.h>
Packit 4a5d52
#include <errno.h>
Packit 4a5d52
#include "rename.h"
Packit 4a5d52
#include "util.h"
Packit 4a5d52
Packit 4a5d52
#define REF_IDENTS
Packit 4a5d52
Packit 4a5d52
#define do_binop(rv,op,a,b)		do {		\
Packit 4a5d52
	if (IDL_binop_chktypes (op, a, b))		\
Packit 4a5d52
		YYABORT;				\
Packit 4a5d52
	if (!(__IDL_flags & IDLF_NO_EVAL_CONST)) {	\
Packit 4a5d52
		rv = IDL_binop_eval (op, a, b);		\
Packit 4a5d52
		IDL_tree_free (a);			\
Packit 4a5d52
		IDL_tree_free (b);			\
Packit 4a5d52
		if (!rv) YYABORT;			\
Packit 4a5d52
	} else {					\
Packit 4a5d52
		rv = IDL_binop_new (op, a, b);		\
Packit 4a5d52
	}						\
Packit 4a5d52
} while (0)
Packit 4a5d52
Packit 4a5d52
#define do_unaryop(rv,op,a)		do {		\
Packit 4a5d52
	if (IDL_unaryop_chktypes (op, a))		\
Packit 4a5d52
		YYABORT;				\
Packit 4a5d52
	if (!(__IDL_flags & IDLF_NO_EVAL_CONST)) {	\
Packit 4a5d52
		rv = IDL_unaryop_eval (op, a);		\
Packit 4a5d52
		IDL_tree_free (a);			\
Packit 4a5d52
		if (!rv) YYABORT;			\
Packit 4a5d52
	} else {					\
Packit 4a5d52
		rv = IDL_unaryop_new (op, a);		\
Packit 4a5d52
	}						\
Packit 4a5d52
} while (0)
Packit 4a5d52
Packit 4a5d52
#define IS_INHIBIT_STATE()				\
Packit 4a5d52
	(__IDL_inhibits > 0 ||				\
Packit 4a5d52
	  ((__IDL_flags & IDLF_INHIBIT_INCLUDES) &&	\
Packit 4a5d52
	     (__IDL_flagsi & IDLFP_IN_INCLUDES) ) )
Packit 4a5d52
Packit 4a5d52
Packit 4a5d52
#define assign_declspec(tree,declspec)	do {		\
Packit 4a5d52
	IDL_NODE_DECLSPEC (tree) = declspec;		\
Packit 4a5d52
	if ( IS_INHIBIT_STATE() ) {			\
Packit 4a5d52
		IDL_NODE_DECLSPEC (tree) |=		\
Packit 4a5d52
			IDLF_DECLSPEC_EXIST |		\
Packit 4a5d52
			IDLF_DECLSPEC_INHIBIT;		\
Packit 4a5d52
	}						\
Packit 4a5d52
	if ( __IDL_pidl > 0 ) {				\
Packit 4a5d52
		IDL_NODE_DECLSPEC (tree) |=		\
Packit 4a5d52
			IDLF_DECLSPEC_PIDL;		\
Packit 4a5d52
	}						\
Packit 4a5d52
} while (0)
Packit 4a5d52
Packit 4a5d52
#define assign_props(tree,props)	do {		\
Packit 4a5d52
	if (__IDL_flags & IDLF_PROPERTIES)		\
Packit 4a5d52
		IDL_NODE_PROPERTIES (tree) = (props);	\
Packit 4a5d52
	else						\
Packit 4a5d52
		__IDL_free_properties (props);		\
Packit 4a5d52
} while (0)
Packit 4a5d52
Packit 4a5d52
extern int		yylex				(void);
Packit 4a5d52
static IDL_declspec_t	IDL_parse_declspec		(const char *strspec);
Packit 4a5d52
static int		IDL_binop_chktypes		(enum IDL_binop op,
Packit 4a5d52
							 IDL_tree a,
Packit 4a5d52
							 IDL_tree b);
Packit 4a5d52
static int		IDL_unaryop_chktypes		(enum IDL_unaryop op,
Packit 4a5d52
							 IDL_tree a);
Packit 4a5d52
static IDL_tree		IDL_binop_eval			(enum IDL_binop op,
Packit 4a5d52
							 IDL_tree a,
Packit 4a5d52
							 IDL_tree b);
Packit 4a5d52
static IDL_tree		IDL_unaryop_eval		(enum IDL_unaryop op,
Packit 4a5d52
							 IDL_tree a);
Packit 4a5d52
static IDL_tree		list_start			(IDL_tree a,
Packit 4a5d52
							 gboolean filter_null);
Packit 4a5d52
static IDL_tree		list_chain			(IDL_tree a,
Packit 4a5d52
							 IDL_tree b,
Packit 4a5d52
							 gboolean filter_null);
Packit 4a5d52
static IDL_tree		zlist_chain			(IDL_tree a,
Packit 4a5d52
							 IDL_tree b,
Packit 4a5d52
							 gboolean filter_null);
Packit 4a5d52
static int		do_token_error			(IDL_tree p,
Packit 4a5d52
							 const char *message,
Packit 4a5d52
							 gboolean prev);
Packit 4a5d52
static void		illegal_context_type_error	(IDL_tree p,
Packit 4a5d52
							 const char *what);
Packit 4a5d52
static void		illegal_type_error		(IDL_tree p,
Packit 4a5d52
							 const char *message);
Packit 4a5d52
%}
Packit 4a5d52
Packit 4a5d52
%union {
Packit 4a5d52
	IDL_tree tree;
Packit 4a5d52
	struct {
Packit 4a5d52
		IDL_tree tree;
Packit 4a5d52
		gpointer data;
Packit 4a5d52
	} treedata;
Packit 4a5d52
	GHashTable *hash_table;
Packit 4a5d52
	char *str;
Packit 4a5d52
	gboolean boolean;
Packit 4a5d52
	IDL_declspec_t declspec;
Packit 4a5d52
	IDL_longlong_t integer;
Packit 4a5d52
	double floatp;
Packit 4a5d52
	enum IDL_unaryop unaryop;
Packit 4a5d52
	enum IDL_param_attr paramattr;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
/* Terminals */
Packit 4a5d52
%token			TOK_ANY
Packit 4a5d52
%token			TOK_ATTRIBUTE
Packit 4a5d52
%token			TOK_BOOLEAN
Packit 4a5d52
%token			TOK_CASE
Packit 4a5d52
%token			TOK_CHAR
Packit 4a5d52
%token			TOK_CONST
Packit 4a5d52
%token			TOK_CONTEXT
Packit 4a5d52
%token			TOK_DEFAULT
Packit 4a5d52
%token			TOK_DOUBLE
Packit 4a5d52
%token			TOK_ENUM
Packit 4a5d52
%token			TOK_EXCEPTION
Packit 4a5d52
%token			TOK_FALSE
Packit 4a5d52
%token			TOK_FIXED
Packit 4a5d52
%token			TOK_FLOAT
Packit 4a5d52
%token			TOK_IN 
Packit 4a5d52
%token			TOK_INOUT
Packit 4a5d52
%token			TOK_INTERFACE
Packit 4a5d52
%token			TOK_LONG
Packit 4a5d52
%token			TOK_MODULE
Packit 4a5d52
%token			TOK_NATIVE
Packit 4a5d52
%token			TOK_OBJECT
Packit 4a5d52
%token			TOK_OCTET
Packit 4a5d52
%token			TOK_ONEWAY
Packit 4a5d52
%token			TOK_OP_SCOPE
Packit 4a5d52
%token			TOK_OP_SHL
Packit 4a5d52
%token			TOK_OP_SHR
Packit 4a5d52
%token			TOK_OUT
Packit 4a5d52
%token			TOK_RAISES
Packit 4a5d52
%token			TOK_READONLY 
Packit 4a5d52
%token			TOK_SEQUENCE
Packit 4a5d52
%token			TOK_SHORT
Packit 4a5d52
%token			TOK_STRING
Packit 4a5d52
%token			TOK_STRUCT
Packit 4a5d52
%token			TOK_SWITCH
Packit 4a5d52
%token			TOK_TRUE
Packit 4a5d52
%token			TOK_TYPECODE
Packit 4a5d52
%token			TOK_TYPEDEF
Packit 4a5d52
%token			TOK_UNION
Packit 4a5d52
%token			TOK_UNSIGNED
Packit 4a5d52
%token			TOK_VARARGS
Packit 4a5d52
%token			TOK_VOID
Packit 4a5d52
%token			TOK_WCHAR
Packit 4a5d52
%token			TOK_WSTRING
Packit 4a5d52
%token <floatp>		TOK_FLOATP
Packit 4a5d52
%token <integer>	TOK_INTEGER
Packit 4a5d52
%token <str>		TOK_DECLSPEC TOK_PROP_KEY
Packit 4a5d52
%token <str>		TOK_PROP_VALUE TOK_NATIVE_TYPE
Packit 4a5d52
%token <str>		TOK_IDENT TOK_SQSTRING TOK_DQSTRING TOK_FIXEDP
Packit 4a5d52
%token <tree>		TOK_CODEFRAG
Packit 4a5d52
%token <tree>		TOK_SRCFILE
Packit 4a5d52
Packit 4a5d52
/* Non-Terminals */
Packit 4a5d52
%type <tree>		add_expr
Packit 4a5d52
%type <tree>		and_expr
Packit 4a5d52
%type <tree>		any_type
Packit 4a5d52
%type <tree>		array_declarator
Packit 4a5d52
%type <tree>		attr_dcl
Packit 4a5d52
%type <tree>		attr_dcl_def
Packit 4a5d52
%type <tree>		base_type_spec
Packit 4a5d52
%type <tree>		boolean_lit
Packit 4a5d52
%type <tree>		boolean_type
Packit 4a5d52
%type <tree>		case_label
Packit 4a5d52
%type <tree>		case_label_list
Packit 4a5d52
%type <tree>		case_stmt
Packit 4a5d52
%type <tree>		case_stmt_list
Packit 4a5d52
%type <tree>		char_lit
Packit 4a5d52
%type <tree>		char_type
Packit 4a5d52
%type <tree>		codefrag
Packit 4a5d52
%type <tree>		complex_declarator
Packit 4a5d52
%type <tree>		const_dcl
Packit 4a5d52
%type <tree>		const_dcl_def
Packit 4a5d52
%type <tree>		const_exp
Packit 4a5d52
%type <tree>		const_type
Packit 4a5d52
%type <tree>		constr_type_spec
Packit 4a5d52
%type <tree>		context_expr
Packit 4a5d52
%type <tree>		cur_ns_new_or_prev_ident
Packit 4a5d52
%type <tree>		declarator
Packit 4a5d52
%type <tree>		declarator_list
Packit 4a5d52
%type <tree>		definition
Packit 4a5d52
%type <tree>		definition_list
Packit 4a5d52
%type <tree>		element_spec
Packit 4a5d52
%type <tree>		enum_type
Packit 4a5d52
%type <tree>		enumerator_list
Packit 4a5d52
%type <tree>		except_dcl
Packit 4a5d52
%type <tree>		except_dcl_def
Packit 4a5d52
%type <tree>		export
Packit 4a5d52
%type <tree>		export_list
Packit 4a5d52
%type <tree>		fixed_array_size
Packit 4a5d52
%type <tree>		fixed_array_size_list
Packit 4a5d52
%type <tree>		fixed_pt_const_type
Packit 4a5d52
%type <tree>		fixed_pt_lit
Packit 4a5d52
%type <tree>		fixed_pt_type
Packit 4a5d52
%type <tree>		floating_pt_lit
Packit 4a5d52
%type <tree>		floating_pt_type
Packit 4a5d52
%type <tree>		ident
Packit 4a5d52
%type <tree>		illegal_ident
Packit 4a5d52
%type <tree>		integer_lit
Packit 4a5d52
%type <tree>		integer_type
Packit 4a5d52
%type <tree>		interface
Packit 4a5d52
%type <tree>		interface_body
Packit 4a5d52
%type <tree>		interface_catch_ident
Packit 4a5d52
%type <tree>		is_context_expr
Packit 4a5d52
%type <tree>		is_raises_expr
Packit 4a5d52
%type <tree>		literal
Packit 4a5d52
%type <tree>		member
Packit 4a5d52
%type <tree>		member_list
Packit 4a5d52
%type <tree>		member_zlist
Packit 4a5d52
%type <tree>		module
Packit 4a5d52
%type <tree>		mult_expr
Packit 4a5d52
%type <tree>		new_ident
Packit 4a5d52
%type <tree>		new_or_prev_scope
Packit 4a5d52
%type <tree>		new_scope
Packit 4a5d52
%type <tree>		ns_global_ident
Packit 4a5d52
%type <tree>		ns_new_ident
Packit 4a5d52
%type <tree>		ns_prev_ident
Packit 4a5d52
%type <tree>		ns_scoped_name
Packit 4a5d52
%type <tree>		object_type
Packit 4a5d52
%type <tree>		octet_type
Packit 4a5d52
%type <tree>		op_dcl
Packit 4a5d52
%type <tree>		op_dcl_def
Packit 4a5d52
%type <tree>		op_param_type_spec
Packit 4a5d52
%type <tree>		op_param_type_spec_illegal
Packit 4a5d52
%type <tree>		op_type_spec
Packit 4a5d52
%type <tree>		or_expr
Packit 4a5d52
%type <tree>		param_dcl
Packit 4a5d52
%type <tree>		param_dcl_list
Packit 4a5d52
%type <tree>		param_type_spec
Packit 4a5d52
%type <tree>		pop_scope
Packit 4a5d52
%type <tree>		positive_int_const
Packit 4a5d52
%type <tree>		primary_expr
Packit 4a5d52
%type <tree>		raises_expr
Packit 4a5d52
%type <tree>		scoped_name
Packit 4a5d52
%type <tree>		scoped_name_list
Packit 4a5d52
%type <tree>		sequence_type
Packit 4a5d52
%type <tree>		shift_expr
Packit 4a5d52
%type <tree>		simple_declarator
Packit 4a5d52
%type <tree>		simple_declarator_list
Packit 4a5d52
%type <tree>		simple_type_spec
Packit 4a5d52
%type <tree>		specification
Packit 4a5d52
%type <tree>		srcfile
Packit 4a5d52
%type <tree>		string_lit
Packit 4a5d52
%type <tree>		string_lit_list
Packit 4a5d52
%type <tree>		string_type
Packit 4a5d52
%type <tree>		struct_type
Packit 4a5d52
%type <tree>		switch_body
Packit 4a5d52
%type <tree>		switch_type_spec
Packit 4a5d52
%type <tree>		template_type_spec
Packit 4a5d52
%type <tree>		type_dcl
Packit 4a5d52
%type <tree>		type_dcl_def
Packit 4a5d52
%type <tree>		type_declarator
Packit 4a5d52
%type <tree>		type_spec
Packit 4a5d52
%type <tree>		unary_expr
Packit 4a5d52
%type <tree>		union_type
Packit 4a5d52
%type <tree>		useless_semicolon
Packit 4a5d52
%type <tree>		wide_char_type
Packit 4a5d52
%type <tree>		wide_string_type
Packit 4a5d52
%type <tree>		xor_expr
Packit 4a5d52
%type <tree>		z_definition_list
Packit 4a5d52
%type <tree>		z_inheritance
Packit 4a5d52
%type <tree>		z_new_ident_catch
Packit 4a5d52
%type <tree>		z_new_scope_catch
Packit 4a5d52
%type <tree>		typecode_type
Packit 4a5d52
Packit 4a5d52
%type <treedata>	parameter_dcls
Packit 4a5d52
%type <declspec>	z_declspec module_declspec
Packit 4a5d52
%type <hash_table>	z_props prop_hash
Packit 4a5d52
%type <boolean>		is_readonly is_oneway
Packit 4a5d52
%type <boolean>		is_varargs is_cvarargs
Packit 4a5d52
%type <integer>		signed_int unsigned_int
Packit 4a5d52
%type <paramattr>	param_attribute
Packit 4a5d52
%type <str>		sqstring dqstring dqstring_cat
Packit 4a5d52
%type <unaryop>		unary_op
Packit 4a5d52
Packit 4a5d52
%%
Packit 4a5d52
Packit 4a5d52
specification:		/* empty */			{ yyerror ("Empty file"); YYABORT; }
Packit 4a5d52
|			definition_list			{ __IDL_root = $1; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
z_definition_list:	/* empty */			{ $$ = NULL; }
Packit 4a5d52
|			definition_list
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
definition_list:	definition			{ $$ = list_start ($1, TRUE); }
Packit 4a5d52
|			definition_list definition	{ $$ = list_chain ($1, $2, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
check_semicolon:	';'
Packit 4a5d52
|			/* empty */			{
Packit 4a5d52
	if (do_token_error ($<tree>0, "Missing semicolon after", TRUE))
Packit 4a5d52
		YYABORT;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
useless_semicolon:	';'				{
Packit 4a5d52
	yyerror ("Dangling semicolon has no effect");
Packit 4a5d52
	$$ = NULL;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
check_comma:		','
Packit 4a5d52
|			/* empty */			{
Packit 4a5d52
	if (do_token_error ($<tree>0, "Missing comma after", TRUE))
Packit 4a5d52
		YYABORT;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
illegal_ident:		scoped_name			{
Packit 4a5d52
	if (IDL_NODE_UP ($1))
Packit 4a5d52
		do_token_error (IDL_NODE_UP ($1), "Illegal context for", FALSE);
Packit 4a5d52
	else
Packit 4a5d52
		yyerror ("Illegal context for identifier");
Packit 4a5d52
	YYABORT;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
definition:		type_dcl check_semicolon
Packit 4a5d52
|			const_dcl check_semicolon
Packit 4a5d52
|			except_dcl check_semicolon
Packit 4a5d52
|			interface check_semicolon
Packit 4a5d52
|			module check_semicolon
Packit 4a5d52
|			codefrag
Packit 4a5d52
|			srcfile
Packit 4a5d52
|			illegal_ident
Packit 4a5d52
|			useless_semicolon
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
module_declspec:	z_declspec TOK_MODULE
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
module:			module_declspec
Packit 4a5d52
			new_or_prev_scope		{
Packit 4a5d52
	if (IDL_NODE_UP ($2) != NULL &&
Packit 4a5d52
	    IDL_NODE_TYPE (IDL_NODE_UP ($2)) != IDLN_MODULE) {
Packit 4a5d52
		yyerror ("Module definition conflicts");
Packit 4a5d52
		do_token_error (IDL_NODE_UP ($2), "with", FALSE);
Packit 4a5d52
		YYABORT;
Packit 4a5d52
	}
Packit 4a5d52
}			'{'
Packit 4a5d52
				z_definition_list
Packit 4a5d52
			'}' pop_scope			{
Packit 4a5d52
	IDL_tree module;
Packit 4a5d52
Packit 4a5d52
	if ($5 == NULL) {
Packit 4a5d52
		yyerrorv ("Empty module declaration `%s' is not legal IDL",
Packit 4a5d52
			  IDL_IDENT ($2).str);
Packit 4a5d52
		module = NULL;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	if (__IDL_flags & IDLF_COMBINE_REOPENED_MODULES) {
Packit 4a5d52
		if (IDL_NODE_UP ($2) == NULL)
Packit 4a5d52
			module = IDL_module_new ($2, $5);
Packit 4a5d52
		else {
Packit 4a5d52
			module = IDL_NODE_UP ($2);
Packit 4a5d52
			IDL_MODULE (module).definition_list =
Packit 4a5d52
				IDL_list_concat (IDL_MODULE (module).definition_list, $5);
Packit 4a5d52
			module = NULL;
Packit 4a5d52
		}
Packit 4a5d52
	} else
Packit 4a5d52
		module = IDL_module_new ($2, $5);
Packit 4a5d52
Packit 4a5d52
	$$ = module;
Packit 4a5d52
	if ($$) assign_declspec ($$, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
/* We only catch these errors for non-pidl because we want to be able to compile
Packit 4a5d52
   the OMG CORBA .idl files which define interfaces by these names */
Packit 4a5d52
interface_catch_ident:	new_or_prev_scope
Packit 4a5d52
|			TOK_OBJECT			{
Packit 4a5d52
	yyerror ("Interfaces cannot be named `Object'");
Packit 4a5d52
	YYABORT;
Packit 4a5d52
}
Packit 4a5d52
|			TOK_TYPECODE			{
Packit 4a5d52
	yyerror ("Interfaces cannot be named `TypeCode'");
Packit 4a5d52
	YYABORT;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
interface:		z_declspec
Packit 4a5d52
			z_props
Packit 4a5d52
			TOK_INTERFACE
Packit 4a5d52
			interface_catch_ident		{
Packit 4a5d52
	assert ($4 != NULL);
Packit 4a5d52
	assert (IDL_NODE_TYPE ($4) == IDLN_IDENT);
Packit 4a5d52
	assert (IDL_IDENT_TO_NS ($4) != NULL);
Packit 4a5d52
	assert (IDL_NODE_TYPE (IDL_IDENT_TO_NS ($4)) == IDLN_GENTREE);
Packit 4a5d52
Packit 4a5d52
	if (IDL_NODE_UP ($4) != NULL &&
Packit 4a5d52
	    IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_INTERFACE &&
Packit 4a5d52
	    IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_FORWARD_DCL) {
Packit 4a5d52
		yyerrorl ("Interface definition conflicts",
Packit 4a5d52
			  __IDL_prev_token_line - __IDL_cur_token_line);
Packit 4a5d52
		do_token_error (IDL_NODE_UP ($4), "with", FALSE);
Packit 4a5d52
		YYABORT;
Packit 4a5d52
	} else if (IDL_NODE_UP ($4) != NULL &&
Packit 4a5d52
		   IDL_NODE_TYPE (IDL_NODE_UP ($4)) != IDLN_FORWARD_DCL) {
Packit 4a5d52
		yyerrorv ("Cannot redeclare interface `%s'", IDL_IDENT ($4).str);
Packit 4a5d52
		IDL_tree_error ($4, "Previous declaration of interface `%s'", IDL_IDENT ($4).str);
Packit 4a5d52
		YYABORT;
Packit 4a5d52
	} else if (IDL_NODE_UP ($4) != NULL &&
Packit 4a5d52
		   IDL_NODE_TYPE (IDL_NODE_UP ($4)) == IDLN_FORWARD_DCL)
Packit 4a5d52
		__IDL_assign_this_location ($4, __IDL_cur_filename, __IDL_cur_line);
Packit 4a5d52
}
Packit 4a5d52
			pop_scope
Packit 4a5d52
			z_inheritance			{
Packit 4a5d52
	IDL_GENTREE (IDL_IDENT_TO_NS ($4))._import = $7;
Packit 4a5d52
	IDL_ns_push_scope (__IDL_root_ns, IDL_IDENT_TO_NS ($4));
Packit 4a5d52
	if (IDL_ns_check_for_ambiguous_inheritance ($4, $7))
Packit 4a5d52
		__IDL_is_okay = FALSE;
Packit 4a5d52
}			'{'
Packit 4a5d52
				interface_body
Packit 4a5d52
			'}' pop_scope			{
Packit 4a5d52
 	$$ = IDL_interface_new ($4, $7, $10);
Packit 4a5d52
	assign_declspec ($$, $1);
Packit 4a5d52
	assign_props (IDL_INTERFACE ($$).ident, $2);
Packit 4a5d52
}
Packit 4a5d52
|			z_declspec
Packit 4a5d52
			z_props
Packit 4a5d52
			TOK_INTERFACE
Packit 4a5d52
			interface_catch_ident
Packit 4a5d52
			pop_scope			{
Packit 4a5d52
	if ($2) yywarningv (IDL_WARNING1,
Packit 4a5d52
			    "Ignoring properties for forward declaration `%s'",
Packit 4a5d52
			    IDL_IDENT ($4).str);
Packit 4a5d52
	$$ = IDL_forward_dcl_new ($4);
Packit 4a5d52
	assign_declspec ($$, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
z_inheritance:		/* empty */			{ $$ = NULL; }
Packit 4a5d52
|			':' scoped_name_list		{
Packit 4a5d52
	GHashTable *table = g_hash_table_new (g_direct_hash, g_direct_equal);
Packit 4a5d52
	gboolean die = FALSE;
Packit 4a5d52
	IDL_tree p = $2;
Packit 4a5d52
Packit 4a5d52
	assert (IDL_NODE_TYPE (p) == IDLN_LIST);
Packit 4a5d52
	for (; p != NULL && !die; p = IDL_LIST (p).next) {
Packit 4a5d52
		assert (IDL_LIST (p).data != NULL);
Packit 4a5d52
		assert (IDL_NODE_TYPE (IDL_LIST (p).data) == IDLN_IDENT);
Packit 4a5d52
Packit 4a5d52
		if (g_hash_table_lookup_extended (table, IDL_LIST (p).data, NULL, NULL)) {
Packit 4a5d52
			char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0);
Packit 4a5d52
			yyerrorv ("Cannot inherit from interface `%s' more than once", s);
Packit 4a5d52
			g_free (s);
Packit 4a5d52
			die = TRUE;
Packit 4a5d52
			break;
Packit 4a5d52
		} else
Packit 4a5d52
			g_hash_table_insert (table, IDL_LIST (p).data, NULL);
Packit 4a5d52
Packit 4a5d52
		if (IDL_NODE_TYPE (IDL_NODE_UP (IDL_LIST (p).data)) == IDLN_FORWARD_DCL) {
Packit 4a5d52
			char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0);
Packit 4a5d52
			yyerrorv ("Incomplete definition of interface `%s'", s);
Packit 4a5d52
			IDL_tree_error (IDL_LIST (p).data,
Packit 4a5d52
					"Previous forward declaration of `%s'", s);
Packit 4a5d52
			g_free (s);
Packit 4a5d52
			die = TRUE;
Packit 4a5d52
		}
Packit 4a5d52
		else if (IDL_NODE_TYPE (IDL_NODE_UP (IDL_LIST (p).data)) != IDLN_INTERFACE) {
Packit 4a5d52
			char *s = IDL_ns_ident_to_qstring (IDL_LIST (p).data, "::", 0);
Packit 4a5d52
			yyerrorv ("`%s' is not an interface", s);
Packit 4a5d52
			IDL_tree_error (IDL_LIST (p).data,
Packit 4a5d52
					"Previous declaration of `%s'", s);
Packit 4a5d52
			g_free (s);
Packit 4a5d52
			die = TRUE;
Packit 4a5d52
		}
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	g_hash_table_destroy (table);
Packit 4a5d52
Packit 4a5d52
	if (die)
Packit 4a5d52
		YYABORT;
Packit 4a5d52
Packit 4a5d52
	$$ = $2;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
scoped_name_list:	scoped_name			{ $$ = list_start ($1, TRUE); }
Packit 4a5d52
|			scoped_name_list
Packit 4a5d52
			check_comma scoped_name		{ $$ = list_chain ($1, $3, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
interface_body:		export_list
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
export_list:		/* empty */			{ $$ = NULL; }
Packit 4a5d52
|			export_list export		{ $$ = zlist_chain ($1, $2, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
export:			type_dcl check_semicolon
Packit 4a5d52
|			except_dcl check_semicolon
Packit 4a5d52
|			op_dcl check_semicolon
Packit 4a5d52
|			attr_dcl check_semicolon
Packit 4a5d52
|			const_dcl check_semicolon
Packit 4a5d52
|			codefrag
Packit 4a5d52
|			useless_semicolon
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
type_dcl:		z_declspec type_dcl_def		{
Packit 4a5d52
	$$ = $2;
Packit 4a5d52
	assign_declspec ($$, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
type_dcl_def:		z_props TOK_TYPEDEF
Packit 4a5d52
			type_declarator			{
Packit 4a5d52
	IDL_tree_node node;
Packit 4a5d52
	IDL_tree p, dcl;
Packit 4a5d52
Packit 4a5d52
	$$ = $3;
Packit 4a5d52
	node.properties = $1;
Packit 4a5d52
	for (p = IDL_TYPE_DCL ($3).dcls; p; p = IDL_LIST (p).next) {
Packit 4a5d52
		dcl = IDL_LIST (p).data;
Packit 4a5d52
		IDL_tree_properties_copy (&node, dcl);
Packit 4a5d52
	}
Packit 4a5d52
	__IDL_free_properties (node.properties);
Packit 4a5d52
}
Packit 4a5d52
|			struct_type
Packit 4a5d52
|			union_type
Packit 4a5d52
|			enum_type
Packit 4a5d52
|			z_props TOK_NATIVE
Packit 4a5d52
			simple_declarator		{
Packit 4a5d52
	$$ = IDL_native_new ($3);
Packit 4a5d52
	assign_props (IDL_NATIVE ($$).ident, $1);
Packit 4a5d52
}
Packit 4a5d52
|			z_props TOK_NATIVE simple_declarator
Packit 4a5d52
			'('				{
Packit 4a5d52
	/* Enable native type scanning */
Packit 4a5d52
	if (__IDL_pidl > 0)
Packit 4a5d52
		__IDL_flagsi |= IDLFP_NATIVE;
Packit 4a5d52
	else {
Packit 4a5d52
		yyerror ("Native syntax not enabled");
Packit 4a5d52
		YYABORT;
Packit 4a5d52
	}
Packit 4a5d52
}			TOK_NATIVE_TYPE			{
Packit 4a5d52
	$$ = IDL_native_new ($3);
Packit 4a5d52
	IDL_NATIVE ($$).user_type = $6;
Packit 4a5d52
	assign_props (IDL_NATIVE ($$).ident, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
type_declarator:	type_spec declarator_list	{ $$ = IDL_type_dcl_new ($1, $2); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
type_spec:		simple_type_spec
Packit 4a5d52
|			constr_type_spec
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
simple_type_spec:	base_type_spec
Packit 4a5d52
|			template_type_spec
Packit 4a5d52
|			scoped_name
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
constr_type_spec:	struct_type
Packit 4a5d52
|			union_type
Packit 4a5d52
|			enum_type
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
z_new_ident_catch:	/* empty */			{
Packit 4a5d52
	yyerrorv ("Missing identifier in %s definition", $<str>0);
Packit 4a5d52
	YYABORT;
Packit 4a5d52
}
Packit 4a5d52
|			new_ident
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
z_new_scope_catch:	/* empty */			{
Packit 4a5d52
	yyerrorv ("Missing identifier in %s definition", $<str>0);
Packit 4a5d52
	YYABORT;
Packit 4a5d52
}
Packit 4a5d52
|			new_scope
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
struct_type:		z_props TOK_STRUCT
Packit 4a5d52
			{ $<str>$ = "struct"; }
Packit 4a5d52
			z_new_scope_catch '{'		{
Packit 4a5d52
	g_hash_table_insert (__IDL_structunion_ht, $4, $4);
Packit 4a5d52
	$<tree>$ = IDL_type_struct_new ($4, NULL);
Packit 4a5d52
}				member_list
Packit 4a5d52
			'}' pop_scope			{
Packit 4a5d52
	g_hash_table_remove (__IDL_structunion_ht, $4);
Packit 4a5d52
	$$ = $<tree>6;
Packit 4a5d52
	__IDL_assign_up_node ($$, $7);
Packit 4a5d52
	IDL_TYPE_STRUCT ($$).member_list = $7;
Packit 4a5d52
	assign_props (IDL_TYPE_STRUCT ($$).ident, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
union_type:		z_props TOK_UNION
Packit 4a5d52
			{ $<str>$ = "union"; }
Packit 4a5d52
			z_new_scope_catch TOK_SWITCH '('
Packit 4a5d52
				switch_type_spec
Packit 4a5d52
			')' '{'				{
Packit 4a5d52
	g_hash_table_insert (__IDL_structunion_ht, $4, $4);
Packit 4a5d52
	$<tree>$ = IDL_type_union_new ($4, $7, NULL);
Packit 4a5d52
}				switch_body
Packit 4a5d52
			'}' pop_scope			{
Packit 4a5d52
	g_hash_table_remove (__IDL_structunion_ht, $4);
Packit 4a5d52
	$$ = $<tree>10;
Packit 4a5d52
	__IDL_assign_up_node ($$, $11);
Packit 4a5d52
	IDL_TYPE_UNION ($$).switch_body = $11;
Packit 4a5d52
	assign_props (IDL_TYPE_UNION ($$).ident, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
switch_type_spec:	integer_type
Packit 4a5d52
|			char_type
Packit 4a5d52
|			boolean_type
Packit 4a5d52
|			enum_type
Packit 4a5d52
|			scoped_name
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
switch_body:		case_stmt_list
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
case_stmt_list:		case_stmt			{ $$ = list_start ($1, TRUE); }
Packit 4a5d52
|			case_stmt_list case_stmt	{ $$ = list_chain ($1, $2, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
case_stmt:		case_label_list
Packit 4a5d52
			element_spec check_semicolon	{ $$ = IDL_case_stmt_new ($1, $2); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
element_spec:		type_spec declarator		{
Packit 4a5d52
	char *s;
Packit 4a5d52
Packit 4a5d52
	$$ = IDL_member_new ($1, list_start ($2, TRUE));
Packit 4a5d52
	if (IDL_NODE_TYPE ($1) == IDLN_IDENT &&
Packit 4a5d52
	    g_hash_table_lookup (__IDL_structunion_ht, $1)) {
Packit 4a5d52
		s = IDL_ns_ident_to_qstring ($2, "::", 0);
Packit 4a5d52
		yyerrorv ("Member `%s'", s);
Packit 4a5d52
		do_token_error (IDL_NODE_UP ($1), "recurses", TRUE);
Packit 4a5d52
		g_free (s);
Packit 4a5d52
	}
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
case_label_list:	case_label			{ $$ = list_start ($1, FALSE); }
Packit 4a5d52
|			case_label_list case_label	{ $$ = list_chain ($1, $2, FALSE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
case_label:		TOK_CASE const_exp ':'		{ $$ = $2; }
Packit 4a5d52
|			TOK_DEFAULT ':'			{ $$ = NULL; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
const_dcl:		z_declspec const_dcl_def	{
Packit 4a5d52
	$$ = $2;
Packit 4a5d52
	assign_declspec ($$, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
const_dcl_def:		TOK_CONST const_type new_ident
Packit 4a5d52
			'=' const_exp			{
Packit 4a5d52
	$$ = IDL_const_dcl_new ($2, $3, $5);
Packit 4a5d52
	/* Should probably do some type checking here... */
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
except_dcl:		z_declspec except_dcl_def	{
Packit 4a5d52
	$$ = $2;
Packit 4a5d52
	assign_declspec ($$, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
except_dcl_def:		TOK_EXCEPTION new_scope '{'
Packit 4a5d52
				member_zlist
Packit 4a5d52
			'}' pop_scope			{ $$ = IDL_except_dcl_new ($2, $4); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
member_zlist:		/* empty */			{ $$ = NULL; }
Packit 4a5d52
|			member_zlist member		{ $$ = zlist_chain ($1, $2, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
is_readonly:		/* empty */			{ $$ = FALSE; }
Packit 4a5d52
|			TOK_READONLY			{ $$ = TRUE; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
attr_dcl:		z_declspec attr_dcl_def		{
Packit 4a5d52
	$$ = $2;
Packit 4a5d52
	assign_declspec ($$, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
attr_dcl_def:		z_props
Packit 4a5d52
			is_readonly
Packit 4a5d52
			TOK_ATTRIBUTE
Packit 4a5d52
			{ $<str>$ = "attribute"; }
Packit 4a5d52
			param_type_spec
Packit 4a5d52
			simple_declarator_list		{
Packit 4a5d52
	IDL_tree_node node;
Packit 4a5d52
	IDL_tree p, dcl;
Packit 4a5d52
Packit 4a5d52
	$$ = IDL_attr_dcl_new ($2, $5, $6);
Packit 4a5d52
	node.properties = $1;
Packit 4a5d52
	for (p = $6; p; p = IDL_LIST (p).next) {
Packit 4a5d52
		dcl = IDL_LIST (p).data;
Packit 4a5d52
		IDL_tree_properties_copy (&node, dcl);
Packit 4a5d52
	}
Packit 4a5d52
	__IDL_free_properties (node.properties);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
param_type_spec:	op_param_type_spec
Packit 4a5d52
|			TOK_VOID			{
Packit 4a5d52
	yyerrorv ("Illegal type `void' for %s", $<str>0);
Packit 4a5d52
	$$ = NULL;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
op_param_type_spec_illegal:
Packit 4a5d52
			sequence_type
Packit 4a5d52
|			constr_type_spec
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
op_param_type_spec:	base_type_spec
Packit 4a5d52
|			string_type
Packit 4a5d52
|			wide_string_type
Packit 4a5d52
|			fixed_pt_type
Packit 4a5d52
|			scoped_name
Packit 4a5d52
|			op_param_type_spec_illegal	{
Packit 4a5d52
	illegal_context_type_error ($1, $<str>0);
Packit 4a5d52
	$$ = $1;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
is_oneway:		/* empty */			{ $$ = FALSE; }
Packit 4a5d52
|			TOK_ONEWAY			{ $$ = TRUE; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
op_dcl:		z_declspec op_dcl_def			{
Packit 4a5d52
	$$ = $2;
Packit 4a5d52
	assign_declspec ($$, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
op_dcl_def:		z_props
Packit 4a5d52
			is_oneway
Packit 4a5d52
			op_type_spec
Packit 4a5d52
			new_scope parameter_dcls pop_scope
Packit 4a5d52
			is_raises_expr
Packit 4a5d52
			is_context_expr			{
Packit 4a5d52
	$$ = IDL_op_dcl_new ($2, $3, $4, $5.tree, $7, $8);
Packit 4a5d52
	IDL_OP_DCL ($$).f_varargs = GPOINTER_TO_INT ($5.data);
Packit 4a5d52
	assign_props (IDL_OP_DCL ($$).ident, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
op_type_spec:		{ $<str>$ = "operation return value"; }
Packit 4a5d52
			op_param_type_spec		{ $$ = $2; }
Packit 4a5d52
|			TOK_VOID			{ $$ = NULL; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
is_varargs:		/* empty */			{ $$ = FALSE; }
Packit 4a5d52
|			TOK_VARARGS			{ $$ = TRUE; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
is_cvarargs:		/* empty */			{ $$ = FALSE; }
Packit 4a5d52
|			',' TOK_VARARGS			{ $$ = TRUE; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
parameter_dcls:		'('
Packit 4a5d52
			param_dcl_list
Packit 4a5d52
			is_cvarargs
Packit 4a5d52
			')'				{
Packit 4a5d52
	$$.tree = $2;
Packit 4a5d52
	$$.data = GINT_TO_POINTER ($3);
Packit 4a5d52
}
Packit 4a5d52
|			'(' is_varargs ')'		{
Packit 4a5d52
	$$.tree = NULL;
Packit 4a5d52
	$$.data = GINT_TO_POINTER ($2);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
param_dcl_list:		param_dcl			{ $$ = list_start ($1, TRUE); }
Packit 4a5d52
|			param_dcl_list
Packit 4a5d52
			check_comma param_dcl		{ $$ = list_chain ($1, $3, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
param_dcl:		z_props
Packit 4a5d52
			param_attribute
Packit 4a5d52
			{ $<str>$ = "parameter"; }
Packit 4a5d52
			param_type_spec
Packit 4a5d52
			simple_declarator		{
Packit 4a5d52
	$$ = IDL_param_dcl_new ($2, $4, $5);
Packit 4a5d52
	assign_props (IDL_PARAM_DCL ($$).simple_declarator, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
param_attribute:	TOK_IN				{ $$ = IDL_PARAM_IN; }
Packit 4a5d52
|			TOK_OUT				{ $$ = IDL_PARAM_OUT; }
Packit 4a5d52
|			TOK_INOUT			{ $$ = IDL_PARAM_INOUT; }
Packit 4a5d52
|			param_type_spec			{
Packit 4a5d52
	yyerrorv ("Missing direction attribute (in, out, inout) before parameter");
Packit 4a5d52
	IDL_tree_free ($1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
is_raises_expr:		/* empty */			{ $$ = NULL; }
Packit 4a5d52
|			raises_expr
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
is_context_expr:	/* empty */			{ $$ = NULL; }
Packit 4a5d52
|			context_expr
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
raises_expr:		TOK_RAISES '('
Packit 4a5d52
				scoped_name_list
Packit 4a5d52
			')'				{ $$ = $3; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
context_expr:		TOK_CONTEXT '('
Packit 4a5d52
				string_lit_list
Packit 4a5d52
			')'				{ $$ = $3; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
const_type:		integer_type
Packit 4a5d52
|			char_type
Packit 4a5d52
|			octet_type
Packit 4a5d52
|			wide_char_type
Packit 4a5d52
|			boolean_type
Packit 4a5d52
|			floating_pt_type
Packit 4a5d52
|			string_type
Packit 4a5d52
|			wide_string_type
Packit 4a5d52
|			fixed_pt_const_type
Packit 4a5d52
|			scoped_name
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
const_exp:		or_expr
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
or_expr:		xor_expr
Packit 4a5d52
|			or_expr '|' xor_expr		{ do_binop ($$, IDL_BINOP_OR, $1, $3); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
xor_expr:		and_expr
Packit 4a5d52
|			xor_expr '^' and_expr		{ do_binop ($$, IDL_BINOP_XOR, $1, $3); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
and_expr:		shift_expr
Packit 4a5d52
|			and_expr '&' shift_expr		{ do_binop ($$, IDL_BINOP_AND, $1, $3); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
shift_expr:		add_expr
Packit 4a5d52
|			shift_expr TOK_OP_SHR add_expr	{ do_binop ($$, IDL_BINOP_SHR, $1, $3); }
Packit 4a5d52
|			shift_expr TOK_OP_SHL add_expr	{ do_binop ($$, IDL_BINOP_SHL, $1, $3); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
add_expr:		mult_expr
Packit 4a5d52
|			add_expr '+' mult_expr		{ do_binop ($$, IDL_BINOP_ADD, $1, $3); }
Packit 4a5d52
|			add_expr '-' mult_expr		{ do_binop ($$, IDL_BINOP_SUB, $1, $3); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
mult_expr:		unary_expr
Packit 4a5d52
|			mult_expr '*' unary_expr	{ do_binop ($$, IDL_BINOP_MULT, $1, $3); }
Packit 4a5d52
|			mult_expr '/' unary_expr	{ do_binop ($$, IDL_BINOP_DIV, $1, $3); }
Packit 4a5d52
|			mult_expr '%' unary_expr	{ do_binop ($$, IDL_BINOP_MOD, $1, $3); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
unary_expr:		unary_op primary_expr		{ do_unaryop ($$, $1, $2); }
Packit 4a5d52
|			primary_expr
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
unary_op:		'-'				{ $$ = IDL_UNARYOP_MINUS; }
Packit 4a5d52
|			'+'				{ $$ = IDL_UNARYOP_PLUS; }
Packit 4a5d52
|			'~'				{ $$ = IDL_UNARYOP_COMPLEMENT; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
primary_expr:		scoped_name			{
Packit 4a5d52
	IDL_tree p, literal;
Packit 4a5d52
	
Packit 4a5d52
	assert (IDL_NODE_TYPE ($1) == IDLN_IDENT);
Packit 4a5d52
Packit 4a5d52
	p = IDL_NODE_UP ($1);
Packit 4a5d52
	
Packit 4a5d52
	if ((literal = IDL_resolve_const_exp ($1, IDLN_ANY))) {
Packit 4a5d52
		++IDL_NODE_REFS (literal);
Packit 4a5d52
		$$ = literal;
Packit 4a5d52
		IDL_tree_free ($1);
Packit 4a5d52
	} else
Packit 4a5d52
		$$ = $1;
Packit 4a5d52
}
Packit 4a5d52
|			literal
Packit 4a5d52
|			'(' const_exp ')'		{ $$ = $2; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
literal:		integer_lit
Packit 4a5d52
|			string_lit
Packit 4a5d52
|			char_lit
Packit 4a5d52
|			fixed_pt_lit
Packit 4a5d52
|			floating_pt_lit
Packit 4a5d52
|			boolean_lit
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
enum_type:		z_props TOK_ENUM
Packit 4a5d52
			{ $<str>$ = "enum"; }
Packit 4a5d52
			z_new_ident_catch '{'
Packit 4a5d52
				enumerator_list
Packit 4a5d52
			'}'				{
Packit 4a5d52
	$$ = IDL_type_enum_new ($4, $6);
Packit 4a5d52
	assign_props (IDL_TYPE_ENUM ($$).ident, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
scoped_name:		ns_scoped_name			{
Packit 4a5d52
	assert ($1 != NULL);
Packit 4a5d52
	assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE);
Packit 4a5d52
	assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
Packit 4a5d52
	$$ = IDL_GENTREE ($1).data;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
ns_scoped_name:		ns_prev_ident
Packit 4a5d52
|			TOK_OP_SCOPE ns_global_ident	{ $$ = $2; }
Packit 4a5d52
|			ns_scoped_name TOK_OP_SCOPE
Packit 4a5d52
			ident				{
Packit 4a5d52
	IDL_tree p;
Packit 4a5d52
Packit 4a5d52
	assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE);
Packit 4a5d52
	assert (IDL_NODE_TYPE ($3) == IDLN_IDENT);
Packit 4a5d52
Packit 4a5d52
#ifdef YYDEBUG
Packit 4a5d52
	if (yydebug)
Packit 4a5d52
		fprintf (stderr, "ns: looking in `%s' for `%s'\n", 
Packit 4a5d52
		  IDL_IDENT (IDL_GENTREE ($1).data).str, IDL_IDENT($3).str);
Packit 4a5d52
#endif
Packit 4a5d52
Packit 4a5d52
	if ((p = IDL_ns_lookup_this_scope (__IDL_root_ns, $1, $3, NULL)) == NULL) {
Packit 4a5d52
		yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($3).str);
Packit 4a5d52
		IDL_tree_free ($3);
Packit 4a5d52
		YYABORT;
Packit 4a5d52
	}
Packit 4a5d52
	IDL_tree_free ($3);
Packit 4a5d52
#ifdef REF_IDENTS
Packit 4a5d52
	++IDL_NODE_REFS (IDL_GENTREE (p).data);
Packit 4a5d52
#endif
Packit 4a5d52
	$$ = p;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
enumerator_list:	new_ident			{ $$ = list_start ($1, TRUE); }
Packit 4a5d52
|			enumerator_list
Packit 4a5d52
			check_comma new_ident		{ $$ = list_chain ($1, $3, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
member_list:		member				{ $$ = list_start ($1, TRUE); }
Packit 4a5d52
|			member_list member		{ $$ = list_chain ($1, $2, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
member:			type_spec declarator_list
Packit 4a5d52
			check_semicolon			{
Packit 4a5d52
	char *s;
Packit 4a5d52
Packit 4a5d52
	$$ = IDL_member_new ($1, $2);
Packit 4a5d52
	if (IDL_NODE_TYPE ($1) == IDLN_IDENT &&
Packit 4a5d52
	    g_hash_table_lookup (__IDL_structunion_ht, $1)) {
Packit 4a5d52
		s = IDL_ns_ident_to_qstring (IDL_LIST ($2).data, "::", 0);
Packit 4a5d52
		yyerrorv ("Member `%s'", s);
Packit 4a5d52
		do_token_error (IDL_NODE_UP ($1), "recurses", TRUE);
Packit 4a5d52
		g_free (s);
Packit 4a5d52
	}
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
base_type_spec:		floating_pt_type
Packit 4a5d52
|			integer_type
Packit 4a5d52
|			char_type
Packit 4a5d52
|			wide_char_type
Packit 4a5d52
|			boolean_type
Packit 4a5d52
|			octet_type
Packit 4a5d52
|			any_type
Packit 4a5d52
|			object_type
Packit 4a5d52
|			typecode_type
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
template_type_spec:	sequence_type
Packit 4a5d52
|			string_type
Packit 4a5d52
|			wide_string_type
Packit 4a5d52
|			fixed_pt_type
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
sequence_type:		TOK_SEQUENCE '<'
Packit 4a5d52
				simple_type_spec ',' positive_int_const
Packit 4a5d52
			'>'				{ $$ = IDL_type_sequence_new ($3, $5); }
Packit 4a5d52
|			TOK_SEQUENCE '<'
Packit 4a5d52
				simple_type_spec
Packit 4a5d52
			'>'				{ $$ = IDL_type_sequence_new ($3, NULL); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
floating_pt_type:	TOK_FLOAT			{ $$ = IDL_type_float_new (IDL_FLOAT_TYPE_FLOAT); }
Packit 4a5d52
|			TOK_DOUBLE			{ $$ = IDL_type_float_new (IDL_FLOAT_TYPE_DOUBLE); }
Packit 4a5d52
|			TOK_LONG TOK_DOUBLE		{ $$ = IDL_type_float_new (IDL_FLOAT_TYPE_LONGDOUBLE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
fixed_pt_type:		TOK_FIXED '<'
Packit 4a5d52
				positive_int_const ',' integer_lit
Packit 4a5d52
			'>'				{ $$ = IDL_type_fixed_new ($3, $5); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
fixed_pt_const_type:	TOK_FIXED			{ $$ = IDL_type_fixed_new (NULL, NULL); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
integer_type:		signed_int			{ $$ = IDL_type_integer_new (TRUE, $1); }
Packit 4a5d52
|			unsigned_int			{ $$ = IDL_type_integer_new (FALSE, $1); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
signed_int:		signed_short_int		{ $$ = IDL_INTEGER_TYPE_SHORT; }
Packit 4a5d52
|			signed_long_int			{ $$ = IDL_INTEGER_TYPE_LONG; }
Packit 4a5d52
|			signed_longlong_int		{ $$ = IDL_INTEGER_TYPE_LONGLONG; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
signed_short_int:	TOK_SHORT
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
signed_long_int:	TOK_LONG
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
signed_longlong_int:	TOK_LONG TOK_LONG
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
unsigned_int:		unsigned_short_int		{ $$ = IDL_INTEGER_TYPE_SHORT; }
Packit 4a5d52
|			unsigned_long_int		{ $$ = IDL_INTEGER_TYPE_LONG; }
Packit 4a5d52
|			unsigned_longlong_int		{ $$ = IDL_INTEGER_TYPE_LONGLONG; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
unsigned_short_int:	TOK_UNSIGNED TOK_SHORT
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
unsigned_long_int:	TOK_UNSIGNED TOK_LONG
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
unsigned_longlong_int:	TOK_UNSIGNED TOK_LONG TOK_LONG
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
char_type:		TOK_CHAR			{ $$ = IDL_type_char_new (); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
wide_char_type:		TOK_WCHAR			{ $$ = IDL_type_wide_char_new (); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
boolean_type:		TOK_BOOLEAN			{ $$ = IDL_type_boolean_new (); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
octet_type:		TOK_OCTET			{ $$ = IDL_type_octet_new (); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
any_type:		TOK_ANY				{ $$ = IDL_type_any_new (); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
object_type:		TOK_OBJECT			{ $$ = IDL_type_object_new (); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
typecode_type:		TOK_TYPECODE			{ $$ = IDL_type_typecode_new (); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
string_type:		TOK_STRING '<'
Packit 4a5d52
				positive_int_const
Packit 4a5d52
				'>'			{ $$ = IDL_type_string_new ($3); }
Packit 4a5d52
|			TOK_STRING			{ $$ = IDL_type_string_new (NULL); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
wide_string_type:	TOK_WSTRING '<'
Packit 4a5d52
				positive_int_const
Packit 4a5d52
			'>'				{ $$ = IDL_type_wide_string_new ($3); }
Packit 4a5d52
|			TOK_WSTRING			{ $$ = IDL_type_wide_string_new (NULL); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
declarator_list:	declarator			{ $$ = list_start ($1, TRUE); }
Packit 4a5d52
|			declarator_list 
Packit 4a5d52
			check_comma declarator		{ $$ = list_chain ($1, $3, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
declarator:		simple_declarator
Packit 4a5d52
|			complex_declarator
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
simple_declarator:	new_ident
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
complex_declarator:	array_declarator
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
simple_declarator_list:	simple_declarator		{ $$ = list_start ($1, TRUE); }
Packit 4a5d52
|			simple_declarator_list
Packit 4a5d52
			check_comma simple_declarator	{ $$ = list_chain ($1, $3, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
array_declarator:	new_ident
Packit 4a5d52
			fixed_array_size_list		{
Packit 4a5d52
	IDL_tree p;
Packit 4a5d52
	int i;
Packit 4a5d52
Packit 4a5d52
	$$ = IDL_type_array_new ($1, $2);
Packit 4a5d52
	for (i = 1, p = $2; p; ++i, p = IDL_LIST (p).next)
Packit 4a5d52
		if (!IDL_LIST (p).data) {
Packit 4a5d52
			char *s = IDL_ns_ident_to_qstring ($1, "::", 0);
Packit 4a5d52
			yyerrorv ("Missing value in dimension %d of array `%s'", i, s);
Packit 4a5d52
			g_free (s);
Packit 4a5d52
		}
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
fixed_array_size_list:	fixed_array_size		{ $$ = list_start ($1, FALSE); }
Packit 4a5d52
|			fixed_array_size_list
Packit 4a5d52
			fixed_array_size		{ $$ = list_chain ($1, $2, FALSE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
fixed_array_size:	'[' positive_int_const ']'	{ $$ = $2; }
Packit 4a5d52
|			'[' ']'				{ $$ = NULL; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
prop_hash:		TOK_PROP_KEY
Packit 4a5d52
			TOK_PROP_VALUE			{
Packit 4a5d52
	$$ = g_hash_table_new (IDL_strcase_hash, IDL_strcase_equal);
Packit 4a5d52
	g_hash_table_insert ($$, $1, $2);
Packit 4a5d52
}
Packit 4a5d52
|			prop_hash ','
Packit 4a5d52
			TOK_PROP_KEY
Packit 4a5d52
			TOK_PROP_VALUE			{
Packit 4a5d52
	$$ = $1;
Packit 4a5d52
	g_hash_table_insert ($$, $3, $4);
Packit 4a5d52
}
Packit 4a5d52
|			TOK_PROP_KEY			{
Packit 4a5d52
	$$ = g_hash_table_new (IDL_strcase_hash, IDL_strcase_equal);
Packit 4a5d52
	g_hash_table_insert ($$, $1, g_strdup (""));
Packit 4a5d52
}
Packit 4a5d52
|			prop_hash ','
Packit 4a5d52
			TOK_PROP_KEY			{
Packit 4a5d52
	$$ = $1;
Packit 4a5d52
	g_hash_table_insert ($$, $3, g_strdup (""));
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
ident:			TOK_IDENT			{ $$ = IDL_ident_new ($1); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
new_ident:		ns_new_ident			{
Packit 4a5d52
	assert ($1 != NULL);
Packit 4a5d52
	assert (IDL_NODE_TYPE ($1) == IDLN_GENTREE);
Packit 4a5d52
	assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
Packit 4a5d52
	$$ = IDL_GENTREE ($1).data;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
new_scope:		ns_new_ident			{
Packit 4a5d52
	IDL_tree	old_top = IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data;
Packit 4a5d52
	IDL_ns_push_scope (__IDL_root_ns, $1);
Packit 4a5d52
#ifdef YYDEBUG
Packit 4a5d52
	if (yydebug)
Packit 4a5d52
		fprintf (stderr, "ns: entering new scope `%s' of `%s'\n", 
Packit 4a5d52
		       IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str, IDL_IDENT(old_top).str);
Packit 4a5d52
#endif
Packit 4a5d52
	assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
Packit 4a5d52
	$$ = IDL_GENTREE ($1).data;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
new_or_prev_scope:	cur_ns_new_or_prev_ident	{
Packit 4a5d52
	IDL_tree	old_top = IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data;
Packit 4a5d52
	IDL_ns_push_scope (__IDL_root_ns, $1);
Packit 4a5d52
	assert (IDL_NS (__IDL_root_ns).current != NULL);
Packit 4a5d52
	assert (IDL_NODE_TYPE (IDL_NS (__IDL_root_ns).current) == IDLN_GENTREE);
Packit 4a5d52
	assert (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data != NULL);
Packit 4a5d52
	assert (IDL_NODE_TYPE (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data) == IDLN_IDENT);
Packit 4a5d52
#ifdef YYDEBUG
Packit 4a5d52
	if (yydebug)
Packit 4a5d52
		fprintf (stderr,"ns: entering new/prev scope `%s' of `%s'\n",
Packit 4a5d52
		       IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str, IDL_IDENT(old_top).str);
Packit 4a5d52
#endif
Packit 4a5d52
	assert (IDL_NODE_TYPE (IDL_GENTREE ($1).data) == IDLN_IDENT);
Packit 4a5d52
	$$ = IDL_GENTREE ($1).data;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
pop_scope:		/* empty */			{
Packit 4a5d52
	IDL_tree cur_top = IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data;
Packit 4a5d52
	IDL_ns_pop_scope (__IDL_root_ns);
Packit 4a5d52
#ifdef YYDEBUG
Packit 4a5d52
	if (yydebug)
Packit 4a5d52
		fprintf (stderr, "ns: pop scope from `%s' to `%s'\n", 
Packit 4a5d52
		       IDL_IDENT(cur_top).str,
Packit 4a5d52
		       IDL_IDENT (IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str);
Packit 4a5d52
#endif
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
ns_new_ident:		ident				{
Packit 4a5d52
	IDL_tree p;
Packit 4a5d52
Packit 4a5d52
	if ((p = IDL_ns_place_new (__IDL_root_ns, $1)) == NULL) {
Packit 4a5d52
		IDL_tree q;
Packit 4a5d52
		int i;
Packit 4a5d52
Packit 4a5d52
		p = IDL_ns_lookup_cur_scope (__IDL_root_ns, $1, NULL);
Packit 4a5d52
Packit 4a5d52
		for (i = 0, q = IDL_GENTREE (p).data;
Packit 4a5d52
		     q && (IDL_NODE_TYPE (q) == IDLN_IDENT ||
Packit 4a5d52
			   IDL_NODE_TYPE (q) == IDLN_LIST) && i < 4;
Packit 4a5d52
		     ++i)
Packit 4a5d52
			if (IDL_NODE_UP (q))
Packit 4a5d52
				q = IDL_NODE_UP (q);
Packit 4a5d52
Packit 4a5d52
		if (q) {
Packit 4a5d52
			IDL_tree_error ($1, "`%s' conflicts", IDL_IDENT ($1).str);
Packit 4a5d52
			do_token_error (q, "with", FALSE);
Packit 4a5d52
		} else
Packit 4a5d52
			yyerrorv ("`%s' duplicate identifier", IDL_IDENT ($1).str);
Packit 4a5d52
Packit 4a5d52
		IDL_tree_free ($1);
Packit 4a5d52
		YYABORT;
Packit 4a5d52
	}
Packit 4a5d52
	assert (IDL_IDENT ($1)._ns_ref == p);
Packit 4a5d52
#ifdef REF_IDENTS
Packit 4a5d52
	++IDL_NODE_REFS (IDL_GENTREE (p).data);
Packit 4a5d52
#endif
Packit 4a5d52
	if (__IDL_new_ident_comments != NULL) {
Packit 4a5d52
		assert (IDL_IDENT ($1).comments == NULL);
Packit 4a5d52
		IDL_IDENT ($1).comments = __IDL_new_ident_comments;
Packit 4a5d52
		__IDL_new_ident_comments = NULL;
Packit 4a5d52
	}
Packit 4a5d52
	$$ = p;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
ns_prev_ident:		ident				{
Packit 4a5d52
	IDL_tree p;
Packit 4a5d52
Packit 4a5d52
	if ((p = IDL_ns_resolve_ident (__IDL_root_ns, $1)) == NULL) {
Packit 4a5d52
		yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($1).str);
Packit 4a5d52
		IDL_tree_free ($1);
Packit 4a5d52
		YYABORT;
Packit 4a5d52
	}
Packit 4a5d52
	IDL_tree_free ($1);
Packit 4a5d52
	assert (IDL_GENTREE (p).data != NULL);
Packit 4a5d52
	assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p);
Packit 4a5d52
#ifdef REF_IDENTS
Packit 4a5d52
	++IDL_NODE_REFS (IDL_GENTREE (p).data);
Packit 4a5d52
#endif
Packit 4a5d52
	$$ = p;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
cur_ns_new_or_prev_ident:
Packit 4a5d52
			ident				{
Packit 4a5d52
	IDL_tree p;
Packit 4a5d52
Packit 4a5d52
	if ((p = IDL_ns_lookup_cur_scope (__IDL_root_ns, $1, NULL)) == NULL) {
Packit 4a5d52
#ifdef YYDEBUG
Packit 4a5d52
		if (yydebug)
Packit 4a5d52
			fprintf (stderr, "ns: place_new `%s' in `%s'\n", 
Packit 4a5d52
		  	  IDL_IDENT($1).str,
Packit 4a5d52
			  IDL_IDENT(IDL_GENTREE (IDL_NS (__IDL_root_ns).current).data).str );
Packit 4a5d52
#endif
Packit 4a5d52
		p = IDL_ns_place_new (__IDL_root_ns, $1);
Packit 4a5d52
		assert (p != NULL);
Packit 4a5d52
		assert (IDL_IDENT ($1)._ns_ref == p);
Packit 4a5d52
		if (__IDL_new_ident_comments != NULL) {
Packit 4a5d52
			assert (IDL_IDENT ($1).comments == NULL);
Packit 4a5d52
			IDL_IDENT ($1).comments = __IDL_new_ident_comments;
Packit 4a5d52
			__IDL_new_ident_comments = NULL;
Packit 4a5d52
		}
Packit 4a5d52
	} else {
Packit 4a5d52
		IDL_tree_free ($1);
Packit 4a5d52
		assert (IDL_GENTREE (p).data != NULL);
Packit 4a5d52
		assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p);
Packit 4a5d52
	}
Packit 4a5d52
#ifdef REF_IDENTS
Packit 4a5d52
	++IDL_NODE_REFS (IDL_GENTREE (p).data);
Packit 4a5d52
#endif
Packit 4a5d52
	$$ = p;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
ns_global_ident:	ident				{
Packit 4a5d52
	IDL_tree p;
Packit 4a5d52
Packit 4a5d52
	if ((p = IDL_ns_lookup_this_scope (
Packit 4a5d52
		__IDL_root_ns,IDL_NS (__IDL_root_ns).file, $1, NULL)) == NULL) {
Packit 4a5d52
		yyerrorv ("`%s' undeclared identifier", IDL_IDENT ($1).str);
Packit 4a5d52
		IDL_tree_free ($1);
Packit 4a5d52
		YYABORT;
Packit 4a5d52
	}
Packit 4a5d52
	IDL_tree_free ($1);
Packit 4a5d52
	assert (IDL_GENTREE (p).data != NULL);
Packit 4a5d52
	assert (IDL_IDENT (IDL_GENTREE (p).data)._ns_ref == p);
Packit 4a5d52
#ifdef REF_IDENTS
Packit 4a5d52
	++IDL_NODE_REFS (IDL_GENTREE (p).data);
Packit 4a5d52
#endif
Packit 4a5d52
	$$ = p;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
string_lit_list:	string_lit			{ $$ = list_start ($1, TRUE); }
Packit 4a5d52
|			string_lit_list
Packit 4a5d52
			check_comma string_lit		{ $$ = list_chain ($1, $3, TRUE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
positive_int_const:	const_exp			{
Packit 4a5d52
	IDL_tree literal, ident = NULL;
Packit 4a5d52
	IDL_longlong_t value = 0;
Packit 4a5d52
Packit 4a5d52
	if ((literal = IDL_resolve_const_exp ($1, IDLN_INTEGER))) {
Packit 4a5d52
		assert (IDL_NODE_TYPE (literal) == IDLN_INTEGER);
Packit 4a5d52
		++IDL_NODE_REFS (literal);
Packit 4a5d52
		value = IDL_INTEGER (literal).value;
Packit 4a5d52
		if ( literal != $1 )
Packit 4a5d52
			IDL_tree_free ($1);
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	if (literal && IDL_NODE_UP (literal) &&
Packit 4a5d52
	    IDL_NODE_TYPE (IDL_NODE_UP (literal)) == IDLN_CONST_DCL)
Packit 4a5d52
		ident = IDL_CONST_DCL (IDL_NODE_UP (literal)).ident;
Packit 4a5d52
	
Packit 4a5d52
	if (literal == NULL) {
Packit 4a5d52
		if (!(__IDL_flags & IDLF_NO_EVAL_CONST))
Packit 4a5d52
			yyerror ("Could not resolve constant expression");
Packit 4a5d52
		$$ = $1;
Packit 4a5d52
	} else if (value == 0) {
Packit 4a5d52
		yyerror ("Zero array size is illegal");
Packit 4a5d52
		if (ident)
Packit 4a5d52
			IDL_tree_error (ident, "From constant declared here");
Packit 4a5d52
		$$ = NULL;
Packit 4a5d52
	} else if (value < 0) {
Packit 4a5d52
		yywarningv (IDL_WARNING1, "Cannot use negative value %"
Packit 4a5d52
			    IDL_LL "d, using %" IDL_LL "d",
Packit 4a5d52
			   value, -value);
Packit 4a5d52
		if (ident)
Packit 4a5d52
			IDL_tree_warning (ident,
Packit 4a5d52
					  IDL_WARNING1, "From constant declared here");
Packit 4a5d52
		$$ = IDL_integer_new (-value);
Packit 4a5d52
	}
Packit 4a5d52
	else
Packit 4a5d52
		$$ = IDL_integer_new (value);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
z_declspec:		/* empty */			{ $$ = 0; }
Packit 4a5d52
|			TOK_DECLSPEC			{
Packit 4a5d52
	$$ = IDL_parse_declspec ($1);
Packit 4a5d52
	g_free ($1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
z_props:		/* empty */			{ $$ = NULL; }
Packit 4a5d52
|			'['				{
Packit 4a5d52
	/* Enable property scanning */
Packit 4a5d52
	if (__IDL_flags & IDLF_PROPERTIES)
Packit 4a5d52
		__IDL_flagsi |= IDLFP_PROPERTIES;
Packit 4a5d52
	else {
Packit 4a5d52
		yyerror ("Property syntax not enabled");
Packit 4a5d52
		YYABORT;
Packit 4a5d52
	}
Packit 4a5d52
}			prop_hash
Packit 4a5d52
			']'				{ $$ = $3; }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
integer_lit:		TOK_INTEGER			{ $$ = IDL_integer_new ($1); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
string_lit:		dqstring_cat			{ $$ = IDL_string_new ($1); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
char_lit:		sqstring			{ $$ = IDL_char_new ($1); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
fixed_pt_lit:		TOK_FIXEDP			{ $$ = IDL_fixed_new ($1); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
floating_pt_lit:	TOK_FLOATP			{ $$ = IDL_float_new ($1); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
boolean_lit:		TOK_TRUE			{ $$ = IDL_boolean_new (TRUE); }
Packit 4a5d52
|			TOK_FALSE			{ $$ = IDL_boolean_new (FALSE); }
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
codefrag:		z_declspec TOK_CODEFRAG		{
Packit 4a5d52
	$$ = $2;
Packit 4a5d52
	assign_declspec ($$, $1);
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
srcfile:		TOK_SRCFILE		{
Packit 4a5d52
	$$ = $1;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
dqstring_cat:		dqstring
Packit 4a5d52
|			dqstring_cat dqstring		{
Packit 4a5d52
	char *catstr = g_malloc (strlen ($1) + strlen ($2) + 1);
Packit 4a5d52
	strcpy (catstr, $1); g_free ($1);
Packit 4a5d52
	strcat (catstr, $2); g_free ($2);
Packit 4a5d52
	$$ = catstr;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
dqstring:		TOK_DQSTRING			{
Packit 4a5d52
	char *s = IDL_do_escapes ($1);
Packit 4a5d52
	g_free ($1);
Packit 4a5d52
	$$ = s;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
sqstring:		TOK_SQSTRING			{
Packit 4a5d52
	char *s = IDL_do_escapes ($1);
Packit 4a5d52
	g_free ($1);
Packit 4a5d52
	$$ = s;
Packit 4a5d52
}
Packit 4a5d52
	;
Packit 4a5d52
Packit 4a5d52
%%
Packit 4a5d52
Packit 4a5d52
void __IDL_parser_reset (void)
Packit 4a5d52
{
Packit 4a5d52
	yyclearin;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static const char *IDL_ns_get_cur_prefix (IDL_ns ns)
Packit 4a5d52
{
Packit 4a5d52
	IDL_tree p;
Packit 4a5d52
Packit 4a5d52
	p = IDL_NS (ns).current;
Packit 4a5d52
Packit 4a5d52
	assert (p != NULL);
Packit 4a5d52
Packit 4a5d52
	while (p && !IDL_GENTREE (p)._cur_prefix)
Packit 4a5d52
		p = IDL_NODE_UP (p);
Packit 4a5d52
Packit 4a5d52
	return p ? IDL_GENTREE (p)._cur_prefix : NULL;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
gchar *IDL_ns_ident_make_repo_id (IDL_ns ns, IDL_tree p,
Packit 4a5d52
				  const char *p_prefix, int *major, int *minor)
Packit 4a5d52
{
Packit 4a5d52
	GString *s = g_string_new (NULL);
Packit 4a5d52
	const char *prefix;
Packit 4a5d52
	char *q;
Packit 4a5d52
Packit 4a5d52
	assert (p != NULL);
Packit 4a5d52
	
Packit 4a5d52
	if (IDL_NODE_TYPE (p) == IDLN_IDENT)
Packit 4a5d52
		p = IDL_IDENT_TO_NS (p);
Packit 4a5d52
Packit 4a5d52
	assert (p != NULL);
Packit 4a5d52
Packit 4a5d52
	prefix = p_prefix ? p_prefix : IDL_ns_get_cur_prefix (ns);
Packit 4a5d52
Packit 4a5d52
	q = IDL_ns_ident_to_qstring (p, "/", 0);
Packit 4a5d52
	g_string_printf (s, "IDL:%s%s%s:%d.%d",
Packit 4a5d52
			  prefix ? prefix : "",
Packit 4a5d52
			  prefix && *prefix ? "/" : "",
Packit 4a5d52
			  q,
Packit 4a5d52
			  major ? *major : 1,
Packit 4a5d52
			  minor ? *minor : 0);
Packit 4a5d52
	g_free (q);
Packit 4a5d52
Packit 4a5d52
	q = s->str;
Packit 4a5d52
	g_string_free (s, FALSE);
Packit 4a5d52
Packit 4a5d52
	return q;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static const char *get_name_token (const char *s, char **tok)
Packit 4a5d52
{
Packit 4a5d52
	const char *begin = s;
Packit 4a5d52
	int state = 0;
Packit 4a5d52
Packit 4a5d52
	if (!s)
Packit 4a5d52
		return NULL;
Packit 4a5d52
Packit 4a5d52
	while (g_ascii_isspace (*s)) ++s;
Packit 4a5d52
	
Packit 4a5d52
	while (1) switch (state) {
Packit 4a5d52
	case 0:		/* Unknown */
Packit 4a5d52
		if (*s == ':')
Packit 4a5d52
			state = 1;
Packit 4a5d52
		else if (isalnum ((int)*s) || *s == '_') {
Packit 4a5d52
			begin = s;
Packit 4a5d52
			state = 2;
Packit 4a5d52
		} else
Packit 4a5d52
			return NULL;
Packit 4a5d52
		break;
Packit 4a5d52
	case 1:		/* Scope */
Packit 4a5d52
		if (strncmp (s, "::", 2) == 0) {
Packit 4a5d52
			char *r = g_malloc (3);
Packit 4a5d52
			strcpy (r, "::");
Packit 4a5d52
			*tok = r;
Packit 4a5d52
			return s + 2;
Packit 4a5d52
		} else	/* Invalid */
Packit 4a5d52
			return NULL;
Packit 4a5d52
		break;
Packit 4a5d52
	case 2:
Packit 4a5d52
		if (isalnum ((int)*s) || *s == '_')
Packit 4a5d52
			++s;
Packit 4a5d52
		else {
Packit 4a5d52
			char *r = g_malloc (s - begin + 1);
Packit 4a5d52
			strncpy (r, begin, s - begin + 1);
Packit 4a5d52
			r[s - begin] = 0;
Packit 4a5d52
			*tok = r;
Packit 4a5d52
			return s;
Packit 4a5d52
		}
Packit 4a5d52
		break;
Packit 4a5d52
	}
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree IDL_ns_pragma_parse_name (IDL_ns ns, const char *s)
Packit 4a5d52
{
Packit 4a5d52
	IDL_tree p = IDL_NS (ns).current, q;
Packit 4a5d52
	int start = 1;
Packit 4a5d52
	char *tok;
Packit 4a5d52
Packit 4a5d52
	/* This is a hack to allow directives for an ident (such
Packit 4a5d52
	 * as and interface) to be located within the scope of
Packit 4a5d52
	 * that identifier. */
Packit 4a5d52
	if ( p && (q=IDL_GENTREE(p).data)!=0
Packit 4a5d52
	  && IDL_NODE_TYPE(q)==IDLN_IDENT
Packit 4a5d52
	  && strcmp(s,IDL_IDENT(q).str)==0 ) {
Packit 4a5d52
		return p;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	while (p && *s && (s = get_name_token (s, &tok))) {
Packit 4a5d52
		if (tok == NULL)
Packit 4a5d52
			return NULL;
Packit 4a5d52
		if (strcmp (tok, "::") == 0) {
Packit 4a5d52
			if (start) {
Packit 4a5d52
				/* Globally scoped */
Packit 4a5d52
				p = IDL_NS (ns).file;
Packit 4a5d52
			}
Packit 4a5d52
			g_free (tok);
Packit 4a5d52
		} else {
Packit 4a5d52
			IDL_tree ident = IDL_ident_new (tok);
Packit 4a5d52
			p = IDL_ns_lookup_this_scope (__IDL_root_ns, p, ident, NULL);
Packit 4a5d52
			IDL_tree_free (ident);
Packit 4a5d52
		}
Packit 4a5d52
		start = 0;
Packit 4a5d52
	}
Packit 4a5d52
	
Packit 4a5d52
	return p;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
void IDL_ns_ID (IDL_ns ns, const char *s)
Packit 4a5d52
{
Packit 4a5d52
	char name[1024], id[1024];
Packit 4a5d52
	IDL_tree p, ident;
Packit 4a5d52
	int n;
Packit 4a5d52
Packit 4a5d52
	n = sscanf (s, "%1023s \"%1023s\"", name, id);
Packit 4a5d52
	if (n < 2 && __IDL_is_parsing) {
Packit 4a5d52
		yywarning (IDL_WARNING1, "Malformed pragma ID");
Packit 4a5d52
		return;
Packit 4a5d52
	}
Packit 4a5d52
	if (id[strlen (id) - 1] == '"')
Packit 4a5d52
		id[strlen (id) - 1] = 0;
Packit 4a5d52
Packit 4a5d52
	p = IDL_ns_pragma_parse_name (__IDL_root_ns, name);
Packit 4a5d52
	if (!p && __IDL_is_parsing) {
Packit 4a5d52
		yywarningv (IDL_WARNING1, "Unknown identifier `%s' in pragma ID", name);
Packit 4a5d52
		return;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	/* We have resolved the identifier, so assign the repo id */
Packit 4a5d52
	assert (IDL_NODE_TYPE (p) == IDLN_GENTREE);
Packit 4a5d52
	assert (IDL_GENTREE (p).data != NULL);
Packit 4a5d52
	assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT);
Packit 4a5d52
	ident = IDL_GENTREE (p).data;
Packit 4a5d52
Packit 4a5d52
	if (IDL_IDENT_REPO_ID (ident) != NULL)
Packit 4a5d52
		g_free (IDL_IDENT_REPO_ID (ident));
Packit 4a5d52
Packit 4a5d52
	IDL_IDENT_REPO_ID (ident) = g_strdup (id);
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
void IDL_ns_version (IDL_ns ns, const char *s)
Packit 4a5d52
{
Packit 4a5d52
	char name[1024];
Packit 4a5d52
	int n, major, minor;
Packit 4a5d52
	IDL_tree p, ident;
Packit 4a5d52
Packit 4a5d52
	n = sscanf (s, "%1023s %u.%u", name, &major, &minor);
Packit 4a5d52
	if (n < 3 && __IDL_is_parsing) {
Packit 4a5d52
		yywarning (IDL_WARNING1, "Malformed pragma version");
Packit 4a5d52
		return;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	p = IDL_ns_pragma_parse_name (__IDL_root_ns, name);
Packit 4a5d52
	if (!p && __IDL_is_parsing) {
Packit 4a5d52
		yywarningv (IDL_WARNING1, "Unknown identifier `%s' in pragma version", name);
Packit 4a5d52
		return;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	/* We have resolved the identifier, so assign the repo id */
Packit 4a5d52
	assert (IDL_NODE_TYPE (p) == IDLN_GENTREE);
Packit 4a5d52
	assert (IDL_GENTREE (p).data != NULL);
Packit 4a5d52
	assert (IDL_NODE_TYPE (IDL_GENTREE (p).data) == IDLN_IDENT);
Packit 4a5d52
	ident = IDL_GENTREE (p).data;
Packit 4a5d52
Packit 4a5d52
	if (IDL_IDENT_REPO_ID (ident) != NULL) {
Packit 4a5d52
		char *v = strrchr (IDL_IDENT_REPO_ID (ident), ':');
Packit 4a5d52
		if (v) {
Packit 4a5d52
			GString *s;
Packit 4a5d52
Packit 4a5d52
			*v = 0;
Packit 4a5d52
			s = g_string_new (NULL);
Packit 4a5d52
			g_string_printf (s, "%s:%d.%d",
Packit 4a5d52
					  IDL_IDENT_REPO_ID (ident), major, minor);
Packit 4a5d52
			g_free (IDL_IDENT_REPO_ID (ident));
Packit 4a5d52
			IDL_IDENT_REPO_ID (ident) = s->str;
Packit 4a5d52
			g_string_free (s, FALSE);
Packit 4a5d52
		} else if (__IDL_is_parsing)
Packit 4a5d52
			yywarningv (IDL_WARNING1, "Cannot find RepositoryID OMG IDL version in ID `%s'",
Packit 4a5d52
				    IDL_IDENT_REPO_ID (ident));
Packit 4a5d52
	} else
Packit 4a5d52
		IDL_IDENT_REPO_ID (ident) =
Packit 4a5d52
			IDL_ns_ident_make_repo_id (
Packit 4a5d52
				__IDL_root_ns, p, NULL, &major, &minor);
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
int IDL_inhibit_get (void)
Packit 4a5d52
{
Packit 4a5d52
	g_return_val_if_fail (__IDL_is_parsing, -1);
Packit 4a5d52
Packit 4a5d52
	return __IDL_inhibits;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
void IDL_inhibit_push (void)
Packit 4a5d52
{
Packit 4a5d52
	g_return_if_fail (__IDL_is_parsing);
Packit 4a5d52
Packit 4a5d52
	++__IDL_inhibits;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
void IDL_inhibit_pop (void)
Packit 4a5d52
{
Packit 4a5d52
	g_return_if_fail (__IDL_is_parsing);
Packit 4a5d52
Packit 4a5d52
	if (--__IDL_inhibits < 0)
Packit 4a5d52
		__IDL_inhibits = 0;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static void IDL_inhibit (IDL_ns ns, const char *s)
Packit 4a5d52
{
Packit 4a5d52
	if (g_ascii_strcasecmp ("push", s) == 0)
Packit 4a5d52
		IDL_inhibit_push ();
Packit 4a5d52
	else if (g_ascii_strcasecmp ("pop", s) == 0)
Packit 4a5d52
		IDL_inhibit_pop ();
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static void IDL_typecodes_as_tok (IDL_ns ns, const char *s)
Packit 4a5d52
{
Packit 4a5d52
	if (g_ascii_strcasecmp ("push", s) == 0)
Packit 4a5d52
		++(__IDL_typecodes_as_tok);
Packit 4a5d52
	else if (g_ascii_strcasecmp ("pop", s) == 0)
Packit 4a5d52
		--(__IDL_typecodes_as_tok);
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static void IDL_pidl (IDL_ns ns, const char *s)
Packit 4a5d52
{
Packit 4a5d52
	if (g_ascii_strcasecmp ("push", s) == 0)
Packit 4a5d52
		++(__IDL_pidl);
Packit 4a5d52
	else if (g_ascii_strcasecmp ("pop", s) == 0)
Packit 4a5d52
		--(__IDL_pidl);
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
void __IDL_do_pragma (const char *s)
Packit 4a5d52
{
Packit 4a5d52
	int n;
Packit 4a5d52
	char directive[256];
Packit 4a5d52
Packit 4a5d52
	g_return_if_fail (__IDL_is_parsing);
Packit 4a5d52
	g_return_if_fail (s != NULL);
Packit 4a5d52
Packit 4a5d52
	if (sscanf (s, "%255s%n", directive, &n) < 1)
Packit 4a5d52
		return;
Packit 4a5d52
	s += n;
Packit 4a5d52
	while (g_ascii_isspace (*s)) ++s;
Packit 4a5d52
Packit 4a5d52
	if (strcmp (directive, "prefix") == 0)
Packit 4a5d52
		IDL_ns_prefix (__IDL_root_ns, s);
Packit 4a5d52
	else if (strcmp (directive, "ID") == 0)
Packit 4a5d52
		IDL_ns_ID (__IDL_root_ns, s);
Packit 4a5d52
	else if (strcmp (directive, "version") == 0)
Packit 4a5d52
		IDL_ns_version (__IDL_root_ns, s);
Packit 4a5d52
	else if (strcmp (directive, "inhibit") == 0)
Packit 4a5d52
		IDL_inhibit (__IDL_root_ns, s);
Packit 4a5d52
	else if (strcmp (directive, "typecodes_as_tok") == 0)
Packit 4a5d52
		IDL_typecodes_as_tok (__IDL_root_ns, s);
Packit 4a5d52
	else if (strcmp (directive, "pidl") == 0)
Packit 4a5d52
		IDL_pidl (__IDL_root_ns, s);
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_declspec_t IDL_parse_declspec (const char *strspec)
Packit 4a5d52
{
Packit 4a5d52
	IDL_declspec_t flags = IDLF_DECLSPEC_EXIST;
Packit 4a5d52
Packit 4a5d52
	if (strspec == NULL)
Packit 4a5d52
		return flags;
Packit 4a5d52
Packit 4a5d52
	if (strcmp (strspec, "inhibit") == 0)
Packit 4a5d52
		flags |= IDLF_DECLSPEC_INHIBIT;
Packit 4a5d52
	if (strcmp (strspec, "pidl") == 0)
Packit 4a5d52
		flags |= IDLF_DECLSPEC_PIDL;
Packit 4a5d52
	else if (__IDL_is_parsing)
Packit 4a5d52
		yywarningv (IDL_WARNING1, "Ignoring unknown declspec `%s'", strspec);
Packit 4a5d52
Packit 4a5d52
	return flags;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
IDL_tree IDL_file_set (const char *filename, int line)
Packit 4a5d52
{
Packit 4a5d52
	IDL_fileinfo *fi;
Packit 4a5d52
	IDL_tree tree = NULL;
Packit 4a5d52
Packit 4a5d52
	g_return_val_if_fail (__IDL_is_parsing, NULL);
Packit 4a5d52
Packit 4a5d52
	if (filename) {
Packit 4a5d52
		const char *oldfilename = __IDL_cur_filename;
Packit 4a5d52
		gboolean wasInhibit = IS_INHIBIT_STATE();
Packit 4a5d52
		gboolean isTop = 
Packit 4a5d52
#ifdef HAVE_CPP_PIPE_STDIN
Packit 4a5d52
			strlen (filename)==0;
Packit 4a5d52
#else
Packit 4a5d52
			__IDL_tmp_filename &&
Packit 4a5d52
			strcmp (filename, __IDL_tmp_filename)==0;
Packit 4a5d52
#endif
Packit 4a5d52
		if ( isTop ) {
Packit 4a5d52
			filename = __IDL_real_filename;
Packit 4a5d52
			__IDL_flagsi &= ~IDLFP_IN_INCLUDES;
Packit 4a5d52
		} else {
Packit 4a5d52
			__IDL_flagsi |= IDLFP_IN_INCLUDES;
Packit 4a5d52
		}
Packit 4a5d52
Packit 4a5d52
		if ((fi=g_hash_table_lookup(__IDL_filename_hash, filename)) ) {
Packit 4a5d52
			__IDL_cur_fileinfo = fi;
Packit 4a5d52
			++(fi->seenCnt);
Packit 4a5d52
		} else {
Packit 4a5d52
			fi = g_new0 (IDL_fileinfo, 1);
Packit 4a5d52
			fi->name = g_strdup(filename);
Packit 4a5d52
			g_hash_table_insert (__IDL_filename_hash, fi->name, fi);
Packit 4a5d52
		}
Packit 4a5d52
		__IDL_cur_fileinfo = fi;
Packit 4a5d52
		__IDL_cur_filename = fi->name;
Packit 4a5d52
		if ( (__IDL_flags & IDLF_SRCFILES)!=0
Packit 4a5d52
		  && (oldfilename==0 
Packit 4a5d52
		  	    || strcmp(oldfilename,fi->name)!=0) ) {
Packit 4a5d52
			tree = IDL_srcfile_new(fi->name, fi->seenCnt, isTop, wasInhibit);
Packit 4a5d52
		}
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	if (__IDL_cur_line > 0)
Packit 4a5d52
		__IDL_cur_line = line;
Packit 4a5d52
	return tree;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
void IDL_file_get (const char **filename, int *line)
Packit 4a5d52
{
Packit 4a5d52
	g_return_if_fail (__IDL_is_parsing);
Packit 4a5d52
Packit 4a5d52
	if (filename)
Packit 4a5d52
		*filename = __IDL_cur_filename;
Packit 4a5d52
Packit 4a5d52
	if (line)
Packit 4a5d52
		*line = __IDL_cur_line;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static int do_token_error (IDL_tree p, const char *message, gboolean prev)
Packit 4a5d52
{
Packit 4a5d52
	int dienow;
Packit 4a5d52
	char *what = NULL, *who = NULL;
Packit 4a5d52
Packit 4a5d52
	assert (p != NULL);
Packit 4a5d52
Packit 4a5d52
	dienow = IDL_tree_get_node_info (p, &what, &who);
Packit 4a5d52
Packit 4a5d52
	assert (what != NULL);
Packit 4a5d52
	
Packit 4a5d52
	if (who && *who)
Packit 4a5d52
		IDL_tree_error (p, "%s %s `%s'", message, what, who);
Packit 4a5d52
	else
Packit 4a5d52
		IDL_tree_error (p, "%s %s", message, what);
Packit 4a5d52
	
Packit 4a5d52
	return dienow;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static void illegal_context_type_error (IDL_tree p, const char *what)
Packit 4a5d52
{
Packit 4a5d52
	GString *s = g_string_new (NULL);
Packit 4a5d52
Packit 4a5d52
	g_string_printf (s, "Illegal type `%%s' for %s", what);
Packit 4a5d52
	illegal_type_error (p, s->str);
Packit 4a5d52
	g_string_free (s, TRUE);
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static void illegal_type_error (IDL_tree p, const char *message)
Packit 4a5d52
{
Packit 4a5d52
	GString *s;
Packit 4a5d52
Packit 4a5d52
	s = IDL_tree_to_IDL_string (p, NULL, IDLF_OUTPUT_NO_NEWLINES);
Packit 4a5d52
	yyerrorv (message, s->str);
Packit 4a5d52
	g_string_free (s, TRUE);
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree list_start (IDL_tree a, gboolean filter_null)
Packit 4a5d52
{
Packit 4a5d52
	IDL_tree p;
Packit 4a5d52
Packit 4a5d52
	if (!a && filter_null)
Packit 4a5d52
		return NULL;
Packit 4a5d52
Packit 4a5d52
	p = IDL_list_new (a);
Packit 4a5d52
Packit 4a5d52
	return p;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree list_chain (IDL_tree a, IDL_tree b, gboolean filter_null)
Packit 4a5d52
{
Packit 4a5d52
	IDL_tree p;
Packit 4a5d52
Packit 4a5d52
	if (filter_null) {
Packit 4a5d52
		if (!b)
Packit 4a5d52
			return a;
Packit 4a5d52
		if (!a)
Packit 4a5d52
			return list_start (b, filter_null);
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	p = IDL_list_new (b);
Packit 4a5d52
	a = IDL_list_concat (a, p);
Packit 4a5d52
Packit 4a5d52
	return a;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree zlist_chain (IDL_tree a, IDL_tree b, gboolean filter_null)
Packit 4a5d52
{
Packit 4a5d52
	if (a == NULL)
Packit 4a5d52
		return list_start (b, filter_null);
Packit 4a5d52
	else
Packit 4a5d52
		return list_chain (a, b, filter_null);
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static int IDL_binop_chktypes (enum IDL_binop op, IDL_tree a, IDL_tree b)
Packit 4a5d52
{
Packit 4a5d52
	if (IDL_NODE_TYPE (a) != IDLN_BINOP &&
Packit 4a5d52
	    IDL_NODE_TYPE (b) != IDLN_BINOP &&
Packit 4a5d52
	    IDL_NODE_TYPE (a) != IDLN_UNARYOP &&
Packit 4a5d52
	    IDL_NODE_TYPE (b) != IDLN_UNARYOP &&
Packit 4a5d52
	    IDL_NODE_TYPE (a) != IDL_NODE_TYPE (b)) {
Packit 4a5d52
		yyerror ("Invalid mix of types in constant expression");
Packit 4a5d52
		return -1;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	switch (op) {
Packit 4a5d52
	case IDL_BINOP_MULT:
Packit 4a5d52
	case IDL_BINOP_DIV:
Packit 4a5d52
	case IDL_BINOP_ADD:
Packit 4a5d52
	case IDL_BINOP_SUB:
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_MOD:
Packit 4a5d52
	case IDL_BINOP_SHR:
Packit 4a5d52
	case IDL_BINOP_SHL:
Packit 4a5d52
	case IDL_BINOP_AND:
Packit 4a5d52
	case IDL_BINOP_OR:
Packit 4a5d52
	case IDL_BINOP_XOR:
Packit 4a5d52
		if ((IDL_NODE_TYPE (a) != IDLN_INTEGER ||
Packit 4a5d52
		     IDL_NODE_TYPE (b) != IDLN_INTEGER) &&
Packit 4a5d52
		    !(IDL_NODE_TYPE (a) == IDLN_BINOP ||
Packit 4a5d52
		      IDL_NODE_TYPE (b) == IDLN_BINOP ||
Packit 4a5d52
		      IDL_NODE_TYPE (a) == IDLN_UNARYOP ||
Packit 4a5d52
		      IDL_NODE_TYPE (b) == IDLN_UNARYOP)) {
Packit 4a5d52
			yyerror ("Invalid operation on non-integer value");
Packit 4a5d52
			return -1;
Packit 4a5d52
		}
Packit 4a5d52
		break;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	return 0;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static int IDL_unaryop_chktypes (enum IDL_unaryop op, IDL_tree a)
Packit 4a5d52
{
Packit 4a5d52
	switch (op) {
Packit 4a5d52
	case IDL_UNARYOP_PLUS:
Packit 4a5d52
	case IDL_UNARYOP_MINUS:
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_UNARYOP_COMPLEMENT:
Packit 4a5d52
		if (IDL_NODE_TYPE (a) != IDLN_INTEGER &&
Packit 4a5d52
		    !(IDL_NODE_TYPE (a) == IDLN_BINOP ||
Packit 4a5d52
		      IDL_NODE_TYPE (a) == IDLN_UNARYOP)) {
Packit 4a5d52
			yyerror ("Operand to complement must be integer");
Packit 4a5d52
			return -1;
Packit 4a5d52
		}
Packit 4a5d52
		break;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	return 0;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree IDL_binop_eval_integer (enum IDL_binop op, IDL_tree a, IDL_tree b)
Packit 4a5d52
{
Packit 4a5d52
	IDL_tree p = NULL;
Packit 4a5d52
Packit 4a5d52
	assert (IDL_NODE_TYPE (a) == IDLN_INTEGER);
Packit 4a5d52
Packit 4a5d52
	switch (op) {
Packit 4a5d52
	case IDL_BINOP_MULT:
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value * IDL_INTEGER (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_DIV:
Packit 4a5d52
		if (IDL_INTEGER (b).value == 0) {
Packit 4a5d52
			yyerror ("Divide by zero in constant expression");
Packit 4a5d52
			return NULL;
Packit 4a5d52
		}
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value / IDL_INTEGER (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_ADD:
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value + IDL_INTEGER (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_SUB:
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value - IDL_INTEGER (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_MOD:
Packit 4a5d52
		if (IDL_INTEGER (b).value == 0) {
Packit 4a5d52
			yyerror ("Modulo by zero in constant expression");
Packit 4a5d52
			return NULL;
Packit 4a5d52
		}
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value % IDL_INTEGER (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_SHR:
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value >> IDL_INTEGER (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_SHL:
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value << IDL_INTEGER (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_AND:
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value & IDL_INTEGER (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_OR:
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value | IDL_INTEGER (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_XOR:
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value ^ IDL_INTEGER (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	return p;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree IDL_binop_eval_float (enum IDL_binop op, IDL_tree a, IDL_tree b)
Packit 4a5d52
{
Packit 4a5d52
	IDL_tree p = NULL;
Packit 4a5d52
Packit 4a5d52
	assert (IDL_NODE_TYPE (a) == IDLN_FLOAT);
Packit 4a5d52
Packit 4a5d52
	switch (op) {
Packit 4a5d52
	case IDL_BINOP_MULT:
Packit 4a5d52
		p = IDL_float_new (IDL_FLOAT (a).value * IDL_FLOAT (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_DIV:
Packit 4a5d52
		if (IDL_FLOAT (b).value == 0.0) {
Packit 4a5d52
			yyerror ("Divide by zero in constant expression");
Packit 4a5d52
			return NULL;
Packit 4a5d52
		}
Packit 4a5d52
		p = IDL_float_new (IDL_FLOAT (a).value / IDL_FLOAT (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_ADD:
Packit 4a5d52
		p = IDL_float_new (IDL_FLOAT (a).value + IDL_FLOAT (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_BINOP_SUB:
Packit 4a5d52
		p = IDL_float_new (IDL_FLOAT (a).value - IDL_FLOAT (b).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	default:
Packit 4a5d52
		break;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	return p;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree IDL_binop_eval (enum IDL_binop op, IDL_tree a, IDL_tree b)
Packit 4a5d52
{
Packit 4a5d52
	assert (IDL_NODE_TYPE (a) == IDL_NODE_TYPE (b));
Packit 4a5d52
Packit 4a5d52
	switch (IDL_NODE_TYPE (a)) {
Packit 4a5d52
	case IDLN_INTEGER: return IDL_binop_eval_integer (op, a, b);
Packit 4a5d52
	case IDLN_FLOAT: return IDL_binop_eval_float (op, a, b);
Packit 4a5d52
	default: return NULL;
Packit 4a5d52
	}
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree IDL_unaryop_eval_integer (enum IDL_unaryop op, IDL_tree a)
Packit 4a5d52
{
Packit 4a5d52
	IDL_tree p = NULL;
Packit 4a5d52
Packit 4a5d52
	assert (IDL_NODE_TYPE (a) == IDLN_INTEGER);
Packit 4a5d52
Packit 4a5d52
	switch (op) {
Packit 4a5d52
	case IDL_UNARYOP_PLUS:
Packit 4a5d52
		p = IDL_integer_new (IDL_INTEGER (a).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_UNARYOP_MINUS:
Packit 4a5d52
		p = IDL_integer_new (-IDL_INTEGER (a).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_UNARYOP_COMPLEMENT:
Packit 4a5d52
		p = IDL_integer_new (~IDL_INTEGER (a).value);
Packit 4a5d52
		break;
Packit 4a5d52
	}
Packit 4a5d52
       
Packit 4a5d52
	return p;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree IDL_unaryop_eval_fixed (enum IDL_unaryop op, IDL_tree a)
Packit 4a5d52
{
Packit 4a5d52
	IDL_tree p = NULL;
Packit 4a5d52
Packit 4a5d52
	assert (IDL_NODE_TYPE (a) == IDLN_FIXED);
Packit 4a5d52
Packit 4a5d52
	switch (op) {
Packit 4a5d52
	case IDL_UNARYOP_PLUS:
Packit 4a5d52
		p = IDL_fixed_new (IDL_FIXED (a).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	default:
Packit 4a5d52
		break;
Packit 4a5d52
	}
Packit 4a5d52
       
Packit 4a5d52
	return p;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree IDL_unaryop_eval_float (enum IDL_unaryop op, IDL_tree a)
Packit 4a5d52
{
Packit 4a5d52
	IDL_tree p = NULL;
Packit 4a5d52
Packit 4a5d52
	assert (IDL_NODE_TYPE (a) == IDLN_FLOAT);
Packit 4a5d52
Packit 4a5d52
	switch (op) {
Packit 4a5d52
	case IDL_UNARYOP_PLUS:
Packit 4a5d52
		p = IDL_float_new (IDL_FLOAT (a).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	case IDL_UNARYOP_MINUS:
Packit 4a5d52
		p = IDL_float_new (-IDL_FLOAT (a).value);
Packit 4a5d52
		break;
Packit 4a5d52
Packit 4a5d52
	default:
Packit 4a5d52
		break;
Packit 4a5d52
	}
Packit 4a5d52
       
Packit 4a5d52
	return p;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
static IDL_tree IDL_unaryop_eval (enum IDL_unaryop op, IDL_tree a)
Packit 4a5d52
{
Packit 4a5d52
	switch (IDL_NODE_TYPE (a)) {
Packit 4a5d52
	case IDLN_INTEGER: return IDL_unaryop_eval_integer (op, a);
Packit 4a5d52
	case IDLN_FIXED: return IDL_unaryop_eval_fixed (op, a);
Packit 4a5d52
	case IDLN_FLOAT: return IDL_unaryop_eval_float (op, a);
Packit 4a5d52
	default: return NULL;
Packit 4a5d52
	}
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
IDL_tree IDL_resolve_const_exp (IDL_tree p, IDL_tree_type type)
Packit 4a5d52
{
Packit 4a5d52
	gboolean resolved_value = FALSE, die = FALSE;
Packit 4a5d52
	gboolean wrong_type = FALSE;
Packit 4a5d52
Packit 4a5d52
	while (!resolved_value && !die) {
Packit 4a5d52
		if (IDL_NODE_TYPE (p) == IDLN_IDENT) {
Packit 4a5d52
			IDL_tree q = IDL_NODE_UP (p);
Packit 4a5d52
			
Packit 4a5d52
			assert (q != NULL);
Packit 4a5d52
			if (IDL_NODE_UP (q) &&
Packit 4a5d52
			    IDL_NODE_TYPE (IDL_NODE_UP (q)) == IDLN_TYPE_ENUM) {
Packit 4a5d52
				p = q;
Packit 4a5d52
				die = TRUE;
Packit 4a5d52
				break;
Packit 4a5d52
			} else if (IDL_NODE_TYPE (q) != IDLN_CONST_DCL) {
Packit 4a5d52
				p = q;
Packit 4a5d52
				wrong_type = TRUE;
Packit 4a5d52
				die = TRUE;
Packit 4a5d52
			} else
Packit 4a5d52
 				p = IDL_CONST_DCL (q).const_exp;
Packit 4a5d52
		}
Packit 4a5d52
		
Packit 4a5d52
		if (p == NULL ||
Packit 4a5d52
		    IDL_NODE_TYPE (p) == IDLN_BINOP ||
Packit 4a5d52
		    IDL_NODE_TYPE (p) == IDLN_UNARYOP) {
Packit 4a5d52
			die = TRUE;
Packit 4a5d52
			continue;
Packit 4a5d52
		}
Packit 4a5d52
		
Packit 4a5d52
		resolved_value = IDL_NODE_IS_LITERAL (p);
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	if (resolved_value &&
Packit 4a5d52
	    type != IDLN_ANY &&
Packit 4a5d52
	    IDL_NODE_TYPE (p) != type)
Packit 4a5d52
		wrong_type = TRUE;
Packit 4a5d52
	
Packit 4a5d52
	if (wrong_type) {
Packit 4a5d52
		yyerror ("Invalid type for constant");
Packit 4a5d52
		IDL_tree_error (p, "Previous resolved type declaration");
Packit 4a5d52
		return NULL;
Packit 4a5d52
	}
Packit 4a5d52
Packit 4a5d52
	return resolved_value ? p : NULL;
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
void IDL_queue_new_ident_comment (const char *str)
Packit 4a5d52
{
Packit 4a5d52
	g_return_if_fail (str != NULL);
Packit 4a5d52
Packit 4a5d52
	__IDL_new_ident_comments = g_slist_append (__IDL_new_ident_comments, g_strdup (str));
Packit 4a5d52
}
Packit 4a5d52
Packit 4a5d52
/*
Packit 4a5d52
 * Local variables:
Packit 4a5d52
 * mode: C
Packit 4a5d52
 * c-basic-offset: 8
Packit 4a5d52
 * tab-width: 8
Packit 4a5d52
 * indent-tabs-mode: t
Packit 4a5d52
 * End:
Packit 4a5d52
 */