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