xref: /AOO41X/main/idlc/source/parser.y (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir /*
29*cdf0e10cSrcweir  * parser.yy - BISON grammar for IDLC 1.0
30*cdf0e10cSrcweir  */
31*cdf0e10cSrcweir 
32*cdf0e10cSrcweir %{
33*cdf0e10cSrcweir #include <string.h>
34*cdf0e10cSrcweir 
35*cdf0e10cSrcweir #ifndef _IDLC_IDLC_HXX_
36*cdf0e10cSrcweir #include <idlc/idlc.hxx>
37*cdf0e10cSrcweir #endif
38*cdf0e10cSrcweir #ifndef _IDLC_ERRORHANDLER_HXX_
39*cdf0e10cSrcweir #include <idlc/errorhandler.hxx>
40*cdf0e10cSrcweir #endif
41*cdf0e10cSrcweir #ifndef _IDLC_FEHELPER_HXX_
42*cdf0e10cSrcweir #include <idlc/fehelper.hxx>
43*cdf0e10cSrcweir #endif
44*cdf0e10cSrcweir #ifndef _IDLC_EXPRESSION_HXX_
45*cdf0e10cSrcweir #include <idlc/astexpression.hxx>
46*cdf0e10cSrcweir #endif
47*cdf0e10cSrcweir #ifndef _IDLC_ASTCONSTANTS_HXX_
48*cdf0e10cSrcweir #include <idlc/astconstants.hxx>
49*cdf0e10cSrcweir #endif
50*cdf0e10cSrcweir #ifndef _IDLC_ASTCONSTANT_HXX_
51*cdf0e10cSrcweir #include <idlc/astconstant.hxx>
52*cdf0e10cSrcweir #endif
53*cdf0e10cSrcweir #ifndef _IDLC_ASTARRAY_HXX_
54*cdf0e10cSrcweir #include <idlc/astarray.hxx>
55*cdf0e10cSrcweir #endif
56*cdf0e10cSrcweir #ifndef _IDLC_ASTBASETYPE_HXX_
57*cdf0e10cSrcweir #include <idlc/astbasetype.hxx>
58*cdf0e10cSrcweir #endif
59*cdf0e10cSrcweir #ifndef _IDLC_ASTTYPEDEF_HXX_
60*cdf0e10cSrcweir #include <idlc/asttypedef.hxx>
61*cdf0e10cSrcweir #endif
62*cdf0e10cSrcweir #ifndef _IDLC_ASTEXCEPTION_HXX_
63*cdf0e10cSrcweir #include <idlc/astexception.hxx>
64*cdf0e10cSrcweir #endif
65*cdf0e10cSrcweir #ifndef _IDLC_ASTMEMBER_HXX_
66*cdf0e10cSrcweir #include <idlc/astmember.hxx>
67*cdf0e10cSrcweir #endif
68*cdf0e10cSrcweir #ifndef _IDLC_ASTENUM_HXX_
69*cdf0e10cSrcweir #include <idlc/astenum.hxx>
70*cdf0e10cSrcweir #endif
71*cdf0e10cSrcweir #ifndef _IDLC_ASTSEQUENCE_HXX_
72*cdf0e10cSrcweir #include <idlc/astsequence.hxx>
73*cdf0e10cSrcweir #endif
74*cdf0e10cSrcweir #ifndef _IDLC_ASTATTRIBUTE_HXX_
75*cdf0e10cSrcweir #include <idlc/astattribute.hxx>
76*cdf0e10cSrcweir #endif
77*cdf0e10cSrcweir #ifndef _IDLC_ASTOPERATION_HXX_
78*cdf0e10cSrcweir #include <idlc/astoperation.hxx>
79*cdf0e10cSrcweir #endif
80*cdf0e10cSrcweir #ifndef _IDLC_ASTPARAMETER_HXX_
81*cdf0e10cSrcweir #include <idlc/astparameter.hxx>
82*cdf0e10cSrcweir #endif
83*cdf0e10cSrcweir #ifndef _IDLC_ASTINTERFACEMEMBER_HXX_
84*cdf0e10cSrcweir #include <idlc/astinterfacemember.hxx>
85*cdf0e10cSrcweir #endif
86*cdf0e10cSrcweir #ifndef _IDLC_ASTSERVICEMEMBER_HXX_
87*cdf0e10cSrcweir #include <idlc/astservicemember.hxx>
88*cdf0e10cSrcweir #endif
89*cdf0e10cSrcweir #ifndef _IDLC_ASTOBSERVES_HXX_
90*cdf0e10cSrcweir #include <idlc/astobserves.hxx>
91*cdf0e10cSrcweir #endif
92*cdf0e10cSrcweir #ifndef _IDLC_ASTNEEDS_HXX_
93*cdf0e10cSrcweir #include <idlc/astneeds.hxx>
94*cdf0e10cSrcweir #endif
95*cdf0e10cSrcweir #ifndef _IDLC_ASTUNION_HXX_
96*cdf0e10cSrcweir #include <idlc/astunion.hxx>
97*cdf0e10cSrcweir #endif
98*cdf0e10cSrcweir #include "idlc/aststructinstance.hxx"
99*cdf0e10cSrcweir 
100*cdf0e10cSrcweir #include "attributeexceptions.hxx"
101*cdf0e10cSrcweir 
102*cdf0e10cSrcweir #include "rtl/strbuf.hxx"
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir #include <algorithm>
105*cdf0e10cSrcweir #include <vector>
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir using namespace ::rtl;
108*cdf0e10cSrcweir 
109*cdf0e10cSrcweir #define YYDEBUG 1
110*cdf0e10cSrcweir #define YYERROR_VERBOSE 1
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir extern int yylex(void);
113*cdf0e10cSrcweir void yyerror(char const *);
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir void checkIdentifier(::rtl::OString* id)
116*cdf0e10cSrcweir {
117*cdf0e10cSrcweir     static short check = 0;
118*cdf0e10cSrcweir     if (check == 0) {
119*cdf0e10cSrcweir         if (idlc()->getOptions()->isValid("-cid"))
120*cdf0e10cSrcweir             check = 1;
121*cdf0e10cSrcweir         else
122*cdf0e10cSrcweir             check = 2;
123*cdf0e10cSrcweir     }
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir     if ( id->indexOf('_') >= 0 )
126*cdf0e10cSrcweir         if ( (id->pData->buffer[0] >= 97 && id->pData->buffer[0] <= 122)
127*cdf0e10cSrcweir              || id->pData->buffer[0] == '_') {
128*cdf0e10cSrcweir             if (check == 1) {
129*cdf0e10cSrcweir                 ::rtl::OStringBuffer msg(25 + id->getLength());
130*cdf0e10cSrcweir                 msg.append("mismatched identifier '");
131*cdf0e10cSrcweir                 msg.append(*id);
132*cdf0e10cSrcweir                 msg.append("'");
133*cdf0e10cSrcweir                 idlc()->error()->syntaxError(idlc()->getParseState(),
134*cdf0e10cSrcweir                                          idlc()->getLineNumber(),
135*cdf0e10cSrcweir                                          msg.getStr());
136*cdf0e10cSrcweir             }
137*cdf0e10cSrcweir             else
138*cdf0e10cSrcweir                 idlc()->error()->warning0(WIDL_WRONG_NAMING_CONV, id->getStr());
139*cdf0e10cSrcweir         }
140*cdf0e10cSrcweir }
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir void reportDoubleMemberDeclarations(
143*cdf0e10cSrcweir     AstInterface::DoubleMemberDeclarations const & doubleMembers)
144*cdf0e10cSrcweir {
145*cdf0e10cSrcweir     for (AstInterface::DoubleMemberDeclarations::const_iterator i(
146*cdf0e10cSrcweir              doubleMembers.begin());
147*cdf0e10cSrcweir          i != doubleMembers.end(); ++i)
148*cdf0e10cSrcweir     {
149*cdf0e10cSrcweir         idlc()->error()->error2(EIDL_DOUBLE_MEMBER, i->first, i->second);
150*cdf0e10cSrcweir     }
151*cdf0e10cSrcweir }
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir void addInheritedInterface(
154*cdf0e10cSrcweir     AstInterface * ifc, rtl::OString const & name, bool optional,
155*cdf0e10cSrcweir     rtl::OUString const & documentation)
156*cdf0e10cSrcweir {
157*cdf0e10cSrcweir     AstDeclaration * decl = ifc->lookupByName(name);
158*cdf0e10cSrcweir     AstDeclaration const * resolved = resolveTypedefs(decl);
159*cdf0e10cSrcweir     if (resolved != 0 && resolved->getNodeType() == NT_interface) {
160*cdf0e10cSrcweir         if (idlc()->error()->checkPublished(decl)) {
161*cdf0e10cSrcweir             if (!static_cast< AstInterface const * >(resolved)->isDefined()) {
162*cdf0e10cSrcweir                 idlc()->error()->inheritanceError(
163*cdf0e10cSrcweir                     NT_interface, &ifc->getScopedName(), decl);
164*cdf0e10cSrcweir             } else {
165*cdf0e10cSrcweir                 AstInterface::DoubleDeclarations doubleDecls(
166*cdf0e10cSrcweir                     ifc->checkInheritedInterfaceClashes(
167*cdf0e10cSrcweir                         static_cast< AstInterface const * >(resolved),
168*cdf0e10cSrcweir                         optional));
169*cdf0e10cSrcweir                 if (doubleDecls.interfaces.empty()
170*cdf0e10cSrcweir                     && doubleDecls.members.empty())
171*cdf0e10cSrcweir                 {
172*cdf0e10cSrcweir                     ifc->addInheritedInterface(
173*cdf0e10cSrcweir                         static_cast< AstType * >(decl), optional,
174*cdf0e10cSrcweir                         documentation);
175*cdf0e10cSrcweir                 } else {
176*cdf0e10cSrcweir                     for (AstInterface::DoubleInterfaceDeclarations::iterator i(
177*cdf0e10cSrcweir                              doubleDecls.interfaces.begin());
178*cdf0e10cSrcweir                          i != doubleDecls.interfaces.end(); ++i)
179*cdf0e10cSrcweir                     {
180*cdf0e10cSrcweir                         idlc()->error()->error1(
181*cdf0e10cSrcweir                             EIDL_DOUBLE_INHERITANCE, *i);
182*cdf0e10cSrcweir                     }
183*cdf0e10cSrcweir                     reportDoubleMemberDeclarations(doubleDecls.members);
184*cdf0e10cSrcweir                 }
185*cdf0e10cSrcweir             }
186*cdf0e10cSrcweir         }
187*cdf0e10cSrcweir     } else {
188*cdf0e10cSrcweir         idlc()->error()->lookupError(
189*cdf0e10cSrcweir             EIDL_INTERFACEMEMBER_LOOKUP, name, scopeAsDecl(ifc));
190*cdf0e10cSrcweir     }
191*cdf0e10cSrcweir }
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir AstDeclaration const * createNamedType(
194*cdf0e10cSrcweir     rtl::OString const * scopedName, DeclList const * typeArgs)
195*cdf0e10cSrcweir {
196*cdf0e10cSrcweir     AstDeclaration * decl = idlc()->scopes()->topNonNull()->lookupByName(
197*cdf0e10cSrcweir         *scopedName);
198*cdf0e10cSrcweir     AstDeclaration const * resolved = resolveTypedefs(decl);
199*cdf0e10cSrcweir     if (decl == 0) {
200*cdf0e10cSrcweir         idlc()->error()->lookupError(*scopedName);
201*cdf0e10cSrcweir     } else if (!idlc()->error()->checkPublished(decl)) {
202*cdf0e10cSrcweir         decl = 0;
203*cdf0e10cSrcweir     } else if (resolved->getNodeType() == NT_struct) {
204*cdf0e10cSrcweir         if (static_cast< AstStruct const * >(resolved)->getTypeParameterCount()
205*cdf0e10cSrcweir             != (typeArgs == 0 ? 0 : typeArgs->size()))
206*cdf0e10cSrcweir         {
207*cdf0e10cSrcweir             idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS);
208*cdf0e10cSrcweir             decl = 0;
209*cdf0e10cSrcweir         } else if (typeArgs != 0) {
210*cdf0e10cSrcweir             AstScope * global = idlc()->scopes()->bottom();
211*cdf0e10cSrcweir             AstDeclaration * inst = new AstStructInstance(
212*cdf0e10cSrcweir                 static_cast< AstType * >(decl), typeArgs, global);
213*cdf0e10cSrcweir             decl = global->addDeclaration(inst);
214*cdf0e10cSrcweir             if (decl != inst) {
215*cdf0e10cSrcweir                 delete inst;
216*cdf0e10cSrcweir             }
217*cdf0e10cSrcweir         }
218*cdf0e10cSrcweir     } else if (decl->isType()) {
219*cdf0e10cSrcweir         if (typeArgs != 0) {
220*cdf0e10cSrcweir             idlc()->error()->error0(EIDL_WRONG_NUMBER_OF_TYPE_ARGUMENTS);
221*cdf0e10cSrcweir             decl = 0;
222*cdf0e10cSrcweir         }
223*cdf0e10cSrcweir     } else {
224*cdf0e10cSrcweir         idlc()->error()->noTypeError(decl);
225*cdf0e10cSrcweir         decl = 0;
226*cdf0e10cSrcweir     }
227*cdf0e10cSrcweir     delete scopedName;
228*cdf0e10cSrcweir     delete typeArgs;
229*cdf0e10cSrcweir     return decl;
230*cdf0e10cSrcweir }
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir bool includes(AstDeclaration const * type1, AstDeclaration const * type2) {
233*cdf0e10cSrcweir     OSL_ASSERT(type2 != 0);
234*cdf0e10cSrcweir     if (type1 != 0) {
235*cdf0e10cSrcweir         if (type1->getNodeType() == NT_instantiated_struct) {
236*cdf0e10cSrcweir             AstStructInstance const * inst
237*cdf0e10cSrcweir                 = static_cast< AstStructInstance const * >(type1);
238*cdf0e10cSrcweir             if (inst->getTypeTemplate() == type2) {
239*cdf0e10cSrcweir                 return true;
240*cdf0e10cSrcweir             }
241*cdf0e10cSrcweir             for (DeclList::const_iterator i(inst->getTypeArgumentsBegin());
242*cdf0e10cSrcweir                  i != inst->getTypeArgumentsEnd(); ++i)
243*cdf0e10cSrcweir             {
244*cdf0e10cSrcweir                 if (includes(*i, type2)) {
245*cdf0e10cSrcweir                     return true;
246*cdf0e10cSrcweir                 }
247*cdf0e10cSrcweir             }
248*cdf0e10cSrcweir         } else if (type1 == type2) {
249*cdf0e10cSrcweir             return true;
250*cdf0e10cSrcweir         }
251*cdf0e10cSrcweir     }
252*cdf0e10cSrcweir     return false;
253*cdf0e10cSrcweir }
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir // Suppress any warnings from generated code:
256*cdf0e10cSrcweir #if defined __GNUC__
257*cdf0e10cSrcweir #pragma GCC system_header
258*cdf0e10cSrcweir #elif defined __SUNPRO_CC
259*cdf0e10cSrcweir #pragma disable_warn
260*cdf0e10cSrcweir #elif defined _MSC_VER
261*cdf0e10cSrcweir #pragma warning(push, 1)
262*cdf0e10cSrcweir #pragma warning(disable: 4273 4701 4706)
263*cdf0e10cSrcweir #endif
264*cdf0e10cSrcweir %}
265*cdf0e10cSrcweir /*
266*cdf0e10cSrcweir  * Declare the type of values in the grammar
267*cdf0e10cSrcweir  */
268*cdf0e10cSrcweir %union {
269*cdf0e10cSrcweir 	ExprType				etval;     /* Expression type */
270*cdf0e10cSrcweir 	AstDeclaration*		dclval;    /* Declaration */
271*cdf0e10cSrcweir     AstDeclaration const * cdclval;
272*cdf0e10cSrcweir     DeclList * dclsval;
273*cdf0e10cSrcweir 	AstExpression*		exval;		/* expression value */
274*cdf0e10cSrcweir 	ExprList*				exlval;	/* expression list value */
275*cdf0e10cSrcweir 	FeDeclarator*			fdval;		/* declarator value */
276*cdf0e10cSrcweir 	FeDeclList*			dlval;		/* declarator list value */
277*cdf0e10cSrcweir 	FeInheritanceHeader*	ihval;		/* inheritance header value */
278*cdf0e10cSrcweir 	::rtl::OString*		sval;		/* OString value */
279*cdf0e10cSrcweir     std::vector< rtl::OString > * svals;
280*cdf0e10cSrcweir 	sal_Char* 			strval;	/* sal_Char* value */
281*cdf0e10cSrcweir 	sal_Bool				bval;		/* sal_Boolean* value */
282*cdf0e10cSrcweir 	sal_Int64				ival;		/* sal_Int64 value */
283*cdf0e10cSrcweir     sal_uInt64 uval; /* sal_uInt64 value */
284*cdf0e10cSrcweir 	sal_uInt32			ulval;		/* sal_uInt32 value */
285*cdf0e10cSrcweir 	double					dval;		/* double value */
286*cdf0e10cSrcweir 	float					fval;		/* float value */
287*cdf0e10cSrcweir 	StringList*			slval;		/* StringList value	*/
288*cdf0e10cSrcweir 	LabelList*			llval;		/* LabelList value	*/
289*cdf0e10cSrcweir 	AstUnionLabel*		lbval;		/* union label value */
290*cdf0e10cSrcweir 	AstMember*			mval;		/* member value */
291*cdf0e10cSrcweir     AttributeExceptions::Part attexcpval;
292*cdf0e10cSrcweir     AttributeExceptions attexcval;
293*cdf0e10cSrcweir }
294*cdf0e10cSrcweir 
295*cdf0e10cSrcweir /*
296*cdf0e10cSrcweir  * Token types: These are returned by the lexer
297*cdf0e10cSrcweir  */
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir %token <sval>		IDL_IDENTIFIER
300*cdf0e10cSrcweir %token 			IDL_ATTRIBUTE
301*cdf0e10cSrcweir %token				IDL_BOUND
302*cdf0e10cSrcweir %token 			IDL_CASE
303*cdf0e10cSrcweir %token 			IDL_CONST
304*cdf0e10cSrcweir %token 			IDL_CONSTANTS
305*cdf0e10cSrcweir %token				IDL_CONSTRAINED
306*cdf0e10cSrcweir %token 			IDL_DEFAULT
307*cdf0e10cSrcweir %token 			IDL_ENUM
308*cdf0e10cSrcweir %token 			IDL_EXCEPTION
309*cdf0e10cSrcweir %token 			IDL_INTERFACE
310*cdf0e10cSrcweir %token 			IDL_MAYBEAMBIGUOUS
311*cdf0e10cSrcweir %token 			IDL_MAYBEDEFAULT
312*cdf0e10cSrcweir %token 			IDL_MAYBEVOID
313*cdf0e10cSrcweir %token 			IDL_MODULE
314*cdf0e10cSrcweir %token 			IDL_NEEDS
315*cdf0e10cSrcweir %token 			IDL_OBSERVES
316*cdf0e10cSrcweir %token 			IDL_OPTIONAL
317*cdf0e10cSrcweir %token 			IDL_PROPERTY
318*cdf0e10cSrcweir %token 			IDL_RAISES
319*cdf0e10cSrcweir %token 			IDL_READONLY
320*cdf0e10cSrcweir %token 			IDL_REMOVEABLE
321*cdf0e10cSrcweir %token 			IDL_SERVICE
322*cdf0e10cSrcweir %token 			IDL_SEQUENCE
323*cdf0e10cSrcweir %token 			IDL_SINGLETON
324*cdf0e10cSrcweir %token 			IDL_STRUCT
325*cdf0e10cSrcweir %token 			IDL_SWITCH
326*cdf0e10cSrcweir %token 			IDL_TYPEDEF
327*cdf0e10cSrcweir %token				IDL_TRANSIENT
328*cdf0e10cSrcweir %token 			IDL_UNION
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir %token 			IDL_ANY
331*cdf0e10cSrcweir %token 			IDL_CHAR
332*cdf0e10cSrcweir %token 			IDL_BOOLEAN
333*cdf0e10cSrcweir %token 			IDL_BYTE
334*cdf0e10cSrcweir %token 			IDL_DOUBLE
335*cdf0e10cSrcweir %token 			IDL_FLOAT
336*cdf0e10cSrcweir %token 			IDL_HYPER
337*cdf0e10cSrcweir %token 			IDL_LONG
338*cdf0e10cSrcweir %token 			IDL_SHORT
339*cdf0e10cSrcweir %token 			IDL_VOID
340*cdf0e10cSrcweir %token 			IDL_STRING
341*cdf0e10cSrcweir %token 			IDL_TYPE
342*cdf0e10cSrcweir %token 			IDL_UNSIGNED
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir %token 			IDL_TRUE
345*cdf0e10cSrcweir %token 			IDL_FALSE
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir %token 			IDL_IN
348*cdf0e10cSrcweir %token 			IDL_OUT
349*cdf0e10cSrcweir %token 			IDL_INOUT
350*cdf0e10cSrcweir %token 			IDL_ONEWAY
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir %token IDL_GET
353*cdf0e10cSrcweir %token IDL_SET
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir %token IDL_PUBLISHED
356*cdf0e10cSrcweir 
357*cdf0e10cSrcweir %token IDL_ELLIPSIS
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir %token <strval>	IDL_LEFTSHIFT
360*cdf0e10cSrcweir %token <strval>	IDL_RIGHTSHIFT
361*cdf0e10cSrcweir %token <strval> 	IDL_SCOPESEPARATOR
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir %token <ival>		IDL_INTEGER_LITERAL
364*cdf0e10cSrcweir %token <uval> IDL_INTEGER_ULITERAL
365*cdf0e10cSrcweir %token <dval>		IDL_FLOATING_PT_LITERAL
366*cdf0e10cSrcweir 
367*cdf0e10cSrcweir /*
368*cdf0e10cSrcweir  * These are production names:
369*cdf0e10cSrcweir  */
370*cdf0e10cSrcweir %type <dclval>	type_dcl const_dcl
371*cdf0e10cSrcweir %type <dclval>	array_declarator
372*cdf0e10cSrcweir %type <dclval>  exception_name
373*cdf0e10cSrcweir %type <cdclval> array_type constructed_type_spec enum_type op_type_spec
374*cdf0e10cSrcweir %type <cdclval> sequence_type_spec simple_type_spec struct_type switch_type_spec
375*cdf0e10cSrcweir %type <cdclval> template_type_spec type_spec union_type
376*cdf0e10cSrcweir %type <cdclval> fundamental_type type_arg type_or_parameter
377*cdf0e10cSrcweir %type <dclsval> opt_raises raises exception_list
378*cdf0e10cSrcweir %type <attexcpval> opt_attribute_get_raises attribute_get_raises
379*cdf0e10cSrcweir %type <attexcpval> opt_attribute_set_raises attribute_set_raises
380*cdf0e10cSrcweir %type <dclsval> opt_type_args type_args
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir %type <sval>    identifier
383*cdf0e10cSrcweir %type <sval>	interface_decl
384*cdf0e10cSrcweir %type <sval>	scoped_name inheritance_spec
385*cdf0e10cSrcweir %type <slval>  	scoped_names at_least_one_scoped_name
386*cdf0e10cSrcweir 
387*cdf0e10cSrcweir %type <etval>	const_type integer_type char_type boolean_type
388*cdf0e10cSrcweir %type <etval>	floating_pt_type any_type signed_int string_type
389*cdf0e10cSrcweir %type <etval>	unsigned_int base_type_spec byte_type type_type
390*cdf0e10cSrcweir 
391*cdf0e10cSrcweir %type <exval>	expression const_expr or_expr xor_expr and_expr
392*cdf0e10cSrcweir %type <exval>	add_expr mult_expr unary_expr primary_expr shift_expr
393*cdf0e10cSrcweir %type <exval>	literal positive_int_expr array_dim
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir %type <exlval> 	at_least_one_array_dim array_dims
396*cdf0e10cSrcweir 
397*cdf0e10cSrcweir %type <fdval> 	declarator simple_declarator complex_declarator
398*cdf0e10cSrcweir %type <dlval> 	declarators at_least_one_declarator
399*cdf0e10cSrcweir 
400*cdf0e10cSrcweir %type <ihval>	exception_header structure_header interfaceheader
401*cdf0e10cSrcweir 
402*cdf0e10cSrcweir %type <ulval> 	flag_header opt_attrflags opt_attrflag operation_head
403*cdf0e10cSrcweir %type <ulval>	direction service_interface_header service_service_header
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir %type <llval>	case_labels at_least_one_case_label
406*cdf0e10cSrcweir %type <lbval>	case_label
407*cdf0e10cSrcweir %type <mval>	element_spec
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir %type <bval>    optional_inherited_interface opt_rest opt_service_body
410*cdf0e10cSrcweir 
411*cdf0e10cSrcweir %type <attexcval> opt_attribute_block attribute_block_rest opt_attribute_raises
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir %type <svals> opt_type_params type_params
414*cdf0e10cSrcweir 
415*cdf0e10cSrcweir %%
416*cdf0e10cSrcweir /*
417*cdf0e10cSrcweir  * Grammar start here
418*cdf0e10cSrcweir  */
419*cdf0e10cSrcweir start : definitions;
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir definitions :
422*cdf0e10cSrcweir 	definition definitions
423*cdf0e10cSrcweir 	| /* EMPTY */
424*cdf0e10cSrcweir 	;
425*cdf0e10cSrcweir 
426*cdf0e10cSrcweir definition :
427*cdf0e10cSrcweir     opt_published publishable_definition
428*cdf0e10cSrcweir 	| module_dcl
429*cdf0e10cSrcweir 	{
430*cdf0e10cSrcweir 		idlc()->setParseState(PS_ModuleDeclSeen);
431*cdf0e10cSrcweir 	}
432*cdf0e10cSrcweir 	';'
433*cdf0e10cSrcweir 	{
434*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
435*cdf0e10cSrcweir 	}
436*cdf0e10cSrcweir 	| error ';'
437*cdf0e10cSrcweir 	{
438*cdf0e10cSrcweir 		yyerror("definitions");
439*cdf0e10cSrcweir 		yyerrok;
440*cdf0e10cSrcweir 	}
441*cdf0e10cSrcweir 	;
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir opt_published:
444*cdf0e10cSrcweir     IDL_PUBLISHED { idlc()->setPublished(true); }
445*cdf0e10cSrcweir     | /* empty */ { idlc()->setPublished(false); }
446*cdf0e10cSrcweir     ;
447*cdf0e10cSrcweir 
448*cdf0e10cSrcweir publishable_definition:
449*cdf0e10cSrcweir 	type_dcl
450*cdf0e10cSrcweir 	{
451*cdf0e10cSrcweir 		idlc()->setParseState(PS_TypeDeclSeen);
452*cdf0e10cSrcweir 	}
453*cdf0e10cSrcweir 	';'
454*cdf0e10cSrcweir 	{
455*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
456*cdf0e10cSrcweir 	}
457*cdf0e10cSrcweir 	| const_dcl
458*cdf0e10cSrcweir 	{
459*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstantDeclSeen);
460*cdf0e10cSrcweir 	}
461*cdf0e10cSrcweir 	';'
462*cdf0e10cSrcweir 	{
463*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
464*cdf0e10cSrcweir 	}
465*cdf0e10cSrcweir 	| exception_dcl
466*cdf0e10cSrcweir 	{
467*cdf0e10cSrcweir 		idlc()->setParseState(PS_ExceptionDeclSeen);
468*cdf0e10cSrcweir 	}
469*cdf0e10cSrcweir 	';'
470*cdf0e10cSrcweir 	{
471*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
472*cdf0e10cSrcweir 	}
473*cdf0e10cSrcweir 	| interface
474*cdf0e10cSrcweir 	{
475*cdf0e10cSrcweir 		idlc()->setParseState(PS_InterfaceDeclSeen);
476*cdf0e10cSrcweir 	}
477*cdf0e10cSrcweir 	';'
478*cdf0e10cSrcweir 	{
479*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
480*cdf0e10cSrcweir 	}
481*cdf0e10cSrcweir 	| service_dcl
482*cdf0e10cSrcweir 	{
483*cdf0e10cSrcweir 		idlc()->setParseState(PS_ServiceDeclSeen);
484*cdf0e10cSrcweir 	}
485*cdf0e10cSrcweir 	';'
486*cdf0e10cSrcweir 	{
487*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
488*cdf0e10cSrcweir 	}
489*cdf0e10cSrcweir 	| singleton_dcl
490*cdf0e10cSrcweir 	{
491*cdf0e10cSrcweir 		idlc()->setParseState(PS_SingletonDeclSeen);
492*cdf0e10cSrcweir 	}
493*cdf0e10cSrcweir 	';'
494*cdf0e10cSrcweir 	{
495*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
496*cdf0e10cSrcweir 	}
497*cdf0e10cSrcweir 	| constants_dcl
498*cdf0e10cSrcweir 	{
499*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstantsDeclSeen);
500*cdf0e10cSrcweir 	}
501*cdf0e10cSrcweir 	';'
502*cdf0e10cSrcweir 	{
503*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
504*cdf0e10cSrcweir 	}
505*cdf0e10cSrcweir     ;
506*cdf0e10cSrcweir 
507*cdf0e10cSrcweir module_dcl :
508*cdf0e10cSrcweir 	IDL_MODULE
509*cdf0e10cSrcweir 	{
510*cdf0e10cSrcweir 		idlc()->setParseState(PS_ModuleSeen);
511*cdf0e10cSrcweir         idlc()->setPublished(false);
512*cdf0e10cSrcweir 	}
513*cdf0e10cSrcweir 	identifier
514*cdf0e10cSrcweir 	{
515*cdf0e10cSrcweir         idlc()->setParseState(PS_ModuleIDSeen);
516*cdf0e10cSrcweir         checkIdentifier($3);
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir         AstScope* 		pScope = idlc()->scopes()->topNonNull();
519*cdf0e10cSrcweir         AstModule* 		pModule = NULL;
520*cdf0e10cSrcweir         AstDeclaration*	pExists = NULL;
521*cdf0e10cSrcweir 
522*cdf0e10cSrcweir         if ( pScope )
523*cdf0e10cSrcweir         {
524*cdf0e10cSrcweir         	pModule = new AstModule(*$3, pScope);
525*cdf0e10cSrcweir 			if( (pExists = pScope->lookupForAdd(pModule)) )
526*cdf0e10cSrcweir 			{
527*cdf0e10cSrcweir 				pExists->setInMainfile(idlc()->isInMainFile());
528*cdf0e10cSrcweir 				pExists->setFileName(pModule->getFileName());
529*cdf0e10cSrcweir                 if (pExists->isPredefined())
530*cdf0e10cSrcweir                 {
531*cdf0e10cSrcweir                     pExists->setPredefined(false);
532*cdf0e10cSrcweir                     if (pExists->getDocumentation().getLength() == 0 &&
533*cdf0e10cSrcweir                         pModule->getDocumentation().getLength() > 0)
534*cdf0e10cSrcweir                     {
535*cdf0e10cSrcweir                         pExists->setDocumentation(pModule->getDocumentation());
536*cdf0e10cSrcweir                     }
537*cdf0e10cSrcweir                 }
538*cdf0e10cSrcweir 				delete(pModule);
539*cdf0e10cSrcweir 				pModule = (AstModule*)pExists;
540*cdf0e10cSrcweir 			} else
541*cdf0e10cSrcweir 			{
542*cdf0e10cSrcweir 				pScope->addDeclaration(pModule);
543*cdf0e10cSrcweir 			}
544*cdf0e10cSrcweir 			idlc()->scopes()->push(pModule);
545*cdf0e10cSrcweir         }
546*cdf0e10cSrcweir         delete $3;
547*cdf0e10cSrcweir     }
548*cdf0e10cSrcweir     '{'
549*cdf0e10cSrcweir     {
550*cdf0e10cSrcweir         idlc()->setParseState(PS_ModuleSqSeen);
551*cdf0e10cSrcweir     }
552*cdf0e10cSrcweir 	definitions
553*cdf0e10cSrcweir 	{
554*cdf0e10cSrcweir 		idlc()->setParseState(PS_ModuleBodySeen);
555*cdf0e10cSrcweir 	}
556*cdf0e10cSrcweir 	'}'
557*cdf0e10cSrcweir 	{
558*cdf0e10cSrcweir 		idlc()->setParseState(PS_ModuleQsSeen);
559*cdf0e10cSrcweir 		/*
560*cdf0e10cSrcweir 		 * Finished with this module - pop it from the scope stack
561*cdf0e10cSrcweir 		 */
562*cdf0e10cSrcweir 		idlc()->scopes()->pop();
563*cdf0e10cSrcweir 	}
564*cdf0e10cSrcweir 	;
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir interface :
567*cdf0e10cSrcweir 	interface_dcl
568*cdf0e10cSrcweir 	| forward_dcl
569*cdf0e10cSrcweir 	;
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir interface_decl :
572*cdf0e10cSrcweir 	IDL_INTERFACE
573*cdf0e10cSrcweir 	{
574*cdf0e10cSrcweir 		idlc()->setParseState(PS_InterfaceSeen);
575*cdf0e10cSrcweir 	}
576*cdf0e10cSrcweir 	identifier
577*cdf0e10cSrcweir 	{
578*cdf0e10cSrcweir 		idlc()->setParseState(PS_InterfaceIDSeen);
579*cdf0e10cSrcweir        checkIdentifier($3);
580*cdf0e10cSrcweir 		$$ = $3;
581*cdf0e10cSrcweir 	}
582*cdf0e10cSrcweir 	;
583*cdf0e10cSrcweir 
584*cdf0e10cSrcweir forward_dcl :
585*cdf0e10cSrcweir 	interface_decl
586*cdf0e10cSrcweir 	{
587*cdf0e10cSrcweir 		idlc()->setParseState(PS_ForwardDeclSeen);
588*cdf0e10cSrcweir 
589*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
590*cdf0e10cSrcweir 		AstInterface*	pForward = NULL;
591*cdf0e10cSrcweir 		AstDeclaration*	pDecl = NULL;
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir         /*
594*cdf0e10cSrcweir 		 * Make a new forward interface node and add it to its enclosing scope
595*cdf0e10cSrcweir 		 */
596*cdf0e10cSrcweir 		if ( pScope && $1 )
597*cdf0e10cSrcweir 		{
598*cdf0e10cSrcweir 			pForward = new AstInterface(*$1, NULL, pScope);
599*cdf0e10cSrcweir 
600*cdf0e10cSrcweir 			if ( pDecl = pScope->lookupByName(pForward->getScopedName()) )
601*cdf0e10cSrcweir 			{
602*cdf0e10cSrcweir 				if ( (pDecl != pForward) &&
603*cdf0e10cSrcweir 					 (pDecl->getNodeType() == NT_interface) )
604*cdf0e10cSrcweir 				{
605*cdf0e10cSrcweir 					delete pForward;
606*cdf0e10cSrcweir 				} else
607*cdf0e10cSrcweir 				{
608*cdf0e10cSrcweir 					idlc()->error()->error2(EIDL_REDEF_SCOPE, scopeAsDecl(pScope), pDecl);
609*cdf0e10cSrcweir 				}
610*cdf0e10cSrcweir 			} else
611*cdf0e10cSrcweir 			{
612*cdf0e10cSrcweir 				/*
613*cdf0e10cSrcweir 				 * Add the interface to its definition scope
614*cdf0e10cSrcweir 				 */
615*cdf0e10cSrcweir 				pScope->addDeclaration(pForward);
616*cdf0e10cSrcweir 			}
617*cdf0e10cSrcweir 		}
618*cdf0e10cSrcweir 		delete $1;
619*cdf0e10cSrcweir 	}
620*cdf0e10cSrcweir 	;
621*cdf0e10cSrcweir 
622*cdf0e10cSrcweir interface_dcl :
623*cdf0e10cSrcweir 	interfaceheader
624*cdf0e10cSrcweir 	{
625*cdf0e10cSrcweir 		idlc()->setParseState(PS_InterfaceHeadSeen);
626*cdf0e10cSrcweir 
627*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
628*cdf0e10cSrcweir 		AstInterface*	pInterface = NULL;
629*cdf0e10cSrcweir 		AstInterface*	pForward = NULL;
630*cdf0e10cSrcweir 		AstDeclaration*	pDecl = NULL;
631*cdf0e10cSrcweir 
632*cdf0e10cSrcweir         /*
633*cdf0e10cSrcweir 		 * Make a new interface node and add it to its enclosing scope
634*cdf0e10cSrcweir 		 */
635*cdf0e10cSrcweir 		if ( pScope && $1 )
636*cdf0e10cSrcweir 		{
637*cdf0e10cSrcweir 			pInterface = new AstInterface(
638*cdf0e10cSrcweir                 *$1->getName(),
639*cdf0e10cSrcweir                 static_cast< AstInterface * >($1->getInherits()), pScope);
640*cdf0e10cSrcweir 			if ( pInterface &&
641*cdf0e10cSrcweir 				(pDecl = pScope->lookupByName(pInterface->getScopedName())) )
642*cdf0e10cSrcweir 			{
643*cdf0e10cSrcweir 				/*
644*cdf0e10cSrcweir 				 * See if we're defining a forward declared interface.
645*cdf0e10cSrcweir 				 */
646*cdf0e10cSrcweir 				if (pDecl->getNodeType() == NT_interface)
647*cdf0e10cSrcweir 				{
648*cdf0e10cSrcweir 					pForward = (AstInterface*)pDecl;
649*cdf0e10cSrcweir 					if ( !pForward->isDefined() )
650*cdf0e10cSrcweir 					{
651*cdf0e10cSrcweir 						/*
652*cdf0e10cSrcweir 						 * Check if redefining in same scope
653*cdf0e10cSrcweir 						 */
654*cdf0e10cSrcweir 						if ( pForward->getScope() != pScope )
655*cdf0e10cSrcweir 						{
656*cdf0e10cSrcweir 							if ( pForward->getScopedName() != pInterface->getScopedName() )
657*cdf0e10cSrcweir 							{
658*cdf0e10cSrcweir 								idlc()->error()->error3(EIDL_SCOPE_CONFLICT,
659*cdf0e10cSrcweir 										 pInterface, pForward, scopeAsDecl(pScope));
660*cdf0e10cSrcweir 							}
661*cdf0e10cSrcweir 						}
662*cdf0e10cSrcweir                         else if ( !pInterface->isPublished()
663*cdf0e10cSrcweir                                   && pForward->isPublished() )
664*cdf0e10cSrcweir                         {
665*cdf0e10cSrcweir                             idlc()->error()->error0(EIDL_PUBLISHED_FORWARD);
666*cdf0e10cSrcweir                         }
667*cdf0e10cSrcweir 						/*
668*cdf0e10cSrcweir 						 * All OK, set full definition
669*cdf0e10cSrcweir 						 */
670*cdf0e10cSrcweir 						else
671*cdf0e10cSrcweir 						{
672*cdf0e10cSrcweir                             pForward->forwardDefined(*pInterface);
673*cdf0e10cSrcweir 							delete pInterface;
674*cdf0e10cSrcweir 							pInterface = pForward;
675*cdf0e10cSrcweir 						}
676*cdf0e10cSrcweir 					} else {
677*cdf0e10cSrcweir                         // special handling for XInterface because it is predefined
678*cdf0e10cSrcweir                         if ( pForward->isPredefined() &&
679*cdf0e10cSrcweir                              pForward->getScopedName() == "com::sun::star::uno::XInterface")
680*cdf0e10cSrcweir                         {
681*cdf0e10cSrcweir                             /* replace the predefined XInterface */
682*cdf0e10cSrcweir                             *pForward = *pInterface;
683*cdf0e10cSrcweir                             delete pInterface;
684*cdf0e10cSrcweir                             pInterface = pForward;
685*cdf0e10cSrcweir                         }
686*cdf0e10cSrcweir 
687*cdf0e10cSrcweir                     }
688*cdf0e10cSrcweir 				}
689*cdf0e10cSrcweir 			} else
690*cdf0e10cSrcweir 			{
691*cdf0e10cSrcweir 				/*
692*cdf0e10cSrcweir 				 * Add the interface to its definition scope
693*cdf0e10cSrcweir 				 */
694*cdf0e10cSrcweir 				pScope->addDeclaration(pInterface);
695*cdf0e10cSrcweir 			}
696*cdf0e10cSrcweir 		}
697*cdf0e10cSrcweir 		/*
698*cdf0e10cSrcweir 		 * Push it on the scope stack
699*cdf0e10cSrcweir 		 */
700*cdf0e10cSrcweir 		idlc()->scopes()->push(pInterface);
701*cdf0e10cSrcweir 		delete($1);
702*cdf0e10cSrcweir 	}
703*cdf0e10cSrcweir 	'{'
704*cdf0e10cSrcweir 	{
705*cdf0e10cSrcweir 		idlc()->setParseState(PS_InterfaceSqSeen);
706*cdf0e10cSrcweir 	}
707*cdf0e10cSrcweir 	exports
708*cdf0e10cSrcweir 	{
709*cdf0e10cSrcweir         AstInterface * ifc = static_cast< AstInterface * >(
710*cdf0e10cSrcweir             idlc()->scopes()->topNonNull());
711*cdf0e10cSrcweir         if (!ifc->hasMandatoryInheritedInterfaces()
712*cdf0e10cSrcweir             && ifc->getScopedName() != "com::sun::star::uno::XInterface")
713*cdf0e10cSrcweir         {
714*cdf0e10cSrcweir             addInheritedInterface(
715*cdf0e10cSrcweir                 ifc, rtl::OString("::com::sun::star::uno::XInterface"), false,
716*cdf0e10cSrcweir                 rtl::OUString());
717*cdf0e10cSrcweir         }
718*cdf0e10cSrcweir         ifc->setDefined();
719*cdf0e10cSrcweir 		idlc()->setParseState(PS_InterfaceBodySeen);
720*cdf0e10cSrcweir 	}
721*cdf0e10cSrcweir 	'}'
722*cdf0e10cSrcweir 	{
723*cdf0e10cSrcweir 		idlc()->setParseState(PS_InterfaceQsSeen);
724*cdf0e10cSrcweir 		/*
725*cdf0e10cSrcweir 		 * Done with this interface - pop it off the scopes stack
726*cdf0e10cSrcweir 		 */
727*cdf0e10cSrcweir 		idlc()->scopes()->pop();
728*cdf0e10cSrcweir 	}
729*cdf0e10cSrcweir 	| error '}'
730*cdf0e10cSrcweir 	{
731*cdf0e10cSrcweir 		yyerror("interface definition");
732*cdf0e10cSrcweir 		yyerrok;
733*cdf0e10cSrcweir 	}
734*cdf0e10cSrcweir 	;
735*cdf0e10cSrcweir 
736*cdf0e10cSrcweir interfaceheader :
737*cdf0e10cSrcweir 	interface_decl inheritance_spec
738*cdf0e10cSrcweir 	{
739*cdf0e10cSrcweir 		idlc()->setParseState(PS_InheritSpecSeen);
740*cdf0e10cSrcweir 
741*cdf0e10cSrcweir 		$$ = new FeInheritanceHeader(NT_interface, $1, $2, 0);
742*cdf0e10cSrcweir 		delete $2;
743*cdf0e10cSrcweir 	}
744*cdf0e10cSrcweir 	;
745*cdf0e10cSrcweir 
746*cdf0e10cSrcweir inheritance_spec :
747*cdf0e10cSrcweir 	':'
748*cdf0e10cSrcweir 	{
749*cdf0e10cSrcweir 		idlc()->setParseState(PS_InheritColonSeen);
750*cdf0e10cSrcweir 	}
751*cdf0e10cSrcweir 	scoped_name
752*cdf0e10cSrcweir 	{
753*cdf0e10cSrcweir         $$ = $3;
754*cdf0e10cSrcweir 	}
755*cdf0e10cSrcweir 	| /* EMPTY */
756*cdf0e10cSrcweir 	{
757*cdf0e10cSrcweir 		$$ = NULL;
758*cdf0e10cSrcweir 	}
759*cdf0e10cSrcweir 	;
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir exports :
762*cdf0e10cSrcweir 	exports export
763*cdf0e10cSrcweir 	| /* EMPTY */
764*cdf0e10cSrcweir 	;
765*cdf0e10cSrcweir 
766*cdf0e10cSrcweir export :
767*cdf0e10cSrcweir     attribute
768*cdf0e10cSrcweir 	{
769*cdf0e10cSrcweir 		idlc()->setParseState(PS_AttributeDeclSeen);
770*cdf0e10cSrcweir 	}
771*cdf0e10cSrcweir 	';'
772*cdf0e10cSrcweir 	{
773*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
774*cdf0e10cSrcweir 	}
775*cdf0e10cSrcweir 	| operation
776*cdf0e10cSrcweir 	{
777*cdf0e10cSrcweir 		idlc()->setParseState(PS_OperationDeclSeen);
778*cdf0e10cSrcweir 	}
779*cdf0e10cSrcweir 	';'
780*cdf0e10cSrcweir 	{
781*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
782*cdf0e10cSrcweir 	}
783*cdf0e10cSrcweir     | interface_inheritance_decl
784*cdf0e10cSrcweir     {
785*cdf0e10cSrcweir 		idlc()->setParseState(PS_InterfaceInheritanceDeclSeen);
786*cdf0e10cSrcweir     }
787*cdf0e10cSrcweir     ';'
788*cdf0e10cSrcweir 	{
789*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
790*cdf0e10cSrcweir 	}
791*cdf0e10cSrcweir     ;
792*cdf0e10cSrcweir 
793*cdf0e10cSrcweir attribute :
794*cdf0e10cSrcweir 	flag_header
795*cdf0e10cSrcweir 	simple_type_spec
796*cdf0e10cSrcweir 	{
797*cdf0e10cSrcweir 		idlc()->setParseState(PS_AttrTypeSeen);
798*cdf0e10cSrcweir 	}
799*cdf0e10cSrcweir     simple_declarator
800*cdf0e10cSrcweir 	{
801*cdf0e10cSrcweir 		idlc()->setParseState(PS_AttrCompleted);
802*cdf0e10cSrcweir         if (($1 & ~(AF_BOUND | AF_READONLY)) != AF_ATTRIBUTE) {
803*cdf0e10cSrcweir             idlc()->error()->flagError(EIDL_BAD_ATTRIBUTE_FLAGS, $1);
804*cdf0e10cSrcweir         }
805*cdf0e10cSrcweir         AstInterface * scope = static_cast< AstInterface * >(
806*cdf0e10cSrcweir             idlc()->scopes()->top());
807*cdf0e10cSrcweir         AstAttribute * attr = new AstAttribute(
808*cdf0e10cSrcweir             $1, $4->compose($2), $4->getName(), scope);
809*cdf0e10cSrcweir         delete $4;
810*cdf0e10cSrcweir         AstInterface::DoubleMemberDeclarations doubleMembers(
811*cdf0e10cSrcweir             scope->checkMemberClashes(attr));
812*cdf0e10cSrcweir         if (doubleMembers.empty()) {
813*cdf0e10cSrcweir             scope->addMember(attr);
814*cdf0e10cSrcweir         } else {
815*cdf0e10cSrcweir             reportDoubleMemberDeclarations(doubleMembers);
816*cdf0e10cSrcweir         }
817*cdf0e10cSrcweir         idlc()->scopes()->push(attr);
818*cdf0e10cSrcweir     }
819*cdf0e10cSrcweir     opt_attribute_block
820*cdf0e10cSrcweir     {
821*cdf0e10cSrcweir         static_cast< AstAttribute * >(idlc()->scopes()->top())->setExceptions(
822*cdf0e10cSrcweir             $6.get.documentation, $6.get.exceptions, $6.set.documentation,
823*cdf0e10cSrcweir             $6.set.exceptions);
824*cdf0e10cSrcweir         delete $6.get.documentation;
825*cdf0e10cSrcweir         delete $6.get.exceptions;
826*cdf0e10cSrcweir         delete $6.set.documentation;
827*cdf0e10cSrcweir         delete $6.set.exceptions;
828*cdf0e10cSrcweir         idlc()->scopes()->pop();
829*cdf0e10cSrcweir     }
830*cdf0e10cSrcweir 	;
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir flag_header :
833*cdf0e10cSrcweir 	'[' opt_attrflags ']'
834*cdf0e10cSrcweir 	{
835*cdf0e10cSrcweir 		idlc()->setParseState(PS_FlagHeaderSeen);
836*cdf0e10cSrcweir 		$$ = $2;
837*cdf0e10cSrcweir 	}
838*cdf0e10cSrcweir 	;
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir opt_attrflags :
841*cdf0e10cSrcweir 	opt_attrflags ',' opt_attrflag
842*cdf0e10cSrcweir 	{
843*cdf0e10cSrcweir 		if ( ($1 & $3) == $3 )
844*cdf0e10cSrcweir  			idlc()->error()->flagError(EIDL_DEFINED_ATTRIBUTEFLAG, $3);
845*cdf0e10cSrcweir 
846*cdf0e10cSrcweir  		$$ = $1 | $3;
847*cdf0e10cSrcweir 	}
848*cdf0e10cSrcweir 	| opt_attrflag
849*cdf0e10cSrcweir 	{
850*cdf0e10cSrcweir 		$$ = $1;
851*cdf0e10cSrcweir 	}
852*cdf0e10cSrcweir 	;
853*cdf0e10cSrcweir 
854*cdf0e10cSrcweir opt_attrflag :
855*cdf0e10cSrcweir 	IDL_ATTRIBUTE
856*cdf0e10cSrcweir 	{
857*cdf0e10cSrcweir 		idlc()->setParseState(PS_AttrSeen);
858*cdf0e10cSrcweir 		$$ = AF_ATTRIBUTE;
859*cdf0e10cSrcweir 	}
860*cdf0e10cSrcweir 	| IDL_PROPERTY
861*cdf0e10cSrcweir 	{
862*cdf0e10cSrcweir 		idlc()->setParseState(PS_PropertySeen);
863*cdf0e10cSrcweir 		$$ = AF_PROPERTY;
864*cdf0e10cSrcweir 	}
865*cdf0e10cSrcweir 	| IDL_READONLY
866*cdf0e10cSrcweir 	{
867*cdf0e10cSrcweir 		idlc()->setParseState(PS_ReadOnlySeen);
868*cdf0e10cSrcweir 		$$ = AF_READONLY;
869*cdf0e10cSrcweir 	}
870*cdf0e10cSrcweir 	| IDL_OPTIONAL
871*cdf0e10cSrcweir 	{
872*cdf0e10cSrcweir 		idlc()->setParseState(PS_OptionalSeen);
873*cdf0e10cSrcweir 		$$ = AF_OPTIONAL;
874*cdf0e10cSrcweir 	}
875*cdf0e10cSrcweir 	| IDL_MAYBEVOID
876*cdf0e10cSrcweir 	{
877*cdf0e10cSrcweir 		idlc()->setParseState(PS_MayBeVoidSeen);
878*cdf0e10cSrcweir 		$$ = AF_MAYBEVOID;
879*cdf0e10cSrcweir 	}
880*cdf0e10cSrcweir 	| IDL_BOUND
881*cdf0e10cSrcweir 	{
882*cdf0e10cSrcweir 		idlc()->setParseState(PS_BoundSeen);
883*cdf0e10cSrcweir 		$$ = AF_BOUND;
884*cdf0e10cSrcweir 	}
885*cdf0e10cSrcweir 	| IDL_CONSTRAINED
886*cdf0e10cSrcweir 	{
887*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstrainedSeen);
888*cdf0e10cSrcweir 		$$ = AF_CONSTRAINED;
889*cdf0e10cSrcweir 	}
890*cdf0e10cSrcweir 	| IDL_TRANSIENT
891*cdf0e10cSrcweir 	{
892*cdf0e10cSrcweir 		idlc()->setParseState(PS_TransientSeen);
893*cdf0e10cSrcweir 		$$ = AF_TRANSIENT;
894*cdf0e10cSrcweir 	}
895*cdf0e10cSrcweir 	| IDL_MAYBEAMBIGUOUS
896*cdf0e10cSrcweir 	{
897*cdf0e10cSrcweir 		idlc()->setParseState(PS_MayBeAmbigiousSeen);
898*cdf0e10cSrcweir 		$$ = AF_MAYBEAMBIGUOUS;
899*cdf0e10cSrcweir 	}
900*cdf0e10cSrcweir 	| IDL_MAYBEDEFAULT
901*cdf0e10cSrcweir 	{
902*cdf0e10cSrcweir 		idlc()->setParseState(PS_MayBeDefaultSeen);
903*cdf0e10cSrcweir 		$$ = AF_MAYBEDEFAULT;
904*cdf0e10cSrcweir 	}
905*cdf0e10cSrcweir 	| IDL_REMOVEABLE
906*cdf0e10cSrcweir 	{
907*cdf0e10cSrcweir 		idlc()->setParseState(PS_RemoveableSeen);
908*cdf0e10cSrcweir 		$$ = AF_REMOVEABLE;
909*cdf0e10cSrcweir 	}
910*cdf0e10cSrcweir 	| error ']'
911*cdf0e10cSrcweir 	{
912*cdf0e10cSrcweir        yyerror("unknown property|attribute flag");
913*cdf0e10cSrcweir 		yyerrok;
914*cdf0e10cSrcweir 	}
915*cdf0e10cSrcweir 	;
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir opt_attribute_block:
918*cdf0e10cSrcweir     '{' attribute_block_rest { $$ = $2; }
919*cdf0e10cSrcweir     | /* empty */
920*cdf0e10cSrcweir     {
921*cdf0e10cSrcweir         $$.get.documentation = 0;
922*cdf0e10cSrcweir         $$.get.exceptions = 0;
923*cdf0e10cSrcweir         $$.set.documentation = 0;
924*cdf0e10cSrcweir         $$.set.exceptions = 0;
925*cdf0e10cSrcweir     }
926*cdf0e10cSrcweir     ;
927*cdf0e10cSrcweir 
928*cdf0e10cSrcweir attribute_block_rest:
929*cdf0e10cSrcweir     opt_attribute_raises '}'
930*cdf0e10cSrcweir     | error '}'
931*cdf0e10cSrcweir     {
932*cdf0e10cSrcweir         yyerror("bad attribute raises block");
933*cdf0e10cSrcweir         yyerrok;
934*cdf0e10cSrcweir         $$.get.documentation = 0;
935*cdf0e10cSrcweir         $$.get.exceptions = 0;
936*cdf0e10cSrcweir         $$.set.documentation = 0;
937*cdf0e10cSrcweir         $$.set.exceptions = 0;
938*cdf0e10cSrcweir     }
939*cdf0e10cSrcweir     ;
940*cdf0e10cSrcweir 
941*cdf0e10cSrcweir opt_attribute_raises:
942*cdf0e10cSrcweir     attribute_get_raises
943*cdf0e10cSrcweir     opt_attribute_set_raises
944*cdf0e10cSrcweir     {
945*cdf0e10cSrcweir         $$.get = $1;
946*cdf0e10cSrcweir         $$.set = $2;
947*cdf0e10cSrcweir     }
948*cdf0e10cSrcweir     | attribute_set_raises
949*cdf0e10cSrcweir     opt_attribute_get_raises
950*cdf0e10cSrcweir     {
951*cdf0e10cSrcweir         $$.get = $2;
952*cdf0e10cSrcweir         $$.set = $1;
953*cdf0e10cSrcweir     }
954*cdf0e10cSrcweir     | /* empty */
955*cdf0e10cSrcweir     {
956*cdf0e10cSrcweir         $$.get.documentation = 0;
957*cdf0e10cSrcweir         $$.get.exceptions = 0;
958*cdf0e10cSrcweir         $$.set.documentation = 0;
959*cdf0e10cSrcweir         $$.set.exceptions = 0;
960*cdf0e10cSrcweir     }
961*cdf0e10cSrcweir     ;
962*cdf0e10cSrcweir 
963*cdf0e10cSrcweir opt_attribute_get_raises:
964*cdf0e10cSrcweir     attribute_get_raises
965*cdf0e10cSrcweir     | /* empty */ { $$.documentation = 0; $$.exceptions = 0; }
966*cdf0e10cSrcweir     ;
967*cdf0e10cSrcweir 
968*cdf0e10cSrcweir attribute_get_raises:
969*cdf0e10cSrcweir     IDL_GET raises ';'
970*cdf0e10cSrcweir     {
971*cdf0e10cSrcweir         $$.documentation = new rtl::OUString(
972*cdf0e10cSrcweir             rtl::OStringToOUString(
973*cdf0e10cSrcweir                 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
974*cdf0e10cSrcweir         $$.exceptions = $2;
975*cdf0e10cSrcweir     }
976*cdf0e10cSrcweir     ;
977*cdf0e10cSrcweir 
978*cdf0e10cSrcweir opt_attribute_set_raises:
979*cdf0e10cSrcweir     attribute_set_raises
980*cdf0e10cSrcweir     | /* empty */ { $$.documentation = 0; $$.exceptions = 0; }
981*cdf0e10cSrcweir     ;
982*cdf0e10cSrcweir 
983*cdf0e10cSrcweir attribute_set_raises:
984*cdf0e10cSrcweir     IDL_SET
985*cdf0e10cSrcweir     {
986*cdf0e10cSrcweir         if (static_cast< AstAttribute * >(idlc()->scopes()->top())->
987*cdf0e10cSrcweir             isReadonly())
988*cdf0e10cSrcweir         {
989*cdf0e10cSrcweir             idlc()->error()->error0(EIDL_READONLY_ATTRIBUTE_SET_EXCEPTIONS);
990*cdf0e10cSrcweir         }
991*cdf0e10cSrcweir     }
992*cdf0e10cSrcweir     raises ';'
993*cdf0e10cSrcweir     {
994*cdf0e10cSrcweir         $$.documentation = new rtl::OUString(
995*cdf0e10cSrcweir             rtl::OStringToOUString(
996*cdf0e10cSrcweir                 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
997*cdf0e10cSrcweir         $$.exceptions = $3;
998*cdf0e10cSrcweir     }
999*cdf0e10cSrcweir     ;
1000*cdf0e10cSrcweir 
1001*cdf0e10cSrcweir operation :
1002*cdf0e10cSrcweir 	operation_head
1003*cdf0e10cSrcweir 	op_type_spec
1004*cdf0e10cSrcweir 	{
1005*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpTypeSeen);
1006*cdf0e10cSrcweir 	}
1007*cdf0e10cSrcweir 	identifier
1008*cdf0e10cSrcweir 	{
1009*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpIDSeen);
1010*cdf0e10cSrcweir        checkIdentifier($4);
1011*cdf0e10cSrcweir 
1012*cdf0e10cSrcweir 		AstInterface * pScope = static_cast< AstInterface * >(
1013*cdf0e10cSrcweir             idlc()->scopes()->top());
1014*cdf0e10cSrcweir 		AstOperation* 	pOp = NULL;
1015*cdf0e10cSrcweir 
1016*cdf0e10cSrcweir 		/*
1017*cdf0e10cSrcweir 		 * Create a node representing an operation on an interface
1018*cdf0e10cSrcweir 		 * and add it to its enclosing scope
1019*cdf0e10cSrcweir 		 */
1020*cdf0e10cSrcweir 		if ( pScope && $2 )
1021*cdf0e10cSrcweir 		{
1022*cdf0e10cSrcweir 			AstType *pType = (AstType*)$2;
1023*cdf0e10cSrcweir 			if ( !pType || (pType->getNodeType() == NT_exception) )
1024*cdf0e10cSrcweir 			{
1025*cdf0e10cSrcweir 				// type ERROR
1026*cdf0e10cSrcweir 			} else
1027*cdf0e10cSrcweir 			{
1028*cdf0e10cSrcweir 				pOp = new AstOperation($1, pType, *$4, pScope);
1029*cdf0e10cSrcweir 
1030*cdf0e10cSrcweir                 AstInterface::DoubleMemberDeclarations doubleMembers(
1031*cdf0e10cSrcweir                     pScope->checkMemberClashes(pOp));
1032*cdf0e10cSrcweir                 if (doubleMembers.empty()) {
1033*cdf0e10cSrcweir                     pScope->addMember(pOp);
1034*cdf0e10cSrcweir                 } else {
1035*cdf0e10cSrcweir                     reportDoubleMemberDeclarations(doubleMembers);
1036*cdf0e10cSrcweir                 }
1037*cdf0e10cSrcweir 			}
1038*cdf0e10cSrcweir 		}
1039*cdf0e10cSrcweir 		delete $4;
1040*cdf0e10cSrcweir 		/*
1041*cdf0e10cSrcweir 		 * Push the operation scope onto the scopes stack
1042*cdf0e10cSrcweir 		 */
1043*cdf0e10cSrcweir 		idlc()->scopes()->push(pOp);
1044*cdf0e10cSrcweir 	}
1045*cdf0e10cSrcweir 	'('
1046*cdf0e10cSrcweir 	{
1047*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpSqSeen);
1048*cdf0e10cSrcweir 	}
1049*cdf0e10cSrcweir 	parameters
1050*cdf0e10cSrcweir 	{
1051*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpParsCompleted);
1052*cdf0e10cSrcweir 	}
1053*cdf0e10cSrcweir 	')'
1054*cdf0e10cSrcweir 	{
1055*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpQsSeen);
1056*cdf0e10cSrcweir 	}
1057*cdf0e10cSrcweir 	opt_raises
1058*cdf0e10cSrcweir 	{
1059*cdf0e10cSrcweir 		AstScope*		pScope = idlc()->scopes()->topNonNull();
1060*cdf0e10cSrcweir 		AstOperation* 	pOp = NULL;
1061*cdf0e10cSrcweir 		/*
1062*cdf0e10cSrcweir 		 * Add exceptions and context to the operation
1063*cdf0e10cSrcweir 		 */
1064*cdf0e10cSrcweir 		if ( pScope && pScope->getScopeNodeType() == NT_operation)
1065*cdf0e10cSrcweir 		{
1066*cdf0e10cSrcweir 			pOp = (AstOperation*)pScope;
1067*cdf0e10cSrcweir 
1068*cdf0e10cSrcweir 			if ( pOp )
1069*cdf0e10cSrcweir 				pOp->setExceptions($12);
1070*cdf0e10cSrcweir 		}
1071*cdf0e10cSrcweir         delete $12;
1072*cdf0e10cSrcweir 		/*
1073*cdf0e10cSrcweir 		 * Done with this operation. Pop its scope from the scopes stack
1074*cdf0e10cSrcweir 		 */
1075*cdf0e10cSrcweir 		idlc()->scopes()->pop();
1076*cdf0e10cSrcweir 	}
1077*cdf0e10cSrcweir 	;
1078*cdf0e10cSrcweir 
1079*cdf0e10cSrcweir operation_head :
1080*cdf0e10cSrcweir 	'['
1081*cdf0e10cSrcweir 	IDL_ONEWAY
1082*cdf0e10cSrcweir 	{
1083*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpOnewaySeen);
1084*cdf0e10cSrcweir 	}
1085*cdf0e10cSrcweir 	']'
1086*cdf0e10cSrcweir 	{
1087*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpHeadSeen);
1088*cdf0e10cSrcweir 		$$ = OP_ONEWAY;
1089*cdf0e10cSrcweir 	}
1090*cdf0e10cSrcweir 	| /* EMPTY */
1091*cdf0e10cSrcweir 	{
1092*cdf0e10cSrcweir 		$$ = OP_NONE;
1093*cdf0e10cSrcweir 	}
1094*cdf0e10cSrcweir 	;
1095*cdf0e10cSrcweir 
1096*cdf0e10cSrcweir op_type_spec :
1097*cdf0e10cSrcweir 	simple_type_spec
1098*cdf0e10cSrcweir 	| IDL_VOID
1099*cdf0e10cSrcweir 	{
1100*cdf0e10cSrcweir 		$$ = idlc()->scopes()->bottom()->lookupPrimitiveType(ET_void);
1101*cdf0e10cSrcweir 	}
1102*cdf0e10cSrcweir 	;
1103*cdf0e10cSrcweir 
1104*cdf0e10cSrcweir parameters :
1105*cdf0e10cSrcweir 	parameter
1106*cdf0e10cSrcweir 	| parameters
1107*cdf0e10cSrcweir 	','
1108*cdf0e10cSrcweir 	{
1109*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpParCommaSeen);
1110*cdf0e10cSrcweir 	}
1111*cdf0e10cSrcweir 	parameter
1112*cdf0e10cSrcweir 	| /* EMPTY */
1113*cdf0e10cSrcweir 	| error ','
1114*cdf0e10cSrcweir 	{
1115*cdf0e10cSrcweir 		yyerror("parameter definition");
1116*cdf0e10cSrcweir 		yyerrok;
1117*cdf0e10cSrcweir 	}
1118*cdf0e10cSrcweir 	;
1119*cdf0e10cSrcweir 
1120*cdf0e10cSrcweir parameter :
1121*cdf0e10cSrcweir 	'['
1122*cdf0e10cSrcweir 	direction
1123*cdf0e10cSrcweir 	']'
1124*cdf0e10cSrcweir 	{
1125*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpParDirSeen);
1126*cdf0e10cSrcweir 	}
1127*cdf0e10cSrcweir 	simple_type_spec
1128*cdf0e10cSrcweir 	{
1129*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpParTypeSeen);
1130*cdf0e10cSrcweir 	}
1131*cdf0e10cSrcweir     opt_rest
1132*cdf0e10cSrcweir 	declarator
1133*cdf0e10cSrcweir 	{
1134*cdf0e10cSrcweir 		idlc()->setParseState(PS_OpParDeclSeen);
1135*cdf0e10cSrcweir 
1136*cdf0e10cSrcweir         AstOperation * pScope = static_cast< AstOperation * >(
1137*cdf0e10cSrcweir             idlc()->scopes()->top());
1138*cdf0e10cSrcweir 		AstParameter* 	pParam = NULL;
1139*cdf0e10cSrcweir 
1140*cdf0e10cSrcweir 		/*
1141*cdf0e10cSrcweir 		 * Create a node representing an argument to an operation
1142*cdf0e10cSrcweir 		 * Add it to the enclosing scope (the operation scope)
1143*cdf0e10cSrcweir 		 */
1144*cdf0e10cSrcweir 		if ( pScope && $5 && $8 )
1145*cdf0e10cSrcweir 		{
1146*cdf0e10cSrcweir             AstType const * pType = $8->compose($5);
1147*cdf0e10cSrcweir 			if ( pType )
1148*cdf0e10cSrcweir 			{
1149*cdf0e10cSrcweir                 if (pScope->isConstructor() && $2 != DIR_IN) {
1150*cdf0e10cSrcweir                     idlc()->error()->error0(EIDL_CONSTRUCTOR_PARAMETER_NOT_IN);
1151*cdf0e10cSrcweir                 }
1152*cdf0e10cSrcweir                 if (pScope->isVariadic()) {
1153*cdf0e10cSrcweir                     idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_LAST);
1154*cdf0e10cSrcweir                 }
1155*cdf0e10cSrcweir                 if ($7) {
1156*cdf0e10cSrcweir                     AstDeclaration const * type = resolveTypedefs(pType);
1157*cdf0e10cSrcweir                     if (type->getNodeType() != NT_predefined
1158*cdf0e10cSrcweir                         || (static_cast< AstBaseType const * >(type)->
1159*cdf0e10cSrcweir                             getExprType() != ET_any))
1160*cdf0e10cSrcweir                     {
1161*cdf0e10cSrcweir                         idlc()->error()->error0(EIDL_REST_PARAMETER_NOT_ANY);
1162*cdf0e10cSrcweir                     }
1163*cdf0e10cSrcweir                     if (pScope->isConstructor()) {
1164*cdf0e10cSrcweir                         if (pScope->getIteratorBegin()
1165*cdf0e10cSrcweir                             != pScope->getIteratorEnd())
1166*cdf0e10cSrcweir                         {
1167*cdf0e10cSrcweir                             idlc()->error()->error0(
1168*cdf0e10cSrcweir                                 EIDL_CONSTRUCTOR_REST_PARAMETER_NOT_FIRST);
1169*cdf0e10cSrcweir                         }
1170*cdf0e10cSrcweir                     } else {
1171*cdf0e10cSrcweir                         idlc()->error()->error0(EIDL_METHOD_HAS_REST_PARAMETER);
1172*cdf0e10cSrcweir                     }
1173*cdf0e10cSrcweir                 }
1174*cdf0e10cSrcweir 
1175*cdf0e10cSrcweir 				pParam = new AstParameter(
1176*cdf0e10cSrcweir                     static_cast< Direction >($2), $7, pType, $8->getName(),
1177*cdf0e10cSrcweir                     pScope);
1178*cdf0e10cSrcweir 
1179*cdf0e10cSrcweir 				if ( !$8->checkType($5) )
1180*cdf0e10cSrcweir 				{
1181*cdf0e10cSrcweir 					// WARNING
1182*cdf0e10cSrcweir 				}
1183*cdf0e10cSrcweir 
1184*cdf0e10cSrcweir 				pScope->addDeclaration(pParam);
1185*cdf0e10cSrcweir 			}
1186*cdf0e10cSrcweir 		}
1187*cdf0e10cSrcweir 	}
1188*cdf0e10cSrcweir 	| error
1189*cdf0e10cSrcweir 	simple_type_spec
1190*cdf0e10cSrcweir 	{
1191*cdf0e10cSrcweir 		idlc()->setParseState(PS_NoState);
1192*cdf0e10cSrcweir 		yyerrok;
1193*cdf0e10cSrcweir 	}
1194*cdf0e10cSrcweir 	;
1195*cdf0e10cSrcweir 
1196*cdf0e10cSrcweir direction :
1197*cdf0e10cSrcweir 	IDL_IN
1198*cdf0e10cSrcweir 	{
1199*cdf0e10cSrcweir 		$$ = DIR_IN;
1200*cdf0e10cSrcweir 	}
1201*cdf0e10cSrcweir 	| IDL_OUT
1202*cdf0e10cSrcweir 	{
1203*cdf0e10cSrcweir 		$$ = DIR_OUT;
1204*cdf0e10cSrcweir 	}
1205*cdf0e10cSrcweir 	| IDL_INOUT
1206*cdf0e10cSrcweir 	{
1207*cdf0e10cSrcweir 		$$ = DIR_INOUT;
1208*cdf0e10cSrcweir 	}
1209*cdf0e10cSrcweir 	;
1210*cdf0e10cSrcweir 
1211*cdf0e10cSrcweir opt_rest:
1212*cdf0e10cSrcweir     IDL_ELLIPSIS
1213*cdf0e10cSrcweir     {
1214*cdf0e10cSrcweir         $$ = true;
1215*cdf0e10cSrcweir     }
1216*cdf0e10cSrcweir     | /* empty */
1217*cdf0e10cSrcweir     {
1218*cdf0e10cSrcweir         $$ = false;
1219*cdf0e10cSrcweir     }
1220*cdf0e10cSrcweir     ;
1221*cdf0e10cSrcweir 
1222*cdf0e10cSrcweir opt_raises:
1223*cdf0e10cSrcweir     raises
1224*cdf0e10cSrcweir     | /* empty */
1225*cdf0e10cSrcweir     {
1226*cdf0e10cSrcweir         $$ = 0;
1227*cdf0e10cSrcweir     }
1228*cdf0e10cSrcweir     ;
1229*cdf0e10cSrcweir 
1230*cdf0e10cSrcweir raises:
1231*cdf0e10cSrcweir     IDL_RAISES
1232*cdf0e10cSrcweir     {
1233*cdf0e10cSrcweir         idlc()->setParseState(PS_RaiseSeen);
1234*cdf0e10cSrcweir     }
1235*cdf0e10cSrcweir     '('
1236*cdf0e10cSrcweir     {
1237*cdf0e10cSrcweir         idlc()->setParseState(PS_RaiseSqSeen);
1238*cdf0e10cSrcweir     }
1239*cdf0e10cSrcweir     exception_list
1240*cdf0e10cSrcweir     ')'
1241*cdf0e10cSrcweir     {
1242*cdf0e10cSrcweir         idlc()->setParseState(PS_RaiseQsSeen);
1243*cdf0e10cSrcweir         $$ = $5;
1244*cdf0e10cSrcweir     }
1245*cdf0e10cSrcweir     ;
1246*cdf0e10cSrcweir 
1247*cdf0e10cSrcweir exception_list:
1248*cdf0e10cSrcweir     exception_name
1249*cdf0e10cSrcweir     {
1250*cdf0e10cSrcweir         $$ = new DeclList;
1251*cdf0e10cSrcweir         $$->push_back($1);
1252*cdf0e10cSrcweir     }
1253*cdf0e10cSrcweir     | exception_list ',' exception_name
1254*cdf0e10cSrcweir     {
1255*cdf0e10cSrcweir         $1->push_back($3);
1256*cdf0e10cSrcweir         $$ = $1;
1257*cdf0e10cSrcweir     }
1258*cdf0e10cSrcweir     ;
1259*cdf0e10cSrcweir 
1260*cdf0e10cSrcweir exception_name:
1261*cdf0e10cSrcweir     scoped_name
1262*cdf0e10cSrcweir     {
1263*cdf0e10cSrcweir         // The topmost scope is either an AstOperation (for interface methods
1264*cdf0e10cSrcweir         // and service constructors) or an AstAttribute (for interface
1265*cdf0e10cSrcweir         // attributes), so look up exception names in the next-to-topmost scope:
1266*cdf0e10cSrcweir         AstDeclaration * decl = idlc()->scopes()->nextToTop()->lookupByName(
1267*cdf0e10cSrcweir             *$1);
1268*cdf0e10cSrcweir         if (decl == 0) {
1269*cdf0e10cSrcweir             idlc()->error()->lookupError(*$1);
1270*cdf0e10cSrcweir         } else if (!idlc()->error()->checkPublished(decl)) {
1271*cdf0e10cSrcweir             decl = 0;
1272*cdf0e10cSrcweir         } else if (decl->getNodeType() != NT_exception) {
1273*cdf0e10cSrcweir             idlc()->error()->error1(EIDL_ILLEGAL_RAISES, decl);
1274*cdf0e10cSrcweir             decl = 0;
1275*cdf0e10cSrcweir         }
1276*cdf0e10cSrcweir         delete $1;
1277*cdf0e10cSrcweir         $$ = decl;
1278*cdf0e10cSrcweir     }
1279*cdf0e10cSrcweir     ;
1280*cdf0e10cSrcweir 
1281*cdf0e10cSrcweir interface_inheritance_decl:
1282*cdf0e10cSrcweir     optional_inherited_interface
1283*cdf0e10cSrcweir     IDL_INTERFACE
1284*cdf0e10cSrcweir     {
1285*cdf0e10cSrcweir         idlc()->setParseState(PS_ServiceIFHeadSeen);
1286*cdf0e10cSrcweir     }
1287*cdf0e10cSrcweir     scoped_name
1288*cdf0e10cSrcweir     {
1289*cdf0e10cSrcweir         AstInterface * ifc = static_cast< AstInterface * >(
1290*cdf0e10cSrcweir             idlc()->scopes()->top());
1291*cdf0e10cSrcweir         if (ifc->usesSingleInheritance()) {
1292*cdf0e10cSrcweir             idlc()->error()->error0(EIDL_MIXED_INHERITANCE);
1293*cdf0e10cSrcweir         } else {
1294*cdf0e10cSrcweir             addInheritedInterface(
1295*cdf0e10cSrcweir                 ifc, *$4, $1,
1296*cdf0e10cSrcweir                 rtl::OStringToOUString(
1297*cdf0e10cSrcweir                     idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
1298*cdf0e10cSrcweir         }
1299*cdf0e10cSrcweir         delete $4;
1300*cdf0e10cSrcweir     }
1301*cdf0e10cSrcweir     ;
1302*cdf0e10cSrcweir 
1303*cdf0e10cSrcweir optional_inherited_interface:
1304*cdf0e10cSrcweir     '[' IDL_OPTIONAL ']' { $$ = true; }
1305*cdf0e10cSrcweir     | /* EMPTY */ { $$ = false; }
1306*cdf0e10cSrcweir     ;
1307*cdf0e10cSrcweir 
1308*cdf0e10cSrcweir constants_exports :
1309*cdf0e10cSrcweir 	constants_export constants_exports
1310*cdf0e10cSrcweir 	| /* EMPTY */
1311*cdf0e10cSrcweir 	;
1312*cdf0e10cSrcweir 
1313*cdf0e10cSrcweir constants_export :
1314*cdf0e10cSrcweir 	const_dcl
1315*cdf0e10cSrcweir 	{
1316*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstantDeclSeen);
1317*cdf0e10cSrcweir 	}
1318*cdf0e10cSrcweir 	';' {};
1319*cdf0e10cSrcweir 
1320*cdf0e10cSrcweir const_dcl :
1321*cdf0e10cSrcweir 	IDL_CONST
1322*cdf0e10cSrcweir 	{
1323*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstSeen);
1324*cdf0e10cSrcweir 	}
1325*cdf0e10cSrcweir 	const_type
1326*cdf0e10cSrcweir 	{
1327*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstTypeSeen);
1328*cdf0e10cSrcweir 	}
1329*cdf0e10cSrcweir 	identifier
1330*cdf0e10cSrcweir 	{
1331*cdf0e10cSrcweir         idlc()->setParseState(PS_ConstIDSeen);
1332*cdf0e10cSrcweir         checkIdentifier($5);
1333*cdf0e10cSrcweir 	}
1334*cdf0e10cSrcweir 	'='
1335*cdf0e10cSrcweir 	{
1336*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstAssignSeen);
1337*cdf0e10cSrcweir 	}
1338*cdf0e10cSrcweir 	expression
1339*cdf0e10cSrcweir 	{
1340*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstExprSeen);
1341*cdf0e10cSrcweir 
1342*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
1343*cdf0e10cSrcweir 		AstConstant*	pConstant = NULL;
1344*cdf0e10cSrcweir 
1345*cdf0e10cSrcweir 		if ( $9 && pScope )
1346*cdf0e10cSrcweir 		{
1347*cdf0e10cSrcweir 			if ( !$9->coerce($3) )
1348*cdf0e10cSrcweir 			{
1349*cdf0e10cSrcweir 				idlc()->error()->coercionError($9, $3);
1350*cdf0e10cSrcweir 			} else
1351*cdf0e10cSrcweir 			{
1352*cdf0e10cSrcweir 				pConstant = new AstConstant($3, $9, *$5, pScope);
1353*cdf0e10cSrcweir 				pScope->addDeclaration(pConstant);
1354*cdf0e10cSrcweir 			}
1355*cdf0e10cSrcweir 		}
1356*cdf0e10cSrcweir 		delete $5;
1357*cdf0e10cSrcweir 	}
1358*cdf0e10cSrcweir 	;
1359*cdf0e10cSrcweir 
1360*cdf0e10cSrcweir constants_dcl :
1361*cdf0e10cSrcweir 	IDL_CONSTANTS
1362*cdf0e10cSrcweir 	{
1363*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstantsSeen);
1364*cdf0e10cSrcweir 	}
1365*cdf0e10cSrcweir 	identifier
1366*cdf0e10cSrcweir 	{
1367*cdf0e10cSrcweir         idlc()->setParseState(PS_ConstantsIDSeen);
1368*cdf0e10cSrcweir         checkIdentifier($3);
1369*cdf0e10cSrcweir 	}
1370*cdf0e10cSrcweir 	'{'
1371*cdf0e10cSrcweir 	{
1372*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstantsSqSeen);
1373*cdf0e10cSrcweir 
1374*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
1375*cdf0e10cSrcweir 		AstConstants*	pConstants = NULL;
1376*cdf0e10cSrcweir 		AstDeclaration*	pExists = NULL;
1377*cdf0e10cSrcweir 
1378*cdf0e10cSrcweir 		if ( pScope )
1379*cdf0e10cSrcweir 		{
1380*cdf0e10cSrcweir 			pConstants = new AstConstants(*$3, pScope);
1381*cdf0e10cSrcweir 			if( (pExists = pScope->lookupForAdd(pConstants)) )
1382*cdf0e10cSrcweir 			{
1383*cdf0e10cSrcweir 				pExists->setInMainfile(idlc()->isInMainFile());
1384*cdf0e10cSrcweir 				delete(pConstants);
1385*cdf0e10cSrcweir 				pConstants = (AstConstants*)pExists;
1386*cdf0e10cSrcweir 			} else
1387*cdf0e10cSrcweir 			{
1388*cdf0e10cSrcweir 				pScope->addDeclaration(pConstants);
1389*cdf0e10cSrcweir 			}
1390*cdf0e10cSrcweir 			idlc()->scopes()->push(pConstants);
1391*cdf0e10cSrcweir 		}
1392*cdf0e10cSrcweir 		delete $3;
1393*cdf0e10cSrcweir 	}
1394*cdf0e10cSrcweir 	constants_exports
1395*cdf0e10cSrcweir 	{
1396*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstantsBodySeen);
1397*cdf0e10cSrcweir 	}
1398*cdf0e10cSrcweir 	'}'
1399*cdf0e10cSrcweir 	{
1400*cdf0e10cSrcweir 		idlc()->setParseState(PS_ConstantsQsSeen);
1401*cdf0e10cSrcweir 		/*
1402*cdf0e10cSrcweir 		 * Finished with this constants - pop it from the scope stack
1403*cdf0e10cSrcweir 		 */
1404*cdf0e10cSrcweir 		idlc()->scopes()->pop();
1405*cdf0e10cSrcweir 	}
1406*cdf0e10cSrcweir 	;
1407*cdf0e10cSrcweir 
1408*cdf0e10cSrcweir expression : const_expr ;
1409*cdf0e10cSrcweir 
1410*cdf0e10cSrcweir const_expr : or_expr ;
1411*cdf0e10cSrcweir 
1412*cdf0e10cSrcweir or_expr :
1413*cdf0e10cSrcweir 	xor_expr
1414*cdf0e10cSrcweir 	| or_expr '|' xor_expr
1415*cdf0e10cSrcweir 	{
1416*cdf0e10cSrcweir 		$$ = new AstExpression(EC_or, $1, $3);
1417*cdf0e10cSrcweir 	}
1418*cdf0e10cSrcweir 	;
1419*cdf0e10cSrcweir 
1420*cdf0e10cSrcweir xor_expr :
1421*cdf0e10cSrcweir 	and_expr
1422*cdf0e10cSrcweir 	| xor_expr '^' and_expr
1423*cdf0e10cSrcweir 	{
1424*cdf0e10cSrcweir 		$$ = new AstExpression(EC_xor, $1, $3);
1425*cdf0e10cSrcweir 	}
1426*cdf0e10cSrcweir 	;
1427*cdf0e10cSrcweir 
1428*cdf0e10cSrcweir and_expr :
1429*cdf0e10cSrcweir 	shift_expr
1430*cdf0e10cSrcweir 	| and_expr '&' shift_expr
1431*cdf0e10cSrcweir 	{
1432*cdf0e10cSrcweir 		$$ = new AstExpression(EC_and, $1, $3);
1433*cdf0e10cSrcweir 	}
1434*cdf0e10cSrcweir 	;
1435*cdf0e10cSrcweir 
1436*cdf0e10cSrcweir shift_expr :
1437*cdf0e10cSrcweir 	add_expr
1438*cdf0e10cSrcweir 	| shift_expr IDL_LEFTSHIFT add_expr
1439*cdf0e10cSrcweir 	{
1440*cdf0e10cSrcweir 		$$ = new AstExpression(EC_left, $1, $3);
1441*cdf0e10cSrcweir 	}
1442*cdf0e10cSrcweir 	| shift_expr IDL_RIGHTSHIFT add_expr
1443*cdf0e10cSrcweir 	{
1444*cdf0e10cSrcweir 		$$ = new AstExpression(EC_right, $1, $3);
1445*cdf0e10cSrcweir 	}
1446*cdf0e10cSrcweir 	;
1447*cdf0e10cSrcweir 
1448*cdf0e10cSrcweir add_expr :
1449*cdf0e10cSrcweir 	mult_expr
1450*cdf0e10cSrcweir 	| add_expr '+' mult_expr
1451*cdf0e10cSrcweir 	{
1452*cdf0e10cSrcweir 		$$ = new AstExpression(EC_add, $1, $3);
1453*cdf0e10cSrcweir 	}
1454*cdf0e10cSrcweir 	| add_expr '-' mult_expr
1455*cdf0e10cSrcweir 	{
1456*cdf0e10cSrcweir 		$$ = new AstExpression(EC_minus, $1, $3);
1457*cdf0e10cSrcweir 	}
1458*cdf0e10cSrcweir 	;
1459*cdf0e10cSrcweir 
1460*cdf0e10cSrcweir mult_expr :
1461*cdf0e10cSrcweir 	unary_expr
1462*cdf0e10cSrcweir 	| mult_expr '*' unary_expr
1463*cdf0e10cSrcweir 	{
1464*cdf0e10cSrcweir 		$$ = new AstExpression(EC_mul, $1, $3);
1465*cdf0e10cSrcweir 	}
1466*cdf0e10cSrcweir 	| mult_expr '/' unary_expr
1467*cdf0e10cSrcweir 	{
1468*cdf0e10cSrcweir 		$$ = new AstExpression(EC_div, $1, $3);
1469*cdf0e10cSrcweir 	}
1470*cdf0e10cSrcweir 	| mult_expr '%' unary_expr
1471*cdf0e10cSrcweir 	{
1472*cdf0e10cSrcweir 		$$ = new AstExpression(EC_mod, $1, $3);
1473*cdf0e10cSrcweir 	}
1474*cdf0e10cSrcweir 	;
1475*cdf0e10cSrcweir 
1476*cdf0e10cSrcweir unary_expr :
1477*cdf0e10cSrcweir 	primary_expr
1478*cdf0e10cSrcweir 	| '+' primary_expr
1479*cdf0e10cSrcweir 	{
1480*cdf0e10cSrcweir 		$$ = new AstExpression(EC_u_plus, $2, NULL);
1481*cdf0e10cSrcweir 	}
1482*cdf0e10cSrcweir 	| '-' primary_expr
1483*cdf0e10cSrcweir 	{
1484*cdf0e10cSrcweir 		$$ = new AstExpression(EC_u_minus, $2, NULL);
1485*cdf0e10cSrcweir 	}
1486*cdf0e10cSrcweir 	| '~' primary_expr
1487*cdf0e10cSrcweir 	{
1488*cdf0e10cSrcweir 	}
1489*cdf0e10cSrcweir 	;
1490*cdf0e10cSrcweir 
1491*cdf0e10cSrcweir primary_expr :
1492*cdf0e10cSrcweir 	scoped_name
1493*cdf0e10cSrcweir 	{
1494*cdf0e10cSrcweir 		/*
1495*cdf0e10cSrcweir 		 * An expression which is a scoped name is not resolved now,
1496*cdf0e10cSrcweir 		 * but only when it is evaluated (such as when it is assigned
1497*cdf0e10cSrcweir 		 * as a constant value)
1498*cdf0e10cSrcweir 		 */
1499*cdf0e10cSrcweir 		$$ = new AstExpression($1);
1500*cdf0e10cSrcweir 	}
1501*cdf0e10cSrcweir 	| literal
1502*cdf0e10cSrcweir 	| '(' const_expr ')'
1503*cdf0e10cSrcweir 	{
1504*cdf0e10cSrcweir 		$$ = $2;
1505*cdf0e10cSrcweir 	}
1506*cdf0e10cSrcweir 	;
1507*cdf0e10cSrcweir 
1508*cdf0e10cSrcweir literal :
1509*cdf0e10cSrcweir 	IDL_INTEGER_LITERAL
1510*cdf0e10cSrcweir 	{
1511*cdf0e10cSrcweir 		$$ = new AstExpression($1);
1512*cdf0e10cSrcweir 	}
1513*cdf0e10cSrcweir     | IDL_INTEGER_ULITERAL
1514*cdf0e10cSrcweir     {
1515*cdf0e10cSrcweir         $$ = new AstExpression($1);
1516*cdf0e10cSrcweir     }
1517*cdf0e10cSrcweir 	| IDL_FLOATING_PT_LITERAL
1518*cdf0e10cSrcweir 	{
1519*cdf0e10cSrcweir 		$$ = new AstExpression($1);
1520*cdf0e10cSrcweir 	}
1521*cdf0e10cSrcweir 	| IDL_TRUE
1522*cdf0e10cSrcweir 	{
1523*cdf0e10cSrcweir 		$$ = new AstExpression((sal_Int32)1, ET_boolean);
1524*cdf0e10cSrcweir 	}
1525*cdf0e10cSrcweir 	| IDL_FALSE
1526*cdf0e10cSrcweir 	{
1527*cdf0e10cSrcweir 		$$ = new AstExpression((sal_Int32)0, ET_boolean);
1528*cdf0e10cSrcweir 	}
1529*cdf0e10cSrcweir 	;
1530*cdf0e10cSrcweir 
1531*cdf0e10cSrcweir positive_int_expr :
1532*cdf0e10cSrcweir 	const_expr
1533*cdf0e10cSrcweir 	{
1534*cdf0e10cSrcweir 		$1->evaluate(EK_const);
1535*cdf0e10cSrcweir 		if ( !$1->coerce(ET_ulong) )
1536*cdf0e10cSrcweir 		{
1537*cdf0e10cSrcweir 			idlc()->error()->coercionError($1, ET_ulong);
1538*cdf0e10cSrcweir 			delete $1;
1539*cdf0e10cSrcweir 			$$ = NULL;
1540*cdf0e10cSrcweir 		}
1541*cdf0e10cSrcweir 	}
1542*cdf0e10cSrcweir 	;
1543*cdf0e10cSrcweir 
1544*cdf0e10cSrcweir const_type :
1545*cdf0e10cSrcweir 	integer_type
1546*cdf0e10cSrcweir 	| char_type
1547*cdf0e10cSrcweir 	| byte_type
1548*cdf0e10cSrcweir 	| boolean_type
1549*cdf0e10cSrcweir 	| floating_pt_type
1550*cdf0e10cSrcweir 	| scoped_name
1551*cdf0e10cSrcweir 	{
1552*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
1553*cdf0e10cSrcweir         AstDeclaration const * type = 0;
1554*cdf0e10cSrcweir 
1555*cdf0e10cSrcweir 		/*
1556*cdf0e10cSrcweir 		 * If the constant's type is a scoped name, it must resolve
1557*cdf0e10cSrcweir 		 * to a scalar constant type
1558*cdf0e10cSrcweir 		 */
1559*cdf0e10cSrcweir 		if ( pScope && (type = pScope->lookupByName(*$1)) ) {
1560*cdf0e10cSrcweir             if (!idlc()->error()->checkPublished(type))
1561*cdf0e10cSrcweir             {
1562*cdf0e10cSrcweir                 type = 0;
1563*cdf0e10cSrcweir             }
1564*cdf0e10cSrcweir             else
1565*cdf0e10cSrcweir             {
1566*cdf0e10cSrcweir                 type = resolveTypedefs(type);
1567*cdf0e10cSrcweir                 if (type->getNodeType() == NT_predefined)
1568*cdf0e10cSrcweir                 {
1569*cdf0e10cSrcweir                     $$ = static_cast< AstBaseType const * >(type)->
1570*cdf0e10cSrcweir                         getExprType();
1571*cdf0e10cSrcweir                 } else
1572*cdf0e10cSrcweir                     $$ = ET_any;
1573*cdf0e10cSrcweir             }
1574*cdf0e10cSrcweir 		} else
1575*cdf0e10cSrcweir 			$$ = ET_any;
1576*cdf0e10cSrcweir 	}
1577*cdf0e10cSrcweir 	;
1578*cdf0e10cSrcweir 
1579*cdf0e10cSrcweir exception_header :
1580*cdf0e10cSrcweir 	IDL_EXCEPTION
1581*cdf0e10cSrcweir 	{
1582*cdf0e10cSrcweir 		idlc()->setParseState(PS_ExceptSeen);
1583*cdf0e10cSrcweir 	}
1584*cdf0e10cSrcweir 	identifier
1585*cdf0e10cSrcweir  	{
1586*cdf0e10cSrcweir         idlc()->setParseState(PS_ExceptIDSeen);
1587*cdf0e10cSrcweir         checkIdentifier($3);
1588*cdf0e10cSrcweir 	}
1589*cdf0e10cSrcweir 	inheritance_spec
1590*cdf0e10cSrcweir 	{
1591*cdf0e10cSrcweir 		idlc()->setParseState(PS_InheritSpecSeen);
1592*cdf0e10cSrcweir 
1593*cdf0e10cSrcweir 		$$ = new FeInheritanceHeader(NT_exception, $3, $5, 0);
1594*cdf0e10cSrcweir 		delete $5;
1595*cdf0e10cSrcweir 	}
1596*cdf0e10cSrcweir 	;
1597*cdf0e10cSrcweir 
1598*cdf0e10cSrcweir exception_dcl :
1599*cdf0e10cSrcweir 	exception_header
1600*cdf0e10cSrcweir 	{
1601*cdf0e10cSrcweir 		idlc()->setParseState(PS_ExceptHeaderSeen);
1602*cdf0e10cSrcweir 
1603*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
1604*cdf0e10cSrcweir 		AstException*	pExcept = NULL;
1605*cdf0e10cSrcweir 
1606*cdf0e10cSrcweir 		if ( pScope )
1607*cdf0e10cSrcweir 		{
1608*cdf0e10cSrcweir 			AstException* pBase = static_cast< AstException* >(
1609*cdf0e10cSrcweir                 $1->getInherits());
1610*cdf0e10cSrcweir 			pExcept = new AstException(*$1->getName(), pBase, pScope);
1611*cdf0e10cSrcweir 			pScope->addDeclaration(pExcept);
1612*cdf0e10cSrcweir 		}
1613*cdf0e10cSrcweir 		/*
1614*cdf0e10cSrcweir 		 * Push the scope of the exception on the scopes stack
1615*cdf0e10cSrcweir 		 */
1616*cdf0e10cSrcweir 		idlc()->scopes()->push(pExcept);
1617*cdf0e10cSrcweir 		delete $1;
1618*cdf0e10cSrcweir 	}
1619*cdf0e10cSrcweir 	'{'
1620*cdf0e10cSrcweir 	{
1621*cdf0e10cSrcweir 		idlc()->setParseState(PS_ExceptSqSeen);
1622*cdf0e10cSrcweir 	}
1623*cdf0e10cSrcweir 	members
1624*cdf0e10cSrcweir 	{
1625*cdf0e10cSrcweir 		idlc()->setParseState(PS_ExceptBodySeen);
1626*cdf0e10cSrcweir 	}
1627*cdf0e10cSrcweir 	'}'
1628*cdf0e10cSrcweir 	{
1629*cdf0e10cSrcweir 		idlc()->setParseState(PS_ExceptQsSeen);
1630*cdf0e10cSrcweir 		/* this exception is finished, pop its scope from the stack */
1631*cdf0e10cSrcweir 		idlc()->scopes()->pop();
1632*cdf0e10cSrcweir 	}
1633*cdf0e10cSrcweir 	;
1634*cdf0e10cSrcweir 
1635*cdf0e10cSrcweir property :
1636*cdf0e10cSrcweir 	flag_header
1637*cdf0e10cSrcweir 	simple_type_spec
1638*cdf0e10cSrcweir 	{
1639*cdf0e10cSrcweir 		idlc()->setParseState(PS_PropertyTypeSeen);
1640*cdf0e10cSrcweir 	}
1641*cdf0e10cSrcweir 	at_least_one_declarator
1642*cdf0e10cSrcweir 	{
1643*cdf0e10cSrcweir 		idlc()->setParseState(PS_PropertyCompleted);
1644*cdf0e10cSrcweir 
1645*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
1646*cdf0e10cSrcweir 		AstAttribute* 	pAttr = NULL;
1647*cdf0e10cSrcweir 		FeDeclList*		pList = $4;
1648*cdf0e10cSrcweir 		FeDeclarator*	pDecl = NULL;
1649*cdf0e10cSrcweir         AstType const * pType = NULL;
1650*cdf0e10cSrcweir 
1651*cdf0e10cSrcweir 		if ( pScope->getScopeNodeType() == NT_singleton )
1652*cdf0e10cSrcweir 		{
1653*cdf0e10cSrcweir 			idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1654*cdf0e10cSrcweir 		} else
1655*cdf0e10cSrcweir 		{
1656*cdf0e10cSrcweir 			if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE )
1657*cdf0e10cSrcweir 				idlc()->error()->flagError(EIDL_WRONGATTRIBUTEKEYWORD, AF_ATTRIBUTE);
1658*cdf0e10cSrcweir 
1659*cdf0e10cSrcweir 			if ( ($1 & AF_PROPERTY) != AF_PROPERTY )
1660*cdf0e10cSrcweir 				idlc()->error()->flagError(EIDL_MISSINGATTRIBUTEKEYWORD, AF_PROPERTY);
1661*cdf0e10cSrcweir 
1662*cdf0e10cSrcweir 			/*
1663*cdf0e10cSrcweir 			 * Create nodes representing attributes and add them to the
1664*cdf0e10cSrcweir 			 * enclosing scope
1665*cdf0e10cSrcweir 			 */
1666*cdf0e10cSrcweir 			if ( pScope && $2 && pList )
1667*cdf0e10cSrcweir 			{
1668*cdf0e10cSrcweir 				FeDeclList::iterator iter = pList->begin();
1669*cdf0e10cSrcweir 				FeDeclList::iterator end = pList->end();
1670*cdf0e10cSrcweir 
1671*cdf0e10cSrcweir 				while (iter != end)
1672*cdf0e10cSrcweir 				{
1673*cdf0e10cSrcweir 					pDecl = (*iter);
1674*cdf0e10cSrcweir 					if ( !pDecl )
1675*cdf0e10cSrcweir 					{
1676*cdf0e10cSrcweir 						iter++;
1677*cdf0e10cSrcweir 						continue;
1678*cdf0e10cSrcweir 					}
1679*cdf0e10cSrcweir 
1680*cdf0e10cSrcweir 					pType = pDecl->compose($2);
1681*cdf0e10cSrcweir 
1682*cdf0e10cSrcweir 					if ( !pType )
1683*cdf0e10cSrcweir 					{
1684*cdf0e10cSrcweir 						iter++;
1685*cdf0e10cSrcweir 						continue;
1686*cdf0e10cSrcweir 					}
1687*cdf0e10cSrcweir 
1688*cdf0e10cSrcweir 					pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope);
1689*cdf0e10cSrcweir 
1690*cdf0e10cSrcweir 					pScope->addDeclaration(pAttr);
1691*cdf0e10cSrcweir 					iter++;
1692*cdf0e10cSrcweir 					delete pDecl;
1693*cdf0e10cSrcweir 				}
1694*cdf0e10cSrcweir 			}
1695*cdf0e10cSrcweir 		}
1696*cdf0e10cSrcweir 
1697*cdf0e10cSrcweir 		if ( pList )
1698*cdf0e10cSrcweir 			delete pList;
1699*cdf0e10cSrcweir 	}
1700*cdf0e10cSrcweir 	| error ';'
1701*cdf0e10cSrcweir 	{
1702*cdf0e10cSrcweir 		yyerror("property");
1703*cdf0e10cSrcweir 		yyerrok;
1704*cdf0e10cSrcweir 	}
1705*cdf0e10cSrcweir 	;
1706*cdf0e10cSrcweir 
1707*cdf0e10cSrcweir service_exports :
1708*cdf0e10cSrcweir 	service_exports service_export
1709*cdf0e10cSrcweir 	| /* EMPTY */
1710*cdf0e10cSrcweir 	;
1711*cdf0e10cSrcweir 
1712*cdf0e10cSrcweir service_export :
1713*cdf0e10cSrcweir 	service_interface_header
1714*cdf0e10cSrcweir 	at_least_one_scoped_name
1715*cdf0e10cSrcweir 	';'
1716*cdf0e10cSrcweir 	{
1717*cdf0e10cSrcweir 		idlc()->setParseState(PS_ServiceMemberSeen);
1718*cdf0e10cSrcweir 
1719*cdf0e10cSrcweir 		AstScope* 			pScope = idlc()->scopes()->topNonNull();
1720*cdf0e10cSrcweir 		AstDeclaration* 	pDecl = NULL;
1721*cdf0e10cSrcweir 		AstInterfaceMember* pIMember = NULL;
1722*cdf0e10cSrcweir 
1723*cdf0e10cSrcweir 		if ( pScope->getScopeNodeType() == NT_singleton )
1724*cdf0e10cSrcweir 		{
1725*cdf0e10cSrcweir 			idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1726*cdf0e10cSrcweir 		} else
1727*cdf0e10cSrcweir 		{
1728*cdf0e10cSrcweir 			/*
1729*cdf0e10cSrcweir 			 * Create a node representing a class member.
1730*cdf0e10cSrcweir 			 * Store it in the enclosing scope
1731*cdf0e10cSrcweir 	         */
1732*cdf0e10cSrcweir 			if ( pScope && $2 )
1733*cdf0e10cSrcweir 			{
1734*cdf0e10cSrcweir 				StringList::iterator iter = $2->begin();
1735*cdf0e10cSrcweir 				StringList::iterator end = $2->end();
1736*cdf0e10cSrcweir 
1737*cdf0e10cSrcweir 				while ( iter != end )
1738*cdf0e10cSrcweir 				{
1739*cdf0e10cSrcweir 					pDecl = pScope->lookupByName(*iter);
1740*cdf0e10cSrcweir 					if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1741*cdf0e10cSrcweir 					{
1742*cdf0e10cSrcweir                         /* we relax the strict published check and allow to add new
1743*cdf0e10cSrcweir                          * interfaces if they are optional
1744*cdf0e10cSrcweir                          */
1745*cdf0e10cSrcweir                         bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL);
1746*cdf0e10cSrcweir                         if ( idlc()->error()->checkPublished(pDecl, bOptional) )
1747*cdf0e10cSrcweir                         {
1748*cdf0e10cSrcweir                             pIMember = new AstInterfaceMember(
1749*cdf0e10cSrcweir                                 $1, (AstInterface*)pDecl, *iter, pScope);
1750*cdf0e10cSrcweir                             pScope->addDeclaration(pIMember);
1751*cdf0e10cSrcweir                         }
1752*cdf0e10cSrcweir 					} else
1753*cdf0e10cSrcweir 					{
1754*cdf0e10cSrcweir 						idlc()->error()->
1755*cdf0e10cSrcweir 							lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1756*cdf0e10cSrcweir 					}
1757*cdf0e10cSrcweir 					iter++;
1758*cdf0e10cSrcweir 				}
1759*cdf0e10cSrcweir 			}
1760*cdf0e10cSrcweir 		}
1761*cdf0e10cSrcweir 		delete $2;
1762*cdf0e10cSrcweir 	}
1763*cdf0e10cSrcweir 	| service_service_header
1764*cdf0e10cSrcweir 	at_least_one_scoped_name
1765*cdf0e10cSrcweir 	';'
1766*cdf0e10cSrcweir 	{
1767*cdf0e10cSrcweir 		idlc()->setParseState(PS_ServiceMemberSeen);
1768*cdf0e10cSrcweir 
1769*cdf0e10cSrcweir 		AstScope* 		  pScope = idlc()->scopes()->topNonNull();
1770*cdf0e10cSrcweir 		AstDeclaration*   pDecl = NULL;
1771*cdf0e10cSrcweir 		AstServiceMember* pSMember = NULL;
1772*cdf0e10cSrcweir 
1773*cdf0e10cSrcweir 		/*
1774*cdf0e10cSrcweir 		 * Create a node representing a class member.
1775*cdf0e10cSrcweir 		 * Store it in the enclosing scope
1776*cdf0e10cSrcweir          */
1777*cdf0e10cSrcweir 		if ( pScope && $2 )
1778*cdf0e10cSrcweir 		{
1779*cdf0e10cSrcweir 			StringList::iterator iter = $2->begin();
1780*cdf0e10cSrcweir 			StringList::iterator end = $2->end();
1781*cdf0e10cSrcweir 
1782*cdf0e10cSrcweir 			while ( iter != end )
1783*cdf0e10cSrcweir 			{
1784*cdf0e10cSrcweir 				pDecl = pScope->lookupByName(*iter);
1785*cdf0e10cSrcweir 				if ( pDecl && (pDecl->getNodeType() == NT_service) )
1786*cdf0e10cSrcweir 				{
1787*cdf0e10cSrcweir 					if ( pScope->getScopeNodeType() == NT_singleton && pScope->nMembers() > 0 )
1788*cdf0e10cSrcweir 						idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1789*cdf0e10cSrcweir                     else if ( idlc()->error()->checkPublished(pDecl) )
1790*cdf0e10cSrcweir                     {
1791*cdf0e10cSrcweir                         pSMember = new AstServiceMember(
1792*cdf0e10cSrcweir                             $1, (AstService*)pDecl, *iter, pScope);
1793*cdf0e10cSrcweir                         pScope->addDeclaration(pSMember);
1794*cdf0e10cSrcweir                     }
1795*cdf0e10cSrcweir 				} else
1796*cdf0e10cSrcweir 				{
1797*cdf0e10cSrcweir 					idlc()->error()->
1798*cdf0e10cSrcweir 						lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1799*cdf0e10cSrcweir 				}
1800*cdf0e10cSrcweir 				iter++;
1801*cdf0e10cSrcweir 			}
1802*cdf0e10cSrcweir 		}
1803*cdf0e10cSrcweir 		delete $2;
1804*cdf0e10cSrcweir 	}
1805*cdf0e10cSrcweir 	| IDL_OBSERVES
1806*cdf0e10cSrcweir 	at_least_one_scoped_name
1807*cdf0e10cSrcweir 	';'
1808*cdf0e10cSrcweir 	{
1809*cdf0e10cSrcweir 		idlc()->setParseState(PS_ServiceMemberSeen);
1810*cdf0e10cSrcweir 
1811*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
1812*cdf0e10cSrcweir 		AstDeclaration* pDecl = NULL;
1813*cdf0e10cSrcweir 		AstObserves* 	pObserves = NULL;
1814*cdf0e10cSrcweir 
1815*cdf0e10cSrcweir 		if ( pScope->getScopeNodeType() == NT_singleton )
1816*cdf0e10cSrcweir 		{
1817*cdf0e10cSrcweir 			idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1818*cdf0e10cSrcweir 		} else
1819*cdf0e10cSrcweir 		{
1820*cdf0e10cSrcweir 			/*
1821*cdf0e10cSrcweir 			 * Create a node representing a class member.
1822*cdf0e10cSrcweir 			 * Store it in the enclosing scope
1823*cdf0e10cSrcweir 	         */
1824*cdf0e10cSrcweir 			if ( pScope && $2 )
1825*cdf0e10cSrcweir 			{
1826*cdf0e10cSrcweir 				StringList::iterator iter = $2->begin();
1827*cdf0e10cSrcweir 				StringList::iterator end = $2->end();
1828*cdf0e10cSrcweir 
1829*cdf0e10cSrcweir 				while ( iter != end )
1830*cdf0e10cSrcweir 				{
1831*cdf0e10cSrcweir 					pDecl = pScope->lookupByName(*iter);
1832*cdf0e10cSrcweir 					if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1833*cdf0e10cSrcweir 					{
1834*cdf0e10cSrcweir 						pObserves = new AstObserves((AstInterface*)pDecl, *iter, pScope);
1835*cdf0e10cSrcweir 						pScope->addDeclaration(pObserves);
1836*cdf0e10cSrcweir 					} else
1837*cdf0e10cSrcweir 					{
1838*cdf0e10cSrcweir 						idlc()->error()->
1839*cdf0e10cSrcweir 							lookupError(EIDL_INTERFACEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1840*cdf0e10cSrcweir 					}
1841*cdf0e10cSrcweir 					iter++;
1842*cdf0e10cSrcweir 				}
1843*cdf0e10cSrcweir 			}
1844*cdf0e10cSrcweir 		}
1845*cdf0e10cSrcweir 		delete $2;
1846*cdf0e10cSrcweir 	}
1847*cdf0e10cSrcweir 	| IDL_NEEDS
1848*cdf0e10cSrcweir 	at_least_one_scoped_name
1849*cdf0e10cSrcweir 	';'
1850*cdf0e10cSrcweir 	{
1851*cdf0e10cSrcweir 		idlc()->setParseState(PS_ServiceMemberSeen);
1852*cdf0e10cSrcweir 
1853*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
1854*cdf0e10cSrcweir 		AstDeclaration*	pDecl = NULL;
1855*cdf0e10cSrcweir 		AstNeeds*	   	pNeeds = NULL;
1856*cdf0e10cSrcweir 
1857*cdf0e10cSrcweir 		if ( pScope->getScopeNodeType() == NT_singleton )
1858*cdf0e10cSrcweir 		{
1859*cdf0e10cSrcweir 			idlc()->error()->error0(EIDL_ILLEGAL_ADD);
1860*cdf0e10cSrcweir 		} else
1861*cdf0e10cSrcweir 		{
1862*cdf0e10cSrcweir 			/*
1863*cdf0e10cSrcweir 			 * Create a node representing a class member.
1864*cdf0e10cSrcweir 			 * Store it in the enclosing scope
1865*cdf0e10cSrcweir 	         */
1866*cdf0e10cSrcweir 			if ( pScope && $2 )
1867*cdf0e10cSrcweir 			{
1868*cdf0e10cSrcweir 				StringList::iterator iter = $2->begin();
1869*cdf0e10cSrcweir 				StringList::iterator end = $2->end();
1870*cdf0e10cSrcweir 
1871*cdf0e10cSrcweir 				while ( iter != end )
1872*cdf0e10cSrcweir 				{
1873*cdf0e10cSrcweir 					pDecl = pScope->lookupByName(*iter);
1874*cdf0e10cSrcweir 					if ( pDecl && (pDecl->getNodeType() == NT_service) )
1875*cdf0e10cSrcweir 					{
1876*cdf0e10cSrcweir 						pNeeds = new AstNeeds((AstService*)pDecl, *iter, pScope);
1877*cdf0e10cSrcweir 						pScope->addDeclaration(pNeeds);
1878*cdf0e10cSrcweir 					} else
1879*cdf0e10cSrcweir 					{
1880*cdf0e10cSrcweir 						idlc()->error()->
1881*cdf0e10cSrcweir 							lookupError(EIDL_SERVICEMEMBER_LOOKUP, *iter, scopeAsDecl(pScope));
1882*cdf0e10cSrcweir 					}
1883*cdf0e10cSrcweir 					iter++;
1884*cdf0e10cSrcweir 				}
1885*cdf0e10cSrcweir 			}
1886*cdf0e10cSrcweir 		}
1887*cdf0e10cSrcweir 		delete $2;
1888*cdf0e10cSrcweir 	}
1889*cdf0e10cSrcweir 	| property
1890*cdf0e10cSrcweir 	';'
1891*cdf0e10cSrcweir 	{
1892*cdf0e10cSrcweir 		idlc()->setParseState(PS_PropertyDeclSeen);
1893*cdf0e10cSrcweir 	}
1894*cdf0e10cSrcweir 	;
1895*cdf0e10cSrcweir 
1896*cdf0e10cSrcweir service_interface_header :
1897*cdf0e10cSrcweir 	IDL_INTERFACE
1898*cdf0e10cSrcweir 	{
1899*cdf0e10cSrcweir 		idlc()->setParseState(PS_ServiceIFHeadSeen);
1900*cdf0e10cSrcweir 		$$ = AF_INVALID;
1901*cdf0e10cSrcweir 	}
1902*cdf0e10cSrcweir 	| flag_header
1903*cdf0e10cSrcweir 	IDL_INTERFACE
1904*cdf0e10cSrcweir 	{
1905*cdf0e10cSrcweir 		idlc()->setParseState(PS_ServiceIFHeadSeen);
1906*cdf0e10cSrcweir 		if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1907*cdf0e10cSrcweir 			idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1);
1908*cdf0e10cSrcweir 		$$ = $1;
1909*cdf0e10cSrcweir 	}
1910*cdf0e10cSrcweir 	;
1911*cdf0e10cSrcweir 
1912*cdf0e10cSrcweir service_service_header :
1913*cdf0e10cSrcweir 	IDL_SERVICE
1914*cdf0e10cSrcweir 	{
1915*cdf0e10cSrcweir 		idlc()->setParseState(PS_ServiceSHeadSeen);
1916*cdf0e10cSrcweir 		$$ = AF_INVALID;
1917*cdf0e10cSrcweir 	}
1918*cdf0e10cSrcweir 	| flag_header
1919*cdf0e10cSrcweir 	IDL_SERVICE
1920*cdf0e10cSrcweir 	{
1921*cdf0e10cSrcweir 		idlc()->setParseState(PS_ServiceSHeadSeen);
1922*cdf0e10cSrcweir 		if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1923*cdf0e10cSrcweir 			idlc()->error()->flagError(EIDL_OPTIONALEXPECTED, $1);
1924*cdf0e10cSrcweir 		$$ = $1;
1925*cdf0e10cSrcweir 	}
1926*cdf0e10cSrcweir 	;
1927*cdf0e10cSrcweir 
1928*cdf0e10cSrcweir service_dcl :
1929*cdf0e10cSrcweir 	IDL_SERVICE
1930*cdf0e10cSrcweir 	{
1931*cdf0e10cSrcweir 		idlc()->setParseState(PS_ServiceSeen);
1932*cdf0e10cSrcweir 	}
1933*cdf0e10cSrcweir 	identifier
1934*cdf0e10cSrcweir  	{
1935*cdf0e10cSrcweir         idlc()->setParseState(PS_ServiceIDSeen);
1936*cdf0e10cSrcweir         checkIdentifier($3);
1937*cdf0e10cSrcweir 
1938*cdf0e10cSrcweir         AstScope* 	pScope = idlc()->scopes()->topNonNull();
1939*cdf0e10cSrcweir         AstService*	pService = NULL;
1940*cdf0e10cSrcweir 
1941*cdf0e10cSrcweir         /*
1942*cdf0e10cSrcweir          * Make a new service and add it to the enclosing scope
1943*cdf0e10cSrcweir          */
1944*cdf0e10cSrcweir         if (pScope != NULL)
1945*cdf0e10cSrcweir         {
1946*cdf0e10cSrcweir             pService = new AstService(*$3, pScope);
1947*cdf0e10cSrcweir             pScope->addDeclaration(pService);
1948*cdf0e10cSrcweir         }
1949*cdf0e10cSrcweir         delete $3;
1950*cdf0e10cSrcweir         /*
1951*cdf0e10cSrcweir          * Push it on the stack
1952*cdf0e10cSrcweir          */
1953*cdf0e10cSrcweir         idlc()->scopes()->push(pService);
1954*cdf0e10cSrcweir 	}
1955*cdf0e10cSrcweir     service_dfn
1956*cdf0e10cSrcweir 	{
1957*cdf0e10cSrcweir 		/* this service is finished, pop its scope from the stack */
1958*cdf0e10cSrcweir 		idlc()->scopes()->pop();
1959*cdf0e10cSrcweir 	}
1960*cdf0e10cSrcweir 	;
1961*cdf0e10cSrcweir 
1962*cdf0e10cSrcweir service_dfn:
1963*cdf0e10cSrcweir     service_interface_dfn
1964*cdf0e10cSrcweir     | service_obsolete_dfn
1965*cdf0e10cSrcweir     ;
1966*cdf0e10cSrcweir 
1967*cdf0e10cSrcweir service_interface_dfn:
1968*cdf0e10cSrcweir     ':' scoped_name
1969*cdf0e10cSrcweir     {
1970*cdf0e10cSrcweir         AstScope * scope = idlc()->scopes()->nextToTop();
1971*cdf0e10cSrcweir             // skip the scope pushed by service_dcl
1972*cdf0e10cSrcweir         AstDeclaration * decl = scope->lookupByName(*$2);
1973*cdf0e10cSrcweir         if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) {
1974*cdf0e10cSrcweir             if (idlc()->error()->checkPublished(decl)) {
1975*cdf0e10cSrcweir                 idlc()->scopes()->top()->addDeclaration(decl);
1976*cdf0e10cSrcweir             }
1977*cdf0e10cSrcweir         } else {
1978*cdf0e10cSrcweir             idlc()->error()->lookupError(
1979*cdf0e10cSrcweir                 EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope));
1980*cdf0e10cSrcweir         }
1981*cdf0e10cSrcweir         delete $2;
1982*cdf0e10cSrcweir     }
1983*cdf0e10cSrcweir     opt_service_body
1984*cdf0e10cSrcweir     {
1985*cdf0e10cSrcweir         AstService * s = static_cast< AstService * >(idlc()->scopes()->top());
1986*cdf0e10cSrcweir         if (s != 0) {
1987*cdf0e10cSrcweir             s->setDefaultConstructor(!$4);
1988*cdf0e10cSrcweir         }
1989*cdf0e10cSrcweir     }
1990*cdf0e10cSrcweir     ;
1991*cdf0e10cSrcweir 
1992*cdf0e10cSrcweir opt_service_body:
1993*cdf0e10cSrcweir     service_body { $$ = true; }
1994*cdf0e10cSrcweir     | /* empty */ { $$ = false; }
1995*cdf0e10cSrcweir     ;
1996*cdf0e10cSrcweir 
1997*cdf0e10cSrcweir service_body:
1998*cdf0e10cSrcweir     '{'
1999*cdf0e10cSrcweir     constructors
2000*cdf0e10cSrcweir     '}'
2001*cdf0e10cSrcweir     ;
2002*cdf0e10cSrcweir 
2003*cdf0e10cSrcweir constructors:
2004*cdf0e10cSrcweir     constructors constructor
2005*cdf0e10cSrcweir     | /* empty */
2006*cdf0e10cSrcweir     ;
2007*cdf0e10cSrcweir 
2008*cdf0e10cSrcweir constructor:
2009*cdf0e10cSrcweir     identifier
2010*cdf0e10cSrcweir     {
2011*cdf0e10cSrcweir         checkIdentifier($1);
2012*cdf0e10cSrcweir         AstScope * scope = idlc()->scopes()->top();
2013*cdf0e10cSrcweir         AstOperation * ctor = new AstOperation(OP_NONE, 0, *$1, scope);
2014*cdf0e10cSrcweir         delete $1;
2015*cdf0e10cSrcweir         scope->addDeclaration(ctor);
2016*cdf0e10cSrcweir 		idlc()->scopes()->push(ctor);
2017*cdf0e10cSrcweir     }
2018*cdf0e10cSrcweir     '('
2019*cdf0e10cSrcweir     parameters
2020*cdf0e10cSrcweir     ')'
2021*cdf0e10cSrcweir     opt_raises
2022*cdf0e10cSrcweir     {
2023*cdf0e10cSrcweir         static_cast< AstOperation * >(idlc()->scopes()->top())->setExceptions(
2024*cdf0e10cSrcweir             $6);
2025*cdf0e10cSrcweir         delete $6;
2026*cdf0e10cSrcweir         idlc()->scopes()->pop();
2027*cdf0e10cSrcweir         if (static_cast< AstService * >(idlc()->scopes()->top())->
2028*cdf0e10cSrcweir             checkLastConstructor())
2029*cdf0e10cSrcweir         {
2030*cdf0e10cSrcweir             idlc()->error()->error0(EIDL_SIMILAR_CONSTRUCTORS);
2031*cdf0e10cSrcweir         }
2032*cdf0e10cSrcweir     }
2033*cdf0e10cSrcweir     ';'
2034*cdf0e10cSrcweir     ;
2035*cdf0e10cSrcweir 
2036*cdf0e10cSrcweir singleton_dcl :
2037*cdf0e10cSrcweir 	IDL_SINGLETON
2038*cdf0e10cSrcweir 	{
2039*cdf0e10cSrcweir 		idlc()->setParseState(PS_SingletonSeen);
2040*cdf0e10cSrcweir 	}
2041*cdf0e10cSrcweir 	identifier
2042*cdf0e10cSrcweir  	{
2043*cdf0e10cSrcweir         idlc()->setParseState(PS_SingletonIDSeen);
2044*cdf0e10cSrcweir         checkIdentifier($3);
2045*cdf0e10cSrcweir 
2046*cdf0e10cSrcweir 		AstScope* 	pScope = idlc()->scopes()->topNonNull();
2047*cdf0e10cSrcweir 		AstService*	pService = NULL;
2048*cdf0e10cSrcweir 
2049*cdf0e10cSrcweir 		/*
2050*cdf0e10cSrcweir 		 * Make a new service and add it to the enclosing scope
2051*cdf0e10cSrcweir 		 */
2052*cdf0e10cSrcweir 		if (pScope != NULL)
2053*cdf0e10cSrcweir 		{
2054*cdf0e10cSrcweir 			pService = new AstService(NT_singleton, *$3, pScope);
2055*cdf0e10cSrcweir 			pScope->addDeclaration(pService);
2056*cdf0e10cSrcweir 		}
2057*cdf0e10cSrcweir 		delete $3;
2058*cdf0e10cSrcweir 		/*
2059*cdf0e10cSrcweir 		 * Push it on the stack
2060*cdf0e10cSrcweir 		 */
2061*cdf0e10cSrcweir 		idlc()->scopes()->push(pService);
2062*cdf0e10cSrcweir 	}
2063*cdf0e10cSrcweir     singleton_dfn
2064*cdf0e10cSrcweir 	{
2065*cdf0e10cSrcweir 		/* this singelton is finished, pop its scope from the stack */
2066*cdf0e10cSrcweir 		idlc()->scopes()->pop();
2067*cdf0e10cSrcweir 	}
2068*cdf0e10cSrcweir 	;
2069*cdf0e10cSrcweir 
2070*cdf0e10cSrcweir singleton_dfn:
2071*cdf0e10cSrcweir     singleton_interface_dfn
2072*cdf0e10cSrcweir     | service_obsolete_dfn
2073*cdf0e10cSrcweir     ;
2074*cdf0e10cSrcweir 
2075*cdf0e10cSrcweir singleton_interface_dfn:
2076*cdf0e10cSrcweir     ':' scoped_name
2077*cdf0e10cSrcweir     {
2078*cdf0e10cSrcweir         AstScope * scope = idlc()->scopes()->nextToTop();
2079*cdf0e10cSrcweir             // skip the scope (needlessly) pushed by singleton_dcl
2080*cdf0e10cSrcweir         AstDeclaration * decl = scope->lookupByName(*$2);
2081*cdf0e10cSrcweir         if (decl != 0 && resolveTypedefs(decl)->getNodeType() == NT_interface) {
2082*cdf0e10cSrcweir             if (idlc()->error()->checkPublished(decl)) {
2083*cdf0e10cSrcweir                 idlc()->scopes()->top()->addDeclaration(decl);
2084*cdf0e10cSrcweir             }
2085*cdf0e10cSrcweir         } else {
2086*cdf0e10cSrcweir             idlc()->error()->lookupError(
2087*cdf0e10cSrcweir                 EIDL_INTERFACEMEMBER_LOOKUP, *$2, scopeAsDecl(scope));
2088*cdf0e10cSrcweir         }
2089*cdf0e10cSrcweir         delete $2;
2090*cdf0e10cSrcweir     }
2091*cdf0e10cSrcweir     ;
2092*cdf0e10cSrcweir 
2093*cdf0e10cSrcweir service_obsolete_dfn:
2094*cdf0e10cSrcweir     '{'
2095*cdf0e10cSrcweir     {
2096*cdf0e10cSrcweir         idlc()->setParseState(
2097*cdf0e10cSrcweir             idlc()->scopes()->top()->getScopeNodeType() == NT_service
2098*cdf0e10cSrcweir             ? PS_ServiceSqSeen : PS_SingletonSqSeen);
2099*cdf0e10cSrcweir     }
2100*cdf0e10cSrcweir     service_exports
2101*cdf0e10cSrcweir     {
2102*cdf0e10cSrcweir         idlc()->setParseState(
2103*cdf0e10cSrcweir             idlc()->scopes()->top()->getScopeNodeType() == NT_service
2104*cdf0e10cSrcweir             ? PS_ServiceBodySeen : PS_SingletonBodySeen);
2105*cdf0e10cSrcweir     }
2106*cdf0e10cSrcweir     '}'
2107*cdf0e10cSrcweir     {
2108*cdf0e10cSrcweir         idlc()->setParseState(
2109*cdf0e10cSrcweir             idlc()->scopes()->top()->getScopeNodeType() == NT_service
2110*cdf0e10cSrcweir             ? PS_ServiceQsSeen : PS_SingletonQsSeen);
2111*cdf0e10cSrcweir     }
2112*cdf0e10cSrcweir     ;
2113*cdf0e10cSrcweir 
2114*cdf0e10cSrcweir type_dcl :
2115*cdf0e10cSrcweir 	IDL_TYPEDEF
2116*cdf0e10cSrcweir 	{
2117*cdf0e10cSrcweir 		idlc()->setParseState(PS_TypedefSeen);
2118*cdf0e10cSrcweir 	}
2119*cdf0e10cSrcweir 	type_declarator {}
2120*cdf0e10cSrcweir 	| struct_type {}
2121*cdf0e10cSrcweir 	| union_type {}
2122*cdf0e10cSrcweir 	| enum_type {}
2123*cdf0e10cSrcweir 	;
2124*cdf0e10cSrcweir 
2125*cdf0e10cSrcweir type_declarator :
2126*cdf0e10cSrcweir 	type_spec
2127*cdf0e10cSrcweir 	{
2128*cdf0e10cSrcweir 		idlc()->setParseState(PS_TypeSpecSeen);
2129*cdf0e10cSrcweir         if ($1 != 0 && $1->getNodeType() == NT_instantiated_struct) {
2130*cdf0e10cSrcweir             idlc()->error()->error0(EIDL_INSTANTIATED_STRUCT_TYPE_TYPEDEF);
2131*cdf0e10cSrcweir         }
2132*cdf0e10cSrcweir 	}
2133*cdf0e10cSrcweir 	at_least_one_declarator
2134*cdf0e10cSrcweir 	{
2135*cdf0e10cSrcweir 		idlc()->setParseState(PS_DeclaratorsSeen);
2136*cdf0e10cSrcweir 
2137*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
2138*cdf0e10cSrcweir 		AstTypeDef* 	pTypeDef = NULL;
2139*cdf0e10cSrcweir 		FeDeclList*		pList = $3;
2140*cdf0e10cSrcweir 		FeDeclarator*	pDecl = NULL;
2141*cdf0e10cSrcweir         AstType const * pType = NULL;
2142*cdf0e10cSrcweir 
2143*cdf0e10cSrcweir 		/*
2144*cdf0e10cSrcweir 		 * Create nodes representing typedefs and add them to the
2145*cdf0e10cSrcweir 		 * enclosing scope
2146*cdf0e10cSrcweir 		 */
2147*cdf0e10cSrcweir 		if ( pScope && $1 && pList )
2148*cdf0e10cSrcweir 		{
2149*cdf0e10cSrcweir 			FeDeclList::iterator iter = pList->begin();
2150*cdf0e10cSrcweir 			FeDeclList::iterator end = pList->end();
2151*cdf0e10cSrcweir 
2152*cdf0e10cSrcweir 			while (iter != end)
2153*cdf0e10cSrcweir 			{
2154*cdf0e10cSrcweir 				pDecl = (*iter);
2155*cdf0e10cSrcweir 				if ( !pDecl )
2156*cdf0e10cSrcweir 				{
2157*cdf0e10cSrcweir 					iter++;
2158*cdf0e10cSrcweir 					continue;
2159*cdf0e10cSrcweir 				}
2160*cdf0e10cSrcweir 
2161*cdf0e10cSrcweir 				pType = pDecl->compose($1);
2162*cdf0e10cSrcweir 
2163*cdf0e10cSrcweir 				if ( !pType )
2164*cdf0e10cSrcweir 				{
2165*cdf0e10cSrcweir 					iter++;
2166*cdf0e10cSrcweir 					continue;
2167*cdf0e10cSrcweir 				}
2168*cdf0e10cSrcweir 
2169*cdf0e10cSrcweir 				pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope);
2170*cdf0e10cSrcweir 
2171*cdf0e10cSrcweir 				pScope->addDeclaration(pTypeDef);
2172*cdf0e10cSrcweir 				iter++;
2173*cdf0e10cSrcweir 				delete pDecl;
2174*cdf0e10cSrcweir 			}
2175*cdf0e10cSrcweir 			delete pList;
2176*cdf0e10cSrcweir 		}
2177*cdf0e10cSrcweir 	}
2178*cdf0e10cSrcweir 	;
2179*cdf0e10cSrcweir 
2180*cdf0e10cSrcweir at_least_one_declarator :
2181*cdf0e10cSrcweir 	declarator declarators
2182*cdf0e10cSrcweir 	{
2183*cdf0e10cSrcweir 		if ( $2 )
2184*cdf0e10cSrcweir 		{
2185*cdf0e10cSrcweir 			$2->push_back($1);
2186*cdf0e10cSrcweir 			$$ = $2;
2187*cdf0e10cSrcweir 		} else
2188*cdf0e10cSrcweir 		{
2189*cdf0e10cSrcweir 			FeDeclList* pList = new FeDeclList();
2190*cdf0e10cSrcweir 			pList->push_back($1);
2191*cdf0e10cSrcweir 			$$ = pList;
2192*cdf0e10cSrcweir 		}
2193*cdf0e10cSrcweir 	}
2194*cdf0e10cSrcweir 	;
2195*cdf0e10cSrcweir 
2196*cdf0e10cSrcweir declarators :
2197*cdf0e10cSrcweir 	declarators
2198*cdf0e10cSrcweir 	','
2199*cdf0e10cSrcweir 	{
2200*cdf0e10cSrcweir 		idlc()->setParseState(PS_DeclsCommaSeen);
2201*cdf0e10cSrcweir 	}
2202*cdf0e10cSrcweir 	declarator
2203*cdf0e10cSrcweir 	{
2204*cdf0e10cSrcweir 		idlc()->setParseState(PS_DeclsDeclSeen);
2205*cdf0e10cSrcweir 		if ( $1 )
2206*cdf0e10cSrcweir 		{
2207*cdf0e10cSrcweir 			$1->push_back($4);
2208*cdf0e10cSrcweir 			$$ = $1;
2209*cdf0e10cSrcweir 		} else
2210*cdf0e10cSrcweir 		{
2211*cdf0e10cSrcweir 			FeDeclList* pList = new FeDeclList();
2212*cdf0e10cSrcweir 			pList->push_back($4);
2213*cdf0e10cSrcweir 			$$ = pList;
2214*cdf0e10cSrcweir 		}
2215*cdf0e10cSrcweir 	}
2216*cdf0e10cSrcweir 	| /* EMPTY */
2217*cdf0e10cSrcweir 	{
2218*cdf0e10cSrcweir 		$$ = NULL;
2219*cdf0e10cSrcweir 	}
2220*cdf0e10cSrcweir 	;
2221*cdf0e10cSrcweir 
2222*cdf0e10cSrcweir declarator :
2223*cdf0e10cSrcweir 	simple_declarator
2224*cdf0e10cSrcweir 	| complex_declarator
2225*cdf0e10cSrcweir 	;
2226*cdf0e10cSrcweir 
2227*cdf0e10cSrcweir simple_declarator :
2228*cdf0e10cSrcweir 	identifier
2229*cdf0e10cSrcweir 	{
2230*cdf0e10cSrcweir         // For historic reasons, the struct com.sun.star.uno.Uik contains
2231*cdf0e10cSrcweir         // members with illegal names (of the form "m_DataN"); avoid useless
2232*cdf0e10cSrcweir         // warnings about them:
2233*cdf0e10cSrcweir         AstScope * scope = idlc()->scopes()->top();
2234*cdf0e10cSrcweir         if (scope == 0 || scope->getScopeNodeType() != NT_struct
2235*cdf0e10cSrcweir             || (scopeAsDecl(scope)->getScopedName()
2236*cdf0e10cSrcweir                 != "com::sun::star::uno::Uik"))
2237*cdf0e10cSrcweir         {
2238*cdf0e10cSrcweir             checkIdentifier($1);
2239*cdf0e10cSrcweir         }
2240*cdf0e10cSrcweir 
2241*cdf0e10cSrcweir         $$ = new FeDeclarator(*$1, FeDeclarator::FD_simple, NULL);
2242*cdf0e10cSrcweir         delete $1;
2243*cdf0e10cSrcweir 	}
2244*cdf0e10cSrcweir 	;
2245*cdf0e10cSrcweir 
2246*cdf0e10cSrcweir complex_declarator :
2247*cdf0e10cSrcweir 	array_declarator
2248*cdf0e10cSrcweir 	{
2249*cdf0e10cSrcweir 		$$ = new FeDeclarator($1->getLocalName(), FeDeclarator::FD_complex, $1);
2250*cdf0e10cSrcweir 	}
2251*cdf0e10cSrcweir 	;
2252*cdf0e10cSrcweir 
2253*cdf0e10cSrcweir array_declarator :
2254*cdf0e10cSrcweir 	identifier
2255*cdf0e10cSrcweir 	{
2256*cdf0e10cSrcweir         idlc()->setParseState(PS_ArrayIDSeen);
2257*cdf0e10cSrcweir         checkIdentifier($1);
2258*cdf0e10cSrcweir 	}
2259*cdf0e10cSrcweir 	at_least_one_array_dim
2260*cdf0e10cSrcweir 	{
2261*cdf0e10cSrcweir 		idlc()->setParseState(PS_ArrayCompleted);
2262*cdf0e10cSrcweir 		$$ = new AstArray(*$1, NULL, *$3, idlc()->scopes()->bottom());
2263*cdf0e10cSrcweir 		delete $1;
2264*cdf0e10cSrcweir 	}
2265*cdf0e10cSrcweir 	;
2266*cdf0e10cSrcweir 
2267*cdf0e10cSrcweir at_least_one_array_dim :
2268*cdf0e10cSrcweir 	array_dim array_dims
2269*cdf0e10cSrcweir 	{
2270*cdf0e10cSrcweir 		if( $2 )
2271*cdf0e10cSrcweir 		{
2272*cdf0e10cSrcweir 			$2->push_front($1);
2273*cdf0e10cSrcweir 			$$ = $2;
2274*cdf0e10cSrcweir 		} else
2275*cdf0e10cSrcweir 		{
2276*cdf0e10cSrcweir 			ExprList* pList = new ExprList();
2277*cdf0e10cSrcweir 			pList->push_back($1);
2278*cdf0e10cSrcweir 			$$ = pList;
2279*cdf0e10cSrcweir 		}
2280*cdf0e10cSrcweir 	}
2281*cdf0e10cSrcweir 	;
2282*cdf0e10cSrcweir 
2283*cdf0e10cSrcweir array_dims :
2284*cdf0e10cSrcweir 	array_dims array_dim
2285*cdf0e10cSrcweir 	{
2286*cdf0e10cSrcweir 		if( $1 )
2287*cdf0e10cSrcweir 		{
2288*cdf0e10cSrcweir 			$1->push_back($2);
2289*cdf0e10cSrcweir 			$$ = $1;
2290*cdf0e10cSrcweir 		} else
2291*cdf0e10cSrcweir 		{
2292*cdf0e10cSrcweir 			ExprList* pList = new ExprList();
2293*cdf0e10cSrcweir 			pList->push_back($2);
2294*cdf0e10cSrcweir 			$$ = pList;
2295*cdf0e10cSrcweir 		}
2296*cdf0e10cSrcweir 	}
2297*cdf0e10cSrcweir 	| /* EMPTY */
2298*cdf0e10cSrcweir 	{
2299*cdf0e10cSrcweir 		$$ = NULL;
2300*cdf0e10cSrcweir 	}
2301*cdf0e10cSrcweir     ;
2302*cdf0e10cSrcweir 
2303*cdf0e10cSrcweir array_dim :
2304*cdf0e10cSrcweir 	'['
2305*cdf0e10cSrcweir 	{
2306*cdf0e10cSrcweir 		idlc()->setParseState(PS_DimSqSeen);
2307*cdf0e10cSrcweir 	}
2308*cdf0e10cSrcweir 	positive_int_expr
2309*cdf0e10cSrcweir 	{
2310*cdf0e10cSrcweir 		idlc()->setParseState(PS_DimExprSeen);
2311*cdf0e10cSrcweir 	}
2312*cdf0e10cSrcweir 	']'
2313*cdf0e10cSrcweir 	{
2314*cdf0e10cSrcweir 		idlc()->setParseState(PS_DimQsSeen);
2315*cdf0e10cSrcweir 		/*
2316*cdf0e10cSrcweir 		 * Array dimensions are expressions which must be coerced to
2317*cdf0e10cSrcweir 		 * positive integers
2318*cdf0e10cSrcweir 		 */
2319*cdf0e10cSrcweir 		if ( !$3 || !$3->coerce(ET_uhyper) )
2320*cdf0e10cSrcweir 		{
2321*cdf0e10cSrcweir 			idlc()->error()->coercionError($3, ET_uhyper);
2322*cdf0e10cSrcweir 			$$ = NULL;
2323*cdf0e10cSrcweir 		} else
2324*cdf0e10cSrcweir 			$$ = $3;
2325*cdf0e10cSrcweir 	}
2326*cdf0e10cSrcweir 	;
2327*cdf0e10cSrcweir 
2328*cdf0e10cSrcweir at_least_one_scoped_name :
2329*cdf0e10cSrcweir 	scoped_name scoped_names
2330*cdf0e10cSrcweir 	{
2331*cdf0e10cSrcweir 		if ($2)
2332*cdf0e10cSrcweir 		{
2333*cdf0e10cSrcweir 			$2->push_front(*$1);
2334*cdf0e10cSrcweir 		 	$$ = $2;
2335*cdf0e10cSrcweir 		} else
2336*cdf0e10cSrcweir 		{
2337*cdf0e10cSrcweir 			StringList* pNames = new StringList();
2338*cdf0e10cSrcweir 			pNames->push_back(*$1);
2339*cdf0e10cSrcweir 			$$ = pNames;
2340*cdf0e10cSrcweir 		}
2341*cdf0e10cSrcweir 		delete($1);
2342*cdf0e10cSrcweir 	}
2343*cdf0e10cSrcweir 	;
2344*cdf0e10cSrcweir 
2345*cdf0e10cSrcweir scoped_names :
2346*cdf0e10cSrcweir 	scoped_names
2347*cdf0e10cSrcweir 	','
2348*cdf0e10cSrcweir 	{
2349*cdf0e10cSrcweir 		idlc()->setParseState(PS_SNListCommaSeen);
2350*cdf0e10cSrcweir 	}
2351*cdf0e10cSrcweir 	scoped_name
2352*cdf0e10cSrcweir 	{
2353*cdf0e10cSrcweir 		idlc()->setParseState(PS_ScopedNameSeen);
2354*cdf0e10cSrcweir 		if ($1)
2355*cdf0e10cSrcweir 		{
2356*cdf0e10cSrcweir 			$1->push_back(*$4);
2357*cdf0e10cSrcweir 		 	$$ = $1;
2358*cdf0e10cSrcweir 		} else
2359*cdf0e10cSrcweir 		{
2360*cdf0e10cSrcweir 			StringList* pNames = new StringList();
2361*cdf0e10cSrcweir 			pNames->push_back(*$4);
2362*cdf0e10cSrcweir 			$$ = pNames;
2363*cdf0e10cSrcweir 		}
2364*cdf0e10cSrcweir 		delete($4);
2365*cdf0e10cSrcweir 	}
2366*cdf0e10cSrcweir 	| /* EMPTY */
2367*cdf0e10cSrcweir 	{
2368*cdf0e10cSrcweir 		$$ = NULL;
2369*cdf0e10cSrcweir 	}
2370*cdf0e10cSrcweir 	;
2371*cdf0e10cSrcweir 
2372*cdf0e10cSrcweir scoped_name :
2373*cdf0e10cSrcweir 	identifier
2374*cdf0e10cSrcweir 	{
2375*cdf0e10cSrcweir         idlc()->setParseState(PS_SN_IDSeen);
2376*cdf0e10cSrcweir         checkIdentifier($1);
2377*cdf0e10cSrcweir         $$ = $1;
2378*cdf0e10cSrcweir 	}
2379*cdf0e10cSrcweir 	| IDL_SCOPESEPARATOR
2380*cdf0e10cSrcweir 	{
2381*cdf0e10cSrcweir 		idlc()->setParseState(PS_ScopeDelimSeen);
2382*cdf0e10cSrcweir 	}
2383*cdf0e10cSrcweir 	identifier
2384*cdf0e10cSrcweir 	{
2385*cdf0e10cSrcweir         checkIdentifier($3);
2386*cdf0e10cSrcweir         OString* pName = new OString("::");
2387*cdf0e10cSrcweir         *pName += *$3;
2388*cdf0e10cSrcweir         delete $3;
2389*cdf0e10cSrcweir         $$ = pName;
2390*cdf0e10cSrcweir 	}
2391*cdf0e10cSrcweir 	| scoped_name
2392*cdf0e10cSrcweir 	IDL_SCOPESEPARATOR
2393*cdf0e10cSrcweir 	{
2394*cdf0e10cSrcweir 	}
2395*cdf0e10cSrcweir 	identifier
2396*cdf0e10cSrcweir     {
2397*cdf0e10cSrcweir         checkIdentifier($4);
2398*cdf0e10cSrcweir         *$1 += ::rtl::OString("::");
2399*cdf0e10cSrcweir         *$1 += *$4;
2400*cdf0e10cSrcweir         delete $4;
2401*cdf0e10cSrcweir         $$ = $1;
2402*cdf0e10cSrcweir 	}
2403*cdf0e10cSrcweir 	;
2404*cdf0e10cSrcweir 
2405*cdf0e10cSrcweir type_spec :
2406*cdf0e10cSrcweir 	simple_type_spec
2407*cdf0e10cSrcweir 	| constructed_type_spec
2408*cdf0e10cSrcweir 	;
2409*cdf0e10cSrcweir 
2410*cdf0e10cSrcweir simple_type_spec :
2411*cdf0e10cSrcweir     fundamental_type
2412*cdf0e10cSrcweir 	| scoped_name opt_type_args
2413*cdf0e10cSrcweir 	{
2414*cdf0e10cSrcweir         $$ = createNamedType($1, $2);
2415*cdf0e10cSrcweir 	}
2416*cdf0e10cSrcweir 	;
2417*cdf0e10cSrcweir 
2418*cdf0e10cSrcweir fundamental_type:
2419*cdf0e10cSrcweir 	base_type_spec
2420*cdf0e10cSrcweir 	{
2421*cdf0e10cSrcweir 		$$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2422*cdf0e10cSrcweir 	}
2423*cdf0e10cSrcweir 	| template_type_spec
2424*cdf0e10cSrcweir     ;
2425*cdf0e10cSrcweir 
2426*cdf0e10cSrcweir opt_type_args:
2427*cdf0e10cSrcweir     '<' type_args '>' { $$ = $2; }
2428*cdf0e10cSrcweir     | /* empty */ { $$ = 0; }
2429*cdf0e10cSrcweir     ;
2430*cdf0e10cSrcweir 
2431*cdf0e10cSrcweir type_args:
2432*cdf0e10cSrcweir     type_arg
2433*cdf0e10cSrcweir     {
2434*cdf0e10cSrcweir         $$ = new DeclList;
2435*cdf0e10cSrcweir         $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast
2436*cdf0e10cSrcweir     }
2437*cdf0e10cSrcweir     | type_args ',' type_arg
2438*cdf0e10cSrcweir     {
2439*cdf0e10cSrcweir         $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast
2440*cdf0e10cSrcweir         $$ = $1;
2441*cdf0e10cSrcweir     }
2442*cdf0e10cSrcweir     ;
2443*cdf0e10cSrcweir 
2444*cdf0e10cSrcweir type_arg:
2445*cdf0e10cSrcweir     simple_type_spec
2446*cdf0e10cSrcweir     {
2447*cdf0e10cSrcweir         if ($1 != 0 && static_cast< AstType const * >($1)->isUnsigned()) {
2448*cdf0e10cSrcweir             idlc()->error()->error0(EIDL_UNSIGNED_TYPE_ARGUMENT);
2449*cdf0e10cSrcweir         }
2450*cdf0e10cSrcweir         $$ = $1;
2451*cdf0e10cSrcweir     }
2452*cdf0e10cSrcweir     ;
2453*cdf0e10cSrcweir 
2454*cdf0e10cSrcweir base_type_spec :
2455*cdf0e10cSrcweir 	integer_type
2456*cdf0e10cSrcweir 	| floating_pt_type
2457*cdf0e10cSrcweir 	| char_type
2458*cdf0e10cSrcweir 	| boolean_type
2459*cdf0e10cSrcweir 	| byte_type
2460*cdf0e10cSrcweir 	| any_type
2461*cdf0e10cSrcweir 	| type_type
2462*cdf0e10cSrcweir 	| string_type
2463*cdf0e10cSrcweir 	;
2464*cdf0e10cSrcweir 
2465*cdf0e10cSrcweir integer_type :
2466*cdf0e10cSrcweir 	signed_int
2467*cdf0e10cSrcweir 	| unsigned_int
2468*cdf0e10cSrcweir 	;
2469*cdf0e10cSrcweir 
2470*cdf0e10cSrcweir signed_int :
2471*cdf0e10cSrcweir 	IDL_LONG
2472*cdf0e10cSrcweir 	{
2473*cdf0e10cSrcweir 		$$ = ET_long;
2474*cdf0e10cSrcweir 	}
2475*cdf0e10cSrcweir 	| IDL_HYPER
2476*cdf0e10cSrcweir 	{
2477*cdf0e10cSrcweir 		$$ = ET_hyper;
2478*cdf0e10cSrcweir 	}
2479*cdf0e10cSrcweir 	| IDL_SHORT
2480*cdf0e10cSrcweir 	{
2481*cdf0e10cSrcweir 		$$ = ET_short;
2482*cdf0e10cSrcweir 	}
2483*cdf0e10cSrcweir 	;
2484*cdf0e10cSrcweir 
2485*cdf0e10cSrcweir unsigned_int :
2486*cdf0e10cSrcweir 	IDL_UNSIGNED IDL_LONG
2487*cdf0e10cSrcweir 	{
2488*cdf0e10cSrcweir 		$$ = ET_ulong;
2489*cdf0e10cSrcweir 	}
2490*cdf0e10cSrcweir 	| IDL_UNSIGNED IDL_HYPER
2491*cdf0e10cSrcweir 	{
2492*cdf0e10cSrcweir 		$$ = ET_uhyper;
2493*cdf0e10cSrcweir 	}
2494*cdf0e10cSrcweir 	| IDL_UNSIGNED IDL_SHORT
2495*cdf0e10cSrcweir 	{
2496*cdf0e10cSrcweir 		$$ = ET_ushort;
2497*cdf0e10cSrcweir 	}
2498*cdf0e10cSrcweir 	;
2499*cdf0e10cSrcweir 
2500*cdf0e10cSrcweir floating_pt_type :
2501*cdf0e10cSrcweir 	IDL_DOUBLE
2502*cdf0e10cSrcweir 	{
2503*cdf0e10cSrcweir 		$$ = ET_double;
2504*cdf0e10cSrcweir 	}
2505*cdf0e10cSrcweir 	| IDL_FLOAT
2506*cdf0e10cSrcweir 	{
2507*cdf0e10cSrcweir 		$$ = ET_float;
2508*cdf0e10cSrcweir 	}
2509*cdf0e10cSrcweir 	;
2510*cdf0e10cSrcweir 
2511*cdf0e10cSrcweir char_type :
2512*cdf0e10cSrcweir 	IDL_CHAR
2513*cdf0e10cSrcweir 	{
2514*cdf0e10cSrcweir 		$$ = ET_char;
2515*cdf0e10cSrcweir 	}
2516*cdf0e10cSrcweir 	;
2517*cdf0e10cSrcweir 
2518*cdf0e10cSrcweir byte_type :
2519*cdf0e10cSrcweir 	IDL_BYTE
2520*cdf0e10cSrcweir 	{
2521*cdf0e10cSrcweir 		$$ = ET_byte;
2522*cdf0e10cSrcweir 	}
2523*cdf0e10cSrcweir 	;
2524*cdf0e10cSrcweir 
2525*cdf0e10cSrcweir boolean_type :
2526*cdf0e10cSrcweir 	IDL_BOOLEAN
2527*cdf0e10cSrcweir 	{
2528*cdf0e10cSrcweir 		$$ = ET_boolean;
2529*cdf0e10cSrcweir 	}
2530*cdf0e10cSrcweir 	;
2531*cdf0e10cSrcweir 
2532*cdf0e10cSrcweir any_type :
2533*cdf0e10cSrcweir 	IDL_ANY
2534*cdf0e10cSrcweir 	{
2535*cdf0e10cSrcweir 		$$ = ET_any;
2536*cdf0e10cSrcweir 	}
2537*cdf0e10cSrcweir 	;
2538*cdf0e10cSrcweir 
2539*cdf0e10cSrcweir type_type :
2540*cdf0e10cSrcweir 	IDL_TYPE
2541*cdf0e10cSrcweir 	{
2542*cdf0e10cSrcweir 		$$ = ET_type;
2543*cdf0e10cSrcweir 	}
2544*cdf0e10cSrcweir 	;
2545*cdf0e10cSrcweir 
2546*cdf0e10cSrcweir string_type :
2547*cdf0e10cSrcweir 	IDL_STRING
2548*cdf0e10cSrcweir 	{
2549*cdf0e10cSrcweir 		$$ = ET_string;
2550*cdf0e10cSrcweir 	}
2551*cdf0e10cSrcweir 	;
2552*cdf0e10cSrcweir 
2553*cdf0e10cSrcweir template_type_spec :
2554*cdf0e10cSrcweir 	sequence_type_spec
2555*cdf0e10cSrcweir 	| array_type
2556*cdf0e10cSrcweir 	;
2557*cdf0e10cSrcweir 
2558*cdf0e10cSrcweir constructed_type_spec :
2559*cdf0e10cSrcweir 	struct_type
2560*cdf0e10cSrcweir 	| union_type
2561*cdf0e10cSrcweir 	| enum_type
2562*cdf0e10cSrcweir 	;
2563*cdf0e10cSrcweir 
2564*cdf0e10cSrcweir array_type :
2565*cdf0e10cSrcweir 	simple_type_spec
2566*cdf0e10cSrcweir 	{
2567*cdf0e10cSrcweir 		idlc()->setParseState(PS_ArrayTypeSeen);
2568*cdf0e10cSrcweir 	}
2569*cdf0e10cSrcweir 	at_least_one_array_dim
2570*cdf0e10cSrcweir 	{
2571*cdf0e10cSrcweir 		idlc()->setParseState(PS_ArrayCompleted);
2572*cdf0e10cSrcweir 
2573*cdf0e10cSrcweir 		AstScope* pScope = idlc()->scopes()->bottom();
2574*cdf0e10cSrcweir 		AstDeclaration* pDecl = NULL;
2575*cdf0e10cSrcweir 		AstDeclaration* pArray = NULL;
2576*cdf0e10cSrcweir 
2577*cdf0e10cSrcweir 		if ( $1 )
2578*cdf0e10cSrcweir 		{
2579*cdf0e10cSrcweir 			pArray = new AstArray((AstType*)$1, *$3, idlc()->scopes()->bottom());
2580*cdf0e10cSrcweir 			if ( pScope )
2581*cdf0e10cSrcweir 			{
2582*cdf0e10cSrcweir 				pDecl = pScope->addDeclaration(pArray);
2583*cdf0e10cSrcweir 				if ( pArray != pDecl )
2584*cdf0e10cSrcweir 				{
2585*cdf0e10cSrcweir 					// if array type already defined then use it
2586*cdf0e10cSrcweir 					delete pArray;
2587*cdf0e10cSrcweir 					pArray = pDecl;
2588*cdf0e10cSrcweir 				}
2589*cdf0e10cSrcweir 			}
2590*cdf0e10cSrcweir 		}
2591*cdf0e10cSrcweir 		$$ = pArray;
2592*cdf0e10cSrcweir 	}
2593*cdf0e10cSrcweir 	;
2594*cdf0e10cSrcweir 
2595*cdf0e10cSrcweir sequence_type_spec :
2596*cdf0e10cSrcweir 	IDL_SEQUENCE
2597*cdf0e10cSrcweir 	{
2598*cdf0e10cSrcweir 		idlc()->setParseState(PS_SequenceSeen);
2599*cdf0e10cSrcweir 		/*
2600*cdf0e10cSrcweir 		 * Push a sequence marker on scopes stack
2601*cdf0e10cSrcweir 		 */
2602*cdf0e10cSrcweir 		idlc()->scopes()->push(NULL);
2603*cdf0e10cSrcweir 	}
2604*cdf0e10cSrcweir 	'<'
2605*cdf0e10cSrcweir 	{
2606*cdf0e10cSrcweir 		idlc()->setParseState(PS_SequenceSqSeen);
2607*cdf0e10cSrcweir 	}
2608*cdf0e10cSrcweir 	simple_type_spec
2609*cdf0e10cSrcweir 	{
2610*cdf0e10cSrcweir 		idlc()->setParseState(PS_SequenceTypeSeen);
2611*cdf0e10cSrcweir 	}
2612*cdf0e10cSrcweir 	'>'
2613*cdf0e10cSrcweir 	{
2614*cdf0e10cSrcweir 		idlc()->setParseState(PS_SequenceQsSeen);
2615*cdf0e10cSrcweir 		/*
2616*cdf0e10cSrcweir 		 * Remove sequence marker from scopes stack
2617*cdf0e10cSrcweir 		 */
2618*cdf0e10cSrcweir 		if (idlc()->scopes()->top() == NULL)
2619*cdf0e10cSrcweir 			idlc()->scopes()->pop();
2620*cdf0e10cSrcweir 		/*
2621*cdf0e10cSrcweir 		 * Create a node representing a sequence
2622*cdf0e10cSrcweir 		 */
2623*cdf0e10cSrcweir 		AstScope* pScope = idlc()->scopes()->bottom();
2624*cdf0e10cSrcweir 		AstDeclaration* pDecl = NULL;
2625*cdf0e10cSrcweir 		AstDeclaration* pSeq = NULL;
2626*cdf0e10cSrcweir 
2627*cdf0e10cSrcweir 		if ( $5 )
2628*cdf0e10cSrcweir 		{
2629*cdf0e10cSrcweir 			AstType *pType = (AstType*)$5;
2630*cdf0e10cSrcweir 			if ( pType )
2631*cdf0e10cSrcweir 			{
2632*cdf0e10cSrcweir 				pSeq = new AstSequence(pType, pScope);
2633*cdf0e10cSrcweir 				/*
2634*cdf0e10cSrcweir 				 * Add this AstSequence to the types defined in the global scope
2635*cdf0e10cSrcweir 				 */
2636*cdf0e10cSrcweir 				pDecl = pScope->addDeclaration(pSeq);
2637*cdf0e10cSrcweir 				if ( pSeq != pDecl )
2638*cdf0e10cSrcweir 				{
2639*cdf0e10cSrcweir 					// if sequence type already defined then use it
2640*cdf0e10cSrcweir 					delete pSeq;
2641*cdf0e10cSrcweir 					pSeq = pDecl;
2642*cdf0e10cSrcweir 				}
2643*cdf0e10cSrcweir 			}
2644*cdf0e10cSrcweir         }
2645*cdf0e10cSrcweir 		$$ = pSeq;
2646*cdf0e10cSrcweir 	}
2647*cdf0e10cSrcweir 	| error '>'
2648*cdf0e10cSrcweir 	{
2649*cdf0e10cSrcweir 		yyerror("sequence declaration");
2650*cdf0e10cSrcweir 		yyerrok;
2651*cdf0e10cSrcweir         $$ = 0;
2652*cdf0e10cSrcweir 	}
2653*cdf0e10cSrcweir 	;
2654*cdf0e10cSrcweir 
2655*cdf0e10cSrcweir struct_type :
2656*cdf0e10cSrcweir 	structure_header
2657*cdf0e10cSrcweir 	{
2658*cdf0e10cSrcweir 		idlc()->setParseState(PS_StructHeaderSeen);
2659*cdf0e10cSrcweir 
2660*cdf0e10cSrcweir 		AstScope* 	pScope = idlc()->scopes()->topNonNull();
2661*cdf0e10cSrcweir 		AstStruct*	pStruct = NULL;
2662*cdf0e10cSrcweir 
2663*cdf0e10cSrcweir 		if ( pScope )
2664*cdf0e10cSrcweir 		{
2665*cdf0e10cSrcweir 			AstStruct* pBase= static_cast< AstStruct* >($1->getInherits());
2666*cdf0e10cSrcweir             pStruct = new AstStruct(
2667*cdf0e10cSrcweir                 *$1->getName(), $1->getTypeParameters(), pBase, pScope);
2668*cdf0e10cSrcweir 			pScope->addDeclaration(pStruct);
2669*cdf0e10cSrcweir 		}
2670*cdf0e10cSrcweir 		/*
2671*cdf0e10cSrcweir 		 * Push the scope of the struct on the scopes stack
2672*cdf0e10cSrcweir 		 */
2673*cdf0e10cSrcweir 		idlc()->scopes()->push(pStruct);
2674*cdf0e10cSrcweir 		delete $1;
2675*cdf0e10cSrcweir 	}
2676*cdf0e10cSrcweir 	'{'
2677*cdf0e10cSrcweir 	{
2678*cdf0e10cSrcweir 		idlc()->setParseState(PS_StructSqSeen);
2679*cdf0e10cSrcweir 	}
2680*cdf0e10cSrcweir 	at_least_one_member
2681*cdf0e10cSrcweir 	{
2682*cdf0e10cSrcweir 		idlc()->setParseState(PS_StructBodySeen);
2683*cdf0e10cSrcweir 	}
2684*cdf0e10cSrcweir 	'}'
2685*cdf0e10cSrcweir 	{
2686*cdf0e10cSrcweir 		idlc()->setParseState(PS_StructQsSeen);
2687*cdf0e10cSrcweir 		/* this exception is finished, pop its scope from the stack */
2688*cdf0e10cSrcweir 		idlc()->scopes()->pop();
2689*cdf0e10cSrcweir 	}
2690*cdf0e10cSrcweir 	;
2691*cdf0e10cSrcweir 
2692*cdf0e10cSrcweir structure_header :
2693*cdf0e10cSrcweir 	IDL_STRUCT
2694*cdf0e10cSrcweir 	{
2695*cdf0e10cSrcweir         idlc()->setParseState(PS_StructSeen);
2696*cdf0e10cSrcweir 	}
2697*cdf0e10cSrcweir 	identifier
2698*cdf0e10cSrcweir  	{
2699*cdf0e10cSrcweir         idlc()->setParseState(PS_StructIDSeen);
2700*cdf0e10cSrcweir         checkIdentifier($3);
2701*cdf0e10cSrcweir 	}
2702*cdf0e10cSrcweir     opt_type_params
2703*cdf0e10cSrcweir 	inheritance_spec
2704*cdf0e10cSrcweir 	{
2705*cdf0e10cSrcweir         idlc()->setParseState(PS_InheritSpecSeen);
2706*cdf0e10cSrcweir 
2707*cdf0e10cSrcweir         // Polymorphic struct type templates with base types would cause various
2708*cdf0e10cSrcweir         // problems in language bindings, so forbid them here.  For example,
2709*cdf0e10cSrcweir         // GCC prior to version 3.4 fails with code like
2710*cdf0e10cSrcweir         //
2711*cdf0e10cSrcweir         //  struct Base { ... };
2712*cdf0e10cSrcweir         //  template< typename typeparam_T > struct Derived: public Base {
2713*cdf0e10cSrcweir         //      int member1 CPPU_GCC3_ALIGN(Base);
2714*cdf0e10cSrcweir         //      ... };
2715*cdf0e10cSrcweir         //
2716*cdf0e10cSrcweir         // (Note that plain struct types with instantiated polymorphic struct
2717*cdf0e10cSrcweir         // type bases, which might also cause problems in language bindings, are
2718*cdf0e10cSrcweir         // already rejected on a syntactic level.)
2719*cdf0e10cSrcweir         if ($5 != 0 && $6 != 0) {
2720*cdf0e10cSrcweir             idlc()->error()->error0(EIDL_STRUCT_TYPE_TEMPLATE_WITH_BASE);
2721*cdf0e10cSrcweir         }
2722*cdf0e10cSrcweir 
2723*cdf0e10cSrcweir         $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5);
2724*cdf0e10cSrcweir         delete $5;
2725*cdf0e10cSrcweir         delete $6;
2726*cdf0e10cSrcweir 	}
2727*cdf0e10cSrcweir 	;
2728*cdf0e10cSrcweir 
2729*cdf0e10cSrcweir opt_type_params:
2730*cdf0e10cSrcweir     '<' type_params '>' { $$ = $2; }
2731*cdf0e10cSrcweir     | /* empty */ { $$ = 0; }
2732*cdf0e10cSrcweir     ;
2733*cdf0e10cSrcweir 
2734*cdf0e10cSrcweir type_params:
2735*cdf0e10cSrcweir     identifier
2736*cdf0e10cSrcweir     {
2737*cdf0e10cSrcweir         $$ = new std::vector< rtl::OString >;
2738*cdf0e10cSrcweir         $$->push_back(*$1);
2739*cdf0e10cSrcweir         delete $1;
2740*cdf0e10cSrcweir     }
2741*cdf0e10cSrcweir     | type_params ',' identifier
2742*cdf0e10cSrcweir     {
2743*cdf0e10cSrcweir         if (std::find($1->begin(), $1->end(), *$3) != $1->end()) {
2744*cdf0e10cSrcweir             idlc()->error()->error0(EIDL_IDENTICAL_TYPE_PARAMETERS);
2745*cdf0e10cSrcweir         }
2746*cdf0e10cSrcweir         $1->push_back(*$3);
2747*cdf0e10cSrcweir         delete $3;
2748*cdf0e10cSrcweir         $$ = $1;
2749*cdf0e10cSrcweir     }
2750*cdf0e10cSrcweir     ;
2751*cdf0e10cSrcweir 
2752*cdf0e10cSrcweir at_least_one_member : member members ;
2753*cdf0e10cSrcweir 
2754*cdf0e10cSrcweir members :
2755*cdf0e10cSrcweir 	members member
2756*cdf0e10cSrcweir 	| /* EMPTY */
2757*cdf0e10cSrcweir 	;
2758*cdf0e10cSrcweir 
2759*cdf0e10cSrcweir member :
2760*cdf0e10cSrcweir 	type_or_parameter
2761*cdf0e10cSrcweir 	{
2762*cdf0e10cSrcweir 		idlc()->setParseState(PS_MemberTypeSeen);
2763*cdf0e10cSrcweir 	}
2764*cdf0e10cSrcweir 	at_least_one_declarator
2765*cdf0e10cSrcweir 	{
2766*cdf0e10cSrcweir 		idlc()->setParseState(PS_MemberDeclsSeen);
2767*cdf0e10cSrcweir 	}
2768*cdf0e10cSrcweir 	';'
2769*cdf0e10cSrcweir 	{
2770*cdf0e10cSrcweir 		idlc()->setParseState(PS_MemberDeclsCompleted);
2771*cdf0e10cSrcweir 
2772*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
2773*cdf0e10cSrcweir 		AstMember*		pMember = NULL;
2774*cdf0e10cSrcweir 		FeDeclList*		pList = $3;
2775*cdf0e10cSrcweir 		FeDeclarator*	pDecl = NULL;
2776*cdf0e10cSrcweir         AstType const * pType = NULL;
2777*cdf0e10cSrcweir 
2778*cdf0e10cSrcweir 		// !!! check recursive type
2779*cdf0e10cSrcweir 
2780*cdf0e10cSrcweir 		if ( pScope && pList && $1 )
2781*cdf0e10cSrcweir 		{
2782*cdf0e10cSrcweir 			FeDeclList::iterator iter = pList->begin();
2783*cdf0e10cSrcweir 			FeDeclList::iterator end = pList->end();
2784*cdf0e10cSrcweir 			while (iter != end)
2785*cdf0e10cSrcweir 			{
2786*cdf0e10cSrcweir 				pDecl = (*iter);
2787*cdf0e10cSrcweir 				if ( !pDecl )
2788*cdf0e10cSrcweir 				{
2789*cdf0e10cSrcweir 					iter++;
2790*cdf0e10cSrcweir 					continue;
2791*cdf0e10cSrcweir 				}
2792*cdf0e10cSrcweir 
2793*cdf0e10cSrcweir 				pType = pDecl->compose($1);
2794*cdf0e10cSrcweir 
2795*cdf0e10cSrcweir 				if ( !pType )
2796*cdf0e10cSrcweir 				{
2797*cdf0e10cSrcweir 					iter++;
2798*cdf0e10cSrcweir 					continue;
2799*cdf0e10cSrcweir 				}
2800*cdf0e10cSrcweir 
2801*cdf0e10cSrcweir 				pMember = new AstMember(pType, pDecl->getName(), pScope);
2802*cdf0e10cSrcweir 
2803*cdf0e10cSrcweir 				if ( !pDecl->checkType($1) )
2804*cdf0e10cSrcweir 				{
2805*cdf0e10cSrcweir 					// WARNING
2806*cdf0e10cSrcweir 				}
2807*cdf0e10cSrcweir 
2808*cdf0e10cSrcweir 				pScope->addDeclaration(pMember);
2809*cdf0e10cSrcweir 				iter++;
2810*cdf0e10cSrcweir 				delete pDecl;
2811*cdf0e10cSrcweir 			}
2812*cdf0e10cSrcweir 			delete pList;
2813*cdf0e10cSrcweir 		}
2814*cdf0e10cSrcweir 	}
2815*cdf0e10cSrcweir 	| error ';'
2816*cdf0e10cSrcweir 	{
2817*cdf0e10cSrcweir 		yyerror("member definition");
2818*cdf0e10cSrcweir 		yyerrok;
2819*cdf0e10cSrcweir 	}
2820*cdf0e10cSrcweir 	;
2821*cdf0e10cSrcweir 
2822*cdf0e10cSrcweir type_or_parameter:
2823*cdf0e10cSrcweir     fundamental_type
2824*cdf0e10cSrcweir 	| scoped_name opt_type_args
2825*cdf0e10cSrcweir 	{
2826*cdf0e10cSrcweir         AstDeclaration const * decl = 0;
2827*cdf0e10cSrcweir         AstStruct * scope = static_cast< AstStruct * >(idlc()->scopes()->top());
2828*cdf0e10cSrcweir         if (scope != 0 && $2 == 0) {
2829*cdf0e10cSrcweir             decl = scope->findTypeParameter(*$1);
2830*cdf0e10cSrcweir         }
2831*cdf0e10cSrcweir         if (decl != 0) {
2832*cdf0e10cSrcweir             delete $1;
2833*cdf0e10cSrcweir             delete $2;
2834*cdf0e10cSrcweir         } else {
2835*cdf0e10cSrcweir             decl = createNamedType($1, $2);
2836*cdf0e10cSrcweir             if (scope != 0 && includes(decl, scopeAsDecl(scope))) {
2837*cdf0e10cSrcweir                 idlc()->error()->error1(
2838*cdf0e10cSrcweir                     EIDL_RECURSIVE_TYPE, scopeAsDecl(scope));
2839*cdf0e10cSrcweir                 decl = 0;
2840*cdf0e10cSrcweir             }
2841*cdf0e10cSrcweir         }
2842*cdf0e10cSrcweir         $$ = decl;
2843*cdf0e10cSrcweir 	}
2844*cdf0e10cSrcweir     ;
2845*cdf0e10cSrcweir 
2846*cdf0e10cSrcweir enum_type :
2847*cdf0e10cSrcweir 	IDL_ENUM
2848*cdf0e10cSrcweir 	{
2849*cdf0e10cSrcweir 		idlc()->setParseState(PS_EnumSeen);
2850*cdf0e10cSrcweir 	}
2851*cdf0e10cSrcweir 	identifier
2852*cdf0e10cSrcweir 	{
2853*cdf0e10cSrcweir         idlc()->setParseState(PS_EnumIDSeen);
2854*cdf0e10cSrcweir         checkIdentifier($3);
2855*cdf0e10cSrcweir 
2856*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
2857*cdf0e10cSrcweir 		AstEnum*		pEnum = NULL;
2858*cdf0e10cSrcweir 
2859*cdf0e10cSrcweir 		/*
2860*cdf0e10cSrcweir 		 * Create a node representing an enum and add it to its
2861*cdf0e10cSrcweir 		 * enclosing scope
2862*cdf0e10cSrcweir 		 */
2863*cdf0e10cSrcweir 		if (pScope != NULL)
2864*cdf0e10cSrcweir 		{
2865*cdf0e10cSrcweir 			pEnum = new AstEnum(*$3, pScope);
2866*cdf0e10cSrcweir 			/*
2867*cdf0e10cSrcweir 			 * Add it to its defining scope
2868*cdf0e10cSrcweir 			 */
2869*cdf0e10cSrcweir 			pScope->addDeclaration(pEnum);
2870*cdf0e10cSrcweir 		}
2871*cdf0e10cSrcweir 		delete $3;
2872*cdf0e10cSrcweir 		/*
2873*cdf0e10cSrcweir 		 * Push the enum scope on the scopes stack
2874*cdf0e10cSrcweir 		 */
2875*cdf0e10cSrcweir 		idlc()->scopes()->push(pEnum);
2876*cdf0e10cSrcweir 
2877*cdf0e10cSrcweir 	}
2878*cdf0e10cSrcweir 	'{'
2879*cdf0e10cSrcweir 	{
2880*cdf0e10cSrcweir 		idlc()->setParseState(PS_EnumSqSeen);
2881*cdf0e10cSrcweir 	}
2882*cdf0e10cSrcweir 	at_least_one_enumerator
2883*cdf0e10cSrcweir 	{
2884*cdf0e10cSrcweir 		idlc()->setParseState(PS_EnumBodySeen);
2885*cdf0e10cSrcweir 	}
2886*cdf0e10cSrcweir 	'}'
2887*cdf0e10cSrcweir 	{
2888*cdf0e10cSrcweir 		idlc()->setParseState(PS_EnumQsSeen);
2889*cdf0e10cSrcweir 		/*
2890*cdf0e10cSrcweir 		 * Done with this enum. Pop its scope from the scopes stack
2891*cdf0e10cSrcweir 		 */
2892*cdf0e10cSrcweir 		if (idlc()->scopes()->top() == NULL)
2893*cdf0e10cSrcweir 			$$ = NULL;
2894*cdf0e10cSrcweir 		else
2895*cdf0e10cSrcweir 		{
2896*cdf0e10cSrcweir 			$$ = (AstEnum*)idlc()->scopes()->topNonNull();
2897*cdf0e10cSrcweir 			idlc()->scopes()->pop();
2898*cdf0e10cSrcweir 		}
2899*cdf0e10cSrcweir 	}
2900*cdf0e10cSrcweir 	;
2901*cdf0e10cSrcweir 
2902*cdf0e10cSrcweir at_least_one_enumerator : enumerator enumerators ;
2903*cdf0e10cSrcweir 
2904*cdf0e10cSrcweir enumerators :
2905*cdf0e10cSrcweir 	enumerators
2906*cdf0e10cSrcweir 	','
2907*cdf0e10cSrcweir 	{
2908*cdf0e10cSrcweir 		idlc()->setParseState(PS_EnumCommaSeen);
2909*cdf0e10cSrcweir 	}
2910*cdf0e10cSrcweir 	enumerator
2911*cdf0e10cSrcweir 	| /* EMPTY */
2912*cdf0e10cSrcweir 	| error ','
2913*cdf0e10cSrcweir 	{
2914*cdf0e10cSrcweir 		yyerror("enumerator definition");
2915*cdf0e10cSrcweir 		yyerrok;
2916*cdf0e10cSrcweir 	}
2917*cdf0e10cSrcweir 	;
2918*cdf0e10cSrcweir 
2919*cdf0e10cSrcweir enumerator :
2920*cdf0e10cSrcweir 	identifier
2921*cdf0e10cSrcweir 	{
2922*cdf0e10cSrcweir         checkIdentifier($1);
2923*cdf0e10cSrcweir 
2924*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
2925*cdf0e10cSrcweir 		AstEnum*		pEnum = NULL;
2926*cdf0e10cSrcweir 		AstConstant* 	pEnumVal = NULL;
2927*cdf0e10cSrcweir 
2928*cdf0e10cSrcweir 		if ( pScope && pScope->getScopeNodeType() == NT_enum)
2929*cdf0e10cSrcweir 		{
2930*cdf0e10cSrcweir 			pEnum = (AstEnum*)pScope;
2931*cdf0e10cSrcweir 			if (pEnum && $1)
2932*cdf0e10cSrcweir 			{
2933*cdf0e10cSrcweir 				AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount());
2934*cdf0e10cSrcweir 				pEnumVal = new AstConstant(ET_long , NT_enum_val,
2935*cdf0e10cSrcweir 										   pExpr, *$1, pScope);
2936*cdf0e10cSrcweir 			}
2937*cdf0e10cSrcweir 			if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2938*cdf0e10cSrcweir 				idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum);
2939*cdf0e10cSrcweir 
2940*cdf0e10cSrcweir 			pScope->addDeclaration(pEnumVal);
2941*cdf0e10cSrcweir 		}
2942*cdf0e10cSrcweir 		delete $1;
2943*cdf0e10cSrcweir 	}
2944*cdf0e10cSrcweir 	| identifier
2945*cdf0e10cSrcweir 	'='
2946*cdf0e10cSrcweir 	const_expr
2947*cdf0e10cSrcweir 	{
2948*cdf0e10cSrcweir         checkIdentifier($1);
2949*cdf0e10cSrcweir 
2950*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
2951*cdf0e10cSrcweir 		AstEnum*		pEnum = NULL;
2952*cdf0e10cSrcweir 		AstConstant* 	pEnumVal = NULL;
2953*cdf0e10cSrcweir 
2954*cdf0e10cSrcweir 		if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum)
2955*cdf0e10cSrcweir 		{
2956*cdf0e10cSrcweir 			$3->evaluate(EK_const);
2957*cdf0e10cSrcweir 			if ( $3->coerce(ET_long) )
2958*cdf0e10cSrcweir 			{
2959*cdf0e10cSrcweir 				pEnum = (AstEnum*)pScope;
2960*cdf0e10cSrcweir 				if (pEnum)
2961*cdf0e10cSrcweir 				{
2962*cdf0e10cSrcweir 					pEnumVal = new AstConstant(ET_long , NT_enum_val,
2963*cdf0e10cSrcweir 											   $3, *$1, pScope);
2964*cdf0e10cSrcweir 				}
2965*cdf0e10cSrcweir 				if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2966*cdf0e10cSrcweir 					idlc()->error()->error1(EIDL_EVAL_ERROR, pEnum);
2967*cdf0e10cSrcweir 
2968*cdf0e10cSrcweir 				pScope->addDeclaration(pEnumVal);
2969*cdf0e10cSrcweir 			} else
2970*cdf0e10cSrcweir 			{
2971*cdf0e10cSrcweir 				idlc()->error()->coercionError($3, ET_long);
2972*cdf0e10cSrcweir 				delete $3;
2973*cdf0e10cSrcweir 			}
2974*cdf0e10cSrcweir 		}
2975*cdf0e10cSrcweir 		delete $1;
2976*cdf0e10cSrcweir 	}
2977*cdf0e10cSrcweir 	;
2978*cdf0e10cSrcweir 
2979*cdf0e10cSrcweir union_type :
2980*cdf0e10cSrcweir 	IDL_UNION
2981*cdf0e10cSrcweir 	{
2982*cdf0e10cSrcweir 		idlc()->setParseState(PS_UnionSeen);
2983*cdf0e10cSrcweir 	}
2984*cdf0e10cSrcweir 	identifier
2985*cdf0e10cSrcweir 	{
2986*cdf0e10cSrcweir         idlc()->setParseState(PS_UnionIDSeen);
2987*cdf0e10cSrcweir         checkIdentifier($3);
2988*cdf0e10cSrcweir 	}
2989*cdf0e10cSrcweir 	IDL_SWITCH
2990*cdf0e10cSrcweir 	{
2991*cdf0e10cSrcweir 		idlc()->setParseState(PS_SwitchSeen);
2992*cdf0e10cSrcweir 	}
2993*cdf0e10cSrcweir 	'('
2994*cdf0e10cSrcweir 	{
2995*cdf0e10cSrcweir 		idlc()->setParseState(PS_SwitchOpenParSeen);
2996*cdf0e10cSrcweir 	}
2997*cdf0e10cSrcweir 	switch_type_spec
2998*cdf0e10cSrcweir 	{
2999*cdf0e10cSrcweir 		idlc()->setParseState(PS_SwitchTypeSeen);
3000*cdf0e10cSrcweir 	}
3001*cdf0e10cSrcweir 	')'
3002*cdf0e10cSrcweir 	{
3003*cdf0e10cSrcweir 		idlc()->setParseState(PS_SwitchCloseParSeen);
3004*cdf0e10cSrcweir 
3005*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
3006*cdf0e10cSrcweir 		AstUnion*		pUnion = NULL;
3007*cdf0e10cSrcweir 
3008*cdf0e10cSrcweir 		/*
3009*cdf0e10cSrcweir 		 * Create a node representing a union. Add it to its enclosing
3010*cdf0e10cSrcweir 		 * scope
3011*cdf0e10cSrcweir 		 */
3012*cdf0e10cSrcweir 		if ( $9 && pScope )
3013*cdf0e10cSrcweir 		{
3014*cdf0e10cSrcweir 			AstType* pType = (AstType*)$9;
3015*cdf0e10cSrcweir 			if ( !pType)
3016*cdf0e10cSrcweir 			{
3017*cdf0e10cSrcweir 				idlc()->error()->noTypeError($9);
3018*cdf0e10cSrcweir 			} else
3019*cdf0e10cSrcweir 			{
3020*cdf0e10cSrcweir 				pUnion = new AstUnion(*$3, pType, pScope);
3021*cdf0e10cSrcweir 				pScope->addDeclaration(pUnion);
3022*cdf0e10cSrcweir 			}
3023*cdf0e10cSrcweir 		}
3024*cdf0e10cSrcweir 		delete $3;
3025*cdf0e10cSrcweir 		/*
3026*cdf0e10cSrcweir 		 * Push the scope of the union on the scopes stack
3027*cdf0e10cSrcweir 		 */
3028*cdf0e10cSrcweir 		idlc()->scopes()->push(pUnion);
3029*cdf0e10cSrcweir 	}
3030*cdf0e10cSrcweir 	'{'
3031*cdf0e10cSrcweir 	{
3032*cdf0e10cSrcweir 		idlc()->setParseState(PS_UnionSqSeen);
3033*cdf0e10cSrcweir 	}
3034*cdf0e10cSrcweir 	at_least_one_case_branch
3035*cdf0e10cSrcweir 	{
3036*cdf0e10cSrcweir 		idlc()->setParseState(PS_UnionBodySeen);
3037*cdf0e10cSrcweir 	}
3038*cdf0e10cSrcweir 	'}'
3039*cdf0e10cSrcweir 	{
3040*cdf0e10cSrcweir 		idlc()->setParseState(PS_UnionQsSeen);
3041*cdf0e10cSrcweir 		/* this union is finished, pop its scope from the stack */
3042*cdf0e10cSrcweir 		idlc()->scopes()->pop();
3043*cdf0e10cSrcweir 	}
3044*cdf0e10cSrcweir 	;
3045*cdf0e10cSrcweir 
3046*cdf0e10cSrcweir switch_type_spec :
3047*cdf0e10cSrcweir 	integer_type
3048*cdf0e10cSrcweir 	{
3049*cdf0e10cSrcweir 		$$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
3050*cdf0e10cSrcweir 	}
3051*cdf0e10cSrcweir 	| char_type
3052*cdf0e10cSrcweir 	{
3053*cdf0e10cSrcweir 		$$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
3054*cdf0e10cSrcweir 	}
3055*cdf0e10cSrcweir 	| boolean_type
3056*cdf0e10cSrcweir 	{
3057*cdf0e10cSrcweir 		$$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
3058*cdf0e10cSrcweir 	}
3059*cdf0e10cSrcweir 	| enum_type
3060*cdf0e10cSrcweir 	| scoped_name
3061*cdf0e10cSrcweir 	{
3062*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
3063*cdf0e10cSrcweir 		AstBaseType*	pBaseType = NULL;
3064*cdf0e10cSrcweir         AstDeclaration const * pDecl = NULL;
3065*cdf0e10cSrcweir 		AstTypeDef*		pTypeDef = NULL;
3066*cdf0e10cSrcweir 		sal_Bool		bFound = sal_False;
3067*cdf0e10cSrcweir 		/*
3068*cdf0e10cSrcweir 		 * If the constant's type is a scoped name, it must resolve
3069*cdf0e10cSrcweir 		 * to a scalar constant type
3070*cdf0e10cSrcweir 		 */
3071*cdf0e10cSrcweir 		if ( pScope && (pDecl = pScope->lookupByName(*$1)) )
3072*cdf0e10cSrcweir 		{
3073*cdf0e10cSrcweir 			/*
3074*cdf0e10cSrcweir 			 * Look through typedefs
3075*cdf0e10cSrcweir 			 */
3076*cdf0e10cSrcweir 			while ( !bFound )
3077*cdf0e10cSrcweir 			{
3078*cdf0e10cSrcweir 				switch (pDecl->getNodeType())
3079*cdf0e10cSrcweir 				{
3080*cdf0e10cSrcweir 					case NT_enum:
3081*cdf0e10cSrcweir 						$$ = pDecl;
3082*cdf0e10cSrcweir 						bFound = sal_True;
3083*cdf0e10cSrcweir 						break;
3084*cdf0e10cSrcweir 					case NT_predefined:
3085*cdf0e10cSrcweir 						pBaseType = (AstBaseType*)pDecl;
3086*cdf0e10cSrcweir 						if ( pBaseType )
3087*cdf0e10cSrcweir 						{
3088*cdf0e10cSrcweir 							switch (pBaseType->getExprType())
3089*cdf0e10cSrcweir 							{
3090*cdf0e10cSrcweir 								case ET_short:
3091*cdf0e10cSrcweir 								case ET_ushort:
3092*cdf0e10cSrcweir 								case ET_long:
3093*cdf0e10cSrcweir 								case ET_ulong:
3094*cdf0e10cSrcweir 								case ET_hyper:
3095*cdf0e10cSrcweir 								case ET_uhyper:
3096*cdf0e10cSrcweir 								case ET_char:
3097*cdf0e10cSrcweir 								case ET_byte:
3098*cdf0e10cSrcweir 								case ET_boolean:
3099*cdf0e10cSrcweir 									$$ = pBaseType;
3100*cdf0e10cSrcweir 									bFound = sal_True;
3101*cdf0e10cSrcweir 									break;
3102*cdf0e10cSrcweir 								default:
3103*cdf0e10cSrcweir 									$$ = NULL;
3104*cdf0e10cSrcweir 									bFound = sal_True;
3105*cdf0e10cSrcweir 									break;
3106*cdf0e10cSrcweir 							}
3107*cdf0e10cSrcweir 						}
3108*cdf0e10cSrcweir 						break;
3109*cdf0e10cSrcweir 					case NT_typedef:
3110*cdf0e10cSrcweir 						pTypeDef = (AstTypeDef*)pDecl;
3111*cdf0e10cSrcweir 						if ( pTypeDef )
3112*cdf0e10cSrcweir 							pDecl = pTypeDef->getBaseType();
3113*cdf0e10cSrcweir 						break;
3114*cdf0e10cSrcweir 					default:
3115*cdf0e10cSrcweir 						$$ = NULL;
3116*cdf0e10cSrcweir 						bFound = sal_True;
3117*cdf0e10cSrcweir 		               break;
3118*cdf0e10cSrcweir 				}
3119*cdf0e10cSrcweir 			}
3120*cdf0e10cSrcweir 		} else
3121*cdf0e10cSrcweir 			$$ = NULL;
3122*cdf0e10cSrcweir 
3123*cdf0e10cSrcweir 		if ($$ == NULL)
3124*cdf0e10cSrcweir 			idlc()->error()->lookupError(*$1);
3125*cdf0e10cSrcweir 	}
3126*cdf0e10cSrcweir 	;
3127*cdf0e10cSrcweir 
3128*cdf0e10cSrcweir at_least_one_case_branch : case_branch case_branches ;
3129*cdf0e10cSrcweir 
3130*cdf0e10cSrcweir case_branches :
3131*cdf0e10cSrcweir 	case_branches case_branch
3132*cdf0e10cSrcweir 	| /* EMPTY */
3133*cdf0e10cSrcweir 	;
3134*cdf0e10cSrcweir 
3135*cdf0e10cSrcweir case_branch :
3136*cdf0e10cSrcweir 	at_least_one_case_label
3137*cdf0e10cSrcweir 	{
3138*cdf0e10cSrcweir 		idlc()->setParseState(PS_UnionLabelSeen);
3139*cdf0e10cSrcweir 	}
3140*cdf0e10cSrcweir 	element_spec
3141*cdf0e10cSrcweir 	{
3142*cdf0e10cSrcweir 		idlc()->setParseState(PS_UnionElemSeen);
3143*cdf0e10cSrcweir 
3144*cdf0e10cSrcweir 		AstScope* 		pScope = idlc()->scopes()->topNonNull();
3145*cdf0e10cSrcweir 		AstUnionLabel*	pLabel = NULL;
3146*cdf0e10cSrcweir 		AstUnionBranch* pBranch = NULL;
3147*cdf0e10cSrcweir 		AstMember*		pMember = $3;
3148*cdf0e10cSrcweir 
3149*cdf0e10cSrcweir 		/*
3150*cdf0e10cSrcweir 		 * Create several nodes representing branches of a union.
3151*cdf0e10cSrcweir 		 * Add them to the enclosing scope (the union scope)
3152*cdf0e10cSrcweir 		 */
3153*cdf0e10cSrcweir 		if ( pScope && $1 && $3 )
3154*cdf0e10cSrcweir 		{
3155*cdf0e10cSrcweir 			LabelList::iterator iter = $1->begin();
3156*cdf0e10cSrcweir 			LabelList::iterator end = $1->end();
3157*cdf0e10cSrcweir 			for (;iter != end; iter++)
3158*cdf0e10cSrcweir 			{
3159*cdf0e10cSrcweir 				pLabel = *iter;
3160*cdf0e10cSrcweir 				if ( !pLabel )
3161*cdf0e10cSrcweir 				{
3162*cdf0e10cSrcweir 					iter++;
3163*cdf0e10cSrcweir 					continue;
3164*cdf0e10cSrcweir 				}
3165*cdf0e10cSrcweir 				pBranch = new AstUnionBranch(pLabel, pMember->getType(),
3166*cdf0e10cSrcweir                                         	 pMember->getLocalName(), pScope);
3167*cdf0e10cSrcweir 				pScope->addDeclaration(pBranch);
3168*cdf0e10cSrcweir 			}
3169*cdf0e10cSrcweir 		}
3170*cdf0e10cSrcweir 		if ( $1 ) delete($1);
3171*cdf0e10cSrcweir 	}
3172*cdf0e10cSrcweir 	;
3173*cdf0e10cSrcweir 
3174*cdf0e10cSrcweir at_least_one_case_label :
3175*cdf0e10cSrcweir 	case_label case_labels
3176*cdf0e10cSrcweir 	{
3177*cdf0e10cSrcweir 		if ( $2 )
3178*cdf0e10cSrcweir 		{
3179*cdf0e10cSrcweir 			$2->push_front($1);
3180*cdf0e10cSrcweir 		 	$$ = $2;
3181*cdf0e10cSrcweir 		} else
3182*cdf0e10cSrcweir 		{
3183*cdf0e10cSrcweir 			LabelList* pLabels = new LabelList();
3184*cdf0e10cSrcweir 			pLabels->push_back($1);
3185*cdf0e10cSrcweir 			$$ = pLabels;
3186*cdf0e10cSrcweir 		}
3187*cdf0e10cSrcweir 	}
3188*cdf0e10cSrcweir 	;
3189*cdf0e10cSrcweir 
3190*cdf0e10cSrcweir case_labels :
3191*cdf0e10cSrcweir 	case_labels case_label
3192*cdf0e10cSrcweir 	{
3193*cdf0e10cSrcweir 		if ( $1 )
3194*cdf0e10cSrcweir 		{
3195*cdf0e10cSrcweir 			$1->push_back($2);
3196*cdf0e10cSrcweir 		 	$$ = $1;
3197*cdf0e10cSrcweir 		} else
3198*cdf0e10cSrcweir 		{
3199*cdf0e10cSrcweir 			LabelList* pLabels = new LabelList();
3200*cdf0e10cSrcweir 			pLabels->push_back($2);
3201*cdf0e10cSrcweir 			$$ = pLabels;
3202*cdf0e10cSrcweir 		}
3203*cdf0e10cSrcweir 	}
3204*cdf0e10cSrcweir 	| /* EMPTY */
3205*cdf0e10cSrcweir 	{
3206*cdf0e10cSrcweir 		$$ = NULL;
3207*cdf0e10cSrcweir 	}
3208*cdf0e10cSrcweir 	;
3209*cdf0e10cSrcweir 
3210*cdf0e10cSrcweir case_label :
3211*cdf0e10cSrcweir 	IDL_DEFAULT
3212*cdf0e10cSrcweir 	{
3213*cdf0e10cSrcweir 		idlc()->setParseState(PS_DefaultSeen);
3214*cdf0e10cSrcweir 	}
3215*cdf0e10cSrcweir 	':'
3216*cdf0e10cSrcweir 	{
3217*cdf0e10cSrcweir 		idlc()->setParseState(PS_LabelColonSeen);
3218*cdf0e10cSrcweir 		$$ = new AstUnionLabel(UL_default, NULL);
3219*cdf0e10cSrcweir 	}
3220*cdf0e10cSrcweir 	| IDL_CASE
3221*cdf0e10cSrcweir 	{
3222*cdf0e10cSrcweir 		idlc()->setParseState(PS_CaseSeen);
3223*cdf0e10cSrcweir 	}
3224*cdf0e10cSrcweir 	const_expr
3225*cdf0e10cSrcweir 	{
3226*cdf0e10cSrcweir 		idlc()->setParseState(PS_LabelExprSeen);
3227*cdf0e10cSrcweir 	}
3228*cdf0e10cSrcweir 	':'
3229*cdf0e10cSrcweir 	{
3230*cdf0e10cSrcweir 		idlc()->setParseState(PS_LabelColonSeen);
3231*cdf0e10cSrcweir 		$$ = new AstUnionLabel(UL_label, $3);
3232*cdf0e10cSrcweir 	}
3233*cdf0e10cSrcweir 	;
3234*cdf0e10cSrcweir 
3235*cdf0e10cSrcweir element_spec :
3236*cdf0e10cSrcweir 	type_spec
3237*cdf0e10cSrcweir 	{
3238*cdf0e10cSrcweir 		idlc()->setParseState(PS_UnionElemTypeSeen);
3239*cdf0e10cSrcweir 	}
3240*cdf0e10cSrcweir 	declarator
3241*cdf0e10cSrcweir 	{
3242*cdf0e10cSrcweir 		idlc()->setParseState(PS_UnionElemDeclSeen);
3243*cdf0e10cSrcweir 	}
3244*cdf0e10cSrcweir 	';'
3245*cdf0e10cSrcweir 	{
3246*cdf0e10cSrcweir 		idlc()->setParseState(PS_UnionElemCompleted);
3247*cdf0e10cSrcweir 
3248*cdf0e10cSrcweir 		AstScope* pScope = idlc()->scopes()->topNonNull();
3249*cdf0e10cSrcweir 		/*
3250*cdf0e10cSrcweir 		 * Check for illegal recursive use of type
3251*cdf0e10cSrcweir 		 */
3252*cdf0e10cSrcweir //		if ( $1 && AST_illegal_recursive_type($1))
3253*cdf0e10cSrcweir //			idlc()->error()->error1(EIDL_RECURSIVE_TYPE, $1);
3254*cdf0e10cSrcweir 		/*
3255*cdf0e10cSrcweir 		 * Create a field in a union branch
3256*cdf0e10cSrcweir 		 */
3257*cdf0e10cSrcweir 		if ( $1 && $3 )
3258*cdf0e10cSrcweir 		{
3259*cdf0e10cSrcweir             AstType const * pType = $3->compose($1);
3260*cdf0e10cSrcweir 			if ( !pType )
3261*cdf0e10cSrcweir 				$$ = NULL;
3262*cdf0e10cSrcweir 			else
3263*cdf0e10cSrcweir 				$$ = new AstMember(pType, $3->getName(), pScope);
3264*cdf0e10cSrcweir 		} else
3265*cdf0e10cSrcweir 			$$ = NULL;
3266*cdf0e10cSrcweir 
3267*cdf0e10cSrcweir 		if ( $3 ) delete $3;
3268*cdf0e10cSrcweir 	}
3269*cdf0e10cSrcweir 	| error
3270*cdf0e10cSrcweir 	';'
3271*cdf0e10cSrcweir 	{
3272*cdf0e10cSrcweir 		$$ = NULL;
3273*cdf0e10cSrcweir 	}
3274*cdf0e10cSrcweir 	;
3275*cdf0e10cSrcweir 
3276*cdf0e10cSrcweir identifier:
3277*cdf0e10cSrcweir     IDL_IDENTIFIER
3278*cdf0e10cSrcweir     | IDL_GET { $$ = new OString("get"); }
3279*cdf0e10cSrcweir     | IDL_SET { $$ = new OString("set"); }
3280*cdf0e10cSrcweir     | IDL_PUBLISHED { $$ = new OString("published"); }
3281*cdf0e10cSrcweir     ;
3282*cdf0e10cSrcweir 
3283*cdf0e10cSrcweir %%
3284*cdf0e10cSrcweir 
3285*cdf0e10cSrcweir /*
3286*cdf0e10cSrcweir  * Report an error situation discovered in a production
3287*cdf0e10cSrcweir  */
3288*cdf0e10cSrcweir void yyerror(char const *errmsg)
3289*cdf0e10cSrcweir {
3290*cdf0e10cSrcweir 	idlc()->error()->syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg);
3291*cdf0e10cSrcweir 	idlc()->setParseState(PS_NoState);
3292*cdf0e10cSrcweir }
3293