bump product version to 6.3.0.0.beta1
[LibreOffice.git] / idlc / source / parser.y
bloba2b9c645656b4445892e33fb84c16600d964c939
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/strbuf.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 OStringBuffer msg(25 + id->getLength());
79 msg.append("mismatched identifier '");
80 msg.append(*id);
81 msg.append("'");
82 ErrorHandler::syntaxError(idlc()->getParseState(),
83 idlc()->getLineNumber(),
84 msg.getStr());
86 else
87 ErrorHandler::warning0(WarningCode::WrongNamingConvention, id->getStr());
91 static void reportDoubleMemberDeclarations(
92 AstInterface::DoubleMemberDeclarations const & doubleMembers)
94 for (auto const& doubleMember : doubleMembers)
96 ErrorHandler::error2(ErrorCode::DoubleMember, doubleMember.first, doubleMember.second);
100 static void addInheritedInterface(
101 AstInterface * ifc, OString const & name, bool optional,
102 OUString const & documentation)
104 AstDeclaration * decl = ifc->lookupByName(name);
105 AstDeclaration const * resolved = resolveTypedefs(decl);
106 if (resolved != nullptr && resolved->getNodeType() == NT_interface) {
107 if (ErrorHandler::checkPublished(decl)) {
108 if (!static_cast< AstInterface const * >(resolved)->isDefined()) {
109 ErrorHandler::inheritanceError(
110 NT_interface, &ifc->getScopedName(), decl);
111 } else {
112 AstInterface::DoubleDeclarations doubleDecls(
113 ifc->checkInheritedInterfaceClashes(
114 static_cast< AstInterface const * >(resolved),
115 optional));
116 if (doubleDecls.interfaces.empty()
117 && doubleDecls.members.empty())
119 ifc->addInheritedInterface(
120 static_cast< AstType * >(decl), optional,
121 documentation);
122 } else {
123 for (auto const& elem : doubleDecls.interfaces)
125 ErrorHandler::error1(
126 ErrorCode::DoubleInheritance, elem);
128 reportDoubleMemberDeclarations(doubleDecls.members);
132 } else {
133 ErrorHandler::lookupError(
134 ErrorCode::InterfaceMemberLookup, name, scopeAsDecl(ifc));
138 static AstDeclaration const * createNamedType(
139 OString const * scopedName, DeclList const * typeArgs)
141 AstDeclaration * decl = idlc()->scopes()->topNonNull()->lookupByName(
142 *scopedName);
143 AstDeclaration const * resolved = resolveTypedefs(decl);
144 if (decl == nullptr) {
145 ErrorHandler::lookupError(*scopedName);
146 } else if (!ErrorHandler::checkPublished(decl)) {
147 decl = nullptr;
148 } else if (resolved->getNodeType() == NT_struct) {
149 if (static_cast< AstStruct const * >(resolved)->getTypeParameterCount()
150 != (typeArgs == nullptr ? 0 : typeArgs->size()))
152 ErrorHandler::error0(ErrorCode::WrongNumberOfTypeArguments);
153 decl = nullptr;
154 } else if (typeArgs != nullptr) {
155 AstScope * global = idlc()->scopes()->bottom();
156 AstDeclaration * inst = new AstStructInstance(
157 static_cast< AstType * >(decl), typeArgs, global);
158 decl = global->addDeclaration(inst);
159 if (decl != inst) {
160 delete inst;
163 } else if (decl->isType()) {
164 if (typeArgs != nullptr) {
165 ErrorHandler::error0(ErrorCode::WrongNumberOfTypeArguments);
166 decl = nullptr;
168 } else {
169 ErrorHandler::noTypeError(decl);
170 decl = nullptr;
172 delete scopedName;
173 delete typeArgs;
174 return decl;
177 static bool includes(AstDeclaration const * type1, AstDeclaration const * type2) {
178 OSL_ASSERT(type2 != nullptr);
179 if (type1 != nullptr) {
180 if (type1->getNodeType() == NT_instantiated_struct) {
181 AstStructInstance const * inst
182 = static_cast< AstStructInstance const * >(type1);
183 if (inst->getTypeTemplate() == type2) {
184 return true;
186 for (DeclList::const_iterator i(inst->getTypeArgumentsBegin());
187 i != inst->getTypeArgumentsEnd(); ++i)
189 if (includes(*i, type2)) {
190 return true;
193 } else if (type1 == type2) {
194 return true;
197 return false;
200 // Suppress any warnings from generated code:
201 #if defined _MSC_VER
202 #pragma warning(disable: 4702) // unreachable code
203 #endif
206 * Declare the type of values in the grammar
208 %union {
209 ExprType etval; /* Expression type */
210 AstDeclaration* dclval; /* Declaration */
211 AstDeclaration const * cdclval;
212 DeclList * dclsval;
213 AstExpression* exval; /* expression value */
214 FeDeclarator* fdval; /* declarator value */
215 FeDeclList* dlval; /* declarator list value */
216 FeInheritanceHeader* ihval; /* inheritance header value */
217 OString* sval; /* OString value */
218 std::vector< OString > * svals;
219 sal_Char* strval; /* sal_Char* value */
220 bool bval; /* sal_Boolean* value */
221 sal_Int64 ival; /* sal_Int64 value */
222 sal_uInt64 uval; /* sal_uInt64 value */
223 sal_uInt32 ulval; /* sal_uInt32 value */
224 double dval; /* double value */
225 float fval; /* float value */
226 std::list< OString >* slval; /* StringList value */
227 AttributeExceptions::Part attexcpval;
228 AttributeExceptions attexcval;
232 * Token types: These are returned by the lexer
235 %token <sval> IDL_IDENTIFIER
236 %token IDL_ATTRIBUTE
237 %token IDL_BOUND
238 %token IDL_CONST
239 %token IDL_CONSTANTS
240 %token IDL_CONSTRAINED
241 %token IDL_ENUM
242 %token IDL_EXCEPTION
243 %token IDL_INTERFACE
244 %token IDL_MAYBEAMBIGUOUS
245 %token IDL_MAYBEDEFAULT
246 %token IDL_MAYBEVOID
247 %token IDL_MODULE
248 %token IDL_NEEDS
249 %token IDL_OBSERVES
250 %token IDL_OPTIONAL
251 %token IDL_PROPERTY
252 %token IDL_RAISES
253 %token IDL_READONLY
254 %token IDL_REMOVABLE
255 %token IDL_SERVICE
256 %token IDL_SEQUENCE
257 %token IDL_SINGLETON
258 %token IDL_STRUCT
259 %token IDL_TYPEDEF
260 %token IDL_TRANSIENT
262 %token IDL_ANY
263 %token IDL_CHAR
264 %token IDL_BOOLEAN
265 %token IDL_BYTE
266 %token IDL_DOUBLE
267 %token IDL_FLOAT
268 %token IDL_HYPER
269 %token IDL_LONG
270 %token IDL_SHORT
271 %token IDL_VOID
272 %token IDL_STRING
273 %token IDL_TYPE
274 %token IDL_UNSIGNED
276 %token IDL_TRUE
277 %token IDL_FALSE
279 %token IDL_IN
280 %token IDL_OUT
281 %token IDL_INOUT
283 %token IDL_GET
284 %token IDL_SET
286 %token IDL_PUBLISHED
288 %token IDL_ELLIPSIS
290 %token <strval> IDL_LEFTSHIFT
291 %token <strval> IDL_RIGHTSHIFT
292 %token <strval> IDL_SCOPESEPARATOR
294 %token <ival> IDL_INTEGER_LITERAL
295 %token <uval> IDL_INTEGER_ULITERAL
296 %token <dval> IDL_FLOATING_PT_LITERAL
299 * These are production names:
301 %type <dclval> type_dcl
302 %type <dclval> exception_name
303 %type <cdclval> constructed_type_spec enum_type op_type_spec
304 %type <cdclval> sequence_type_spec simple_type_spec struct_type
305 %type <cdclval> type_spec
306 %type <cdclval> fundamental_type type_arg type_or_parameter
307 %type <dclsval> opt_raises raises exception_list
308 %type <attexcpval> opt_attribute_get_raises attribute_get_raises
309 %type <attexcpval> opt_attribute_set_raises attribute_set_raises
310 %type <dclsval> opt_type_args type_args
312 %type <sval> identifier
313 %type <sval> interface_decl
314 %type <sval> scoped_name inheritance_spec
315 %type <slval> scoped_names at_least_one_scoped_name
317 %type <etval> const_type integer_type char_type boolean_type
318 %type <etval> floating_pt_type any_type signed_int string_type
319 %type <etval> unsigned_int base_type_spec byte_type type_type
321 %type <exval> expression const_expr or_expr xor_expr and_expr
322 %type <exval> add_expr mult_expr unary_expr primary_expr shift_expr
323 %type <exval> literal
325 %type <fdval> declarator
326 %type <dlval> declarators at_least_one_declarator
328 %type <ihval> exception_header structure_header interfaceheader
330 %type <ulval> flag_header opt_attrflags opt_attrflag
331 %type <ulval> direction service_interface_header service_service_header
333 %type <bval> optional_inherited_interface opt_rest opt_service_body
335 %type <attexcval> opt_attribute_block attribute_block_rest opt_attribute_raises
337 %type <svals> opt_type_params type_params
341 * Grammar start here
343 start : definitions;
345 definitions :
346 definition definitions
347 | /* EMPTY */
350 definition :
351 opt_published publishable_definition
352 | module_dcl
354 idlc()->setParseState(PS_ModuleDeclSeen);
358 idlc()->setParseState(PS_NoState);
360 | error ';'
362 yyerror("definitions");
363 yyerrok;
367 opt_published:
368 IDL_PUBLISHED { idlc()->setPublished(true); }
369 | /* empty */ { idlc()->setPublished(false); }
372 publishable_definition:
373 type_dcl
375 idlc()->setParseState(PS_TypeDeclSeen);
379 idlc()->setParseState(PS_NoState);
381 | exception_dcl
383 idlc()->setParseState(PS_ExceptionDeclSeen);
387 idlc()->setParseState(PS_NoState);
389 | interface
391 idlc()->setParseState(PS_InterfaceDeclSeen);
395 idlc()->setParseState(PS_NoState);
397 | service_dcl
399 idlc()->setParseState(PS_ServiceDeclSeen);
403 idlc()->setParseState(PS_NoState);
405 | singleton_dcl
407 idlc()->setParseState(PS_SingletonDeclSeen);
411 idlc()->setParseState(PS_NoState);
413 | constants_dcl
415 idlc()->setParseState(PS_ConstantsDeclSeen);
419 idlc()->setParseState(PS_NoState);
423 module_dcl :
424 IDL_MODULE
426 idlc()->setParseState(PS_ModuleSeen);
427 idlc()->setPublished(false);
429 identifier
431 idlc()->setParseState(PS_ModuleIDSeen);
432 checkIdentifier($3);
434 AstScope* pScope = idlc()->scopes()->topNonNull();
435 AstModule* pModule = nullptr;
437 if ( pScope )
439 pModule = new AstModule(*$3, pScope);
440 if( AstDeclaration* pExists = pScope->lookupForAdd(pModule) )
442 pExists->setInMainfile(idlc()->isInMainFile());
443 pExists->setFileName(pModule->getFileName());
444 if (pExists->isPredefined())
446 pExists->setPredefined(false);
447 if (pExists->getDocumentation().getLength() == 0 &&
448 pModule->getDocumentation().getLength() > 0)
450 pExists->setDocumentation(pModule->getDocumentation());
453 delete(pModule);
454 pModule = static_cast<AstModule*>(pExists);
455 } else
457 pScope->addDeclaration(pModule);
459 idlc()->scopes()->push(pModule);
461 delete $3;
465 idlc()->setParseState(PS_ModuleSqSeen);
467 definitions
469 idlc()->setParseState(PS_ModuleBodySeen);
473 idlc()->setParseState(PS_ModuleQsSeen);
475 * Finished with this module - pop it from the scope stack
477 idlc()->scopes()->pop();
481 interface :
482 interface_dcl
483 | forward_dcl
486 interface_decl :
487 IDL_INTERFACE
489 idlc()->setParseState(PS_InterfaceSeen);
491 identifier
493 idlc()->setParseState(PS_InterfaceIDSeen);
494 checkIdentifier($3);
495 $$ = $3;
499 forward_dcl :
500 interface_decl
502 idlc()->setParseState(PS_ForwardDeclSeen);
504 AstScope* pScope = idlc()->scopes()->topNonNull();
505 AstInterface* pForward = nullptr;
506 AstDeclaration* pDecl = nullptr;
509 * Make a new forward interface node and add it to its enclosing scope
511 if ( pScope && $1 )
513 pForward = new AstInterface(*$1, nullptr, pScope);
515 pDecl = pScope->lookupByName(pForward->getScopedName());
516 if ( pDecl )
518 if ( (pDecl != pForward) &&
519 (pDecl->getNodeType() == NT_interface) )
521 delete pForward;
522 } else
524 ErrorHandler::error2(ErrorCode::RedefScope, scopeAsDecl(pScope), pDecl);
526 } else
529 * Add the interface to its definition scope
531 pScope->addDeclaration(pForward);
534 delete $1;
538 interface_dcl :
539 interfaceheader
541 idlc()->setParseState(PS_InterfaceHeadSeen);
543 AstScope* pScope = idlc()->scopes()->topNonNull();
544 AstInterface* pInterface = nullptr;
545 AstInterface* pForward = nullptr;
548 * Make a new interface node and add it to its enclosing scope
550 if ( pScope && $1 )
552 pInterface = new AstInterface(
553 *$1->getName(),
554 static_cast< AstInterface const * >(resolveTypedefs($1->getInherits())), pScope);
555 if ( AstDeclaration* pDecl = pScope->lookupByName(pInterface->getScopedName()) )
558 * See if we're defining a forward declared interface.
560 if (pDecl->getNodeType() == NT_interface)
562 pForward = static_cast<AstInterface*>(pDecl);
563 if ( !pForward->isDefined() )
566 * Check if redefining in same scope
568 if ( pForward->getScope() != pScope )
570 if ( pForward->getScopedName() != pInterface->getScopedName() )
572 ErrorHandler::error3(ErrorCode::ScopeConflict,
573 pInterface, pForward, scopeAsDecl(pScope));
576 else if ( !pInterface->isPublished()
577 && pForward->isPublished() )
579 ErrorHandler::error0(ErrorCode::PublishedForward);
582 * All OK, set full definition
584 else
586 pForward->forwardDefined(*pInterface);
587 delete pInterface;
588 pInterface = pForward;
590 } else {
591 // special handling for XInterface because it is predefined
592 if ( pForward->isPredefined() &&
593 pForward->getScopedName() == "com::sun::star::uno::XInterface")
595 /* replace the predefined XInterface */
596 *pForward = *pInterface;
597 delete pInterface;
598 pInterface = pForward;
603 } else
606 * Add the interface to its definition scope
608 pScope->addDeclaration(pInterface);
612 * Push it on the scope stack
614 idlc()->scopes()->push(pInterface);
615 delete $1;
619 idlc()->setParseState(PS_InterfaceSqSeen);
621 exports
623 AstInterface * ifc = static_cast< AstInterface * >(
624 idlc()->scopes()->topNonNull());
625 if (!ifc->hasMandatoryInheritedInterfaces()
626 && ifc->getScopedName() != "com::sun::star::uno::XInterface")
628 addInheritedInterface(
629 ifc, "::com::sun::star::uno::XInterface", false,
630 OUString());
632 ifc->setDefined();
633 idlc()->setParseState(PS_InterfaceBodySeen);
637 idlc()->setParseState(PS_InterfaceQsSeen);
639 * Done with this interface - pop it off the scopes stack
641 idlc()->scopes()->pop();
643 | error '}'
645 yyerror("interface definition");
646 yyerrok;
650 interfaceheader :
651 interface_decl inheritance_spec
653 idlc()->setParseState(PS_InheritSpecSeen);
655 $$ = new FeInheritanceHeader(NT_interface, $1, $2, nullptr);
656 delete $2;
660 inheritance_spec :
663 idlc()->setParseState(PS_InheritColonSeen);
665 scoped_name
667 $$ = $3;
669 | /* EMPTY */
671 $$ = nullptr;
675 exports :
676 exports export
677 | /* EMPTY */
680 export :
681 attribute
683 idlc()->setParseState(PS_AttributeDeclSeen);
687 idlc()->setParseState(PS_NoState);
689 | operation
691 idlc()->setParseState(PS_OperationDeclSeen);
695 idlc()->setParseState(PS_NoState);
697 | interface_inheritance_decl
699 idlc()->setParseState(PS_InterfaceInheritanceDeclSeen);
703 idlc()->setParseState(PS_NoState);
707 attribute :
708 flag_header
709 simple_type_spec
711 idlc()->setParseState(PS_AttrTypeSeen);
713 declarator
715 idlc()->setParseState(PS_AttrCompleted);
716 if (($1 & ~(AF_BOUND | AF_READONLY)) != AF_ATTRIBUTE) {
717 ErrorHandler::flagError(ErrorCode::BadAttributeFlags, $1);
719 AstInterface * scope = static_cast< AstInterface * >(
720 idlc()->scopes()->top());
721 AstAttribute * attr = new AstAttribute(
722 $1, FeDeclarator::compose($2), $4->getName(), scope);
723 delete $4;
724 AstInterface::DoubleMemberDeclarations doubleMembers(
725 scope->checkMemberClashes(attr));
726 if (doubleMembers.empty()) {
727 scope->addMember(attr);
728 } else {
729 reportDoubleMemberDeclarations(doubleMembers);
731 idlc()->scopes()->push(attr);
733 opt_attribute_block
735 static_cast< AstAttribute * >(idlc()->scopes()->top())->setExceptions(
736 $6.get.documentation, $6.get.exceptions, $6.set.documentation,
737 $6.set.exceptions);
738 delete $6.get.documentation;
739 delete $6.get.exceptions;
740 delete $6.set.documentation;
741 delete $6.set.exceptions;
742 idlc()->scopes()->pop();
746 flag_header :
747 '[' opt_attrflags ']'
749 idlc()->setParseState(PS_FlagHeaderSeen);
750 $$ = $2;
754 opt_attrflags :
755 opt_attrflags ',' opt_attrflag
757 if ( ($1 & $3) == $3 )
758 ErrorHandler::flagError(ErrorCode::DefinedAttributeFlag, $3);
760 $$ = $1 | $3;
762 | opt_attrflag
764 $$ = $1;
768 opt_attrflag :
769 IDL_ATTRIBUTE
771 idlc()->setParseState(PS_AttrSeen);
772 $$ = AF_ATTRIBUTE;
774 | IDL_PROPERTY
776 idlc()->setParseState(PS_PropertySeen);
777 $$ = AF_PROPERTY;
779 | IDL_READONLY
781 idlc()->setParseState(PS_ReadOnlySeen);
782 $$ = AF_READONLY;
784 | IDL_OPTIONAL
786 idlc()->setParseState(PS_OptionalSeen);
787 $$ = AF_OPTIONAL;
789 | IDL_MAYBEVOID
791 idlc()->setParseState(PS_MayBeVoidSeen);
792 $$ = AF_MAYBEVOID;
794 | IDL_BOUND
796 idlc()->setParseState(PS_BoundSeen);
797 $$ = AF_BOUND;
799 | IDL_CONSTRAINED
801 idlc()->setParseState(PS_ConstrainedSeen);
802 $$ = AF_CONSTRAINED;
804 | IDL_TRANSIENT
806 idlc()->setParseState(PS_TransientSeen);
807 $$ = AF_TRANSIENT;
809 | IDL_MAYBEAMBIGUOUS
811 idlc()->setParseState(PS_MayBeAmbigiousSeen);
812 $$ = AF_MAYBEAMBIGUOUS;
814 | IDL_MAYBEDEFAULT
816 idlc()->setParseState(PS_MayBeDefaultSeen);
817 $$ = AF_MAYBEDEFAULT;
819 | IDL_REMOVABLE
821 idlc()->setParseState(PS_RemoveableSeen);
822 $$ = AF_REMOVABLE;
824 | error ']'
826 yyerror("unknown property|attribute flag");
827 yyerrok;
831 opt_attribute_block:
832 '{' attribute_block_rest { $$ = $2; }
833 | /* empty */
835 $$.get.documentation = nullptr;
836 $$.get.exceptions = nullptr;
837 $$.set.documentation = nullptr;
838 $$.set.exceptions = nullptr;
842 attribute_block_rest:
843 opt_attribute_raises '}'
844 | error '}'
846 yyerror("bad attribute raises block");
847 yyerrok;
848 $$.get.documentation = nullptr;
849 $$.get.exceptions = nullptr;
850 $$.set.documentation = nullptr;
851 $$.set.exceptions = nullptr;
855 opt_attribute_raises:
856 attribute_get_raises
857 opt_attribute_set_raises
859 $$.get = $1;
860 $$.set = $2;
862 | attribute_set_raises
863 opt_attribute_get_raises
865 $$.get = $2;
866 $$.set = $1;
868 | /* empty */
870 $$.get.documentation = nullptr;
871 $$.get.exceptions = nullptr;
872 $$.set.documentation = nullptr;
873 $$.set.exceptions = nullptr;
877 opt_attribute_get_raises:
878 attribute_get_raises
879 | /* empty */ { $$.documentation = nullptr; $$.exceptions = nullptr; }
882 attribute_get_raises:
883 IDL_GET raises ';'
885 $$.documentation = new OUString(
886 OStringToOUString(
887 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
888 $$.exceptions = $2;
892 opt_attribute_set_raises:
893 attribute_set_raises
894 | /* empty */ { $$.documentation = nullptr; $$.exceptions = nullptr; }
897 attribute_set_raises:
898 IDL_SET
900 if (static_cast< AstAttribute * >(idlc()->scopes()->top())->
901 isReadonly())
903 ErrorHandler::error0(ErrorCode::ReadOnlyAttributeSetExceptions);
906 raises ';'
908 $$.documentation = new OUString(
909 OStringToOUString(
910 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
911 $$.exceptions = $3;
915 operation :
916 op_type_spec
918 idlc()->setParseState(PS_OpTypeSeen);
920 identifier
922 idlc()->setParseState(PS_OpIDSeen);
923 checkIdentifier($3);
925 AstInterface * pScope = static_cast< AstInterface * >(
926 idlc()->scopes()->top());
927 AstOperation* pOp = nullptr;
930 * Create a node representing an operation on an interface
931 * and add it to its enclosing scope
933 if ( pScope && $1 )
935 AstType const *pType = static_cast<AstType const *>($1);
936 if ( !pType || (pType->getNodeType() == NT_exception) )
938 // type ERROR
939 } else
941 pOp = new AstOperation(pType, *$3, pScope);
943 AstInterface::DoubleMemberDeclarations doubleMembers(
944 pScope->checkMemberClashes(pOp));
945 if (doubleMembers.empty()) {
946 pScope->addMember(pOp);
947 } else {
948 reportDoubleMemberDeclarations(doubleMembers);
952 delete $3;
954 * Push the operation scope onto the scopes stack
956 idlc()->scopes()->push(pOp);
960 idlc()->setParseState(PS_OpSqSeen);
962 parameters
964 idlc()->setParseState(PS_OpParsCompleted);
968 idlc()->setParseState(PS_OpQsSeen);
970 opt_raises
972 AstScope* pScope = idlc()->scopes()->topNonNull();
973 AstOperation* pOp = nullptr;
975 * Add exceptions and context to the operation
977 if ( pScope && pScope->getScopeNodeType() == NT_operation)
979 pOp = static_cast<AstOperation*>(pScope);
981 if ( pOp )
982 pOp->setExceptions($11);
984 delete $11;
986 * Done with this operation. Pop its scope from the scopes stack
988 idlc()->scopes()->pop();
992 op_type_spec :
993 simple_type_spec
994 | IDL_VOID
996 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType(ET_void);
1000 parameters :
1001 parameter
1002 | parameters
1005 idlc()->setParseState(PS_OpParCommaSeen);
1007 parameter
1008 | /* EMPTY */
1009 | error ','
1011 yyerror("parameter definition");
1012 yyerrok;
1016 parameter :
1018 direction
1021 idlc()->setParseState(PS_OpParDirSeen);
1023 simple_type_spec
1025 idlc()->setParseState(PS_OpParTypeSeen);
1027 opt_rest
1028 declarator
1030 idlc()->setParseState(PS_OpParDeclSeen);
1032 AstOperation * pScope = static_cast< AstOperation * >(
1033 idlc()->scopes()->top());
1034 AstParameter* pParam = nullptr;
1037 * Create a node representing an argument to an operation
1038 * Add it to the enclosing scope (the operation scope)
1040 if ( pScope && $5 && $8 )
1042 AstType const * pType = FeDeclarator::compose($5);
1043 if ( pType )
1045 if (pScope->isConstructor() && $2 != DIR_IN) {
1046 ErrorHandler::error0(ErrorCode::ConstructorParameterNotIn);
1048 if (pScope->isVariadic()) {
1049 ErrorHandler::error0(ErrorCode::RestParameterNotLast);
1051 if ($7) {
1052 AstDeclaration const * type = resolveTypedefs(pType);
1053 if (type->getNodeType() != NT_predefined
1054 || (static_cast< AstBaseType const * >(type)->
1055 getExprType() != ET_any))
1057 ErrorHandler::error0(ErrorCode::RestParameterNotAny);
1059 if (pScope->isConstructor()) {
1060 if (pScope->getIteratorBegin()
1061 != pScope->getIteratorEnd())
1063 ErrorHandler::error0(
1064 ErrorCode::ConstructorRestParameterNotFirst);
1066 } else {
1067 ErrorHandler::error0(ErrorCode::MethodHasRestParameter);
1071 pParam = new AstParameter(
1072 static_cast< Direction >($2), $7, pType, $8->getName(),
1073 pScope);
1075 if ( !$8->checkType($5) )
1077 // WARNING
1080 pScope->addDeclaration(pParam);
1084 | error
1085 simple_type_spec
1087 idlc()->setParseState(PS_NoState);
1088 yyerrok;
1092 direction :
1093 IDL_IN
1095 $$ = DIR_IN;
1097 | IDL_OUT
1099 $$ = DIR_OUT;
1101 | IDL_INOUT
1103 $$ = DIR_INOUT;
1107 opt_rest:
1108 IDL_ELLIPSIS
1110 $$ = true;
1112 | /* empty */
1114 $$ = false;
1118 opt_raises:
1119 raises
1120 | /* empty */
1122 $$ = nullptr;
1126 raises:
1127 IDL_RAISES
1129 idlc()->setParseState(PS_RaiseSeen);
1133 idlc()->setParseState(PS_RaiseSqSeen);
1135 exception_list
1138 idlc()->setParseState(PS_RaiseQsSeen);
1139 $$ = $5;
1143 exception_list:
1144 exception_name
1146 $$ = new DeclList;
1147 $$->push_back($1);
1149 | exception_list ',' exception_name
1151 $1->push_back($3);
1152 $$ = $1;
1156 exception_name:
1157 scoped_name
1159 // The topmost scope is either an AstOperation (for interface methods
1160 // and service constructors) or an AstAttribute (for interface
1161 // attributes), so look up exception names in the next-to-topmost scope:
1162 AstDeclaration * decl = idlc()->scopes()->nextToTop()->lookupByName(
1163 *$1);
1164 if (decl == nullptr) {
1165 ErrorHandler::lookupError(*$1);
1166 } else if (!ErrorHandler::checkPublished(decl)) {
1167 decl = nullptr;
1168 } else if (decl->getNodeType() != NT_exception) {
1169 ErrorHandler::error1(ErrorCode::IllegalRaises, decl);
1170 decl = nullptr;
1172 delete $1;
1173 $$ = decl;
1177 interface_inheritance_decl:
1178 optional_inherited_interface
1179 IDL_INTERFACE
1181 idlc()->setParseState(PS_ServiceIFHeadSeen);
1183 scoped_name
1185 AstInterface * ifc = static_cast< AstInterface * >(
1186 idlc()->scopes()->top());
1187 if (ifc->usesSingleInheritance()) {
1188 ErrorHandler::error0(ErrorCode::MixedInheritance);
1189 } else {
1190 addInheritedInterface(
1191 ifc, *$4, $1,
1192 OStringToOUString(
1193 idlc()->getDocumentation(), RTL_TEXTENCODING_UTF8));
1195 delete $4;
1199 optional_inherited_interface:
1200 '[' IDL_OPTIONAL ']' { $$ = true; }
1201 | /* EMPTY */ { $$ = false; }
1204 constants_exports :
1205 constants_export constants_exports
1206 | /* EMPTY */
1209 constants_export :
1210 IDL_CONST
1212 idlc()->setParseState(PS_ConstSeen);
1214 const_type
1216 idlc()->setParseState(PS_ConstTypeSeen);
1218 identifier
1220 idlc()->setParseState(PS_ConstIDSeen);
1221 checkIdentifier($5);
1225 idlc()->setParseState(PS_ConstAssignSeen);
1227 expression
1229 idlc()->setParseState(PS_ConstExprSeen);
1231 AstScope* pScope = idlc()->scopes()->topNonNull();
1232 AstConstant* pConstant = nullptr;
1234 if ( $9 && pScope )
1236 if ( !$9->coerce($3) )
1238 ErrorHandler::coercionError($9, $3);
1239 } else
1241 pConstant = new AstConstant($3, $9, *$5, pScope);
1242 pScope->addDeclaration(pConstant);
1245 delete $5;
1247 idlc()->setParseState(PS_ConstantDeclSeen);
1249 ';' {};
1252 constants_dcl :
1253 IDL_CONSTANTS
1255 idlc()->setParseState(PS_ConstantsSeen);
1257 identifier
1259 idlc()->setParseState(PS_ConstantsIDSeen);
1260 checkIdentifier($3);
1264 idlc()->setParseState(PS_ConstantsSqSeen);
1266 AstScope* pScope = idlc()->scopes()->topNonNull();
1267 AstConstants* pConstants = nullptr;
1269 if ( pScope )
1271 pConstants = new AstConstants(*$3, pScope);
1272 if( AstDeclaration* pExists = pScope->lookupForAdd(pConstants) )
1274 pExists->setInMainfile(idlc()->isInMainFile());
1275 delete(pConstants);
1276 pConstants = static_cast<AstConstants*>(pExists);
1277 } else
1279 pScope->addDeclaration(pConstants);
1281 idlc()->scopes()->push(pConstants);
1283 delete $3;
1285 constants_exports
1287 idlc()->setParseState(PS_ConstantsBodySeen);
1291 idlc()->setParseState(PS_ConstantsQsSeen);
1293 * Finished with this constants - pop it from the scope stack
1295 idlc()->scopes()->pop();
1299 expression : const_expr ;
1301 const_expr : or_expr ;
1303 or_expr :
1304 xor_expr
1305 | or_expr '|' xor_expr
1307 $$ = new AstExpression(ExprComb::Or, $1, $3);
1311 xor_expr :
1312 and_expr
1313 | xor_expr '^' and_expr
1315 $$ = new AstExpression(ExprComb::Xor, $1, $3);
1319 and_expr :
1320 shift_expr
1321 | and_expr '&' shift_expr
1323 $$ = new AstExpression(ExprComb::And, $1, $3);
1327 shift_expr :
1328 add_expr
1329 | shift_expr IDL_LEFTSHIFT add_expr
1331 $$ = new AstExpression(ExprComb::Left, $1, $3);
1333 | shift_expr IDL_RIGHTSHIFT add_expr
1335 $$ = new AstExpression(ExprComb::Right, $1, $3);
1339 add_expr :
1340 mult_expr
1341 | add_expr '+' mult_expr
1343 $$ = new AstExpression(ExprComb::Add, $1, $3);
1345 | add_expr '-' mult_expr
1347 $$ = new AstExpression(ExprComb::Minus, $1, $3);
1351 mult_expr :
1352 unary_expr
1353 | mult_expr '*' unary_expr
1355 $$ = new AstExpression(ExprComb::Mul, $1, $3);
1357 | mult_expr '/' unary_expr
1359 $$ = new AstExpression(ExprComb::Div, $1, $3);
1361 | mult_expr '%' unary_expr
1363 $$ = new AstExpression(ExprComb::Mod, $1, $3);
1367 unary_expr :
1368 primary_expr
1369 | '+' primary_expr
1371 $$ = new AstExpression(ExprComb::UPlus, $2, nullptr);
1373 | '-' primary_expr
1375 $$ = new AstExpression(ExprComb::UMinus, $2, nullptr);
1377 | '~' primary_expr
1382 primary_expr :
1383 scoped_name
1386 * An expression which is a scoped name is not resolved now,
1387 * but only when it is evaluated (such as when it is assigned
1388 * as a constant value)
1390 $$ = new AstExpression($1);
1392 | literal
1393 | '(' const_expr ')'
1395 $$ = $2;
1399 literal :
1400 IDL_INTEGER_LITERAL
1402 $$ = new AstExpression($1);
1404 | IDL_INTEGER_ULITERAL
1406 $$ = new AstExpression($1);
1408 | IDL_FLOATING_PT_LITERAL
1410 $$ = new AstExpression($1);
1412 | IDL_TRUE
1414 $$ = new AstExpression(sal_Int32(1), ET_boolean);
1416 | IDL_FALSE
1418 $$ = new AstExpression(sal_Int32(0), ET_boolean);
1422 const_type :
1423 integer_type
1424 | byte_type
1425 | boolean_type
1426 | floating_pt_type
1427 | scoped_name
1429 AstScope* pScope = idlc()->scopes()->topNonNull();
1430 AstDeclaration const * type = nullptr;
1433 * If the constant's type is a scoped name, it must resolve
1434 * to a scalar constant type
1436 if ( pScope && (type = pScope->lookupByName(*$1)) ) {
1437 if (!ErrorHandler::checkPublished(type))
1439 type = nullptr;
1440 $$ = ET_none;
1442 else
1444 type = resolveTypedefs(type);
1445 if (type->getNodeType() == NT_predefined)
1447 $$ = static_cast< AstBaseType const * >(type)->
1448 getExprType();
1449 } else
1450 $$ = ET_any;
1452 } else
1453 $$ = ET_any;
1457 exception_header :
1458 IDL_EXCEPTION
1460 idlc()->setParseState(PS_ExceptSeen);
1462 identifier
1464 idlc()->setParseState(PS_ExceptIDSeen);
1465 checkIdentifier($3);
1467 inheritance_spec
1469 idlc()->setParseState(PS_InheritSpecSeen);
1471 $$ = new FeInheritanceHeader(NT_exception, $3, $5, nullptr);
1472 delete $5;
1476 exception_dcl :
1477 exception_header
1479 idlc()->setParseState(PS_ExceptHeaderSeen);
1481 AstScope* pScope = idlc()->scopes()->topNonNull();
1482 AstException* pExcept = nullptr;
1484 if ( pScope )
1486 AstException* pBase = static_cast< AstException* >(
1487 $1->getInherits());
1488 pExcept = new AstException(*$1->getName(), pBase, pScope);
1489 pScope->addDeclaration(pExcept);
1492 * Push the scope of the exception on the scopes stack
1494 idlc()->scopes()->push(pExcept);
1495 delete $1;
1499 idlc()->setParseState(PS_ExceptSqSeen);
1501 members
1503 idlc()->setParseState(PS_ExceptBodySeen);
1507 idlc()->setParseState(PS_ExceptQsSeen);
1508 /* this exception is finished, pop its scope from the stack */
1509 idlc()->scopes()->pop();
1513 property :
1514 flag_header
1515 simple_type_spec
1517 idlc()->setParseState(PS_PropertyTypeSeen);
1519 at_least_one_declarator
1521 idlc()->setParseState(PS_PropertyCompleted);
1523 AstScope* pScope = idlc()->scopes()->topNonNull();
1524 AstAttribute* pAttr = nullptr;
1525 FeDeclList* pList = $4;
1526 FeDeclarator* pDecl = nullptr;
1527 AstType const * pType = nullptr;
1529 if ( pScope->getScopeNodeType() == NT_singleton )
1531 ErrorHandler::error0(ErrorCode::IllegalAdd);
1532 } else
1534 if ( ($1 & AF_ATTRIBUTE) == AF_ATTRIBUTE )
1535 ErrorHandler::flagError(ErrorCode::WrongAttributeKeyword, AF_ATTRIBUTE);
1537 if ( ($1 & AF_PROPERTY) != AF_PROPERTY )
1538 ErrorHandler::flagError(ErrorCode::MissingAttributeKeyword, AF_PROPERTY);
1541 * Create nodes representing attributes and add them to the
1542 * enclosing scope
1544 if ( pScope && $2 && pList )
1546 FeDeclList::iterator iter = pList->begin();
1547 FeDeclList::iterator end = pList->end();
1549 while (iter != end)
1551 pDecl = (*iter);
1552 if ( !pDecl )
1554 ++iter;
1555 continue;
1558 pType = FeDeclarator::compose($2);
1560 if ( !pType )
1562 ++iter;
1563 continue;
1566 pAttr = new AstAttribute(NT_property, $1, pType, pDecl->getName(), pScope);
1568 pScope->addDeclaration(pAttr);
1569 ++iter;
1570 delete pDecl;
1575 if ( pList )
1576 delete pList;
1578 | error ';'
1580 yyerror("property");
1581 yyerrok;
1585 service_exports :
1586 service_exports service_export
1587 | /* EMPTY */
1590 service_export :
1591 service_interface_header
1592 at_least_one_scoped_name
1595 idlc()->setParseState(PS_ServiceMemberSeen);
1597 AstScope* pScope = idlc()->scopes()->topNonNull();
1598 AstDeclaration* pDecl = nullptr;
1599 AstInterfaceMember* pIMember = nullptr;
1601 if ( pScope->getScopeNodeType() == NT_singleton )
1603 ErrorHandler::error0(ErrorCode::IllegalAdd);
1604 } else
1607 * Create a node representing a class member.
1608 * Store it in the enclosing scope
1610 if ( pScope && $2 )
1612 for (auto const& elem : *($2))
1614 pDecl = pScope->lookupByName(elem);
1615 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1617 /* we relax the strict published check and allow to add new
1618 * interfaces if they are optional
1620 bool bOptional = (($1 & AF_OPTIONAL) == AF_OPTIONAL);
1621 if ( ErrorHandler::checkPublished(pDecl, bOptional) )
1623 pIMember = new AstInterfaceMember(
1624 $1, static_cast<AstInterface*>(pDecl), elem, pScope);
1625 pScope->addDeclaration(pIMember);
1627 } else
1629 ErrorHandler::lookupError(ErrorCode::InterfaceMemberLookup, elem, scopeAsDecl(pScope));
1634 delete $2;
1636 | service_service_header
1637 at_least_one_scoped_name
1640 idlc()->setParseState(PS_ServiceMemberSeen);
1642 AstScope* pScope = idlc()->scopes()->topNonNull();
1643 AstDeclaration* pDecl = nullptr;
1644 AstServiceMember* pSMember = nullptr;
1647 * Create a node representing a class member.
1648 * Store it in the enclosing scope
1650 if ( pScope && $2 )
1652 for (auto const& elem : *($2))
1654 pDecl = pScope->lookupByName(elem);
1655 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1657 if ( static_cast< AstService * >(pDecl)->isSingleInterfaceBasedService() || (pScope->getScopeNodeType() == NT_singleton && pScope->nMembers() > 0) )
1658 ErrorHandler::error0(ErrorCode::IllegalAdd);
1659 else if ( ErrorHandler::checkPublished(pDecl) )
1661 pSMember = new AstServiceMember(
1662 $1, static_cast<AstService*>(pDecl), elem, pScope);
1663 pScope->addDeclaration(pSMember);
1665 } else
1667 ErrorHandler::lookupError(ErrorCode::ServiceMemberLookup, elem, scopeAsDecl(pScope));
1671 delete $2;
1673 | IDL_OBSERVES
1674 at_least_one_scoped_name
1677 idlc()->setParseState(PS_ServiceMemberSeen);
1679 AstScope* pScope = idlc()->scopes()->topNonNull();
1680 AstDeclaration* pDecl = nullptr;
1681 AstObserves* pObserves = nullptr;
1683 if ( pScope->getScopeNodeType() == NT_singleton )
1685 ErrorHandler::error0(ErrorCode::IllegalAdd);
1686 } else
1689 * Create a node representing a class member.
1690 * Store it in the enclosing scope
1692 if ( pScope && $2 )
1694 for (auto const& elem : *($2))
1696 pDecl = pScope->lookupByName(elem);
1697 if ( pDecl && (pDecl->getNodeType() == NT_interface) )
1699 pObserves = new AstObserves(static_cast<AstInterface*>(pDecl), elem, pScope);
1700 pScope->addDeclaration(pObserves);
1701 } else
1703 ErrorHandler::lookupError(ErrorCode::InterfaceMemberLookup, elem, scopeAsDecl(pScope));
1708 delete $2;
1710 | IDL_NEEDS
1711 at_least_one_scoped_name
1714 idlc()->setParseState(PS_ServiceMemberSeen);
1716 AstScope* pScope = idlc()->scopes()->topNonNull();
1717 AstDeclaration* pDecl = nullptr;
1718 AstNeeds* pNeeds = nullptr;
1720 if ( pScope->getScopeNodeType() == NT_singleton )
1722 ErrorHandler::error0(ErrorCode::IllegalAdd);
1723 } else
1726 * Create a node representing a class member.
1727 * Store it in the enclosing scope
1729 if ( pScope && $2 )
1731 for (auto const& elem : *($2))
1733 pDecl = pScope->lookupByName(elem);
1734 if ( pDecl && (pDecl->getNodeType() == NT_service) )
1736 pNeeds = new AstNeeds(static_cast<AstService*>(pDecl), elem, pScope);
1737 pScope->addDeclaration(pNeeds);
1738 } else
1740 ErrorHandler::lookupError(ErrorCode::ServiceMemberLookup, elem, scopeAsDecl(pScope));
1745 delete $2;
1747 | property
1750 idlc()->setParseState(PS_PropertyDeclSeen);
1754 service_interface_header :
1755 IDL_INTERFACE
1757 idlc()->setParseState(PS_ServiceIFHeadSeen);
1758 $$ = AF_INVALID;
1760 | flag_header
1761 IDL_INTERFACE
1763 idlc()->setParseState(PS_ServiceIFHeadSeen);
1764 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1765 ErrorHandler::flagError(ErrorCode::ExpectedOptional, $1);
1766 $$ = $1;
1770 service_service_header :
1771 IDL_SERVICE
1773 idlc()->setParseState(PS_ServiceSHeadSeen);
1774 $$ = AF_INVALID;
1776 | flag_header
1777 IDL_SERVICE
1779 idlc()->setParseState(PS_ServiceSHeadSeen);
1780 if ( (AF_OPTIONAL != $1) && ( AF_INVALID != $1) )
1781 ErrorHandler::flagError(ErrorCode::ExpectedOptional, $1);
1782 $$ = $1;
1786 service_dcl :
1787 IDL_SERVICE
1789 idlc()->setParseState(PS_ServiceSeen);
1791 identifier
1793 idlc()->setParseState(PS_ServiceIDSeen);
1794 checkIdentifier($3);
1796 AstScope* pScope = idlc()->scopes()->topNonNull();
1797 AstService* pService = nullptr;
1800 * Make a new service and add it to the enclosing scope
1802 if (pScope != nullptr)
1804 pService = new AstService(*$3, pScope);
1805 pScope->addDeclaration(pService);
1807 delete $3;
1809 * Push it on the stack
1811 idlc()->scopes()->push(pService);
1813 service_dfn
1815 /* this service is finished, pop its scope from the stack */
1816 idlc()->scopes()->pop();
1820 service_dfn:
1821 service_interface_dfn
1822 | service_obsolete_dfn
1825 service_interface_dfn:
1826 ':' scoped_name
1828 AstScope * scope = idlc()->scopes()->nextToTop();
1829 // skip the scope pushed by service_dcl
1830 AstDeclaration * decl = scope->lookupByName(*$2);
1831 if (decl != nullptr
1832 && resolveTypedefs(decl)->getNodeType() == NT_interface)
1834 if (ErrorHandler::checkPublished(decl)) {
1835 idlc()->scopes()->top()->addDeclaration(decl);
1837 } else {
1838 ErrorHandler::lookupError(
1839 ErrorCode::InterfaceMemberLookup, *$2, scopeAsDecl(scope));
1841 delete $2;
1843 opt_service_body
1845 AstService * s = static_cast< AstService * >(idlc()->scopes()->top());
1846 if (s != nullptr) {
1847 s->setSingleInterfaceBasedService();
1848 s->setDefaultConstructor(!$4);
1853 opt_service_body:
1854 service_body { $$ = true; }
1855 | /* empty */ { $$ = false; }
1858 service_body:
1860 constructors
1864 constructors:
1865 constructors constructor
1866 | /* empty */
1869 constructor:
1870 identifier
1872 checkIdentifier($1);
1873 AstScope * scope = idlc()->scopes()->top();
1874 AstOperation * ctor = new AstOperation(nullptr, *$1, scope);
1875 delete $1;
1876 scope->addDeclaration(ctor);
1877 idlc()->scopes()->push(ctor);
1880 parameters
1882 opt_raises
1884 static_cast< AstOperation * >(idlc()->scopes()->top())->setExceptions(
1885 $6);
1886 delete $6;
1887 idlc()->scopes()->pop();
1888 if (static_cast< AstService * >(idlc()->scopes()->top())->
1889 checkLastConstructor())
1891 ErrorHandler::error0(ErrorCode::SimilarConstructors);
1897 singleton_dcl :
1898 IDL_SINGLETON
1900 idlc()->setParseState(PS_SingletonSeen);
1902 identifier
1904 idlc()->setParseState(PS_SingletonIDSeen);
1905 checkIdentifier($3);
1907 AstScope* pScope = idlc()->scopes()->topNonNull();
1908 AstService* pService = nullptr;
1911 * Make a new service and add it to the enclosing scope
1913 if (pScope != nullptr)
1915 pService = new AstService(NT_singleton, *$3, pScope);
1916 pScope->addDeclaration(pService);
1918 delete $3;
1920 * Push it on the stack
1922 idlc()->scopes()->push(pService);
1924 singleton_dfn
1926 /* this singelton is finished, pop its scope from the stack */
1927 idlc()->scopes()->pop();
1931 singleton_dfn:
1932 singleton_interface_dfn
1933 | service_obsolete_dfn
1936 singleton_interface_dfn:
1937 ':' scoped_name
1939 AstScope * scope = idlc()->scopes()->nextToTop();
1940 // skip the scope (needlessly) pushed by singleton_dcl
1941 AstDeclaration * decl = scope->lookupByName(*$2);
1942 if (decl != nullptr
1943 && resolveTypedefs(decl)->getNodeType() == NT_interface)
1945 if (ErrorHandler::checkPublished(decl)) {
1946 idlc()->scopes()->top()->addDeclaration(decl);
1948 } else {
1949 ErrorHandler::lookupError(
1950 ErrorCode::InterfaceMemberLookup, *$2, scopeAsDecl(scope));
1952 delete $2;
1956 service_obsolete_dfn:
1959 idlc()->setParseState(
1960 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1961 ? PS_ServiceSqSeen : PS_SingletonSqSeen);
1963 service_exports
1965 idlc()->setParseState(
1966 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1967 ? PS_ServiceBodySeen : PS_SingletonBodySeen);
1971 idlc()->setParseState(
1972 idlc()->scopes()->top()->getScopeNodeType() == NT_service
1973 ? PS_ServiceQsSeen : PS_SingletonQsSeen);
1977 type_dcl :
1978 IDL_TYPEDEF
1980 idlc()->setParseState(PS_TypedefSeen);
1982 type_declarator {}
1983 | struct_type {}
1984 | enum_type {}
1987 type_declarator :
1988 type_spec
1990 idlc()->setParseState(PS_TypeSpecSeen);
1991 if ($1 != nullptr && $1->getNodeType() == NT_instantiated_struct) {
1992 ErrorHandler::error0(ErrorCode::InstantiatedStructTypeTypedef);
1995 at_least_one_declarator
1997 idlc()->setParseState(PS_DeclaratorsSeen);
1999 AstScope* pScope = idlc()->scopes()->topNonNull();
2000 AstTypeDef* pTypeDef = nullptr;
2001 FeDeclList* pList = $3;
2002 FeDeclarator* pDecl = nullptr;
2003 AstType const * pType = nullptr;
2006 * Create nodes representing typedefs and add them to the
2007 * enclosing scope
2009 if ( pScope && $1 && pList )
2011 FeDeclList::iterator iter = pList->begin();
2012 FeDeclList::iterator end = pList->end();
2014 while (iter != end)
2016 pDecl = (*iter);
2017 if ( !pDecl )
2019 ++iter;
2020 continue;
2023 pType = FeDeclarator::compose($1);
2025 if ( !pType )
2027 ++iter;
2028 continue;
2031 pTypeDef = new AstTypeDef(pType, pDecl->getName(), pScope);
2033 pScope->addDeclaration(pTypeDef);
2034 ++iter;
2035 delete pDecl;
2037 delete pList;
2042 at_least_one_declarator :
2043 declarator declarators
2045 if ( $2 )
2047 $2->push_back($1);
2048 $$ = $2;
2049 } else
2051 FeDeclList* pList = new FeDeclList;
2052 pList->push_back($1);
2053 $$ = pList;
2058 declarators :
2059 declarators
2062 idlc()->setParseState(PS_DeclsCommaSeen);
2064 declarator
2066 idlc()->setParseState(PS_DeclsDeclSeen);
2067 if ( $1 )
2069 $1->push_back($4);
2070 $$ = $1;
2071 } else
2073 FeDeclList* pList = new FeDeclList;
2074 pList->push_back($4);
2075 $$ = pList;
2078 | /* EMPTY */
2080 $$ = nullptr;
2084 declarator :
2085 identifier
2087 // For historic reasons, the struct com.sun.star.uno.Uik contains
2088 // members with illegal names (of the form "m_DataN"); avoid useless
2089 // warnings about them:
2090 AstScope * scope = idlc()->scopes()->top();
2091 if (scope == nullptr || scope->getScopeNodeType() != NT_struct
2092 || (scopeAsDecl(scope)->getScopedName()
2093 != "com::sun::star::uno::Uik"))
2095 checkIdentifier($1);
2098 $$ = new FeDeclarator(*$1);
2099 delete $1;
2103 at_least_one_scoped_name :
2104 scoped_name scoped_names
2106 if ($2)
2108 $2->push_front(*$1);
2109 $$ = $2;
2110 } else
2112 std::list< OString >* pScopedNames = new std::list< OString >;
2113 // coverity[copy_paste_error : FALSE] - this is not a cut and paste
2114 pScopedNames->push_back(*$1);
2115 $$ = pScopedNames;
2117 delete $1;
2121 scoped_names :
2122 scoped_names
2125 idlc()->setParseState(PS_SNListCommaSeen);
2127 scoped_name
2129 idlc()->setParseState(PS_ScopedNameSeen);
2130 if ($1)
2132 $1->push_back(*$4);
2133 $$ = $1;
2134 } else
2136 std::list< OString >* pNames = new std::list< OString >;
2137 pNames->push_back(*$4);
2138 $$ = pNames;
2140 delete $4;
2142 | /* EMPTY */
2144 $$ = nullptr;
2148 scoped_name :
2149 identifier
2151 idlc()->setParseState(PS_SN_IDSeen);
2152 checkIdentifier($1);
2153 $$ = $1;
2155 | IDL_SCOPESEPARATOR
2157 idlc()->setParseState(PS_ScopeDelimSeen);
2159 identifier
2161 checkIdentifier($3);
2162 OString* pName = new OString("::");
2163 *pName += *$3;
2164 delete $3;
2165 $$ = pName;
2167 | scoped_name
2168 IDL_SCOPESEPARATOR
2171 identifier
2173 checkIdentifier($4);
2174 *$1 += OString("::");
2175 *$1 += *$4;
2176 delete $4;
2177 $$ = $1;
2181 type_spec :
2182 simple_type_spec
2183 | constructed_type_spec
2186 simple_type_spec :
2187 fundamental_type
2188 | scoped_name opt_type_args
2190 $$ = createNamedType($1, $2);
2194 fundamental_type:
2195 base_type_spec
2197 $$ = idlc()->scopes()->bottom()->lookupPrimitiveType($1);
2199 | sequence_type_spec
2202 opt_type_args:
2203 '<' type_args '>' { $$ = $2; }
2204 | /* empty */ { $$ = nullptr; }
2207 type_args:
2208 type_arg
2210 $$ = new DeclList;
2211 $$->push_back(const_cast< AstDeclaration * >($1)); //TODO: const_cast
2213 | type_args ',' type_arg
2215 $1->push_back(const_cast< AstDeclaration * >($3)); //TODO: const_cast
2216 $$ = $1;
2220 type_arg:
2221 simple_type_spec
2223 if ($1 != nullptr && static_cast< AstType const * >($1)->isUnsigned()) {
2224 ErrorHandler::error0(ErrorCode::UnsignedTypeArgument);
2226 $$ = $1;
2230 base_type_spec :
2231 integer_type
2232 | floating_pt_type
2233 | char_type
2234 | boolean_type
2235 | byte_type
2236 | any_type
2237 | type_type
2238 | string_type
2241 integer_type :
2242 signed_int
2243 | unsigned_int
2246 signed_int :
2247 IDL_LONG
2249 $$ = ET_long;
2251 | IDL_HYPER
2253 $$ = ET_hyper;
2255 | IDL_SHORT
2257 $$ = ET_short;
2261 unsigned_int :
2262 IDL_UNSIGNED IDL_LONG
2264 $$ = ET_ulong;
2266 | IDL_UNSIGNED IDL_HYPER
2268 $$ = ET_uhyper;
2270 | IDL_UNSIGNED IDL_SHORT
2272 $$ = ET_ushort;
2276 floating_pt_type :
2277 IDL_DOUBLE
2279 $$ = ET_double;
2281 | IDL_FLOAT
2283 $$ = ET_float;
2287 char_type :
2288 IDL_CHAR
2290 $$ = ET_char;
2294 byte_type :
2295 IDL_BYTE
2297 $$ = ET_byte;
2301 boolean_type :
2302 IDL_BOOLEAN
2304 $$ = ET_boolean;
2308 any_type :
2309 IDL_ANY
2311 $$ = ET_any;
2315 type_type :
2316 IDL_TYPE
2318 $$ = ET_type;
2322 string_type :
2323 IDL_STRING
2325 $$ = ET_string;
2329 constructed_type_spec :
2330 struct_type
2331 | enum_type
2334 sequence_type_spec :
2335 IDL_SEQUENCE
2337 idlc()->setParseState(PS_SequenceSeen);
2339 * Push a sequence marker on scopes stack
2341 idlc()->scopes()->push(nullptr);
2345 idlc()->setParseState(PS_SequenceSqSeen);
2347 simple_type_spec
2349 idlc()->setParseState(PS_SequenceTypeSeen);
2353 idlc()->setParseState(PS_SequenceQsSeen);
2355 * Remove sequence marker from scopes stack
2357 if (idlc()->scopes()->top() == nullptr)
2358 idlc()->scopes()->pop();
2360 * Create a node representing a sequence
2362 AstScope* pScope = idlc()->scopes()->bottom();
2363 AstDeclaration* pDecl = nullptr;
2364 AstDeclaration* pSeq = nullptr;
2366 if ( $5 )
2368 AstType const *pType = static_cast<AstType const *>($5);
2369 if ( pType )
2371 pSeq = new AstSequence(pType, pScope);
2373 * Add this AstSequence to the types defined in the global scope
2375 pDecl = pScope->addDeclaration(pSeq);
2376 if ( pSeq != pDecl )
2378 // if sequence type already defined then use it
2379 delete pSeq;
2380 pSeq = pDecl;
2384 $$ = pSeq;
2386 | error '>'
2388 yyerror("sequence declaration");
2389 yyerrok;
2390 $$ = nullptr;
2394 struct_type :
2395 structure_header
2397 idlc()->setParseState(PS_StructHeaderSeen);
2399 AstScope* pScope = idlc()->scopes()->topNonNull();
2400 AstStruct* pStruct = nullptr;
2402 if ( pScope )
2404 AstStruct const* pBase= static_cast< AstStruct const* >(resolveTypedefs($1->getInherits()));
2405 pStruct = new AstStruct(
2406 *$1->getName(), $1->getTypeParameters(), pBase, pScope);
2407 pScope->addDeclaration(pStruct);
2410 * Push the scope of the struct on the scopes stack
2412 idlc()->scopes()->push(pStruct);
2413 delete $1;
2417 idlc()->setParseState(PS_StructSqSeen);
2419 at_least_one_member
2421 idlc()->setParseState(PS_StructBodySeen);
2425 idlc()->setParseState(PS_StructQsSeen);
2426 /* this exception is finished, pop its scope from the stack */
2427 idlc()->scopes()->pop();
2431 structure_header :
2432 IDL_STRUCT
2434 idlc()->setParseState(PS_StructSeen);
2436 identifier
2438 idlc()->setParseState(PS_StructIDSeen);
2439 checkIdentifier($3);
2441 opt_type_params
2442 inheritance_spec
2444 idlc()->setParseState(PS_InheritSpecSeen);
2446 // Polymorphic struct type templates with base types would cause various
2447 // problems in language bindings, so forbid them here. For example,
2448 // GCC prior to version 3.4 fails with code like
2450 // struct Base { ... };
2451 // template< typename typeparam_T > struct Derived: public Base {
2452 // int member1 CPPU_GCC3_ALIGN(Base);
2453 // ... };
2455 // (Note that plain struct types with instantiated polymorphic struct
2456 // type bases, which might also cause problems in language bindings, are
2457 // already rejected on a syntactic level.)
2458 if ($5 != nullptr && $6 != nullptr) {
2459 ErrorHandler::error0(ErrorCode::StructTypeTemplateWithBase);
2462 $$ = new FeInheritanceHeader(NT_struct, $3, $6, $5);
2463 delete $5;
2464 delete $6;
2468 opt_type_params:
2469 '<' type_params '>' { $$ = $2; }
2470 | /* empty */ { $$ = nullptr; }
2473 type_params:
2474 identifier
2476 $$ = new std::vector< OString >;
2477 $$->push_back(*$1);
2478 delete $1;
2480 | type_params ',' identifier
2482 if (std::find($1->begin(), $1->end(), *$3) != $1->end()) {
2483 ErrorHandler::error0(ErrorCode::IdenticalTypeParameters);
2485 $1->push_back(*$3);
2486 delete $3;
2487 $$ = $1;
2491 at_least_one_member : member members ;
2493 members :
2494 members member
2495 | /* EMPTY */
2498 member :
2499 type_or_parameter
2501 idlc()->setParseState(PS_MemberTypeSeen);
2503 at_least_one_declarator
2505 idlc()->setParseState(PS_MemberDeclsSeen);
2509 idlc()->setParseState(PS_MemberDeclsCompleted);
2511 AstScope* pScope = idlc()->scopes()->topNonNull();
2512 AstMember* pMember = nullptr;
2513 FeDeclList* pList = $3;
2514 FeDeclarator* pDecl = nullptr;
2515 AstType const * pType = nullptr;
2517 // !!! check recursive type
2519 if ( pScope && pList && $1 )
2521 FeDeclList::iterator iter = pList->begin();
2522 FeDeclList::iterator end = pList->end();
2523 while (iter != end)
2525 pDecl = (*iter);
2526 if ( !pDecl )
2528 ++iter;
2529 continue;
2532 pType = FeDeclarator::compose($1);
2534 if ( !pType )
2536 ++iter;
2537 continue;
2540 pMember = new AstMember(pType, pDecl->getName(), pScope);
2542 if ( !pDecl->checkType($1) )
2544 // WARNING
2547 pScope->addDeclaration(pMember);
2548 ++iter;
2549 delete pDecl;
2551 delete pList;
2554 | error ';'
2556 yyerror("member definition");
2557 yyerrok;
2561 type_or_parameter:
2562 fundamental_type
2563 | scoped_name opt_type_args
2565 AstDeclaration const * decl = nullptr;
2566 AstStruct * scope = static_cast< AstStruct * >(idlc()->scopes()->top());
2567 if (scope != nullptr && $2 == nullptr) {
2568 decl = scope->findTypeParameter(*$1);
2570 if (decl != nullptr) {
2571 delete $1;
2572 delete $2;
2573 } else {
2574 decl = createNamedType($1, $2);
2575 if (scope != nullptr && includes(decl, scopeAsDecl(scope))) {
2576 ErrorHandler::error1(
2577 ErrorCode::RecursiveType, scopeAsDecl(scope));
2578 decl = nullptr;
2581 $$ = decl;
2585 enum_type :
2586 IDL_ENUM
2588 idlc()->setParseState(PS_EnumSeen);
2590 identifier
2592 idlc()->setParseState(PS_EnumIDSeen);
2593 checkIdentifier($3);
2595 AstScope* pScope = idlc()->scopes()->topNonNull();
2596 AstEnum* pEnum = nullptr;
2599 * Create a node representing an enum and add it to its
2600 * enclosing scope
2602 if (pScope != nullptr)
2604 pEnum = new AstEnum(*$3, pScope);
2606 * Add it to its defining scope
2608 pScope->addDeclaration(pEnum);
2610 delete $3;
2612 * Push the enum scope on the scopes stack
2614 idlc()->scopes()->push(pEnum);
2619 idlc()->setParseState(PS_EnumSqSeen);
2621 at_least_one_enumerator
2623 idlc()->setParseState(PS_EnumBodySeen);
2627 idlc()->setParseState(PS_EnumQsSeen);
2629 * Done with this enum. Pop its scope from the scopes stack
2631 if (idlc()->scopes()->top() == nullptr)
2632 $$ = nullptr;
2633 else
2635 $$ = static_cast<AstEnum*>(idlc()->scopes()->topNonNull());
2636 idlc()->scopes()->pop();
2641 at_least_one_enumerator : enumerator enumerators ;
2643 enumerators :
2644 enumerators
2647 idlc()->setParseState(PS_EnumCommaSeen);
2649 enumerator
2650 | /* EMPTY */
2651 | error ','
2653 yyerror("enumerator definition");
2654 yyerrok;
2658 enumerator :
2659 identifier
2661 checkIdentifier($1);
2663 AstScope* pScope = idlc()->scopes()->topNonNull();
2664 AstEnum* pEnum = nullptr;
2665 AstConstant* pEnumVal = nullptr;
2667 if ( pScope && pScope->getScopeNodeType() == NT_enum)
2669 pEnum = static_cast<AstEnum*>(pScope);
2670 if (pEnum && $1)
2672 AstExpression* pExpr = new AstExpression(pEnum->getEnumValueCount());
2673 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2674 pExpr, *$1, pScope);
2676 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2677 ErrorHandler::error1(ErrorCode::Eval, pEnum);
2679 pScope->addDeclaration(pEnumVal);
2681 delete $1;
2683 | identifier
2685 const_expr
2687 checkIdentifier($1);
2689 AstScope* pScope = idlc()->scopes()->topNonNull();
2690 AstEnum* pEnum = nullptr;
2691 AstConstant* pEnumVal = nullptr;
2693 if ( $3 && pScope && pScope->getScopeNodeType() == NT_enum)
2695 $3->evaluate();
2696 if ( $3->coerce(ET_long) )
2698 pEnum = static_cast<AstEnum*>(pScope);
2699 if (pEnum)
2701 pEnumVal = new AstConstant(ET_long , NT_enum_val,
2702 $3, *$1, pScope);
2704 if ( pEnum->checkValue(pEnumVal->getConstValue()) )
2705 ErrorHandler::error1(ErrorCode::Eval, pEnum);
2707 pScope->addDeclaration(pEnumVal);
2708 } else
2710 ErrorHandler::coercionError($3, ET_long);
2711 delete $3;
2714 delete $1;
2718 identifier:
2719 IDL_IDENTIFIER
2720 | IDL_GET { $$ = new OString("get"); }
2721 | IDL_SET { $$ = new OString("set"); }
2722 | IDL_PUBLISHED { $$ = new OString("published"); }
2728 * Report an error situation discovered in a production
2730 void yyerror(char const *errmsg)
2732 ErrorHandler::syntaxError(idlc()->getParseState(), idlc()->getLineNumber(), errmsg);
2733 idlc()->setParseState(PS_NoState);
2736 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */