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