bump product version to 7.2.5.1
[LibreOffice.git] / idlc / source / parser.y
blob29654c32bbbea3f67bba876c002057609dc84fed
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 * parser.yy - BISON grammar for IDLC 1.0
25 #include <string.h>
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>
47 #include <aststructinstance.hxx>
49 #include "attributeexceptions.hxx"
51 #include <rtl/string.hxx>
52 #include <osl/diagnose.h>
54 #include <algorithm>
55 #include <vector>
58 #define YYDEBUG 1
59 #define YYERROR_VERBOSE 1
61 extern int yylex(void);
62 static void yyerror(char const *);
64 static void checkIdentifier(OString const * id)
66 static short check = 0;
67 if (check == 0) {
68 if (idlc()->getOptions()->isValid("-cid"))
69 check = 1;
70 else
71 check = 2;
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());
83 else
84 ErrorHandler::warning0(WarningCode::WrongNamingConvention, id->getStr());
88 static void reportDoubleMemberDeclarations(
89 AstInterface::DoubleMemberDeclarations const & doubleMembers)
91 for (auto const& doubleMember : doubleMembers)
93 ErrorHandler::error2(ErrorCode::DoubleMember, doubleMember.first, doubleMember.second);
97 static void addInheritedInterface(
98 AstInterface * ifc, OString const & name, bool optional,
99 OUString const & documentation)
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())
116 ifc->addInheritedInterface(
117 static_cast< AstType * >(decl), optional,
118 documentation);
119 } else {
120 for (auto const& elem : doubleDecls.interfaces)
122 ErrorHandler::error1(
123 ErrorCode::DoubleInheritance, elem);
125 reportDoubleMemberDeclarations(doubleDecls.members);
129 } else {
130 ErrorHandler::lookupError(
131 ErrorCode::InterfaceMemberLookup, name, scopeAsDecl(ifc));
135 static AstDeclaration const * createNamedType(
136 OString const * scopedName, DeclList const * typeArgs)
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()))
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;
160 } else if (decl->isType()) {
161 if (typeArgs != nullptr) {
162 ErrorHandler::error0(ErrorCode::WrongNumberOfTypeArguments);
163 decl = nullptr;
165 } else {
166 ErrorHandler::noTypeError(decl);
167 decl = nullptr;
169 delete scopedName;
170 delete typeArgs;
171 return decl;
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;
183 for (DeclList::const_iterator i(inst->getTypeArgumentsBegin());
184 i != inst->getTypeArgumentsEnd(); ++i)
186 if (includes(*i, type2)) {
187 return true;
190 } else if (type1 == type2) {
191 return true;
194 return false;
197 // Suppress any warnings from generated code:
198 #if defined _MSC_VER
199 #pragma warning(disable: 4702) // unreachable code
200 #endif
203 * Declare the type of values in the grammar
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;
229 * Token types: These are returned by the lexer
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
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
273 %token IDL_TRUE
274 %token IDL_FALSE
276 %token IDL_IN
277 %token IDL_OUT
278 %token IDL_INOUT
280 %token IDL_GET
281 %token IDL_SET
283 %token IDL_PUBLISHED
285 %token IDL_ELLIPSIS
287 %token <strval> IDL_LEFTSHIFT
288 %token <strval> IDL_RIGHTSHIFT
289 %token <strval> IDL_SCOPESEPARATOR
291 %token <ival> IDL_INTEGER_LITERAL
292 %token <uval> IDL_INTEGER_ULITERAL
293 %token <dval> IDL_FLOATING_PT_LITERAL
296 * These are production names:
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
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
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
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
322 %type <fdval> declarator
323 %type <dlval> declarators at_least_one_declarator
325 %type <ihval> exception_header structure_header interfaceheader
327 %type <ulval> flag_header opt_attrflags opt_attrflag
328 %type <ulval> direction service_interface_header service_service_header
330 %type <bval> optional_inherited_interface opt_rest opt_service_body
332 %type <attexcval> opt_attribute_block attribute_block_rest opt_attribute_raises
334 %type <svals> opt_type_params type_params
338 * Grammar start here
340 start : definitions;
342 definitions :
343 definition definitions
344 | /* EMPTY */
347 definition :
348 opt_published publishable_definition
349 | module_dcl
351 idlc()->setParseState(PS_ModuleDeclSeen);
355 idlc()->setParseState(PS_NoState);
357 | error ';'
359 yyerror("definitions");
360 yyerrok;
364 opt_published:
365 IDL_PUBLISHED { idlc()->setPublished(true); }
366 | /* empty */ { idlc()->setPublished(false); }
369 publishable_definition:
370 type_dcl
372 idlc()->setParseState(PS_TypeDeclSeen);
376 idlc()->setParseState(PS_NoState);
378 | exception_dcl
380 idlc()->setParseState(PS_ExceptionDeclSeen);
384 idlc()->setParseState(PS_NoState);
386 | interface
388 idlc()->setParseState(PS_InterfaceDeclSeen);
392 idlc()->setParseState(PS_NoState);
394 | service_dcl
396 idlc()->setParseState(PS_ServiceDeclSeen);
400 idlc()->setParseState(PS_NoState);
402 | singleton_dcl
404 idlc()->setParseState(PS_SingletonDeclSeen);
408 idlc()->setParseState(PS_NoState);
410 | constants_dcl
412 idlc()->setParseState(PS_ConstantsDeclSeen);
416 idlc()->setParseState(PS_NoState);
420 module_dcl :
421 IDL_MODULE
423 idlc()->setParseState(PS_ModuleSeen);
424 idlc()->setPublished(false);
426 identifier
428 idlc()->setParseState(PS_ModuleIDSeen);
429 checkIdentifier($3);
431 AstScope* pScope = idlc()->scopes()->topNonNull();
432 AstModule* pModule = nullptr;
434 if ( pScope )
436 pModule = new AstModule(*$3, pScope);
437 if( AstDeclaration* pExists = pScope->lookupForAdd(pModule) )
439 pExists->setInMainfile(idlc()->isInMainFile());
440 pExists->setFileName(pModule->getFileName());
441 if (pExists->isPredefined())
443 pExists->setPredefined(false);
444 if (pExists->getDocumentation().getLength() == 0 &&
445 pModule->getDocumentation().getLength() > 0)
447 pExists->setDocumentation(pModule->getDocumentation());
450 delete(pModule);
451 pModule = static_cast<AstModule*>(pExists);
452 } else
454 pScope->addDeclaration(pModule);
456 idlc()->scopes()->push(pModule);
458 delete $3;
462 idlc()->setParseState(PS_ModuleSqSeen);
464 definitions
466 idlc()->setParseState(PS_ModuleBodySeen);
470 idlc()->setParseState(PS_ModuleQsSeen);
472 * Finished with this module - pop it from the scope stack
474 idlc()->scopes()->pop();
478 interface :
479 interface_dcl
480 | forward_dcl
483 interface_decl :
484 IDL_INTERFACE
486 idlc()->setParseState(PS_InterfaceSeen);
488 identifier
490 idlc()->setParseState(PS_InterfaceIDSeen);
491 checkIdentifier($3);
492 $$ = $3;
496 forward_dcl :
497 interface_decl
499 idlc()->setParseState(PS_ForwardDeclSeen);
501 AstScope* pScope = idlc()->scopes()->topNonNull();
502 AstInterface* pForward = nullptr;
503 AstDeclaration* pDecl = nullptr;
506 * Make a new forward interface node and add it to its enclosing scope
508 if ( pScope && $1 )
510 pForward = new AstInterface(*$1, nullptr, pScope);
512 pDecl = pScope->lookupByName(pForward->getScopedName());
513 if ( pDecl )
515 if ( (pDecl != pForward) &&
516 (pDecl->getNodeType() == NT_interface) )
518 delete pForward;
519 } else
521 ErrorHandler::error2(ErrorCode::RedefScope, scopeAsDecl(pScope), pDecl);
523 } else
526 * Add the interface to its definition scope
528 pScope->addDeclaration(pForward);
531 delete $1;
535 interface_dcl :
536 interfaceheader
538 idlc()->setParseState(PS_InterfaceHeadSeen);
540 AstScope* pScope = idlc()->scopes()->topNonNull();
541 AstInterface* pInterface = nullptr;
542 AstInterface* pForward = nullptr;
545 * Make a new interface node and add it to its enclosing scope
547 if ( pScope && $1 )
549 pInterface = new AstInterface(
550 *$1->getName(),
551 static_cast< AstInterface const * >(resolveTypedefs($1->getInherits())), pScope);
552 if ( AstDeclaration* pDecl = pScope->lookupByName(pInterface->getScopedName()) )
555 * See if we're defining a forward declared interface.
557 if (pDecl->getNodeType() == NT_interface)
559 pForward = static_cast<AstInterface*>(pDecl);
560 if ( !pForward->isDefined() )
563 * Check if redefining in same scope
565 if ( pForward->getScope() != pScope )
567 if ( pForward->getScopedName() != pInterface->getScopedName() )
569 ErrorHandler::error3(ErrorCode::ScopeConflict,
570 pInterface, pForward, scopeAsDecl(pScope));
573 else if ( !pInterface->isPublished()
574 && pForward->isPublished() )
576 ErrorHandler::error0(ErrorCode::PublishedForward);
579 * All OK, set full definition
581 else
583 pForward->forwardDefined(*pInterface);
584 delete pInterface;
585 pInterface = pForward;
587 } else {
588 // special handling for XInterface because it is predefined
589 if ( pForward->isPredefined() &&
590 pForward->getScopedName() == "com::sun::star::uno::XInterface")
592 /* replace the predefined XInterface */
593 *pForward = *pInterface;
594 delete pInterface;
595 pInterface = pForward;
600 } else
603 * Add the interface to its definition scope
605 pScope->addDeclaration(pInterface);
609 * Push it on the scope stack
611 idlc()->scopes()->push(pInterface);
612 delete $1;
616 idlc()->setParseState(PS_InterfaceSqSeen);
618 exports
620 AstInterface * ifc = static_cast< AstInterface * >(
621 idlc()->scopes()->topNonNull());
622 if (!ifc->hasMandatoryInheritedInterfaces()
623 && ifc->getScopedName() != "com::sun::star::uno::XInterface")
625 addInheritedInterface(
626 ifc, "::com::sun::star::uno::XInterface", false,
627 OUString());
629 ifc->setDefined();
630 idlc()->setParseState(PS_InterfaceBodySeen);
634 idlc()->setParseState(PS_InterfaceQsSeen);
636 * Done with this interface - pop it off the scopes stack
638 idlc()->scopes()->pop();
640 | error '}'
642 yyerror("interface definition");
643 yyerrok;
647 interfaceheader :
648 interface_decl inheritance_spec
650 idlc()->setParseState(PS_InheritSpecSeen);
652 $$ = new FeInheritanceHeader(NT_interface, $1, $2, nullptr);
653 delete $2;
657 inheritance_spec :
660 idlc()->setParseState(PS_InheritColonSeen);
662 scoped_name
664 $$ = $3;
666 | /* EMPTY */
668 $$ = nullptr;
672 exports :
673 exports export
674 | /* EMPTY */
677 export :
678 attribute
680 idlc()->setParseState(PS_AttributeDeclSeen);
684 idlc()->setParseState(PS_NoState);
686 | operation
688 idlc()->setParseState(PS_OperationDeclSeen);
692 idlc()->setParseState(PS_NoState);
694 | interface_inheritance_decl
696 idlc()->setParseState(PS_InterfaceInheritanceDeclSeen);
700 idlc()->setParseState(PS_NoState);
704 attribute :
705 flag_header
706 simple_type_spec
708 idlc()->setParseState(PS_AttrTypeSeen);
710 declarator
712 idlc()->setParseState(PS_AttrCompleted);
713 if (($1 & ~(AF_BOUND | AF_READONLY)) != AF_ATTRIBUTE) {
714 ErrorHandler::flagError(ErrorCode::BadAttributeFlags, $1);
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);
728 idlc()->scopes()->push(attr);
730 opt_attribute_block
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();
743 flag_header :
744 '[' opt_attrflags ']'
746 idlc()->setParseState(PS_FlagHeaderSeen);
747 $$ = $2;
751 opt_attrflags :
752 opt_attrflags ',' opt_attrflag
754 if ( ($1 & $3) == $3 )
755 ErrorHandler::flagError(ErrorCode::DefinedAttributeFlag, $3);
757 $$ = $1 | $3;
759 | opt_attrflag
761 $$ = $1;
765 opt_attrflag :
766 IDL_ATTRIBUTE
768 idlc()->setParseState(PS_AttrSeen);
769 $$ = AF_ATTRIBUTE;
771 | IDL_PROPERTY
773 idlc()->setParseState(PS_PropertySeen);
774 $$ = AF_PROPERTY;
776 | IDL_READONLY
778 idlc()->setParseState(PS_ReadOnlySeen);
779 $$ = AF_READONLY;
781 | IDL_OPTIONAL
783 idlc()->setParseState(PS_OptionalSeen);
784 $$ = AF_OPTIONAL;
786 | IDL_MAYBEVOID
788 idlc()->setParseState(PS_MayBeVoidSeen);
789 $$ = AF_MAYBEVOID;
791 | IDL_BOUND
793 idlc()->setParseState(PS_BoundSeen);
794 $$ = AF_BOUND;
796 | IDL_CONSTRAINED
798 idlc()->setParseState(PS_ConstrainedSeen);
799 $$ = AF_CONSTRAINED;
801 | IDL_TRANSIENT
803 idlc()->setParseState(PS_TransientSeen);
804 $$ = AF_TRANSIENT;
806 | IDL_MAYBEAMBIGUOUS
808 idlc()->setParseState(PS_MayBeAmbiguousSeen);
809 $$ = AF_MAYBEAMBIGUOUS;
811 | IDL_MAYBEDEFAULT
813 idlc()->setParseState(PS_MayBeDefaultSeen);
814 $$ = AF_MAYBEDEFAULT;
816 | IDL_REMOVABLE
818 idlc()->setParseState(PS_RemoveableSeen);
819 $$ = AF_REMOVABLE;
821 | error ']'
823 yyerror("unknown property|attribute flag");
824 yyerrok;
828 opt_attribute_block:
829 '{' attribute_block_rest { $$ = $2; }
830 | /* empty */
832 $$.get.documentation = nullptr;
833 $$.get.exceptions = nullptr;
834 $$.set.documentation = nullptr;
835 $$.set.exceptions = nullptr;
839 attribute_block_rest:
840 opt_attribute_raises '}'
841 | error '}'
843 yyerror("bad attribute raises block");
844 yyerrok;
845 $$.get.documentation = nullptr;
846 $$.get.exceptions = nullptr;
847 $$.set.documentation = nullptr;
848 $$.set.exceptions = nullptr;
852 opt_attribute_raises:
853 attribute_get_raises
854 opt_attribute_set_raises
856 $$.get = $1;
857 $$.set = $2;
859 | attribute_set_raises
860 opt_attribute_get_raises
862 $$.get = $2;
863 $$.set = $1;
865 | /* empty */
867 $$.get.documentation = nullptr;
868 $$.get.exceptions = nullptr;
869 $$.set.documentation = nullptr;
870 $$.set.exceptions = nullptr;
874 opt_attribute_get_raises:
875 attribute_get_raises
876 | /* empty */ { $$.documentation = nullptr; $$.exceptions = nullptr; }
879 attribute_get_raises:
880 IDL_GET raises ';'
882 $$.documentation = new OUString(
883 OStringToOUString(
884 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
885 $$.exceptions = $2;
889 opt_attribute_set_raises:
890 attribute_set_raises
891 | /* empty */ { $$.documentation = nullptr; $$.exceptions = nullptr; }
894 attribute_set_raises:
895 IDL_SET
897 if (static_cast< AstAttribute * >(idlc()->scopes()->top())->
898 isReadonly())
900 ErrorHandler::error0(ErrorCode::ReadOnlyAttributeSetExceptions);
903 raises ';'
905 $$.documentation = new OUString(
906 OStringToOUString(
907 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
908 $$.exceptions = $3;
912 operation :
913 op_type_spec
915 idlc()->setParseState(PS_OpTypeSeen);
917 identifier
919 idlc()->setParseState(PS_OpIDSeen);
920 checkIdentifier($3);
922 AstInterface * pScope = static_cast< AstInterface * >(
923 idlc()->scopes()->top());
924 AstOperation* pOp = nullptr;
927 * Create a node representing an operation on an interface
928 * and add it to its enclosing scope
930 if ( pScope && $1 )
932 AstType const *pType = static_cast<AstType const *>($1);
933 if ( !pType || (pType->getNodeType() == NT_exception) )
935 // type ERROR
936 } else
938 pOp = new AstOperation(pType, *$3, pScope);
940 AstInterface::DoubleMemberDeclarations doubleMembers(
941 pScope->checkMemberClashes(pOp));
942 if (doubleMembers.empty()) {
943 pScope->addMember(pOp);
944 } else {
945 reportDoubleMemberDeclarations(doubleMembers);
949 delete $3;
951 * Push the operation scope onto the scopes stack
953 idlc()->scopes()->push(pOp);
957 idlc()->setParseState(PS_OpSqSeen);
959 parameters
961 idlc()->setParseState(PS_OpParsCompleted);
965 idlc()->setParseState(PS_OpQsSeen);
967 opt_raises
969 AstScope* pScope = idlc()->scopes()->topNonNull();
970 AstOperation* pOp = nullptr;
972 * Add exceptions and context to the operation
974 if ( pScope && pScope->getScopeNodeType() == NT_operation)
976 pOp = static_cast<AstOperation*>(pScope);
978 if ( pOp )
979 pOp->setExceptions($11);
981 delete $11;
983 * Done with this operation. Pop its scope from the scopes stack
985 idlc()->scopes()->pop();
989 op_type_spec :
990 simple_type_spec
991 | IDL_VOID
993 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType(ET_void);
997 parameters :
998 parameter
999 | parameters
1002 idlc()->setParseState(PS_OpParCommaSeen);
1004 parameter
1005 | /* EMPTY */
1006 | error ','
1008 yyerror("parameter definition");
1009 yyerrok;
1013 parameter :
1015 direction
1018 idlc()->setParseState(PS_OpParDirSeen);
1020 simple_type_spec
1022 idlc()->setParseState(PS_OpParTypeSeen);
1024 opt_rest
1025 declarator
1027 idlc()->setParseState(PS_OpParDeclSeen);
1029 AstOperation * pScope = static_cast< AstOperation * >(
1030 idlc()->scopes()->top());
1031 AstParameter* pParam = nullptr;
1034 * Create a node representing an argument to an operation
1035 * Add it to the enclosing scope (the operation scope)
1037 if ( pScope && $5 && $8 )
1039 AstType const * pType = FeDeclarator::compose($5);
1040 if ( pType )
1042 if (pScope->isConstructor() && $2 != DIR_IN) {
1043 ErrorHandler::error0(ErrorCode::ConstructorParameterNotIn);
1045 if (pScope->isVariadic()) {
1046 ErrorHandler::error0(ErrorCode::RestParameterNotLast);
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))
1054 ErrorHandler::error0(ErrorCode::RestParameterNotAny);
1056 if (pScope->isConstructor()) {
1057 if (pScope->getIteratorBegin()
1058 != pScope->getIteratorEnd())
1060 ErrorHandler::error0(
1061 ErrorCode::ConstructorRestParameterNotFirst);
1063 } else {
1064 ErrorHandler::error0(ErrorCode::MethodHasRestParameter);
1068 pParam = new AstParameter(
1069 static_cast< Direction >($2), $7, pType, $8->getName(),
1070 pScope);
1072 if ( !$8->checkType($5) )
1074 // WARNING
1077 pScope->addDeclaration(pParam);
1081 | error
1082 simple_type_spec
1084 idlc()->setParseState(PS_NoState);
1085 yyerrok;
1089 direction :
1090 IDL_IN
1092 $$ = DIR_IN;
1094 | IDL_OUT
1096 $$ = DIR_OUT;
1098 | IDL_INOUT
1100 $$ = DIR_INOUT;
1104 opt_rest:
1105 IDL_ELLIPSIS
1107 $$ = true;
1109 | /* empty */
1111 $$ = false;
1115 opt_raises:
1116 raises
1117 | /* empty */
1119 $$ = nullptr;
1123 raises:
1124 IDL_RAISES
1126 idlc()->setParseState(PS_RaiseSeen);
1130 idlc()->setParseState(PS_RaiseSqSeen);
1132 exception_list
1135 idlc()->setParseState(PS_RaiseQsSeen);
1136 $$ = $5;
1140 exception_list:
1141 exception_name
1143 $$ = new DeclList;
1144 $$->push_back($1);
1146 | exception_list ',' exception_name
1148 $1->push_back($3);
1149 $$ = $1;
1153 exception_name:
1154 scoped_name
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;
1169 delete $1;
1170 $$ = decl;
1174 interface_inheritance_decl:
1175 optional_inherited_interface
1176 IDL_INTERFACE
1178 idlc()->setParseState(PS_ServiceIFHeadSeen);
1180 scoped_name
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));
1192 delete $4;
1196 optional_inherited_interface:
1197 '[' IDL_OPTIONAL ']' { $$ = true; }
1198 | /* EMPTY */ { $$ = false; }
1201 constants_exports :
1202 constants_export constants_exports
1203 | /* EMPTY */
1206 constants_export :
1207 IDL_CONST
1209 idlc()->setParseState(PS_ConstSeen);
1211 const_type
1213 idlc()->setParseState(PS_ConstTypeSeen);
1215 identifier
1217 idlc()->setParseState(PS_ConstIDSeen);
1218 checkIdentifier($5);
1222 idlc()->setParseState(PS_ConstAssignSeen);
1224 expression
1226 idlc()->setParseState(PS_ConstExprSeen);
1228 AstScope* pScope = idlc()->scopes()->topNonNull();
1229 AstConstant* pConstant = nullptr;
1231 if ( $9 && pScope )
1233 if ( !$9->coerce($3) )
1235 ErrorHandler::coercionError($9, $3);
1236 } else
1238 pConstant = new AstConstant($3, $9, *$5, pScope);
1239 pScope->addDeclaration(pConstant);
1242 delete $5;
1244 idlc()->setParseState(PS_ConstantDeclSeen);
1246 ';' {};
1249 constants_dcl :
1250 IDL_CONSTANTS
1252 idlc()->setParseState(PS_ConstantsSeen);
1254 identifier
1256 idlc()->setParseState(PS_ConstantsIDSeen);
1257 checkIdentifier($3);
1261 idlc()->setParseState(PS_ConstantsSqSeen);
1263 AstScope* pScope = idlc()->scopes()->topNonNull();
1264 AstConstants* pConstants = nullptr;
1266 if ( pScope )
1268 pConstants = new AstConstants(*$3, pScope);
1269 if( AstDeclaration* pExists = pScope->lookupForAdd(pConstants) )
1271 pExists->setInMainfile(idlc()->isInMainFile());
1272 delete(pConstants);
1273 pConstants = static_cast<AstConstants*>(pExists);
1274 } else
1276 pScope->addDeclaration(pConstants);
1278 idlc()->scopes()->push(pConstants);
1280 delete $3;
1282 constants_exports
1284 idlc()->setParseState(PS_ConstantsBodySeen);
1288 idlc()->setParseState(PS_ConstantsQsSeen);
1290 * Finished with this constants - pop it from the scope stack
1292 idlc()->scopes()->pop();
1296 expression : const_expr ;
1298 const_expr : or_expr ;
1300 or_expr :
1301 xor_expr
1302 | or_expr '|' xor_expr
1304 $$ = new AstExpression(ExprComb::Or, $1, $3);
1308 xor_expr :
1309 and_expr
1310 | xor_expr '^' and_expr
1312 $$ = new AstExpression(ExprComb::Xor, $1, $3);
1316 and_expr :
1317 shift_expr
1318 | and_expr '&' shift_expr
1320 $$ = new AstExpression(ExprComb::And, $1, $3);
1324 shift_expr :
1325 add_expr
1326 | shift_expr IDL_LEFTSHIFT add_expr
1328 $$ = new AstExpression(ExprComb::Left, $1, $3);
1330 | shift_expr IDL_RIGHTSHIFT add_expr
1332 $$ = new AstExpression(ExprComb::Right, $1, $3);
1336 add_expr :
1337 mult_expr
1338 | add_expr '+' mult_expr
1340 $$ = new AstExpression(ExprComb::Add, $1, $3);
1342 | add_expr '-' mult_expr
1344 $$ = new AstExpression(ExprComb::Minus, $1, $3);
1348 mult_expr :
1349 unary_expr
1350 | mult_expr '*' unary_expr
1352 $$ = new AstExpression(ExprComb::Mul, $1, $3);
1354 | mult_expr '/' unary_expr
1356 $$ = new AstExpression(ExprComb::Div, $1, $3);
1358 | mult_expr '%' unary_expr
1360 $$ = new AstExpression(ExprComb::Mod, $1, $3);
1364 unary_expr :
1365 primary_expr
1366 | '+' primary_expr
1368 $$ = new AstExpression(ExprComb::UPlus, $2, nullptr);
1370 | '-' primary_expr
1372 $$ = new AstExpression(ExprComb::UMinus, $2, nullptr);
1374 | '~' primary_expr
1379 primary_expr :
1380 scoped_name
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)
1387 $$ = new AstExpression($1);
1389 | literal
1390 | '(' const_expr ')'
1392 $$ = $2;
1396 literal :
1397 IDL_INTEGER_LITERAL
1399 $$ = new AstExpression($1);
1401 | IDL_INTEGER_ULITERAL
1403 $$ = new AstExpression($1);
1405 | IDL_FLOATING_PT_LITERAL
1407 $$ = new AstExpression($1);
1409 | IDL_TRUE
1411 $$ = new AstExpression(sal_Int32(1), ET_boolean);
1413 | IDL_FALSE
1415 $$ = new AstExpression(sal_Int32(0), ET_boolean);
1419 const_type :
1420 integer_type
1421 | byte_type
1422 | boolean_type
1423 | floating_pt_type
1424 | scoped_name
1426 AstScope* pScope = idlc()->scopes()->topNonNull();
1427 AstDeclaration const * type = nullptr;
1430 * If the constant's type is a scoped name, it must resolve
1431 * to a scalar constant type
1433 if ( pScope ) {
1434 type = pScope->lookupByName(*$1);
1435 if (type) {
1436 if (!ErrorHandler::checkPublished(type))
1438 type = nullptr;
1439 $$ = ET_none;
1441 else
1443 type = resolveTypedefs(type);
1444 if (type->getNodeType() == NT_predefined)
1446 $$ = static_cast< AstBaseType const * >(type)->
1447 getExprType();
1448 } else
1449 $$ = ET_any;
1451 } else
1452 $$ = ET_any;
1453 } else
1454 $$ = ET_any;
1458 exception_header :
1459 IDL_EXCEPTION
1461 idlc()->setParseState(PS_ExceptSeen);
1463 identifier
1465 idlc()->setParseState(PS_ExceptIDSeen);
1466 checkIdentifier($3);
1468 inheritance_spec
1470 idlc()->setParseState(PS_InheritSpecSeen);
1472 $$ = new FeInheritanceHeader(NT_exception, $3, $5, nullptr);
1473 delete $5;
1477 exception_dcl :
1478 exception_header
1480 idlc()->setParseState(PS_ExceptHeaderSeen);
1482 AstScope* pScope = idlc()->scopes()->topNonNull();
1483 AstException* pExcept = nullptr;
1485 if ( pScope )
1487 AstException* pBase = static_cast< AstException* >(
1488 $1->getInherits());
1489 pExcept = new AstException(*$1->getName(), pBase, pScope);
1490 pScope->addDeclaration(pExcept);
1493 * Push the scope of the exception on the scopes stack
1495 idlc()->scopes()->push(pExcept);
1496 delete $1;
1500 idlc()->setParseState(PS_ExceptSqSeen);
1502 members
1504 idlc()->setParseState(PS_ExceptBodySeen);
1508 idlc()->setParseState(PS_ExceptQsSeen);
1509 /* this exception is finished, pop its scope from the stack */
1510 idlc()->scopes()->pop();
1514 property :
1515 flag_header
1516 simple_type_spec
1518 idlc()->setParseState(PS_PropertyTypeSeen);
1520 at_least_one_declarator
1522 idlc()->setParseState(PS_PropertyCompleted);
1524 AstScope* pScope = idlc()->scopes()->topNonNull();
1525 AstAttribute* pAttr = nullptr;
1526 FeDeclList* pList = $4;
1527 FeDeclarator* pDecl = nullptr;
1528 AstType const * pType = nullptr;
1530 if ( pScope->getScopeNodeType() == NT_singleton )
1532 ErrorHandler::error0(ErrorCode::IllegalAdd);
1533 } else
1535 if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE )
1536 ErrorHandler::flagError(ErrorCode::WrongAttributeKeyword, AF_ATTRIBUTE);
1538 if ( ($1 & AF_PROPERTY) != AF_PROPERTY )
1539 ErrorHandler::flagError(ErrorCode::MissingAttributeKeyword, AF_PROPERTY);
1542 * Create nodes representing attributes and add them to the
1543 * enclosing scope
1545 if ( pScope && $2 && pList )
1547 FeDeclList::iterator iter = pList->begin();
1548 FeDeclList::iterator end = pList->end();
1550 while (iter != end)
1552 pDecl = (*iter);
1553 if ( !pDecl )
1555 ++iter;
1556 continue;
1559 pType = FeDeclarator::compose($2);
1561 if ( !pType )
1563 ++iter;
1564 continue;
1567 pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope);
1569 pScope->addDeclaration(pAttr);
1570 ++iter;
1571 delete pDecl;
1576 if ( pList )
1577 delete pList;
1579 | error ';'
1581 yyerror("property");
1582 yyerrok;
1586 service_exports :
1587 service_exports service_export
1588 | /* EMPTY */
1591 service_export :
1592 service_interface_header
1593 at_least_one_scoped_name
1596 idlc()->setParseState(PS_ServiceMemberSeen);
1598 AstScope* pScope = idlc()->scopes()->topNonNull();
1599 AstDeclaration* pDecl = nullptr;
1600 AstInterfaceMember* pIMember = nullptr;
1602 if ( pScope->getScopeNodeType() == NT_singleton )
1604 ErrorHandler::error0(ErrorCode::IllegalAdd);
1605 } else
1608 * Create a node representing a class member.
1609 * Store it in the enclosing scope
1611 if ( pScope && $2 )
1613 for (auto const& elem : *($2))
1615 pDecl = pScope->lookupByName(elem);
1616 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1618 /* we relax the strict published check and allow to add new
1619 * interfaces if they are optional
1621 bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL);
1622 if ( ErrorHandler::checkPublished(pDecl, bOptional) )
1624 pIMember = new AstInterfaceMember(
1625 $1, static_cast<AstInterface*>(pDecl), elem, pScope);
1626 pScope->addDeclaration(pIMember);
1628 } else
1630 ErrorHandler::lookupError(ErrorCode::InterfaceMemberLookup, elem, scopeAsDecl(pScope));
1635 delete $2;
1637 | service_service_header
1638 at_least_one_scoped_name
1641 idlc()->setParseState(PS_ServiceMemberSeen);
1643 AstScope* pScope = idlc()->scopes()->topNonNull();
1644 AstDeclaration* pDecl = nullptr;
1645 AstServiceMember* pSMember = nullptr;
1648 * Create a node representing a class member.
1649 * Store it in the enclosing scope
1651 if ( pScope && $2 )
1653 for (auto const& elem : *($2))
1655 pDecl = pScope->lookupByName(elem);
1656 if ( pDecl && (pDecl->getNodeType() == NT_service) )
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) )
1662 pSMember = new AstServiceMember(
1663 $1, static_cast<AstService*>(pDecl), elem, pScope);
1664 pScope->addDeclaration(pSMember);
1666 } else
1668 ErrorHandler::lookupError(ErrorCode::ServiceMemberLookup, elem, scopeAsDecl(pScope));
1672 delete $2;
1674 | IDL_OBSERVES
1675 at_least_one_scoped_name
1678 idlc()->setParseState(PS_ServiceMemberSeen);
1680 AstScope* pScope = idlc()->scopes()->topNonNull();
1681 AstDeclaration* pDecl = nullptr;
1682 AstObserves* pObserves = nullptr;
1684 if ( pScope->getScopeNodeType() == NT_singleton )
1686 ErrorHandler::error0(ErrorCode::IllegalAdd);
1687 } else
1690 * Create a node representing a class member.
1691 * Store it in the enclosing scope
1693 if ( pScope && $2 )
1695 for (auto const& elem : *($2))
1697 pDecl = pScope->lookupByName(elem);
1698 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1700 pObserves = new AstObserves(static_cast<AstInterface*>(pDecl), elem, pScope);
1701 pScope->addDeclaration(pObserves);
1702 } else
1704 ErrorHandler::lookupError(ErrorCode::InterfaceMemberLookup, elem, scopeAsDecl(pScope));
1709 delete $2;
1711 | IDL_NEEDS
1712 at_least_one_scoped_name
1715 idlc()->setParseState(PS_ServiceMemberSeen);
1717 AstScope* pScope = idlc()->scopes()->topNonNull();
1718 AstDeclaration* pDecl = nullptr;
1719 AstNeeds* pNeeds = nullptr;
1721 if ( pScope->getScopeNodeType() == NT_singleton )
1723 ErrorHandler::error0(ErrorCode::IllegalAdd);
1724 } else
1727 * Create a node representing a class member.
1728 * Store it in the enclosing scope
1730 if ( pScope && $2 )
1732 for (auto const& elem : *($2))
1734 pDecl = pScope->lookupByName(elem);
1735 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1737 pNeeds = new AstNeeds(static_cast<AstService*>(pDecl), elem, pScope);
1738 pScope->addDeclaration(pNeeds);
1739 } else
1741 ErrorHandler::lookupError(ErrorCode::ServiceMemberLookup, elem, scopeAsDecl(pScope));
1746 delete $2;
1748 | property
1751 idlc()->setParseState(PS_PropertyDeclSeen);
1755 service_interface_header :
1756 IDL_INTERFACE
1758 idlc()->setParseState(PS_ServiceIFHeadSeen);
1759 $$ = AF_INVALID;
1761 | flag_header
1762 IDL_INTERFACE
1764 idlc()->setParseState(PS_ServiceIFHeadSeen);
1765 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1766 ErrorHandler::flagError(ErrorCode::ExpectedOptional, $1);
1767 $$ = $1;
1771 service_service_header :
1772 IDL_SERVICE
1774 idlc()->setParseState(PS_ServiceSHeadSeen);
1775 $$ = AF_INVALID;
1777 | flag_header
1778 IDL_SERVICE
1780 idlc()->setParseState(PS_ServiceSHeadSeen);
1781 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1782 ErrorHandler::flagError(ErrorCode::ExpectedOptional, $1);
1783 $$ = $1;
1787 service_dcl :
1788 IDL_SERVICE
1790 idlc()->setParseState(PS_ServiceSeen);
1792 identifier
1794 idlc()->setParseState(PS_ServiceIDSeen);
1795 checkIdentifier($3);
1797 AstScope* pScope = idlc()->scopes()->topNonNull();
1798 AstService* pService = nullptr;
1801 * Make a new service and add it to the enclosing scope
1803 if (pScope != nullptr)
1805 pService = new AstService(*$3, pScope);
1806 pScope->addDeclaration(pService);
1808 delete $3;
1810 * Push it on the stack
1812 idlc()->scopes()->push(pService);
1814 service_dfn
1816 /* this service is finished, pop its scope from the stack */
1817 idlc()->scopes()->pop();
1821 service_dfn:
1822 service_interface_dfn
1823 | service_obsolete_dfn
1826 service_interface_dfn:
1827 ':' scoped_name
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)
1835 if (ErrorHandler::checkPublished(decl)) {
1836 idlc()->scopes()->top()->addDeclaration(decl);
1838 } else {
1839 ErrorHandler::lookupError(
1840 ErrorCode::InterfaceMemberLookup, *$2, scopeAsDecl(scope));
1842 delete $2;
1844 opt_service_body
1846 AstService * s = static_cast< AstService * >(idlc()->scopes()->top());
1847 if (s != nullptr) {
1848 s->setSingleInterfaceBasedService();
1849 s->setDefaultConstructor(!$4);
1854 opt_service_body:
1855 service_body { $$ = true; }
1856 | /* empty */ { $$ = false; }
1859 service_body:
1861 constructors
1865 constructors:
1866 constructors constructor
1867 | /* empty */
1870 constructor:
1871 identifier
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);
1881 parameters
1883 opt_raises
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())
1892 ErrorHandler::error0(ErrorCode::SimilarConstructors);
1898 singleton_dcl :
1899 IDL_SINGLETON
1901 idlc()->setParseState(PS_SingletonSeen);
1903 identifier
1905 idlc()->setParseState(PS_SingletonIDSeen);
1906 checkIdentifier($3);
1908 AstScope* pScope = idlc()->scopes()->topNonNull();
1909 AstService* pService = nullptr;
1912 * Make a new service and add it to the enclosing scope
1914 if (pScope != nullptr)
1916 pService = new AstService(NT_singleton, *$3, pScope);
1917 pScope->addDeclaration(pService);
1919 delete $3;
1921 * Push it on the stack
1923 idlc()->scopes()->push(pService);
1925 singleton_dfn
1927 /* this singleton is finished, pop its scope from the stack */
1928 idlc()->scopes()->pop();
1932 singleton_dfn:
1933 singleton_interface_dfn
1934 | service_obsolete_dfn
1937 singleton_interface_dfn:
1938 ':' scoped_name
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)
1946 if (ErrorHandler::checkPublished(decl)) {
1947 idlc()->scopes()->top()->addDeclaration(decl);
1949 } else {
1950 ErrorHandler::lookupError(
1951 ErrorCode::InterfaceMemberLookup, *$2, scopeAsDecl(scope));
1953 delete $2;
1957 service_obsolete_dfn:
1960 idlc()->setParseState(
1961 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1962 ? PS_ServiceSqSeen : PS_SingletonSqSeen);
1964 service_exports
1966 idlc()->setParseState(
1967 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1968 ? PS_ServiceBodySeen : PS_SingletonBodySeen);
1972 idlc()->setParseState(
1973 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1974 ? PS_ServiceQsSeen : PS_SingletonQsSeen);
1978 type_dcl :
1979 IDL_TYPEDEF
1981 idlc()->setParseState(PS_TypedefSeen);
1983 type_declarator {}
1984 | struct_type {}
1985 | enum_type {}
1988 type_declarator :
1989 type_spec
1991 idlc()->setParseState(PS_TypeSpecSeen);
1992 if ($1 != nullptr && $1->getNodeType() == NT_instantiated_struct) {
1993 ErrorHandler::error0(ErrorCode::InstantiatedStructTypeTypedef);
1996 at_least_one_declarator
1998 idlc()->setParseState(PS_DeclaratorsSeen);
2000 AstScope* pScope = idlc()->scopes()->topNonNull();
2001 AstTypeDef* pTypeDef = nullptr;
2002 FeDeclList* pList = $3;
2003 FeDeclarator* pDecl = nullptr;
2004 AstType const * pType = nullptr;
2007 * Create nodes representing typedefs and add them to the
2008 * enclosing scope
2010 if ( pScope && $1 && pList )
2012 FeDeclList::iterator iter = pList->begin();
2013 FeDeclList::iterator end = pList->end();
2015 while (iter != end)
2017 pDecl = (*iter);
2018 if ( !pDecl )
2020 ++iter;
2021 continue;
2024 pType = FeDeclarator::compose($1);
2026 if ( !pType )
2028 ++iter;
2029 continue;
2032 pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope);
2034 pScope->addDeclaration(pTypeDef);
2035 ++iter;
2036 delete pDecl;
2038 delete pList;
2043 at_least_one_declarator :
2044 declarator declarators
2046 if ( $2 )
2048 $2->push_back($1);
2049 $$ = $2;
2050 } else
2052 FeDeclList* pList = new FeDeclList;
2053 pList->push_back($1);
2054 $$ = pList;
2059 declarators :
2060 declarators
2063 idlc()->setParseState(PS_DeclsCommaSeen);
2065 declarator
2067 idlc()->setParseState(PS_DeclsDeclSeen);
2068 if ( $1 )
2070 $1->push_back($4);
2071 $$ = $1;
2072 } else
2074 FeDeclList* pList = new FeDeclList;
2075 pList->push_back($4);
2076 $$ = pList;
2079 | /* EMPTY */
2081 $$ = nullptr;
2085 declarator :
2086 identifier
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"))
2096 checkIdentifier($1);
2099 $$ = new FeDeclarator(*$1);
2100 delete $1;
2104 at_least_one_scoped_name :
2105 scoped_name scoped_names
2107 if ($2)
2109 $2->push_front(*$1);
2110 $$ = $2;
2111 } else
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;
2118 delete $1;
2122 scoped_names :
2123 scoped_names
2126 idlc()->setParseState(PS_SNListCommaSeen);
2128 scoped_name
2130 idlc()->setParseState(PS_ScopedNameSeen);
2131 if ($1)
2133 $1->push_back(*$4);
2134 $$ = $1;
2135 } else
2137 std::list< OString >* pNames = new std::list< OString >;
2138 pNames->push_back(*$4);
2139 $$ = pNames;
2141 delete $4;
2143 | /* EMPTY */
2145 $$ = nullptr;
2149 scoped_name :
2150 identifier
2152 idlc()->setParseState(PS_SN_IDSeen);
2153 checkIdentifier($1);
2154 $$ = $1;
2156 | IDL_SCOPESEPARATOR
2158 idlc()->setParseState(PS_ScopeDelimSeen);
2160 identifier
2162 checkIdentifier($3);
2163 OString* pName = new OString("::");
2164 *pName += *$3;
2165 delete $3;
2166 $$ = pName;
2168 | scoped_name
2169 IDL_SCOPESEPARATOR
2172 identifier
2174 checkIdentifier($4);
2175 *$1 += "::";
2176 *$1 += *$4;
2177 delete $4;
2178 $$ = $1;
2182 type_spec :
2183 simple_type_spec
2184 | constructed_type_spec
2187 simple_type_spec :
2188 fundamental_type
2189 | scoped_name opt_type_args
2191 $$ = createNamedType($1, $2);
2195 fundamental_type:
2196 base_type_spec
2198 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2200 | sequence_type_spec
2203 opt_type_args:
2204 '<' type_args '>' { $$ = $2; }
2205 | /* empty */ { $$ = nullptr; }
2208 type_args:
2209 type_arg
2211 $$ = new DeclList;
2212 $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast
2214 | type_args ',' type_arg
2216 $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast
2217 $$ = $1;
2221 type_arg:
2222 simple_type_spec
2224 if ($1 != nullptr && static_cast< AstType const * >($1)->isUnsigned()) {
2225 ErrorHandler::error0(ErrorCode::UnsignedTypeArgument);
2227 $$ = $1;
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
2242 integer_type :
2243 signed_int
2244 | unsigned_int
2247 signed_int :
2248 IDL_LONG
2250 $$ = ET_long;
2252 | IDL_HYPER
2254 $$ = ET_hyper;
2256 | IDL_SHORT
2258 $$ = ET_short;
2262 unsigned_int :
2263 IDL_UNSIGNED IDL_LONG
2265 $$ = ET_ulong;
2267 | IDL_UNSIGNED IDL_HYPER
2269 $$ = ET_uhyper;
2271 | IDL_UNSIGNED IDL_SHORT
2273 $$ = ET_ushort;
2277 floating_pt_type :
2278 IDL_DOUBLE
2280 $$ = ET_double;
2282 | IDL_FLOAT
2284 $$ = ET_float;
2288 char_type :
2289 IDL_CHAR
2291 $$ = ET_char;
2295 byte_type :
2296 IDL_BYTE
2298 $$ = ET_byte;
2302 boolean_type :
2303 IDL_BOOLEAN
2305 $$ = ET_boolean;
2309 any_type :
2310 IDL_ANY
2312 $$ = ET_any;
2316 type_type :
2317 IDL_TYPE
2319 $$ = ET_type;
2323 string_type :
2324 IDL_STRING
2326 $$ = ET_string;
2330 constructed_type_spec :
2331 struct_type
2332 | enum_type
2335 sequence_type_spec :
2336 IDL_SEQUENCE
2338 idlc()->setParseState(PS_SequenceSeen);
2340 * Push a sequence marker on scopes stack
2342 idlc()->scopes()->push(nullptr);
2346 idlc()->setParseState(PS_SequenceSqSeen);
2348 simple_type_spec
2350 idlc()->setParseState(PS_SequenceTypeSeen);
2354 idlc()->setParseState(PS_SequenceQsSeen);
2356 * Remove sequence marker from scopes stack
2358 if (idlc()->scopes()->top() == nullptr)
2359 idlc()->scopes()->pop();
2361 * Create a node representing a sequence
2363 AstScope* pScope = idlc()->scopes()->bottom();
2364 AstDeclaration* pDecl = nullptr;
2365 AstDeclaration* pSeq = nullptr;
2367 if ( $5 )
2369 AstType const *pType = static_cast<AstType const *>($5);
2370 if ( pType )
2372 pSeq = new AstSequence(pType, pScope);
2374 * Add this AstSequence to the types defined in the global scope
2376 pDecl = pScope->addDeclaration(pSeq);
2377 if ( pSeq != pDecl )
2379 // if sequence type already defined then use it
2380 delete pSeq;
2381 pSeq = pDecl;
2385 $$ = pSeq;
2387 | error '>'
2389 yyerror("sequence declaration");
2390 yyerrok;
2391 $$ = nullptr;
2395 struct_type :
2396 structure_header
2398 idlc()->setParseState(PS_StructHeaderSeen);
2400 AstScope* pScope = idlc()->scopes()->topNonNull();
2401 AstStruct* pStruct = nullptr;
2403 if ( pScope )
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);
2411 * Push the scope of the struct on the scopes stack
2413 idlc()->scopes()->push(pStruct);
2414 delete $1;
2418 idlc()->setParseState(PS_StructSqSeen);
2420 at_least_one_member
2422 idlc()->setParseState(PS_StructBodySeen);
2426 idlc()->setParseState(PS_StructQsSeen);
2427 /* this exception is finished, pop its scope from the stack */
2428 idlc()->scopes()->pop();
2432 structure_header :
2433 IDL_STRUCT
2435 idlc()->setParseState(PS_StructSeen);
2437 identifier
2439 idlc()->setParseState(PS_StructIDSeen);
2440 checkIdentifier($3);
2442 opt_type_params
2443 inheritance_spec
2445 idlc()->setParseState(PS_InheritSpecSeen);
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
2451 // struct Base { ... };
2452 // template< typename typeparam_T > struct Derived: public Base {
2453 // int member1 CPPU_GCC3_ALIGN(Base);
2454 // ... };
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);
2463 $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5);
2464 delete $5;
2465 delete $6;
2469 opt_type_params:
2470 '<' type_params '>' { $$ = $2; }
2471 | /* empty */ { $$ = nullptr; }
2474 type_params:
2475 identifier
2477 $$ = new std::vector< OString >;
2478 $$->push_back(*$1);
2479 delete $1;
2481 | type_params ',' identifier
2483 if (std::find($1->begin(), $1->end(), *$3) != $1->end()) {
2484 ErrorHandler::error0(ErrorCode::IdenticalTypeParameters);
2486 $1->push_back(*$3);
2487 delete $3;
2488 $$ = $1;
2492 at_least_one_member : member members ;
2494 members :
2495 members member
2496 | /* EMPTY */
2499 member :
2500 type_or_parameter
2502 idlc()->setParseState(PS_MemberTypeSeen);
2504 at_least_one_declarator
2506 idlc()->setParseState(PS_MemberDeclsSeen);
2510 idlc()->setParseState(PS_MemberDeclsCompleted);
2512 AstScope* pScope = idlc()->scopes()->topNonNull();
2513 AstMember* pMember = nullptr;
2514 FeDeclList* pList = $3;
2515 FeDeclarator* pDecl = nullptr;
2516 AstType const * pType = nullptr;
2518 // !!! check recursive type
2520 if ( pScope && pList && $1 )
2522 FeDeclList::iterator iter = pList->begin();
2523 FeDeclList::iterator end = pList->end();
2524 while (iter != end)
2526 pDecl = (*iter);
2527 if ( !pDecl )
2529 ++iter;
2530 continue;
2533 pType = FeDeclarator::compose($1);
2535 if ( !pType )
2537 ++iter;
2538 continue;
2541 pMember = new AstMember(pType, pDecl->getName(), pScope);
2543 if ( !pDecl->checkType($1) )
2545 // WARNING
2548 pScope->addDeclaration(pMember);
2549 ++iter;
2550 delete pDecl;
2552 delete pList;
2555 | error ';'
2557 yyerror("member definition");
2558 yyerrok;
2562 type_or_parameter:
2563 fundamental_type
2564 | scoped_name opt_type_args
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);
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;
2582 $$ = decl;
2586 enum_type :
2587 IDL_ENUM
2589 idlc()->setParseState(PS_EnumSeen);
2591 identifier
2593 idlc()->setParseState(PS_EnumIDSeen);
2594 checkIdentifier($3);
2596 AstScope* pScope = idlc()->scopes()->topNonNull();
2597 AstEnum* pEnum = nullptr;
2600 * Create a node representing an enum and add it to its
2601 * enclosing scope
2603 if (pScope != nullptr)
2605 pEnum = new AstEnum(*$3, pScope);
2607 * Add it to its defining scope
2609 pScope->addDeclaration(pEnum);
2611 delete $3;
2613 * Push the enum scope on the scopes stack
2615 idlc()->scopes()->push(pEnum);
2620 idlc()->setParseState(PS_EnumSqSeen);
2622 at_least_one_enumerator
2624 idlc()->setParseState(PS_EnumBodySeen);
2628 idlc()->setParseState(PS_EnumQsSeen);
2630 * Done with this enum. Pop its scope from the scopes stack
2632 if (idlc()->scopes()->top() == nullptr)
2633 $$ = nullptr;
2634 else
2636 $$ = static_cast<AstEnum*>(idlc()->scopes()->topNonNull());
2637 idlc()->scopes()->pop();
2642 at_least_one_enumerator : enumerator enumerators ;
2644 enumerators :
2645 enumerators
2648 idlc()->setParseState(PS_EnumCommaSeen);
2650 enumerator
2651 | /* EMPTY */
2652 | error ','
2654 yyerror("enumerator definition");
2655 yyerrok;
2659 enumerator :
2660 identifier
2662 checkIdentifier($1);
2664 AstScope* pScope = idlc()->scopes()->topNonNull();
2665 AstEnum* pEnum = nullptr;
2666 AstConstant* pEnumVal = nullptr;
2668 if ( pScope && pScope->getScopeNodeType() == NT_enum)
2670 pEnum = static_cast<AstEnum*>(pScope);
2671 if (pEnum && $1)
2673 AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount());
2674 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2675 pExpr, *$1, pScope);
2677 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2678 ErrorHandler::error1(ErrorCode::Eval, pEnum);
2680 pScope->addDeclaration(pEnumVal);
2682 delete $1;
2684 | identifier
2686 const_expr
2688 checkIdentifier($1);
2690 AstScope* pScope = idlc()->scopes()->topNonNull();
2691 AstEnum* pEnum = nullptr;
2692 AstConstant* pEnumVal = nullptr;
2694 if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum)
2696 $3->evaluate();
2697 if ( $3->coerce(ET_long) )
2699 pEnum = static_cast<AstEnum*>(pScope);
2700 if (pEnum)
2702 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2703 $3, *$1, pScope);
2705 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2706 ErrorHandler::error1(ErrorCode::Eval, pEnum);
2708 pScope->addDeclaration(pEnumVal);
2709 } else
2711 ErrorHandler::coercionError($3, ET_long);
2712 delete $3;
2715 delete $1;
2719 identifier:
2720 IDL_IDENTIFIER
2721 | IDL_GET { $$ = new OString("get"); }
2722 | IDL_SET { $$ = new OString("set"); }
2723 | IDL_PUBLISHED { $$ = new OString("published"); }
2729 * Report an error situation discovered in a production
2731 void yyerror(char const *errmsg)
2733 ErrorHandler::syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg);
2734 idlc()->setParseState(PS_NoState);
2737 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */