bump product version to 6.4.0.3
[LibreOffice.git] / idlc / source / parser.y
blob9c055d920a332aae359eee14f34361d2ef5042ba
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 sal_Char* strval; /* sal_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_MayBeAmbigiousSeen);
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 && (type = pScope->lookupByName(*$1)) ) {
1434 if (!ErrorHandler::checkPublished(type))
1436 type = nullptr;
1437 $$ = ET_none;
1439 else
1441 type = resolveTypedefs(type);
1442 if (type->getNodeType() == NT_predefined)
1444 $$ = static_cast< AstBaseType const * >(type)->
1445 getExprType();
1446 } else
1447 $$ = ET_any;
1449 } else
1450 $$ = ET_any;
1454 exception_header :
1455 IDL_EXCEPTION
1457 idlc()->setParseState(PS_ExceptSeen);
1459 identifier
1461 idlc()->setParseState(PS_ExceptIDSeen);
1462 checkIdentifier($3);
1464 inheritance_spec
1466 idlc()->setParseState(PS_InheritSpecSeen);
1468 $$ = new FeInheritanceHeader(NT_exception, $3, $5, nullptr);
1469 delete $5;
1473 exception_dcl :
1474 exception_header
1476 idlc()->setParseState(PS_ExceptHeaderSeen);
1478 AstScope* pScope = idlc()->scopes()->topNonNull();
1479 AstException* pExcept = nullptr;
1481 if ( pScope )
1483 AstException* pBase = static_cast< AstException* >(
1484 $1->getInherits());
1485 pExcept = new AstException(*$1->getName(), pBase, pScope);
1486 pScope->addDeclaration(pExcept);
1489 * Push the scope of the exception on the scopes stack
1491 idlc()->scopes()->push(pExcept);
1492 delete $1;
1496 idlc()->setParseState(PS_ExceptSqSeen);
1498 members
1500 idlc()->setParseState(PS_ExceptBodySeen);
1504 idlc()->setParseState(PS_ExceptQsSeen);
1505 /* this exception is finished, pop its scope from the stack */
1506 idlc()->scopes()->pop();
1510 property :
1511 flag_header
1512 simple_type_spec
1514 idlc()->setParseState(PS_PropertyTypeSeen);
1516 at_least_one_declarator
1518 idlc()->setParseState(PS_PropertyCompleted);
1520 AstScope* pScope = idlc()->scopes()->topNonNull();
1521 AstAttribute* pAttr = nullptr;
1522 FeDeclList* pList = $4;
1523 FeDeclarator* pDecl = nullptr;
1524 AstType const * pType = nullptr;
1526 if ( pScope->getScopeNodeType() == NT_singleton )
1528 ErrorHandler::error0(ErrorCode::IllegalAdd);
1529 } else
1531 if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE )
1532 ErrorHandler::flagError(ErrorCode::WrongAttributeKeyword, AF_ATTRIBUTE);
1534 if ( ($1 & AF_PROPERTY) != AF_PROPERTY )
1535 ErrorHandler::flagError(ErrorCode::MissingAttributeKeyword, AF_PROPERTY);
1538 * Create nodes representing attributes and add them to the
1539 * enclosing scope
1541 if ( pScope && $2 && pList )
1543 FeDeclList::iterator iter = pList->begin();
1544 FeDeclList::iterator end = pList->end();
1546 while (iter != end)
1548 pDecl = (*iter);
1549 if ( !pDecl )
1551 ++iter;
1552 continue;
1555 pType = FeDeclarator::compose($2);
1557 if ( !pType )
1559 ++iter;
1560 continue;
1563 pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope);
1565 pScope->addDeclaration(pAttr);
1566 ++iter;
1567 delete pDecl;
1572 if ( pList )
1573 delete pList;
1575 | error ';'
1577 yyerror("property");
1578 yyerrok;
1582 service_exports :
1583 service_exports service_export
1584 | /* EMPTY */
1587 service_export :
1588 service_interface_header
1589 at_least_one_scoped_name
1592 idlc()->setParseState(PS_ServiceMemberSeen);
1594 AstScope* pScope = idlc()->scopes()->topNonNull();
1595 AstDeclaration* pDecl = nullptr;
1596 AstInterfaceMember* pIMember = nullptr;
1598 if ( pScope->getScopeNodeType() == NT_singleton )
1600 ErrorHandler::error0(ErrorCode::IllegalAdd);
1601 } else
1604 * Create a node representing a class member.
1605 * Store it in the enclosing scope
1607 if ( pScope && $2 )
1609 for (auto const& elem : *($2))
1611 pDecl = pScope->lookupByName(elem);
1612 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1614 /* we relax the strict published check and allow to add new
1615 * interfaces if they are optional
1617 bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL);
1618 if ( ErrorHandler::checkPublished(pDecl, bOptional) )
1620 pIMember = new AstInterfaceMember(
1621 $1, static_cast<AstInterface*>(pDecl), elem, pScope);
1622 pScope->addDeclaration(pIMember);
1624 } else
1626 ErrorHandler::lookupError(ErrorCode::InterfaceMemberLookup, elem, scopeAsDecl(pScope));
1631 delete $2;
1633 | service_service_header
1634 at_least_one_scoped_name
1637 idlc()->setParseState(PS_ServiceMemberSeen);
1639 AstScope* pScope = idlc()->scopes()->topNonNull();
1640 AstDeclaration* pDecl = nullptr;
1641 AstServiceMember* pSMember = nullptr;
1644 * Create a node representing a class member.
1645 * Store it in the enclosing scope
1647 if ( pScope && $2 )
1649 for (auto const& elem : *($2))
1651 pDecl = pScope->lookupByName(elem);
1652 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1654 if ( static_cast< AstService * >(pDecl)->isSingleInterfaceBasedService() || (pScope->getScopeNodeType() == NT_singleton && pScope->nMembers() > 0) )
1655 ErrorHandler::error0(ErrorCode::IllegalAdd);
1656 else if ( ErrorHandler::checkPublished(pDecl) )
1658 pSMember = new AstServiceMember(
1659 $1, static_cast<AstService*>(pDecl), elem, pScope);
1660 pScope->addDeclaration(pSMember);
1662 } else
1664 ErrorHandler::lookupError(ErrorCode::ServiceMemberLookup, elem, scopeAsDecl(pScope));
1668 delete $2;
1670 | IDL_OBSERVES
1671 at_least_one_scoped_name
1674 idlc()->setParseState(PS_ServiceMemberSeen);
1676 AstScope* pScope = idlc()->scopes()->topNonNull();
1677 AstDeclaration* pDecl = nullptr;
1678 AstObserves* pObserves = nullptr;
1680 if ( pScope->getScopeNodeType() == NT_singleton )
1682 ErrorHandler::error0(ErrorCode::IllegalAdd);
1683 } else
1686 * Create a node representing a class member.
1687 * Store it in the enclosing scope
1689 if ( pScope && $2 )
1691 for (auto const& elem : *($2))
1693 pDecl = pScope->lookupByName(elem);
1694 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1696 pObserves = new AstObserves(static_cast<AstInterface*>(pDecl), elem, pScope);
1697 pScope->addDeclaration(pObserves);
1698 } else
1700 ErrorHandler::lookupError(ErrorCode::InterfaceMemberLookup, elem, scopeAsDecl(pScope));
1705 delete $2;
1707 | IDL_NEEDS
1708 at_least_one_scoped_name
1711 idlc()->setParseState(PS_ServiceMemberSeen);
1713 AstScope* pScope = idlc()->scopes()->topNonNull();
1714 AstDeclaration* pDecl = nullptr;
1715 AstNeeds* pNeeds = nullptr;
1717 if ( pScope->getScopeNodeType() == NT_singleton )
1719 ErrorHandler::error0(ErrorCode::IllegalAdd);
1720 } else
1723 * Create a node representing a class member.
1724 * Store it in the enclosing scope
1726 if ( pScope && $2 )
1728 for (auto const& elem : *($2))
1730 pDecl = pScope->lookupByName(elem);
1731 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1733 pNeeds = new AstNeeds(static_cast<AstService*>(pDecl), elem, pScope);
1734 pScope->addDeclaration(pNeeds);
1735 } else
1737 ErrorHandler::lookupError(ErrorCode::ServiceMemberLookup, elem, scopeAsDecl(pScope));
1742 delete $2;
1744 | property
1747 idlc()->setParseState(PS_PropertyDeclSeen);
1751 service_interface_header :
1752 IDL_INTERFACE
1754 idlc()->setParseState(PS_ServiceIFHeadSeen);
1755 $$ = AF_INVALID;
1757 | flag_header
1758 IDL_INTERFACE
1760 idlc()->setParseState(PS_ServiceIFHeadSeen);
1761 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1762 ErrorHandler::flagError(ErrorCode::ExpectedOptional, $1);
1763 $$ = $1;
1767 service_service_header :
1768 IDL_SERVICE
1770 idlc()->setParseState(PS_ServiceSHeadSeen);
1771 $$ = AF_INVALID;
1773 | flag_header
1774 IDL_SERVICE
1776 idlc()->setParseState(PS_ServiceSHeadSeen);
1777 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1778 ErrorHandler::flagError(ErrorCode::ExpectedOptional, $1);
1779 $$ = $1;
1783 service_dcl :
1784 IDL_SERVICE
1786 idlc()->setParseState(PS_ServiceSeen);
1788 identifier
1790 idlc()->setParseState(PS_ServiceIDSeen);
1791 checkIdentifier($3);
1793 AstScope* pScope = idlc()->scopes()->topNonNull();
1794 AstService* pService = nullptr;
1797 * Make a new service and add it to the enclosing scope
1799 if (pScope != nullptr)
1801 pService = new AstService(*$3, pScope);
1802 pScope->addDeclaration(pService);
1804 delete $3;
1806 * Push it on the stack
1808 idlc()->scopes()->push(pService);
1810 service_dfn
1812 /* this service is finished, pop its scope from the stack */
1813 idlc()->scopes()->pop();
1817 service_dfn:
1818 service_interface_dfn
1819 | service_obsolete_dfn
1822 service_interface_dfn:
1823 ':' scoped_name
1825 AstScope * scope = idlc()->scopes()->nextToTop();
1826 // skip the scope pushed by service_dcl
1827 AstDeclaration * decl = scope->lookupByName(*$2);
1828 if (decl != nullptr
1829 && resolveTypedefs(decl)->getNodeType() == NT_interface)
1831 if (ErrorHandler::checkPublished(decl)) {
1832 idlc()->scopes()->top()->addDeclaration(decl);
1834 } else {
1835 ErrorHandler::lookupError(
1836 ErrorCode::InterfaceMemberLookup, *$2, scopeAsDecl(scope));
1838 delete $2;
1840 opt_service_body
1842 AstService * s = static_cast< AstService * >(idlc()->scopes()->top());
1843 if (s != nullptr) {
1844 s->setSingleInterfaceBasedService();
1845 s->setDefaultConstructor(!$4);
1850 opt_service_body:
1851 service_body { $$ = true; }
1852 | /* empty */ { $$ = false; }
1855 service_body:
1857 constructors
1861 constructors:
1862 constructors constructor
1863 | /* empty */
1866 constructor:
1867 identifier
1869 checkIdentifier($1);
1870 AstScope * scope = idlc()->scopes()->top();
1871 AstOperation * ctor = new AstOperation(nullptr, *$1, scope);
1872 delete $1;
1873 scope->addDeclaration(ctor);
1874 idlc()->scopes()->push(ctor);
1877 parameters
1879 opt_raises
1881 static_cast< AstOperation * >(idlc()->scopes()->top())->setExceptions(
1882 $6);
1883 delete $6;
1884 idlc()->scopes()->pop();
1885 if (static_cast< AstService * >(idlc()->scopes()->top())->
1886 checkLastConstructor())
1888 ErrorHandler::error0(ErrorCode::SimilarConstructors);
1894 singleton_dcl :
1895 IDL_SINGLETON
1897 idlc()->setParseState(PS_SingletonSeen);
1899 identifier
1901 idlc()->setParseState(PS_SingletonIDSeen);
1902 checkIdentifier($3);
1904 AstScope* pScope = idlc()->scopes()->topNonNull();
1905 AstService* pService = nullptr;
1908 * Make a new service and add it to the enclosing scope
1910 if (pScope != nullptr)
1912 pService = new AstService(NT_singleton, *$3, pScope);
1913 pScope->addDeclaration(pService);
1915 delete $3;
1917 * Push it on the stack
1919 idlc()->scopes()->push(pService);
1921 singleton_dfn
1923 /* this singleton is finished, pop its scope from the stack */
1924 idlc()->scopes()->pop();
1928 singleton_dfn:
1929 singleton_interface_dfn
1930 | service_obsolete_dfn
1933 singleton_interface_dfn:
1934 ':' scoped_name
1936 AstScope * scope = idlc()->scopes()->nextToTop();
1937 // skip the scope (needlessly) pushed by singleton_dcl
1938 AstDeclaration * decl = scope->lookupByName(*$2);
1939 if (decl != nullptr
1940 && resolveTypedefs(decl)->getNodeType() == NT_interface)
1942 if (ErrorHandler::checkPublished(decl)) {
1943 idlc()->scopes()->top()->addDeclaration(decl);
1945 } else {
1946 ErrorHandler::lookupError(
1947 ErrorCode::InterfaceMemberLookup, *$2, scopeAsDecl(scope));
1949 delete $2;
1953 service_obsolete_dfn:
1956 idlc()->setParseState(
1957 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1958 ? PS_ServiceSqSeen : PS_SingletonSqSeen);
1960 service_exports
1962 idlc()->setParseState(
1963 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1964 ? PS_ServiceBodySeen : PS_SingletonBodySeen);
1968 idlc()->setParseState(
1969 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1970 ? PS_ServiceQsSeen : PS_SingletonQsSeen);
1974 type_dcl :
1975 IDL_TYPEDEF
1977 idlc()->setParseState(PS_TypedefSeen);
1979 type_declarator {}
1980 | struct_type {}
1981 | enum_type {}
1984 type_declarator :
1985 type_spec
1987 idlc()->setParseState(PS_TypeSpecSeen);
1988 if ($1 != nullptr && $1->getNodeType() == NT_instantiated_struct) {
1989 ErrorHandler::error0(ErrorCode::InstantiatedStructTypeTypedef);
1992 at_least_one_declarator
1994 idlc()->setParseState(PS_DeclaratorsSeen);
1996 AstScope* pScope = idlc()->scopes()->topNonNull();
1997 AstTypeDef* pTypeDef = nullptr;
1998 FeDeclList* pList = $3;
1999 FeDeclarator* pDecl = nullptr;
2000 AstType const * pType = nullptr;
2003 * Create nodes representing typedefs and add them to the
2004 * enclosing scope
2006 if ( pScope && $1 && pList )
2008 FeDeclList::iterator iter = pList->begin();
2009 FeDeclList::iterator end = pList->end();
2011 while (iter != end)
2013 pDecl = (*iter);
2014 if ( !pDecl )
2016 ++iter;
2017 continue;
2020 pType = FeDeclarator::compose($1);
2022 if ( !pType )
2024 ++iter;
2025 continue;
2028 pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope);
2030 pScope->addDeclaration(pTypeDef);
2031 ++iter;
2032 delete pDecl;
2034 delete pList;
2039 at_least_one_declarator :
2040 declarator declarators
2042 if ( $2 )
2044 $2->push_back($1);
2045 $$ = $2;
2046 } else
2048 FeDeclList* pList = new FeDeclList;
2049 pList->push_back($1);
2050 $$ = pList;
2055 declarators :
2056 declarators
2059 idlc()->setParseState(PS_DeclsCommaSeen);
2061 declarator
2063 idlc()->setParseState(PS_DeclsDeclSeen);
2064 if ( $1 )
2066 $1->push_back($4);
2067 $$ = $1;
2068 } else
2070 FeDeclList* pList = new FeDeclList;
2071 pList->push_back($4);
2072 $$ = pList;
2075 | /* EMPTY */
2077 $$ = nullptr;
2081 declarator :
2082 identifier
2084 // For historic reasons, the struct com.sun.star.uno.Uik contains
2085 // members with illegal names (of the form "m_DataN"); avoid useless
2086 // warnings about them:
2087 AstScope * scope = idlc()->scopes()->top();
2088 if (scope == nullptr || scope->getScopeNodeType() != NT_struct
2089 || (scopeAsDecl(scope)->getScopedName()
2090 != "com::sun::star::uno::Uik"))
2092 checkIdentifier($1);
2095 $$ = new FeDeclarator(*$1);
2096 delete $1;
2100 at_least_one_scoped_name :
2101 scoped_name scoped_names
2103 if ($2)
2105 $2->push_front(*$1);
2106 $$ = $2;
2107 } else
2109 std::list< OString >* pScopedNames = new std::list< OString >;
2110 // coverity[copy_paste_error : FALSE] - this is not a cut and paste
2111 pScopedNames->push_back(*$1);
2112 $$ = pScopedNames;
2114 delete $1;
2118 scoped_names :
2119 scoped_names
2122 idlc()->setParseState(PS_SNListCommaSeen);
2124 scoped_name
2126 idlc()->setParseState(PS_ScopedNameSeen);
2127 if ($1)
2129 $1->push_back(*$4);
2130 $$ = $1;
2131 } else
2133 std::list< OString >* pNames = new std::list< OString >;
2134 pNames->push_back(*$4);
2135 $$ = pNames;
2137 delete $4;
2139 | /* EMPTY */
2141 $$ = nullptr;
2145 scoped_name :
2146 identifier
2148 idlc()->setParseState(PS_SN_IDSeen);
2149 checkIdentifier($1);
2150 $$ = $1;
2152 | IDL_SCOPESEPARATOR
2154 idlc()->setParseState(PS_ScopeDelimSeen);
2156 identifier
2158 checkIdentifier($3);
2159 OString* pName = new OString("::");
2160 *pName += *$3;
2161 delete $3;
2162 $$ = pName;
2164 | scoped_name
2165 IDL_SCOPESEPARATOR
2168 identifier
2170 checkIdentifier($4);
2171 *$1 += OString("::");
2172 *$1 += *$4;
2173 delete $4;
2174 $$ = $1;
2178 type_spec :
2179 simple_type_spec
2180 | constructed_type_spec
2183 simple_type_spec :
2184 fundamental_type
2185 | scoped_name opt_type_args
2187 $$ = createNamedType($1, $2);
2191 fundamental_type:
2192 base_type_spec
2194 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2196 | sequence_type_spec
2199 opt_type_args:
2200 '<' type_args '>' { $$ = $2; }
2201 | /* empty */ { $$ = nullptr; }
2204 type_args:
2205 type_arg
2207 $$ = new DeclList;
2208 $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast
2210 | type_args ',' type_arg
2212 $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast
2213 $$ = $1;
2217 type_arg:
2218 simple_type_spec
2220 if ($1 != nullptr && static_cast< AstType const * >($1)->isUnsigned()) {
2221 ErrorHandler::error0(ErrorCode::UnsignedTypeArgument);
2223 $$ = $1;
2227 base_type_spec :
2228 integer_type
2229 | floating_pt_type
2230 | char_type
2231 | boolean_type
2232 | byte_type
2233 | any_type
2234 | type_type
2235 | string_type
2238 integer_type :
2239 signed_int
2240 | unsigned_int
2243 signed_int :
2244 IDL_LONG
2246 $$ = ET_long;
2248 | IDL_HYPER
2250 $$ = ET_hyper;
2252 | IDL_SHORT
2254 $$ = ET_short;
2258 unsigned_int :
2259 IDL_UNSIGNED IDL_LONG
2261 $$ = ET_ulong;
2263 | IDL_UNSIGNED IDL_HYPER
2265 $$ = ET_uhyper;
2267 | IDL_UNSIGNED IDL_SHORT
2269 $$ = ET_ushort;
2273 floating_pt_type :
2274 IDL_DOUBLE
2276 $$ = ET_double;
2278 | IDL_FLOAT
2280 $$ = ET_float;
2284 char_type :
2285 IDL_CHAR
2287 $$ = ET_char;
2291 byte_type :
2292 IDL_BYTE
2294 $$ = ET_byte;
2298 boolean_type :
2299 IDL_BOOLEAN
2301 $$ = ET_boolean;
2305 any_type :
2306 IDL_ANY
2308 $$ = ET_any;
2312 type_type :
2313 IDL_TYPE
2315 $$ = ET_type;
2319 string_type :
2320 IDL_STRING
2322 $$ = ET_string;
2326 constructed_type_spec :
2327 struct_type
2328 | enum_type
2331 sequence_type_spec :
2332 IDL_SEQUENCE
2334 idlc()->setParseState(PS_SequenceSeen);
2336 * Push a sequence marker on scopes stack
2338 idlc()->scopes()->push(nullptr);
2342 idlc()->setParseState(PS_SequenceSqSeen);
2344 simple_type_spec
2346 idlc()->setParseState(PS_SequenceTypeSeen);
2350 idlc()->setParseState(PS_SequenceQsSeen);
2352 * Remove sequence marker from scopes stack
2354 if (idlc()->scopes()->top() == nullptr)
2355 idlc()->scopes()->pop();
2357 * Create a node representing a sequence
2359 AstScope* pScope = idlc()->scopes()->bottom();
2360 AstDeclaration* pDecl = nullptr;
2361 AstDeclaration* pSeq = nullptr;
2363 if ( $5 )
2365 AstType const *pType = static_cast<AstType const *>($5);
2366 if ( pType )
2368 pSeq = new AstSequence(pType, pScope);
2370 * Add this AstSequence to the types defined in the global scope
2372 pDecl = pScope->addDeclaration(pSeq);
2373 if ( pSeq != pDecl )
2375 // if sequence type already defined then use it
2376 delete pSeq;
2377 pSeq = pDecl;
2381 $$ = pSeq;
2383 | error '>'
2385 yyerror("sequence declaration");
2386 yyerrok;
2387 $$ = nullptr;
2391 struct_type :
2392 structure_header
2394 idlc()->setParseState(PS_StructHeaderSeen);
2396 AstScope* pScope = idlc()->scopes()->topNonNull();
2397 AstStruct* pStruct = nullptr;
2399 if ( pScope )
2401 AstStruct const* pBase= static_cast< AstStruct const* >(resolveTypedefs($1->getInherits()));
2402 pStruct = new AstStruct(
2403 *$1->getName(), $1->getTypeParameters(), pBase, pScope);
2404 pScope->addDeclaration(pStruct);
2407 * Push the scope of the struct on the scopes stack
2409 idlc()->scopes()->push(pStruct);
2410 delete $1;
2414 idlc()->setParseState(PS_StructSqSeen);
2416 at_least_one_member
2418 idlc()->setParseState(PS_StructBodySeen);
2422 idlc()->setParseState(PS_StructQsSeen);
2423 /* this exception is finished, pop its scope from the stack */
2424 idlc()->scopes()->pop();
2428 structure_header :
2429 IDL_STRUCT
2431 idlc()->setParseState(PS_StructSeen);
2433 identifier
2435 idlc()->setParseState(PS_StructIDSeen);
2436 checkIdentifier($3);
2438 opt_type_params
2439 inheritance_spec
2441 idlc()->setParseState(PS_InheritSpecSeen);
2443 // Polymorphic struct type templates with base types would cause various
2444 // problems in language bindings, so forbid them here. For example,
2445 // GCC prior to version 3.4 fails with code like
2447 // struct Base { ... };
2448 // template< typename typeparam_T > struct Derived: public Base {
2449 // int member1 CPPU_GCC3_ALIGN(Base);
2450 // ... };
2452 // (Note that plain struct types with instantiated polymorphic struct
2453 // type bases, which might also cause problems in language bindings, are
2454 // already rejected on a syntactic level.)
2455 if ($5 != nullptr && $6 != nullptr) {
2456 ErrorHandler::error0(ErrorCode::StructTypeTemplateWithBase);
2459 $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5);
2460 delete $5;
2461 delete $6;
2465 opt_type_params:
2466 '<' type_params '>' { $$ = $2; }
2467 | /* empty */ { $$ = nullptr; }
2470 type_params:
2471 identifier
2473 $$ = new std::vector< OString >;
2474 $$->push_back(*$1);
2475 delete $1;
2477 | type_params ',' identifier
2479 if (std::find($1->begin(), $1->end(), *$3) != $1->end()) {
2480 ErrorHandler::error0(ErrorCode::IdenticalTypeParameters);
2482 $1->push_back(*$3);
2483 delete $3;
2484 $$ = $1;
2488 at_least_one_member : member members ;
2490 members :
2491 members member
2492 | /* EMPTY */
2495 member :
2496 type_or_parameter
2498 idlc()->setParseState(PS_MemberTypeSeen);
2500 at_least_one_declarator
2502 idlc()->setParseState(PS_MemberDeclsSeen);
2506 idlc()->setParseState(PS_MemberDeclsCompleted);
2508 AstScope* pScope = idlc()->scopes()->topNonNull();
2509 AstMember* pMember = nullptr;
2510 FeDeclList* pList = $3;
2511 FeDeclarator* pDecl = nullptr;
2512 AstType const * pType = nullptr;
2514 // !!! check recursive type
2516 if ( pScope && pList && $1 )
2518 FeDeclList::iterator iter = pList->begin();
2519 FeDeclList::iterator end = pList->end();
2520 while (iter != end)
2522 pDecl = (*iter);
2523 if ( !pDecl )
2525 ++iter;
2526 continue;
2529 pType = FeDeclarator::compose($1);
2531 if ( !pType )
2533 ++iter;
2534 continue;
2537 pMember = new AstMember(pType, pDecl->getName(), pScope);
2539 if ( !pDecl->checkType($1) )
2541 // WARNING
2544 pScope->addDeclaration(pMember);
2545 ++iter;
2546 delete pDecl;
2548 delete pList;
2551 | error ';'
2553 yyerror("member definition");
2554 yyerrok;
2558 type_or_parameter:
2559 fundamental_type
2560 | scoped_name opt_type_args
2562 AstDeclaration const * decl = nullptr;
2563 AstStruct * scope = static_cast< AstStruct * >(idlc()->scopes()->top());
2564 if (scope != nullptr && $2 == nullptr) {
2565 decl = scope->findTypeParameter(*$1);
2567 if (decl != nullptr) {
2568 delete $1;
2569 delete $2;
2570 } else {
2571 decl = createNamedType($1, $2);
2572 if (scope != nullptr && includes(decl, scopeAsDecl(scope))) {
2573 ErrorHandler::error1(
2574 ErrorCode::RecursiveType, scopeAsDecl(scope));
2575 decl = nullptr;
2578 $$ = decl;
2582 enum_type :
2583 IDL_ENUM
2585 idlc()->setParseState(PS_EnumSeen);
2587 identifier
2589 idlc()->setParseState(PS_EnumIDSeen);
2590 checkIdentifier($3);
2592 AstScope* pScope = idlc()->scopes()->topNonNull();
2593 AstEnum* pEnum = nullptr;
2596 * Create a node representing an enum and add it to its
2597 * enclosing scope
2599 if (pScope != nullptr)
2601 pEnum = new AstEnum(*$3, pScope);
2603 * Add it to its defining scope
2605 pScope->addDeclaration(pEnum);
2607 delete $3;
2609 * Push the enum scope on the scopes stack
2611 idlc()->scopes()->push(pEnum);
2616 idlc()->setParseState(PS_EnumSqSeen);
2618 at_least_one_enumerator
2620 idlc()->setParseState(PS_EnumBodySeen);
2624 idlc()->setParseState(PS_EnumQsSeen);
2626 * Done with this enum. Pop its scope from the scopes stack
2628 if (idlc()->scopes()->top() == nullptr)
2629 $$ = nullptr;
2630 else
2632 $$ = static_cast<AstEnum*>(idlc()->scopes()->topNonNull());
2633 idlc()->scopes()->pop();
2638 at_least_one_enumerator : enumerator enumerators ;
2640 enumerators :
2641 enumerators
2644 idlc()->setParseState(PS_EnumCommaSeen);
2646 enumerator
2647 | /* EMPTY */
2648 | error ','
2650 yyerror("enumerator definition");
2651 yyerrok;
2655 enumerator :
2656 identifier
2658 checkIdentifier($1);
2660 AstScope* pScope = idlc()->scopes()->topNonNull();
2661 AstEnum* pEnum = nullptr;
2662 AstConstant* pEnumVal = nullptr;
2664 if ( pScope && pScope->getScopeNodeType() == NT_enum)
2666 pEnum = static_cast<AstEnum*>(pScope);
2667 if (pEnum && $1)
2669 AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount());
2670 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2671 pExpr, *$1, pScope);
2673 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2674 ErrorHandler::error1(ErrorCode::Eval, pEnum);
2676 pScope->addDeclaration(pEnumVal);
2678 delete $1;
2680 | identifier
2682 const_expr
2684 checkIdentifier($1);
2686 AstScope* pScope = idlc()->scopes()->topNonNull();
2687 AstEnum* pEnum = nullptr;
2688 AstConstant* pEnumVal = nullptr;
2690 if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum)
2692 $3->evaluate();
2693 if ( $3->coerce(ET_long) )
2695 pEnum = static_cast<AstEnum*>(pScope);
2696 if (pEnum)
2698 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2699 $3, *$1, pScope);
2701 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2702 ErrorHandler::error1(ErrorCode::Eval, pEnum);
2704 pScope->addDeclaration(pEnumVal);
2705 } else
2707 ErrorHandler::coercionError($3, ET_long);
2708 delete $3;
2711 delete $1;
2715 identifier:
2716 IDL_IDENTIFIER
2717 | IDL_GET { $$ = new OString("get"); }
2718 | IDL_SET { $$ = new OString("set"); }
2719 | IDL_PUBLISHED { $$ = new OString("published"); }
2725 * Report an error situation discovered in a production
2727 void yyerror(char const *errmsg)
2729 ErrorHandler::syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg);
2730 idlc()->setParseState(PS_NoState);
2733 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */