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