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