fix baseline build (old cairo) - 'cairo_rectangle_int_t' does not name a type
[LibreOffice.git] / unoidl / source / sourceprovider-parser.y
blobad6c6574f19dd13f8ed12315148895d0c3d1200e
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/.
8 */
10 /*TODO: check Exception, RuntimeException, XInterface defns */
12 %locations
13 %pure-parser
17 #include "sal/config.h"
19 #include <algorithm>
20 #include <cassert>
21 #include <cerrno>
22 #include <cstddef>
23 #include <cstdlib>
24 #include <limits>
25 #include <new>
26 #include <utility>
27 #include <vector>
29 #include <sourceprovider-parser-requires.hxx>
33 %union {
34 sal_uInt64 ival;
35 double fval;
36 OString * sval;
38 bool bval;
39 std::vector<OUString> * excns;
40 unoidl::detail::SourceProviderAccessDecls decls;
41 unoidl::InterfaceTypeEntity::Method::Parameter::Direction dir;
42 unoidl::detail::SourceProviderFlags flags;
43 unoidl::detail::SourceProviderExpr expr;
44 unoidl::detail::SourceProviderType * type;
45 std::vector<unoidl::detail::SourceProviderType> * types;
48 /* TODO: %destructor { delete $$; } <sval> <excns> <type> <types> */
50 %lex-param {yyscan_t yyscanner}
51 %parse-param {yyscan_t yyscanner}
55 #include "osl/file.h"
56 #include "osl/thread.h"
57 #include "sal/log.hxx"
59 #include "sourceprovider-scanner.hxx"
61 #define YYLLOC_DEFAULT(Current, Rhs, N) \
62 do { (Current) = YYRHSLOC((Rhs), (N) ? 1 : 0); } while (0)
64 void yyerror(YYLTYPE * locp, yyscan_t yyscanner, char const * msg) {
65 assert(locp != 0);
66 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
67 data->errorLine = *locp;
68 data->parserError = OString(msg);
71 namespace {
73 void error(YYLTYPE location, yyscan_t yyscanner, OUString const & message) {
74 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
75 data->errorLine = location;
76 data->errorMessage = message;
79 OUString flagName(unoidl::detail::SourceProviderFlags flag) {
80 switch (flag) {
81 case unoidl::detail::FLAG_ATTRIBUTE:
82 return OUString("attribute");
83 case unoidl::detail::FLAG_BOUND:
84 return OUString("bound");
85 case unoidl::detail::FLAG_CONSTRAINED:
86 return OUString("constrained");
87 case unoidl::detail::FLAG_MAYBEAMBIGUOUS:
88 return OUString("maybeambiguous");
89 case unoidl::detail::FLAG_MAYBEDEFAULT:
90 return OUString("maybedefault");
91 case unoidl::detail::FLAG_MAYBEVOID:
92 return OUString("maybevoid");
93 case unoidl::detail::FLAG_OPTIONAL:
94 return OUString("optional");
95 case unoidl::detail::FLAG_PROPERTY:
96 return OUString("property");
97 case unoidl::detail::FLAG_READONLY:
98 return OUString("readonly");
99 case unoidl::detail::FLAG_REMOVABLE:
100 return OUString("removable");
101 case unoidl::detail::FLAG_TRANSIENT:
102 return OUString("transient");
103 default:
104 assert(false && "this cannot happen"); for (;;) { std::abort(); }
108 OUString convertName(OString const * name) {
109 assert(name != 0);
110 OUString s(OStringToOUString(*name, RTL_TEXTENCODING_ASCII_US));
111 delete name;
112 return s;
115 OUString convertToFullName(
116 unoidl::detail::SourceProviderScannerData const * data,
117 OString const * identifier)
119 assert(data != 0);
120 OUString pref;
121 if (!data->modules.empty()) {
122 pref = data->modules.back() + ".";
124 return pref + convertName(identifier);
127 void convertToCurrentName(
128 unoidl::detail::SourceProviderScannerData * data,
129 OString const * identifier)
131 assert(data != 0);
132 assert(data->currentName.isEmpty());
133 data->currentName = convertToFullName(data, identifier);
134 assert(!data->currentName.isEmpty());
137 void clearCurrentState(unoidl::detail::SourceProviderScannerData * data) {
138 assert(data != 0);
139 data->currentName.clear();
140 data->publishedContext = false;
143 unoidl::detail::SourceProviderEntity * getCurrentEntity(
144 unoidl::detail::SourceProviderScannerData * data)
146 assert(data != 0);
147 assert(!data->currentName.isEmpty());
148 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
149 data->entities.find(data->currentName));
150 assert(i != data->entities.end());
151 assert(i->second.kind == unoidl::detail::SourceProviderEntity::KIND_LOCAL);
152 assert(i->second.pad.is());
153 return &i->second;
156 template<typename T> rtl::Reference<T> getCurrentPad(
157 unoidl::detail::SourceProviderScannerData * data)
159 rtl::Reference<T> pad(dynamic_cast<T *>(getCurrentEntity(data)->pad.get()));
160 assert(pad.is());
161 return pad;
164 bool nameHasSameIdentifierAs(OUString const & name, OUString const & identifier)
166 sal_Int32 i = name.lastIndexOf('.') + 1;
167 return identifier.getLength() == name.getLength() - i
168 && name.match(identifier, i);
171 bool coerce(
172 YYLTYPE location, yyscan_t yyscanner,
173 unoidl::detail::SourceProviderExpr * lhs,
174 unoidl::detail::SourceProviderExpr * rhs)
176 assert(lhs != 0);
177 assert(rhs != 0);
178 bool ok = bool(); // avoid warnings
179 switch (lhs->type) {
180 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
181 ok = rhs->type != unoidl::detail::SourceProviderExpr::TYPE_BOOL;
182 break;
183 case unoidl::detail::SourceProviderExpr::TYPE_INT:
184 switch (rhs->type) {
185 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
186 ok = false;
187 break;
188 case unoidl::detail::SourceProviderExpr::TYPE_INT:
189 ok = true;
190 break;
191 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
192 if (lhs->ival >= 0) {
193 lhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
194 ok = true;
195 } else if (rhs->uval <= SAL_MAX_INT64) {
196 rhs->type = unoidl::detail::SourceProviderExpr::TYPE_INT;
197 ok = true;
198 } else {
199 ok = false;
201 break;
202 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
203 lhs->fval = lhs->ival;
204 ok = true;
205 break;
207 break;
208 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
209 switch (rhs->type) {
210 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
211 ok = false;
212 break;
213 case unoidl::detail::SourceProviderExpr::TYPE_INT:
214 if (rhs->ival >= 0) {
215 rhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
216 ok = true;
217 } else if (lhs->uval <= SAL_MAX_INT64) {
218 lhs->type = unoidl::detail::SourceProviderExpr::TYPE_INT;
219 ok = true;
220 } else {
221 ok = false;
223 break;
224 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
225 ok = true;
226 break;
227 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
228 lhs->fval = lhs->uval;
229 ok = true;
230 break;
232 break;
233 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
234 switch (rhs->type) {
235 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
236 ok = false;
237 break;
238 case unoidl::detail::SourceProviderExpr::TYPE_INT:
239 rhs->fval = rhs->ival;
240 ok = true;
241 break;
242 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
243 rhs->fval = rhs->uval;
244 ok = true;
245 break;
246 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
247 ok = true;
248 break;
250 break;
252 if (!ok) {
253 error(location, yyscanner, "cannot coerce binary expression arguments");
255 return ok;
258 unoidl::detail::SourceProviderEntity * findEntity_(
259 unoidl::detail::SourceProviderScannerData * data, OUString * name)
261 assert(data != 0);
262 assert(name != 0);
263 OUString n;
264 if (!name->startsWith(".", &n)) {
265 for (std::vector<OUString>::reverse_iterator i(data->modules.rbegin());
266 i != data->modules.rend(); ++i)
268 n = *i + "." + *name;
269 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator j(
270 data->entities.find(n));
271 if (j != data->entities.end()) {
272 *name = n;
273 return &j->second;
275 rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
276 if (ent.is()) {
277 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator
278 k(data->entities.insert(
279 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
281 unoidl::detail::SourceProviderEntity(
282 unoidl::detail::SourceProviderEntity::KIND_EXTERNAL,
283 ent))).
284 first);
285 *name = n;
286 return &k->second;
289 n = *name;
291 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
292 data->entities.find(n));
293 if (i != data->entities.end()) {
294 *name = n;
295 return &i->second;
297 rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
298 if (ent.is()) {
299 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator
300 j(data->entities.insert(
301 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
303 unoidl::detail::SourceProviderEntity(
304 unoidl::detail::SourceProviderEntity::KIND_EXTERNAL,
305 ent))).
306 first);
307 *name = n;
308 return &j->second;
310 return 0;
313 enum Found { FOUND_ERROR, FOUND_TYPE, FOUND_ENTITY };
315 Found findEntity(
316 YYLTYPE location, yyscan_t yyscanner,
317 unoidl::detail::SourceProviderScannerData * data,
318 bool resolveInterfaceDefinitions, OUString * name,
319 unoidl::detail::SourceProviderEntity const ** entity, bool * typedefed,
320 unoidl::detail::SourceProviderType * typedefedType)
322 //TODO: avoid recursion
323 assert(data != 0);
324 assert(name != 0);
325 assert(entity != 0);
326 unoidl::detail::SourceProviderEntity * e = findEntity_(data, name);
327 OUString n(*name);
328 OUString typeNucleus;
329 std::size_t rank = 0;
330 std::vector<unoidl::detail::SourceProviderType> args;
331 for (;;) {
332 if (e != 0) {
333 switch (e->kind) {
334 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
335 if (e->pad.is()) {
336 break;
338 assert(e->entity.is());
339 // fall through
340 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
341 if (e->entity->getSort() == unoidl::Entity::SORT_TYPEDEF) {
342 if (typedefed != 0) {
343 *typedefed = true;
345 if (data->publishedContext
346 && !static_cast<unoidl::TypedefEntity *>(
347 e->entity.get())->isPublished())
349 error(
350 location, yyscanner,
351 ("type " + *name + " based on unpublished typedef "
352 + n + " used in published context"));
353 return FOUND_ERROR;
355 OUString t(
356 static_cast<unoidl::TypedefEntity *>(e->entity.get())
357 ->getType());
358 typeNucleus = t;
359 while (typeNucleus.startsWith("[]", &typeNucleus)) {
360 if (!args.empty()) {
361 error(
362 location, yyscanner,
363 ("inconsistent type manager: bad type " + *name
364 + (" based on instantiated polymorphic struct"
365 " type based on sequence type named ")
366 + t));
367 return FOUND_ERROR;
369 if (rank == std::numeric_limits<std::size_t>::max()) {
370 error(
371 location, yyscanner,
372 ("bad type " + *name
373 + " based on sequence type of too high rank"));
374 return FOUND_ERROR;
376 ++rank;
378 sal_Int32 i = typeNucleus.indexOf('<');
379 if (i != -1) {
380 if (!args.empty()) {
381 error(
382 location, yyscanner,
383 ("inconsistent type manager: bad type " + *name
384 + (" based on instantiated polymorphic struct"
385 " type based on instantiated polymorphic"
386 " struct type named ")
387 + t));
388 return FOUND_ERROR;
390 OUString tmpl(typeNucleus.copy(0, i));
391 do {
392 ++i; // skip '<' or ','
393 sal_Int32 j = i;
394 for (sal_Int32 level = 0;
395 j != typeNucleus.getLength(); ++j)
397 sal_Unicode c = typeNucleus[j];
398 if (c == ',') {
399 if (level == 0) {
400 break;
402 } else if (c == '<') {
403 ++level;
404 } else if (c == '>') {
405 if (level == 0) {
406 break;
408 --level;
411 if (j != typeNucleus.getLength()) {
412 OUString argName(typeNucleus.copy(i, j - i));
413 unoidl::detail::SourceProviderEntity const *
414 argEnt;
415 unoidl::detail::SourceProviderType argType;
416 switch (
417 findEntity(
418 location, yyscanner, data, false,
419 &argName, &argEnt, 0, &argType))
421 case FOUND_ERROR:
422 return FOUND_ERROR;
423 case FOUND_TYPE:
424 break;
425 case FOUND_ENTITY:
426 if (argEnt == 0) {
427 error(
428 location, yyscanner,
429 (("inconsistent type manager: bad"
430 " instantiated polymorphic struct"
431 " type template type argument ")
432 + argName));
433 return FOUND_ERROR;
434 } else {
435 unoidl::detail::SourceProviderType::Type
436 argT
437 = unoidl::detail::SourceProviderType::Type();
438 // avoid warnings
439 switch (argEnt->kind) {
440 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
441 if (e->pad.is()) {
442 error(
443 location, yyscanner,
444 (("inconsistent type"
445 " manager: bad"
446 " instantiated"
447 " polymorphic struct type"
448 " template type"
449 " argument ")
450 + argName));
451 return FOUND_ERROR;
453 assert(e->entity.is());
454 // fall through
455 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
456 switch (e->entity->getSort()) {
457 case unoidl::Entity::SORT_ENUM_TYPE:
458 argT = unoidl::detail::SourceProviderType::TYPE_ENUM;
459 break;
460 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
461 argT = unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT;
462 break;
463 case unoidl::Entity::SORT_INTERFACE_TYPE:
464 argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
465 break;
466 default:
467 error(
468 location, yyscanner,
469 (("inconsistent type"
470 "manager: bad"
471 " instantiated"
472 " polymorphic struct type"
473 " template type"
474 " argument ")
475 + argName));
476 return FOUND_ERROR;
478 break;
479 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
480 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
481 argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
482 break;
483 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
484 assert(false && "this cannot happen");
486 argType
487 = unoidl::detail::SourceProviderType(
488 argT, argName, argEnt);
490 break;
492 args.push_back(argType);
494 i = j;
495 } while (i != typeNucleus.getLength()
496 && typeNucleus[i] != '>');
497 if (i != typeNucleus.getLength() - 1
498 || typeNucleus[i] != '>')
500 error(
501 location, yyscanner,
502 ("inconsistent type manager: bad type name \""
503 + t + "\""));
504 return FOUND_ERROR;
506 assert(!args.empty());
507 typeNucleus = tmpl;
509 if (typeNucleus.isEmpty()) {
510 error(
511 location, yyscanner,
512 ("inconsistent type manager: bad type name \"" + t
513 + "\""));
514 return FOUND_ERROR;
516 if (typeNucleus == "void") {
517 error(
518 location, yyscanner,
519 ("inconsistent type manager: bad type " + *name
520 + " based on void"));
521 return FOUND_ERROR;
523 if (typeNucleus == "boolean" || typeNucleus == "byte"
524 || typeNucleus == "short"
525 || typeNucleus == "unsigned short"
526 || typeNucleus == "long"
527 || typeNucleus == "unsigned long"
528 || typeNucleus == "hyper"
529 || typeNucleus == "unsigned hyper"
530 || typeNucleus == "float" || typeNucleus == "double"
531 || typeNucleus == "char" || typeNucleus == "string"
532 || typeNucleus == "type" || typeNucleus == "any")
534 if (!args.empty()) {
535 error(
536 location, yyscanner,
537 ("inconsistent type manager: bad type " + *name
538 + (" based on instantiated polymorphic struct"
539 " type based on ")
540 + typeNucleus));
541 return FOUND_ERROR;
543 break;
545 n = "." + typeNucleus;
546 typeNucleus.clear();
547 e = findEntity_(data, &n);
548 continue;
550 break;
551 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
552 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
553 if (resolveInterfaceDefinitions) {
554 rtl::Reference<unoidl::Entity> ent(
555 data->manager->findEntity(n));
556 // Do not allow ent to be of SORT_TYPEDEF:
557 if (!ent.is()
558 || (ent->getSort()
559 != unoidl::Entity::SORT_INTERFACE_TYPE))
561 error(
562 location, yyscanner,
563 (*name + " is based on interface declaration " + n
564 + " that is not an interface type entity"));
565 return FOUND_ERROR;
567 e->kind
568 = unoidl::detail::SourceProviderEntity::KIND_EXTERNAL;
569 e->entity = ent;
571 break;
572 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
573 error(
574 location, yyscanner,
575 *name + " is based on module entity " + n);
576 return FOUND_ERROR;
579 if (!typeNucleus.isEmpty() || rank != 0 || !args.empty()) {
580 if (typeNucleus.isEmpty() && e == 0) {
581 // Found a type name based on an unknown entity:
582 *entity = 0;
583 return FOUND_ENTITY;
585 unoidl::detail::SourceProviderType t;
586 if (args.empty()) {
587 if (typeNucleus == "boolean") {
588 t = unoidl::detail::SourceProviderType(
589 unoidl::detail::SourceProviderType::TYPE_BOOLEAN);
590 } else if (typeNucleus == "byte") {
591 t = unoidl::detail::SourceProviderType(
592 unoidl::detail::SourceProviderType::TYPE_BYTE);
593 } else if (typeNucleus == "short") {
594 t = unoidl::detail::SourceProviderType(
595 unoidl::detail::SourceProviderType::TYPE_SHORT);
596 } else if (typeNucleus == "unsigned short") {
597 t = unoidl::detail::SourceProviderType(
598 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT);
599 } else if (typeNucleus == "long") {
600 t = unoidl::detail::SourceProviderType(
601 unoidl::detail::SourceProviderType::TYPE_LONG);
602 } else if (typeNucleus == "unsigned long") {
603 t = unoidl::detail::SourceProviderType(
604 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG);
605 } else if (typeNucleus == "hyper") {
606 t = unoidl::detail::SourceProviderType(
607 unoidl::detail::SourceProviderType::TYPE_HYPER);
608 } else if (typeNucleus == "unsigned hyper") {
609 t = unoidl::detail::SourceProviderType(
610 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER);
611 } else if (typeNucleus == "float") {
612 t = unoidl::detail::SourceProviderType(
613 unoidl::detail::SourceProviderType::TYPE_FLOAT);
614 } else if (typeNucleus == "double") {
615 t = unoidl::detail::SourceProviderType(
616 unoidl::detail::SourceProviderType::TYPE_DOUBLE);
617 } else if (typeNucleus == "char") {
618 t = unoidl::detail::SourceProviderType(
619 unoidl::detail::SourceProviderType::TYPE_CHAR);
620 } else if (typeNucleus == "string") {
621 t = unoidl::detail::SourceProviderType(
622 unoidl::detail::SourceProviderType::TYPE_STRING);
623 } else if (typeNucleus == "type") {
624 t = unoidl::detail::SourceProviderType(
625 unoidl::detail::SourceProviderType::TYPE_TYPE);
626 } else if (typeNucleus == "any") {
627 t = unoidl::detail::SourceProviderType(
628 unoidl::detail::SourceProviderType::TYPE_ANY);
629 } else {
630 assert(typeNucleus.isEmpty());
631 assert(e != 0);
632 switch (e->kind) {
633 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
634 if (e->pad.is()) {
635 if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
636 e->pad.get())
637 != 0)
639 t = unoidl::detail::SourceProviderType(
640 unoidl::detail::SourceProviderType::TYPE_ENUM,
641 n, e);
642 } else if (dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
643 e->pad.get())
644 != 0)
646 t = unoidl::detail::SourceProviderType(
647 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
648 n, e);
649 } else if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
650 e->pad.get())
651 != 0)
653 error(
654 location, yyscanner,
655 ("bad type " + *name
656 + (" based on recursive reference to"
657 " polymorphic struct type template ")
658 + n));
659 return FOUND_ERROR;
660 } else if (dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
661 e->pad.get())
662 != 0)
664 t = unoidl::detail::SourceProviderType(
665 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
666 n, e);
667 } else if (dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
668 e->pad.get())
669 != 0)
671 t = unoidl::detail::SourceProviderType(
672 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
673 n, e);
674 } else {
675 error(
676 location, yyscanner,
677 ("bad type " + *name
678 + " based on non-type entity " + n));
679 return FOUND_ERROR;
681 break;
683 assert(e->entity.is());
684 // fall through
685 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
686 switch (e->entity->getSort()) {
687 case unoidl::Entity::SORT_ENUM_TYPE:
688 t = unoidl::detail::SourceProviderType(
689 unoidl::detail::SourceProviderType::TYPE_ENUM,
690 n, e);
691 break;
692 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
693 t = unoidl::detail::SourceProviderType(
694 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
695 n, e);
696 break;
697 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
698 error(
699 location, yyscanner,
700 ("bad type " + *name
701 + " based on polymorphic struct type template "
702 + n + " without type arguments"));
703 return FOUND_ERROR;
704 case unoidl::Entity::SORT_EXCEPTION_TYPE:
705 t = unoidl::detail::SourceProviderType(
706 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
707 n, e);
708 break;
709 case unoidl::Entity::SORT_INTERFACE_TYPE:
710 t = unoidl::detail::SourceProviderType(
711 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
712 n, e);
713 break;
714 default:
715 error(
716 location, yyscanner,
717 ("bad type " + *name
718 + " based on non-type entity " + n));
719 return FOUND_ERROR;
721 break;
722 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
723 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
724 t = unoidl::detail::SourceProviderType(
725 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
726 n, e);
727 break;
728 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
729 assert(false && "this cannot happen");
732 } else {
733 assert(typeNucleus.isEmpty());
734 assert(e != 0);
735 switch (e->kind) {
736 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
737 if (e->pad.is()) {
738 error(
739 location, yyscanner,
740 ("bad type " + *name
741 + (" based on instantiated polymorphic struct type"
742 " based on ")
744 + (" that is either not a polymorphic struct type"
745 " template or a recursive reference to a"
746 " polymorphic struct type template")));
747 return FOUND_ERROR;
749 assert(e->entity.is());
750 // fall through
751 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
752 if (e->entity->getSort()
753 == unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)
755 if (args.size()
756 != (static_cast<
757 unoidl::PolymorphicStructTypeTemplateEntity *>(
758 e->entity.get())
759 ->getTypeParameters().size()))
761 error(
762 location, yyscanner,
763 ("bad type " + *name
764 + (" based on instantiated polymorphic struct"
765 " type with ")
766 + OUString::number(args.size())
767 + (" type arguments based on polymorphic"
768 " struct type template ")
769 + n + " with "
770 + OUString::number(
771 static_cast<
772 unoidl::PolymorphicStructTypeTemplateEntity *>(
773 e->entity.get())
774 ->getTypeParameters().size())
775 + " type paramters"));
776 return FOUND_ERROR;
778 t = unoidl::detail::SourceProviderType(n, e, args);
779 break;
781 // fall through
782 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
783 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
784 error(
785 location, yyscanner,
786 ("bad type " + *name
787 + (" based on instantiated polymorphic struct type"
788 " based on ")
790 + " that is not a polymorphic struct type template"));
791 return FOUND_ERROR;
792 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
793 assert(false && "this cannot happen");
796 if (typedefedType != 0) {
797 for (std::size_t i = 0; i != rank; ++i) {
798 t = unoidl::detail::SourceProviderType(&t);
800 *typedefedType = t;
801 typedefedType->typedefName = *name;
803 *entity = 0;
804 return FOUND_TYPE;
806 *entity = e;
807 return FOUND_ENTITY;
812 bool checkTypeArgument(
813 YYLTYPE location, yyscan_t yyscanner,
814 unoidl::detail::SourceProviderType const & type)
816 switch (type.type) {
817 case unoidl::detail::SourceProviderType::TYPE_VOID:
818 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
819 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
820 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
821 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
822 case unoidl::detail::SourceProviderType::TYPE_PARAMETER: //TODO?
823 error(
824 location, yyscanner,
825 "bad instantiated polymorphic struct type argument");
826 return false;
827 case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
828 return checkTypeArgument(location, yyscanner, type.subtypes.front());
829 default:
830 return true;
834 bool checkInstantiatedPolymorphicStructTypeArgument(
835 unoidl::detail::SourceProviderType const & type, OUString const & name)
837 if (type.type
838 == unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT)
840 for (std::vector<unoidl::detail::SourceProviderType>::const_iterator i(
841 type.subtypes.begin());
842 i != type.subtypes.end(); ++i)
844 if (checkInstantiatedPolymorphicStructTypeArgument(*i, name)
845 || i->getName() == name) // no need to worry about typedef
847 return true;
851 return false;
854 std::vector<OUString> annotations(bool deprecated) {
855 std::vector<OUString> ann;
856 if (deprecated) {
857 ann.push_back("deprecated");
859 return ann;
866 %token TOK_ELLIPSIS
867 %token TOK_COLONS
868 %token TOK_LEFTSHIFT
869 %token TOK_RIGHTSHIFT
871 %token TOK_FALSE
872 %token TOK_TRUE
873 %token TOK_ANY
874 %token TOK_ATTRIBUTE
875 %token TOK_BOOLEAN
876 %token TOK_BOUND
877 %token TOK_BYTE
878 %token TOK_CHAR
879 %token TOK_CONST
880 %token TOK_CONSTANTS
881 %token TOK_CONSTRAINED
882 %token TOK_DOUBLE
883 %token TOK_ENUM
884 %token TOK_EXCEPTION
885 %token TOK_FLOAT
886 %token TOK_GET
887 %token TOK_HYPER
888 %token TOK_IN
889 %token TOK_INOUT
890 %token TOK_INTERFACE
891 %token TOK_LONG
892 %token TOK_MAYBEAMBIGUOUS
893 %token TOK_MAYBEDEFAULT
894 %token TOK_MAYBEVOID
895 %token TOK_MODULE
896 %token TOK_OPTIONAL
897 %token TOK_OUT
898 %token TOK_PROPERTY
899 %token TOK_PUBLISHED
900 %token TOK_RAISES
901 %token TOK_READONLY
902 %token TOK_REMOVABLE
903 %token TOK_SEQUENCE
904 %token TOK_SERVICE
905 %token TOK_SET
906 %token TOK_SHORT
907 %token TOK_SINGLETON
908 %token TOK_STRING
909 %token TOK_STRUCT
910 %token TOK_TRANSIENT
911 %token TOK_TYPE
912 %token TOK_TYPEDEF
913 %token TOK_UNSIGNED
914 %token TOK_VOID
916 %token<sval> TOK_IDENTIFIER
917 %token<ival> TOK_INTEGER
918 %token<fval> TOK_FLOATING
920 %token TOK_DEPRECATED
922 %token TOK_ERROR
924 %type<sval> identifier name singleInheritance singleInheritance_opt
925 %type<bval> ctors_opt deprecated_opt ellipsis_opt published_opt
926 %type<decls> attributeAccessDecl attributeAccessDecls
927 %type<dir> direction
928 %type<excns> exceptionSpec exceptionSpec_opt exceptions
929 %type<flags> flag flagSection flagSection_opt flags
930 %type<expr> addExpr andExpr expr multExpr orExpr primaryExpr shiftExpr unaryExpr
931 xorExpr
932 %type<type> type
933 %type<types> typeArguments
935 %initial-action { yylloc = 1; }
939 definitions:
940 definitions definition
941 | /* empty */
944 definition:
945 moduleDecl
946 | enumDefn
947 | plainStructDefn
948 | polymorphicStructTemplateDefn
949 | exceptionDefn
950 | interfaceDefn
951 | typedefDefn
952 | constantGroupDefn
953 | singleInterfaceBasedServiceDefn
954 | accumulationBasedServiceDefn
955 | interfaceBasedSingletonDefn
956 | serviceBasedSingletonDefn
957 | interfaceDecl
960 moduleDecl:
961 TOK_MODULE identifier
963 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
964 OUString name(convertToFullName(data, $2));
965 data->modules.push_back(name);
966 std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
967 data->entities.insert(
968 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
969 name,
970 unoidl::detail::SourceProviderEntity(
971 unoidl::detail::SourceProviderEntity::KIND_MODULE))));
972 if (!p.second
973 && (p.first->second.kind
974 != unoidl::detail::SourceProviderEntity::KIND_MODULE))
976 error(@2, yyscanner, "multiple entities named " + name);
977 YYERROR;
980 '{' definitions '}' ';' { yyget_extra(yyscanner)->modules.pop_back(); }
983 enumDefn:
984 deprecated_opt published_opt TOK_ENUM identifier
986 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
987 data->publishedContext = $2;
988 convertToCurrentName(data, $4);
989 if (!data->entities.insert(
990 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
991 data->currentName,
992 unoidl::detail::SourceProviderEntity(
993 new unoidl::detail::SourceProviderEnumTypeEntityPad(
994 $2)))).
995 second)
997 error(@4, yyscanner, "multiple entities named " + data->currentName);
998 YYERROR;
1001 '{' enumMembers '}' ';'
1003 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1004 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1005 unoidl::detail::SourceProviderEnumTypeEntityPad * pad =
1006 dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
1007 ent->pad.get());
1008 assert(pad != 0);
1009 ent->entity = new unoidl::EnumTypeEntity(
1010 pad->isPublished(), pad->members, annotations($1));
1011 ent->pad.clear();
1012 clearCurrentState(data);
1016 enumMembers:
1017 | enumMembers ',' enumMember
1018 | enumMember
1021 enumMember:
1022 deprecated_opt identifier
1024 OUString id(convertName($2));
1025 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1026 rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
1027 getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
1028 sal_Int32 v;
1029 if (pad->members.empty()) {
1030 v = 0;
1031 } else {
1032 v = pad->members.back().value;
1033 if (v == SAL_MAX_INT32) {
1034 error(
1035 @2, yyscanner,
1036 ("enum " + data->currentName + " member " + id
1037 + " would have out-of-range value 2^31"));
1038 YYERROR;
1040 ++v;
1042 pad->members.push_back(
1043 unoidl::EnumTypeEntity::Member(id, v, annotations($1)));
1045 | deprecated_opt identifier '=' expr
1047 OUString id(convertName($2));
1048 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1049 rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
1050 getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
1051 sal_Int32 v;
1052 switch ($4.type) {
1053 case unoidl::detail::SourceProviderExpr::TYPE_INT:
1054 if ($4.ival < SAL_MIN_INT32 || $4.ival > SAL_MAX_INT32) {
1055 error(
1056 @4, yyscanner,
1057 ("out-of-range enum " + data->currentName + " member " + id
1058 + " value " + OUString::number($4.ival)));
1059 YYERROR;
1061 v = static_cast<sal_Int32>($4.ival);
1062 break;
1063 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
1064 if ($4.uval > SAL_MAX_INT32) {
1065 error(
1066 @4, yyscanner,
1067 ("out-of-range enum " + data->currentName + " member " + id
1068 + " value " + OUString::number($4.uval)));
1069 YYERROR;
1071 v = static_cast<sal_Int32>($4.uval);
1072 break;
1073 default:
1074 error(
1075 @4, yyscanner,
1076 ("non-integer enum " + data->currentName + " member " + id
1077 + " value"));
1078 YYERROR;
1079 break;
1081 pad->members.push_back(
1082 unoidl::EnumTypeEntity::Member(id, v, annotations($1)));
1086 plainStructDefn:
1087 deprecated_opt published_opt TOK_STRUCT identifier singleInheritance_opt
1089 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1090 data->publishedContext = $2;
1091 convertToCurrentName(data, $4);
1092 OUString baseName;
1093 rtl::Reference<unoidl::PlainStructTypeEntity> baseEnt;
1094 if ($5 != 0) {
1095 baseName = convertName($5);
1096 unoidl::detail::SourceProviderEntity const * p;
1097 if (findEntity(@5, yyscanner, data, false, &baseName, &p, 0, 0)
1098 == FOUND_ERROR)
1100 YYERROR;
1102 if (p == 0 || !p->entity.is()
1103 || p->entity->getSort() != unoidl::Entity::SORT_PLAIN_STRUCT_TYPE)
1105 error(
1106 @5, yyscanner,
1107 ("plain struct type " + data->currentName + " base "
1108 + baseName
1109 + " does not resolve to an existing plain struct type"));
1110 YYERROR;
1112 baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
1113 p->entity.get());
1114 if ($2 && !baseEnt->isPublished()) {
1115 error(
1116 @5, yyscanner,
1117 ("published plain struct type " + data->currentName + " base "
1118 + baseName + " is unpublished"));
1119 YYERROR;
1122 if (!data->entities.insert(
1123 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
1124 data->currentName,
1125 unoidl::detail::SourceProviderEntity(
1126 new unoidl::detail::SourceProviderPlainStructTypeEntityPad(
1127 $2, baseName, baseEnt)))).
1128 second)
1130 error(@4, yyscanner, "multiple entities named " + data->currentName);
1131 YYERROR;
1134 '{' structMembers '}' ';'
1136 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1137 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1138 unoidl::detail::SourceProviderPlainStructTypeEntityPad * pad =
1139 dynamic_cast<
1140 unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
1141 ent->pad.get());
1142 assert(pad != 0);
1143 ent->entity = new unoidl::PlainStructTypeEntity(
1144 pad->isPublished(), pad->baseName, pad->members, annotations($1));
1145 ent->pad.clear();
1146 clearCurrentState(data);
1150 polymorphicStructTemplateDefn:
1151 deprecated_opt published_opt TOK_STRUCT identifier '<'
1153 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1154 data->publishedContext = $2;
1155 convertToCurrentName(data, $4);
1156 if (!data->entities.insert(
1157 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
1158 data->currentName,
1159 unoidl::detail::SourceProviderEntity(
1160 new unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad(
1161 $2)))).
1162 second)
1164 error(@4, yyscanner, "multiple entities named " + data->currentName);
1165 YYERROR;
1168 typeParameters '>' '{' structMembers '}' ';'
1170 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1171 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1172 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
1173 pad = dynamic_cast<
1174 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
1175 ent->pad.get());
1176 assert(pad != 0);
1177 ent->entity = new unoidl::PolymorphicStructTypeTemplateEntity(
1178 pad->isPublished(), pad->typeParameters, pad->members,
1179 annotations($1));
1180 ent->pad.clear();
1181 clearCurrentState(data);
1185 typeParameters:
1186 typeParameters ',' identifier
1188 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1189 rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
1190 pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
1191 data));
1192 OUString id(convertName($3));
1193 if (std::find(pad->typeParameters.begin(), pad->typeParameters.end(), id)
1194 != pad->typeParameters.end())
1196 error(
1197 @3, yyscanner,
1198 ("polymorphic struct type template " + data->currentName
1199 + " type parameter " + id
1200 + " has same identifier as another type parameter"));
1201 YYERROR;
1203 pad->typeParameters.push_back(id);
1205 | identifier
1207 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1208 rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
1209 pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
1210 data));
1211 OUString id(convertName($1));
1212 assert(pad->typeParameters.empty());
1213 pad->typeParameters.push_back(id);
1217 exceptionDefn:
1218 deprecated_opt published_opt TOK_EXCEPTION identifier singleInheritance_opt
1220 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1221 data->publishedContext = $2;
1222 convertToCurrentName(data, $4);
1223 OUString baseName;
1224 rtl::Reference<unoidl::ExceptionTypeEntity> baseEnt;
1225 if ($5 != 0) {
1226 baseName = convertName($5);
1227 unoidl::detail::SourceProviderEntity const * p;
1228 if (findEntity(@5, yyscanner, data, false, &baseName, &p, 0, 0)
1229 == FOUND_ERROR)
1231 YYERROR;
1233 if (p == 0 || !p->entity.is()
1234 || p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE)
1236 error(
1237 @5, yyscanner,
1238 ("exception type " + data->currentName + " base " + baseName
1239 + " does not resolve to an existing exception type"));
1240 YYERROR;
1242 baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
1243 p->entity.get());
1244 if ($2 && !baseEnt->isPublished()) {
1245 error(
1246 @5, yyscanner,
1247 ("published exception type " + data->currentName + " base "
1248 + baseName + " is unpublished"));
1249 YYERROR;
1252 if (!data->entities.insert(
1253 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
1254 data->currentName,
1255 unoidl::detail::SourceProviderEntity(
1256 new unoidl::detail::SourceProviderExceptionTypeEntityPad(
1257 $2, baseName, baseEnt)))).
1258 second)
1260 error(@4, yyscanner, "multiple entities named " + data->currentName);
1261 YYERROR;
1264 '{' structMembers '}' ';'
1266 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1267 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1268 unoidl::detail::SourceProviderExceptionTypeEntityPad * pad =
1269 dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
1270 ent->pad.get());
1271 assert(pad != 0);
1272 ent->entity = new unoidl::ExceptionTypeEntity(
1273 pad->isPublished(), pad->baseName, pad->members, annotations($1));
1274 ent->pad.clear();
1275 clearCurrentState(data);
1279 structMembers:
1280 structMembers structMember
1281 | /* empty */
1284 structMember:
1285 deprecated_opt type identifier ';'
1287 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1288 unoidl::detail::SourceProviderType t(*$2);
1289 delete $2;
1290 OUString id(convertName($3));
1291 switch (t.type) {
1292 case unoidl::detail::SourceProviderType::TYPE_VOID:
1293 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1294 error(
1295 @2, yyscanner,
1296 ("illegal struct/exception type " + data->currentName
1297 + " direct member " + id + " type"));
1298 YYERROR;
1299 break;
1300 default:
1301 break;
1303 if (t.type != unoidl::detail::SourceProviderType::TYPE_PARAMETER
1304 && t.getName() == data->currentName) // no need to worry about typedef
1306 error(
1307 @2, yyscanner,
1308 ("struct/exception type " + data->currentName + " direct member "
1309 + id + " has same type as the type itself"));
1310 YYERROR;
1312 if (checkInstantiatedPolymorphicStructTypeArgument(t, data->currentName))
1314 error(
1315 @2, yyscanner,
1316 ("struct/exception type " + data->currentName + " direct member "
1317 + id
1318 + (" has instantiated polymorphic struct type that uses the type"
1319 " itself as an argument")));
1320 YYERROR;
1322 if (nameHasSameIdentifierAs(data->currentName, id)) {
1323 error(
1324 @3, yyscanner,
1325 ("struct/exception type " + data->currentName + " direct member "
1326 + id + " has same unqualified identifer as the type itself"));
1327 YYERROR;
1329 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1330 unoidl::detail::SourceProviderPlainStructTypeEntityPad * p1 =
1331 dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
1332 ent->pad.get());
1333 if (p1 != 0) {
1334 for (std::vector<unoidl::PlainStructTypeEntity::Member>::iterator i(
1335 p1->members.begin());
1336 i != p1->members.end(); ++i)
1338 if (id == i->name) {
1339 error(
1340 @3, yyscanner,
1341 ("plain struct type " + data->currentName
1342 + " direct member " + id
1343 + " has same identifier as another direct member"));
1344 YYERROR;
1347 if (p1->baseEntity.is()) {
1348 OUString baseName(p1->baseName);
1349 for (rtl::Reference<unoidl::PlainStructTypeEntity> baseEnt(
1350 p1->baseEntity);;)
1352 if (nameHasSameIdentifierAs(baseName, id)) {
1353 error(
1354 @3, yyscanner,
1355 ("plain struct type " + data->currentName
1356 + " direct member " + id
1357 + " has same unqalified identifier as base "
1358 + baseName));
1359 YYERROR;
1361 for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator i(
1362 baseEnt->getDirectMembers().begin());
1363 i != baseEnt->getDirectMembers().end(); ++i)
1365 if (id == i->name) {
1366 error(
1367 @3, yyscanner,
1368 ("plain struct type " + data->currentName
1369 + " direct member " + id
1370 + " has same identifier as a member of base "
1371 + baseName));
1372 YYERROR;
1375 baseName = baseEnt->getDirectBase();
1376 if (baseName.isEmpty()) {
1377 break;
1379 unoidl::detail::SourceProviderEntity const * p;
1380 if (findEntity(
1381 @2, yyscanner, data, false, &baseName, &p, 0, 0)
1382 == FOUND_ERROR)
1384 YYERROR;
1386 if (p == 0 || !p->entity.is()
1387 || (p->entity->getSort()
1388 != unoidl::Entity::SORT_PLAIN_STRUCT_TYPE))
1390 error(
1391 @2, yyscanner,
1392 ("inconsistent type manager: plain struct type "
1393 + data->currentName + " base " + baseName
1394 + (" does not resolve to an existing plain struct"
1395 " type")));
1396 YYERROR;
1398 baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
1399 p->entity.get());
1402 p1->members.push_back(
1403 unoidl::PlainStructTypeEntity::Member(
1404 id, t.getName(), annotations($1)));
1405 } else {
1406 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
1407 p2 = dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
1408 ent->pad.get());
1409 if (p2 != 0) {
1410 for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::iterator i(
1411 p2->members.begin());
1412 i != p2->members.end(); ++i)
1414 if (id == i->name) {
1415 error(
1416 @3, yyscanner,
1417 ("polymorphic struct type template "
1418 + data->currentName + " direct member " + id
1419 + " has same identifier as another direct member"));
1420 YYERROR;
1423 p2->members.push_back(
1424 unoidl::PolymorphicStructTypeTemplateEntity::Member(
1425 id, t.getName(),
1426 (t.type
1427 == unoidl::detail::SourceProviderType::TYPE_PARAMETER),
1428 annotations($1)));
1429 } else {
1430 unoidl::detail::SourceProviderExceptionTypeEntityPad * p3
1431 = dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
1432 ent->pad.get());
1433 assert(p3 != 0);
1434 for (std::vector<unoidl::ExceptionTypeEntity::Member>::iterator i(
1435 p3->members.begin());
1436 i != p3->members.end(); ++i)
1438 if (id == i->name) {
1439 error(
1440 @3, yyscanner,
1441 ("exception type " + data->currentName
1442 + " direct member " + id
1443 + " has same identifier as another direct member"));
1444 YYERROR;
1447 if (p3->baseEntity.is()) {
1448 OUString baseName(p3->baseName);
1449 for (rtl::Reference<unoidl::ExceptionTypeEntity> baseEnt(
1450 p3->baseEntity);;)
1452 if (nameHasSameIdentifierAs(baseName, id)) {
1453 error(
1454 @3, yyscanner,
1455 ("exception type " + data->currentName
1456 + " direct member " + id
1457 + " has same unqalified identifier as base "
1458 + baseName));
1459 YYERROR;
1461 for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator i(
1462 baseEnt->getDirectMembers().begin());
1463 i != baseEnt->getDirectMembers().end(); ++i)
1465 if (id == i->name) {
1466 error(
1467 @3, yyscanner,
1468 ("exception type " + data->currentName
1469 + " direct member " + id
1470 + " has same identifier as a member of base "
1471 + baseName));
1472 YYERROR;
1475 baseName = baseEnt->getDirectBase();
1476 if (baseName.isEmpty()) {
1477 break;
1479 unoidl::detail::SourceProviderEntity const * p;
1480 if (findEntity(
1481 @2, yyscanner, data, false, &baseName, &p, 0, 0)
1482 == FOUND_ERROR)
1484 YYERROR;
1486 if (p == 0 || !p->entity.is()
1487 || (p->entity->getSort()
1488 != unoidl::Entity::SORT_EXCEPTION_TYPE))
1490 error(
1491 @2, yyscanner,
1492 ("inconsistent type manager: exception type "
1493 + data->currentName + " base " + baseName
1494 + (" does not resolve to an existing exception"
1495 " type")));
1496 YYERROR;
1498 baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
1499 p->entity.get());
1502 p3->members.push_back(
1503 unoidl::ExceptionTypeEntity::Member(
1504 id, t.getName(), annotations($1)));
1510 interfaceDefn:
1511 deprecated_opt published_opt TOK_INTERFACE identifier singleInheritance_opt
1513 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1514 data->publishedContext = $2;
1515 convertToCurrentName(data, $4);
1516 OUString baseName;
1517 rtl::Reference<unoidl::InterfaceTypeEntity> baseEnt;
1518 if ($5 != 0) {
1519 baseName = convertName($5);
1520 unoidl::detail::SourceProviderEntity const * p;
1521 if (findEntity(@5, yyscanner, data, true, &baseName, &p, 0, 0)
1522 == FOUND_ERROR)
1524 YYERROR;
1526 if (p == 0 || !p->entity.is()
1527 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1529 error(
1530 @5, yyscanner,
1531 ("interface type " + data->currentName + " direct base "
1532 + baseName
1533 + " does not resolve to an existing interface type"));
1534 YYERROR;
1536 baseEnt = static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get());
1537 if ($2 && !baseEnt->isPublished()) {
1538 error(
1539 @5, yyscanner,
1540 ("published interface type " + data->currentName
1541 + " direct base " + baseName + " is unpublished"));
1542 YYERROR;
1545 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
1546 data->entities.find(data->currentName));
1547 if (i != data->entities.end()) {
1548 switch (i->second.kind) {
1549 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
1550 break;
1551 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
1552 if (!$2) {
1553 error(
1554 @4, yyscanner,
1555 ("unpublished interface type " + data->currentName
1556 + " has been declared published"));
1557 YYERROR;
1559 break;
1560 default:
1561 error(
1562 @4, yyscanner,
1563 "multiple entities named " + data->currentName);
1564 YYERROR;
1565 break;
1568 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1569 new unoidl::detail::SourceProviderInterfaceTypeEntityPad(
1570 $2, baseEnt.is()));
1571 if (baseEnt.is()
1572 && !pad->addDirectBase(
1573 @4, yyscanner, data,
1574 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1575 baseName, baseEnt, std::vector<OUString>()),
1576 false))
1578 YYERROR;
1580 data->entities[data->currentName] = unoidl::detail::SourceProviderEntity(
1581 pad.get());
1583 '{' interfaceMembers '}' ';'
1585 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1586 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1587 unoidl::detail::SourceProviderInterfaceTypeEntityPad * pad =
1588 dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
1589 ent->pad.get());
1590 assert(pad != 0);
1591 if (pad->directMandatoryBases.empty()
1592 && data->currentName != "com.sun.star.uno.XInterface")
1594 OUString base(".com.sun.star.uno.XInterface");
1595 unoidl::detail::SourceProviderEntity const * p;
1596 if (findEntity(@4, yyscanner, data, true, &base, &p, 0, 0)
1597 == FOUND_ERROR)
1599 YYERROR;
1601 if (p == 0 || !p->entity.is()
1602 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1604 error(
1605 @3, yyscanner,
1606 ("interface type " + data->currentName
1607 + " implicit direct base " + base
1608 + " does not resolve to an existing interface type"));
1609 YYERROR;
1611 if (!pad->addDirectBase(
1612 @3, yyscanner, data,
1613 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1614 base,
1615 static_cast<unoidl::InterfaceTypeEntity *>(
1616 p->entity.get()),
1617 std::vector<OUString>()),
1618 false))
1620 YYERROR;
1623 std::vector<unoidl::AnnotatedReference> mbases;
1624 for (std::vector<unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase>::const_iterator
1625 i(pad->directMandatoryBases.begin());
1626 i != pad->directMandatoryBases.end(); ++i)
1628 mbases.push_back(unoidl::AnnotatedReference(i->name, i->annotations));
1630 std::vector<unoidl::AnnotatedReference> obases;
1631 for (std::vector<unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase>::const_iterator
1632 i(pad->directOptionalBases.begin());
1633 i != pad->directOptionalBases.end(); ++i)
1635 obases.push_back(unoidl::AnnotatedReference(i->name, i->annotations));
1637 ent->entity = new unoidl::InterfaceTypeEntity(
1638 pad->isPublished(), mbases, obases, pad->directAttributes,
1639 pad->directMethods, annotations($1));
1640 ent->pad.clear();
1641 clearCurrentState(data);
1645 interfaceMembers:
1646 interfaceMembers interfaceMember
1647 | /* empty */
1650 interfaceMember:
1651 interfaceBase
1652 | interfaceAttribute
1653 | interfaceMethod
1656 interfaceBase:
1657 deprecated_opt flagSection_opt TOK_INTERFACE name ';'
1659 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1660 OUString name(convertName($4));
1661 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1662 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1663 data));
1664 if (pad->singleBase) {
1665 error(
1666 @3, yyscanner,
1667 "single-inheritance interface cannot have additional bases");
1668 YYERROR;
1670 if (($2 & ~unoidl::detail::FLAG_OPTIONAL) != 0) {
1671 error(
1672 @2, yyscanner,
1673 "interface base can only be flagged as [optional]");
1674 YYERROR;
1676 bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
1677 OUString orgName(name);
1678 unoidl::detail::SourceProviderEntity const * p;
1679 bool typedefed = false;
1680 if (findEntity(@4, yyscanner, data, true, &name, &p, &typedefed, 0)
1681 == FOUND_ERROR)
1683 YYERROR;
1685 if (p == 0 || !p->entity.is()
1686 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1688 error(
1689 @4, yyscanner,
1690 ("interface type " + data->currentName + " direct base " + name
1691 + " does not resolve to an existing interface type"));
1692 YYERROR;
1694 if (typedefed) {
1695 error(
1696 @4, yyscanner,
1697 ("interface type " + data->currentName + " direct base " + orgName
1698 + " is a typedef"));
1699 YYERROR;
1701 rtl::Reference<unoidl::InterfaceTypeEntity> ent(
1702 static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get()));
1703 if (data->publishedContext && !ent->isPublished()) {
1704 error(
1705 @4, yyscanner,
1706 ("published interface type " + data->currentName + " direct base "
1707 + name + " is unpublished"));
1708 YYERROR;
1710 if (!pad->addDirectBase(
1711 @4, yyscanner, data,
1712 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1713 name, ent, annotations($1)),
1714 opt))
1716 YYERROR;
1721 interfaceAttribute:
1722 deprecated_opt flagSection type identifier
1724 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1725 unoidl::detail::SourceProviderType t(*$3);
1726 delete $3;
1727 OUString id(convertName($4));
1728 if (($2 & unoidl::detail::FLAG_ATTRIBUTE) == 0) {
1729 error(
1730 @2, yyscanner,
1731 "interface attribute must be flagged as [attribute]");
1732 YYERROR;
1734 if (($2
1735 & ~(unoidl::detail::FLAG_ATTRIBUTE | unoidl::detail::FLAG_BOUND
1736 | unoidl::detail::FLAG_READONLY))
1737 != 0)
1739 error(
1740 @2, yyscanner,
1741 ("interface attribute can only be flagged as [attribute,"
1742 " optional]"));
1743 YYERROR;
1745 switch (t.type) {
1746 case unoidl::detail::SourceProviderType::TYPE_VOID:
1747 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1748 error(
1749 @3, yyscanner,
1750 ("illegal interface type " + data->currentName
1751 + " direct attribute " + id + " type"));
1752 YYERROR;
1753 break;
1754 default:
1755 break;
1757 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1758 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1759 data));
1760 if (!pad->addDirectMember(@4, yyscanner, data, id)) {
1761 YYERROR;
1763 pad->directAttributes.push_back(
1764 unoidl::InterfaceTypeEntity::Attribute(
1765 id, t.getName(), ($2 & unoidl::detail::FLAG_BOUND) != 0,
1766 ($2 & unoidl::detail::FLAG_READONLY) != 0,
1767 std::vector<OUString>(), std::vector<OUString>(),
1768 annotations($1)));
1770 attributeAccessDecls_opt ';'
1773 attributeAccessDecls_opt:
1774 '{' attributeAccessDecls '}'
1775 | /* empty */
1778 attributeAccessDecls:
1779 attributeAccessDecls attributeAccessDecl
1781 if (($1 & $2) != 0) {
1782 error(
1783 @2, yyscanner, "duplicate get/set attribute access declaration");
1784 YYERROR;
1786 $$ = unoidl::detail::SourceProviderAccessDecls($1 | $2);
1788 | /* empty */ { $$ = unoidl::detail::SourceProviderAccessDecls(0); }
1791 attributeAccessDecl:
1792 TOK_GET exceptionSpec ';'
1794 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1795 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1796 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1797 data));
1798 assert(!pad->directAttributes.empty());
1799 pad->directAttributes.back().getExceptions = *$2;
1800 delete $2;
1801 $$ = unoidl::detail::ACCESS_DECL_GET;
1803 | TOK_SET exceptionSpec ';'
1805 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1806 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1807 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1808 data));
1809 assert(!pad->directAttributes.empty());
1810 pad->directAttributes.back().setExceptions = *$2;
1811 delete $2;
1812 if (pad->directAttributes.back().readOnly) {
1813 error(
1814 @1, yyscanner,
1815 ("interface type " + data->currentName
1816 + " direct read-only attribute "
1817 + pad->directAttributes.back().name
1818 + " cannot have set access declaration"));
1819 YYERROR;
1821 $$ = unoidl::detail::ACCESS_DECL_SET;
1825 interfaceMethod:
1826 deprecated_opt type identifier
1828 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1829 unoidl::detail::SourceProviderType t(*$2);
1830 delete $2;
1831 OUString id(convertName($3));
1832 if (t.type == unoidl::detail::SourceProviderType::TYPE_EXCEPTION) {
1833 error(
1834 @3, yyscanner,
1835 ("illegal interface type " + data->currentName
1836 + " direct method " + id + " return type"));
1837 YYERROR;
1839 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1840 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1841 data));
1842 if (!pad->addDirectMember(@3, yyscanner, data, id)) {
1843 YYERROR;
1845 pad->directMethods.push_back(
1846 unoidl::InterfaceTypeEntity::Method(
1847 id, t.getName(),
1848 std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>(),
1849 std::vector<OUString>(), annotations($1)));
1851 '(' methodParams_opt ')' exceptionSpec_opt ';'
1853 if ($8 != 0) {
1854 unoidl::detail::SourceProviderScannerData * data
1855 = yyget_extra(yyscanner);
1856 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1857 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1858 data));
1859 assert(!pad->directMethods.empty());
1860 pad->directMethods.back().exceptions = *$8;
1861 delete $8;
1866 methodParams_opt:
1867 methodParams
1868 | /* empty */
1871 methodParams:
1872 methodParams ',' methodParam
1873 | methodParam
1876 methodParam:
1877 '[' direction ']' type identifier
1879 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1880 unoidl::detail::SourceProviderType t(*$4);
1881 delete $4;
1882 OUString id(convertName($5));
1883 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1884 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1885 data));
1886 assert(!pad->directMethods.empty());
1887 switch (t.type) {
1888 case unoidl::detail::SourceProviderType::TYPE_VOID:
1889 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1890 error(
1891 @4, yyscanner,
1892 ("illegal interface type " + data->currentName
1893 + " direct method " + pad->directMethods.back().name
1894 + " parameter " + id + " type"));
1895 YYERROR;
1896 break;
1897 default:
1898 break;
1900 for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::iterator
1901 i(pad->directMethods.back().parameters.begin());
1902 i != pad->directMethods.back().parameters.end(); ++i)
1904 if (id == i->name) {
1905 error(
1906 @5, yyscanner,
1907 ("interface type " + data->currentName + " direct method "
1908 + pad->directMethods.back().name + " parameter " + id
1909 + " has same identifier as another parameter"));
1910 YYERROR;
1913 pad->directMethods.back().parameters.push_back(
1914 unoidl::InterfaceTypeEntity::Method::Parameter(id, t.getName(), $2));
1918 direction:
1919 TOK_IN { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN; }
1920 | TOK_OUT
1921 { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT; }
1922 | TOK_INOUT
1923 { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT; }
1926 typedefDefn:
1927 deprecated_opt published_opt TOK_TYPEDEF type identifier ';'
1929 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1930 data->publishedContext = $2;
1931 unoidl::detail::SourceProviderType t(*$4);
1932 delete $4;
1933 OUString name(convertToFullName(data, $5));
1934 // There is no good reason to forbid typedefs to VOID, to instantiated
1935 // polymorphic struct types, and to exception types, but some old client
1936 // code of registry data expects this typedef restriction (like the
1937 // assert(false) default in handleTypedef in
1938 // codemaker/source/javamaker/javatype.cxx), so forbid them for now:
1939 switch (t.type) {
1940 case unoidl::detail::SourceProviderType::TYPE_VOID:
1941 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1942 case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
1943 error(@4, yyscanner, "bad typedef type");
1944 YYERROR;
1945 break;
1946 case unoidl::detail::SourceProviderType::TYPE_ENUM:
1947 case unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT:
1948 case unoidl::detail::SourceProviderType::TYPE_INTERFACE:
1949 if ($2) {
1950 bool unpub = false;
1951 switch (t.entity->kind) {
1952 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
1953 unpub = true;
1954 break;
1955 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
1956 break;
1957 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
1958 assert(false && "this cannot happen");
1959 default:
1960 assert(t.entity->entity.is() || t.entity->pad.is());
1961 unpub
1962 = !(t.entity->entity.is()
1963 ? static_cast<unoidl::PublishableEntity *>(
1964 t.entity->entity.get())->isPublished()
1965 : t.entity->pad->isPublished());
1966 break;
1968 if (unpub) {
1969 error(
1970 @4, yyscanner,
1971 "published typedef " + name + " type is unpublished");
1972 YYERROR;
1975 break;
1976 case unoidl::detail::SourceProviderType::TYPE_PARAMETER:
1977 assert(false && "this cannot happen");
1978 default:
1979 break;
1981 if (!data->entities.insert(
1982 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
1983 name,
1984 unoidl::detail::SourceProviderEntity(
1985 unoidl::detail::SourceProviderEntity::KIND_LOCAL,
1986 new unoidl::TypedefEntity(
1987 $2, t.getName(), annotations($1))))).
1988 second)
1990 error(@5, yyscanner, "multiple entities named " + name);
1991 YYERROR;
1993 clearCurrentState(data);
1997 constantGroupDefn:
1998 deprecated_opt published_opt TOK_CONSTANTS identifier
2000 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2001 data->publishedContext = $2;
2002 convertToCurrentName(data, $4);
2003 if (!data->entities.insert(
2004 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
2005 data->currentName,
2006 unoidl::detail::SourceProviderEntity(
2007 new unoidl::detail::SourceProviderConstantGroupEntityPad(
2008 $2)))).
2009 second)
2011 error(@4, yyscanner, "multiple entities named " + data->currentName);
2012 YYERROR;
2015 '{' constants '}' ';'
2017 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2018 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
2019 unoidl::detail::SourceProviderConstantGroupEntityPad * pad =
2020 dynamic_cast<unoidl::detail::SourceProviderConstantGroupEntityPad *>(
2021 ent->pad.get());
2022 assert(pad != 0);
2023 ent->entity = new unoidl::ConstantGroupEntity(
2024 pad->isPublished(), pad->members, annotations($1));
2025 ent->pad.clear();
2026 clearCurrentState(data);
2030 constants:
2031 constants constant
2032 | /* empty */
2035 constant:
2036 deprecated_opt TOK_CONST type identifier '=' expr ';'
2038 OUString id(convertName($4));
2039 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2040 rtl::Reference<unoidl::detail::SourceProviderConstantGroupEntityPad> pad(
2041 getCurrentPad<unoidl::detail::SourceProviderConstantGroupEntityPad>(
2042 data));
2043 unoidl::detail::SourceProviderType t(*$3);
2044 delete $3;
2045 unoidl::ConstantValue v(false); // dummy value
2046 switch (t.type) {
2047 case unoidl::detail::SourceProviderType::TYPE_BOOLEAN:
2048 if ($6.type != unoidl::detail::SourceProviderExpr::TYPE_BOOL) {
2049 error(
2050 @6, yyscanner,
2051 ("bad value of boolean-typed constant " + data->currentName
2052 + "." + id));
2053 YYERROR;
2055 v = unoidl::ConstantValue($6.bval);
2056 break;
2057 case unoidl::detail::SourceProviderType::TYPE_BYTE:
2058 switch ($6.type) {
2059 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2060 if ($6.ival < SAL_MIN_INT8 || $6.ival > SAL_MAX_INT8) {
2061 error(
2062 @6, yyscanner,
2063 ("out-of-range byte-typed constant " + data->currentName
2064 + "." + id + " value " + OUString::number($6.ival)));
2065 YYERROR;
2067 v = unoidl::ConstantValue(static_cast<sal_Int8>($6.ival));
2068 break;
2069 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2070 if ($6.uval > SAL_MAX_INT8) {
2071 error(
2072 @6, yyscanner,
2073 ("out-of-range byte-typed constant " + data->currentName
2074 + "." + id + " value " + OUString::number($6.uval)));
2075 YYERROR;
2077 v = unoidl::ConstantValue(static_cast<sal_Int8>($6.uval));
2078 break;
2079 default:
2080 error(
2081 @6, yyscanner,
2082 ("bad value of byte-typed constant " + data->currentName + "."
2083 + id));
2084 YYERROR;
2085 break;
2087 break;
2088 case unoidl::detail::SourceProviderType::TYPE_SHORT:
2089 switch ($6.type) {
2090 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2091 if ($6.ival < SAL_MIN_INT16 || $6.ival > SAL_MAX_INT16) {
2092 error(
2093 @6, yyscanner,
2094 ("out-of-range short-typed constant " + data->currentName
2095 + "." + id + " value " + OUString::number($6.ival)));
2096 YYERROR;
2098 v = unoidl::ConstantValue(static_cast<sal_Int16>($6.ival));
2099 break;
2100 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2101 if ($6.uval > SAL_MAX_INT16) {
2102 error(
2103 @6, yyscanner,
2104 ("out-of-range short-typed constant " + data->currentName
2105 + "." + id + " value " + OUString::number($6.uval)));
2106 YYERROR;
2108 v = unoidl::ConstantValue(static_cast<sal_Int16>($6.uval));
2109 break;
2110 default:
2111 error(
2112 @6, yyscanner,
2113 ("bad value of short-typed constant " + data->currentName
2114 + "." + id));
2115 YYERROR;
2116 break;
2118 break;
2119 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
2120 switch ($6.type) {
2121 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2122 if ($6.ival < 0 || $6.ival > SAL_MAX_UINT16) {
2123 error(
2124 @6, yyscanner,
2125 ("out-of-range unsigned-short-typed constant "
2126 + data->currentName + "." + id + " value "
2127 + OUString::number($6.ival)));
2128 YYERROR;
2130 v = unoidl::ConstantValue(static_cast<sal_uInt16>($6.ival));
2131 break;
2132 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2133 if ($6.uval > SAL_MAX_UINT16) {
2134 error(
2135 @6, yyscanner,
2136 ("out-of-range unsigned-short-typed constant "
2137 + data->currentName + "." + id + " value "
2138 + OUString::number($6.uval)));
2139 YYERROR;
2141 v = unoidl::ConstantValue(static_cast<sal_uInt16>($6.uval));
2142 break;
2143 default:
2144 error(
2145 @6, yyscanner,
2146 ("bad value of unsigned-short-typed constant "
2147 + data->currentName + "." + id));
2148 YYERROR;
2149 break;
2151 break;
2152 case unoidl::detail::SourceProviderType::TYPE_LONG:
2153 switch ($6.type) {
2154 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2155 if ($6.ival < SAL_MIN_INT32 || $6.ival > SAL_MAX_INT32) {
2156 error(
2157 @6, yyscanner,
2158 ("out-of-range long-typed constant " + data->currentName
2159 + "." + id + " value " + OUString::number($6.ival)));
2160 YYERROR;
2162 v = unoidl::ConstantValue(static_cast<sal_Int32>($6.ival));
2163 break;
2164 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2165 if ($6.uval > SAL_MAX_INT32) {
2166 error(
2167 @6, yyscanner,
2168 ("out-of-range long-typed constant " + data->currentName
2169 + "." + id + " value " + OUString::number($6.uval)));
2170 YYERROR;
2172 v = unoidl::ConstantValue(static_cast<sal_Int32>($6.uval));
2173 break;
2174 default:
2175 error(
2176 @6, yyscanner,
2177 ("bad value of long-typed constant " + data->currentName
2178 + "." + id));
2179 YYERROR;
2180 break;
2182 break;
2183 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
2184 switch ($6.type) {
2185 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2186 if ($6.ival < 0 || $6.ival > SAL_MAX_UINT32) {
2187 error(
2188 @6, yyscanner,
2189 ("out-of-range unsigned-long-typed constant "
2190 + data->currentName + "." + id + " value "
2191 + OUString::number($6.ival)));
2192 YYERROR;
2194 v = unoidl::ConstantValue(static_cast<sal_uInt32>($6.ival));
2195 break;
2196 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2197 if ($6.uval > SAL_MAX_UINT32) {
2198 error(
2199 @6, yyscanner,
2200 ("out-of-range unsigned-long-typed constant "
2201 + data->currentName + "." + id + " value "
2202 + OUString::number($6.uval)));
2203 YYERROR;
2205 v = unoidl::ConstantValue(static_cast<sal_uInt32>($6.uval));
2206 break;
2207 default:
2208 error(
2209 @6, yyscanner,
2210 ("bad value of unsigned-long-typed constant "
2211 + data->currentName + "." + id));
2212 YYERROR;
2213 break;
2215 break;
2216 case unoidl::detail::SourceProviderType::TYPE_HYPER:
2217 switch ($6.type) {
2218 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2219 v = unoidl::ConstantValue($6.ival);
2220 break;
2221 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2222 if ($6.uval > SAL_MAX_INT64) {
2223 error(
2224 @6, yyscanner,
2225 ("out-of-range hyper-typed constant " + data->currentName
2226 + "." + id + " value " + OUString::number($6.uval)));
2227 YYERROR;
2229 v = unoidl::ConstantValue(static_cast<sal_Int64>($6.uval));
2230 break;
2231 default:
2232 error(
2233 @6, yyscanner,
2234 ("bad value of hyper-typed constant " + data->currentName
2235 + "." + id));
2236 YYERROR;
2237 break;
2239 break;
2240 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
2241 switch ($6.type) {
2242 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2243 if ($6.ival < 0) {
2244 error(
2245 @6, yyscanner,
2246 ("out-of-range unsigned-hyper-typed constant "
2247 + data->currentName + "." + id + " value "
2248 + OUString::number($6.ival)));
2249 YYERROR;
2251 v = unoidl::ConstantValue(static_cast<sal_uInt64>($6.ival));
2252 break;
2253 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2254 v = unoidl::ConstantValue($6.uval);
2255 break;
2256 default:
2257 error(
2258 @6, yyscanner,
2259 ("bad value of unsigned-hyper-typed constant "
2260 + data->currentName + "." + id));
2261 YYERROR;
2262 break;
2264 break;
2265 case unoidl::detail::SourceProviderType::TYPE_FLOAT:
2266 switch ($6.type) {
2267 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
2268 error(
2269 @6, yyscanner,
2270 ("bad boolean value of float-typed constant "
2271 + data->currentName + "." + id));
2272 YYERROR;
2273 break;
2274 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2275 v = unoidl::ConstantValue(static_cast<float>($6.ival));
2276 break;
2277 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2278 v = unoidl::ConstantValue(static_cast<float>($6.uval));
2279 break;
2280 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
2281 v = unoidl::ConstantValue(static_cast<float>($6.fval));
2282 break;
2284 break;
2285 case unoidl::detail::SourceProviderType::TYPE_DOUBLE:
2286 switch ($6.type) {
2287 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
2288 error(
2289 @6, yyscanner,
2290 ("bad boolean value of double-typed constant "
2291 + data->currentName + "." + id));
2292 YYERROR;
2293 break;
2294 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2295 v = unoidl::ConstantValue(static_cast<double>($6.ival));
2296 break;
2297 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2298 v = unoidl::ConstantValue(static_cast<double>($6.uval));
2299 break;
2300 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
2301 v = unoidl::ConstantValue($6.fval);
2302 break;
2304 break;
2305 default:
2306 error(
2307 @3, yyscanner,
2308 "bad type for constant " + data->currentName + "." + id);
2309 YYERROR;
2310 break;
2312 pad->members.push_back(
2313 unoidl::ConstantGroupEntity::Member(id, v, annotations($1)));
2317 singleInterfaceBasedServiceDefn:
2318 deprecated_opt published_opt TOK_SERVICE identifier singleInheritance
2320 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2321 data->publishedContext = $2;
2322 convertToCurrentName(data, $4);
2323 OUString base(convertName($5));
2324 unoidl::detail::SourceProviderEntity const * p;
2325 if (findEntity(@5, yyscanner, data, false, &base, &p, 0, 0)
2326 == FOUND_ERROR)
2328 YYERROR;
2330 bool ifcBase = false;
2331 bool pubBase = false;
2332 if (p != 0) {
2333 switch (p->kind) {
2334 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
2335 ifcBase = true;
2336 pubBase = false;
2337 break;
2338 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
2339 ifcBase = true;
2340 pubBase = true;
2341 break;
2342 default:
2343 if (p->entity.is()
2344 && (p->entity->getSort()
2345 == unoidl::Entity::SORT_INTERFACE_TYPE))
2347 ifcBase = true;
2348 pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
2349 p->entity.get())->isPublished();
2351 break;
2354 if (!ifcBase) {
2355 error(
2356 @5, yyscanner,
2357 ("single-interface--based service " + data->currentName + " base "
2358 + base + " does not resolve to an interface type"));
2359 YYERROR;
2361 if ($2 && !pubBase) {
2362 error(
2363 @5, yyscanner,
2364 ("published single-interface--based service " + data->currentName
2365 + " base " + base + " is unpublished"));
2366 YYERROR;
2368 if (!data->entities.insert(
2369 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
2370 data->currentName,
2371 unoidl::detail::SourceProviderEntity(
2372 new unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad(
2373 $2, base)))).
2374 second)
2376 error(@4, yyscanner, "multiple entities named " + data->currentName);
2377 YYERROR;
2380 ctors_opt ';'
2382 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2383 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
2384 unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad * pad =
2385 dynamic_cast<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad *>(
2386 ent->pad.get());
2387 assert(pad != 0);
2388 std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor> ctors;
2389 if ($7) {
2390 for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor>::iterator
2391 i(pad->constructors.begin());
2392 i != pad->constructors.end(); ++i)
2394 std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter> parms;
2395 for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter>::iterator
2396 j(i->parameters.begin());
2397 j != i->parameters.end(); ++j)
2399 parms.push_back(
2400 unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter(
2401 j->name, j->type.getName(), j->rest));
2403 ctors.push_back(
2404 unoidl::SingleInterfaceBasedServiceEntity::Constructor(
2405 i->name, parms, i->exceptions, i->annotations));
2407 } else {
2408 assert(pad->constructors.empty());
2409 ctors.push_back(
2410 unoidl::SingleInterfaceBasedServiceEntity::Constructor());
2412 ent->entity = new unoidl::SingleInterfaceBasedServiceEntity(
2413 pad->isPublished(), pad->base, ctors, annotations($1));
2414 ent->pad.clear();
2415 clearCurrentState(data);
2419 ctors_opt:
2420 '{' ctors '}' { $$ = true; }
2421 | /* empty */ { $$ = false; }
2424 ctors:
2425 ctors ctor
2426 | /* empty */
2429 ctor:
2430 deprecated_opt identifier
2432 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2433 OUString id(convertName($2));
2434 rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
2435 pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
2436 data));
2437 for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor>::iterator
2438 i(pad->constructors.begin());
2439 i != pad->constructors.end(); ++i)
2441 if (id == i->name) {
2442 error(
2443 @2, yyscanner,
2444 ("single-interface--based service " + data->currentName
2445 + " constructor " + id
2446 + " has same identifier as another constructor"));
2447 YYERROR;
2450 pad->constructors.push_back(
2451 unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor(
2452 id, annotations($1)));
2454 '(' ctorParams_opt ')' exceptionSpec_opt ';'
2456 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2457 rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
2458 pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
2459 data));
2460 assert(!pad->constructors.empty());
2461 if ($7 != 0) {
2462 pad->constructors.back().exceptions = *$7;
2463 delete $7;
2465 for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor>::iterator
2466 i(pad->constructors.begin());
2467 i != pad->constructors.end() - 1; ++i)
2469 if (i->parameters.size()
2470 == pad->constructors.back().parameters.size())
2472 bool same = true;
2473 for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter>::iterator
2474 j(i->parameters.begin()),
2475 k(pad->constructors.back().parameters.begin());
2476 j != i->parameters.end(); ++j, ++k)
2478 if (!j->type.equals(k->type) || j->rest != k->rest) {
2479 same = false;
2480 break;
2483 if (same) {
2484 error(
2485 @2, yyscanner,
2486 ("single-interface--based service " + data->currentName
2487 + " constructor " + pad->constructors.back().name
2488 + " has similar paramete list to constructor "
2489 + i->name));
2490 YYERROR;
2497 ctorParams_opt:
2498 ctorParams
2499 | /* empty */
2502 ctorParams:
2503 ctorParams ',' ctorParam
2504 | ctorParam
2507 ctorParam:
2508 '[' direction ']' type ellipsis_opt identifier
2510 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2511 unoidl::detail::SourceProviderType t(*$4);
2512 delete $4;
2513 OUString id(convertName($6));
2514 rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
2515 pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
2516 data));
2517 assert(!pad->constructors.empty());
2518 if ($2 != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN) {
2519 error(
2520 @4, yyscanner,
2521 ("single-interface--based service " + data->currentName
2522 + " constructor " + pad->constructors.back().name + " parameter "
2523 + id + " direction must be [in]"));
2524 YYERROR;
2526 switch (t.type) {
2527 case unoidl::detail::SourceProviderType::TYPE_VOID:
2528 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
2529 error(
2530 @4, yyscanner,
2531 ("illegal single-interface--based service " + data->currentName
2532 + " constructor " + pad->constructors.back().name + " parameter "
2533 + id + " type"));
2534 YYERROR;
2535 break;
2536 default:
2537 break;
2539 if ($5) {
2540 if (t.type != unoidl::detail::SourceProviderType::TYPE_ANY) {
2541 error(
2542 @4, yyscanner,
2543 ("illegal single-interface--based service "
2544 + data->currentName + " constructor "
2545 + pad->constructors.back().name + " rest parameter " + id
2546 + " non-any type"));
2547 YYERROR;
2549 if (!pad->constructors.back().parameters.empty()) {
2550 error(
2551 @5, yyscanner,
2552 ("single-interface--based service " + data->currentName
2553 + " constructor " + pad->constructors.back().name
2554 + " rest parameter " + id + " must be first parameter"));
2555 YYERROR;
2557 } else if (!pad->constructors.back().parameters.empty()
2558 && pad->constructors.back().parameters.back().rest)
2560 error(
2561 @1, yyscanner,
2562 ("single-interface--based service " + data->currentName
2563 + " constructor " + pad->constructors.back().name
2564 + " rest parameter must be last parameter"));
2565 YYERROR;
2567 for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter>::iterator
2568 i(pad->constructors.back().parameters.begin());
2569 i != pad->constructors.back().parameters.end(); ++i)
2571 if (id == i->name) {
2572 error(
2573 @6, yyscanner,
2574 ("single-interface--based service " + data->currentName
2575 + " constructor " + pad->constructors.back().name
2576 + " parameter " + id
2577 + " has same identifier as another parameter"));
2578 YYERROR;
2581 pad->constructors.back().parameters.push_back(
2582 unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter(
2583 id, t, $5));
2587 ellipsis_opt:
2588 TOK_ELLIPSIS { $$ = true; }
2589 | /* empty */ { $$ = false; }
2591 accumulationBasedServiceDefn:
2592 deprecated_opt published_opt TOK_SERVICE identifier
2594 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2595 data->publishedContext = $2;
2596 convertToCurrentName(data, $4);
2597 if (!data->entities.insert(
2598 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
2599 data->currentName,
2600 unoidl::detail::SourceProviderEntity(
2601 new unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad(
2602 $2)))).
2603 second)
2605 error(@4, yyscanner, "multiple entities named " + data->currentName);
2606 YYERROR;
2609 '{' serviceMembers '}' ';'
2611 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2612 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
2613 unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad * pad =
2614 dynamic_cast<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad *>(
2615 ent->pad.get());
2616 assert(pad != 0);
2617 ent->entity = new unoidl::AccumulationBasedServiceEntity(
2618 pad->isPublished(), pad->directMandatoryBaseServices,
2619 pad->directOptionalBaseServices, pad->directMandatoryBaseInterfaces,
2620 pad->directOptionalBaseInterfaces, pad->directProperties,
2621 annotations($1));
2622 ent->pad.clear();
2623 clearCurrentState(data);
2627 serviceMembers:
2628 serviceMembers serviceMember
2629 | /* empty */
2632 serviceMember:
2633 serviceBase
2634 | serviceInterfaceBase
2635 | serviceProperty
2638 serviceBase:
2639 deprecated_opt flagSection_opt TOK_SERVICE name ';'
2641 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2642 OUString name(convertName($4));
2643 rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad> pad(
2644 getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
2645 data));
2646 if (($2 & ~unoidl::detail::FLAG_OPTIONAL) != 0) {
2647 error(
2648 @2, yyscanner,
2649 "service base can only be flagged as [optional]");
2650 YYERROR;
2652 bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
2653 unoidl::detail::SourceProviderEntity const * p;
2654 if (findEntity(@4, yyscanner, data, false, &name, &p, 0, 0)
2655 == FOUND_ERROR)
2657 YYERROR;
2659 if (p == 0 || !p->entity.is()
2660 || (p->entity->getSort()
2661 != unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE))
2663 error(
2664 @4, yyscanner,
2665 ("accumulation-based service " + data->currentName
2666 + " direct base service " + name
2667 + " does not resolve to an accumulation-based service"));
2668 YYERROR;
2670 if (data->publishedContext
2671 && !static_cast<unoidl::AccumulationBasedServiceEntity *>(
2672 p->entity.get())->isPublished())
2674 error(
2675 @4, yyscanner,
2676 ("published accumulation-based service " + data->currentName
2677 + " direct base service " + name + " is unpublished"));
2678 YYERROR;
2680 std::vector<unoidl::AnnotatedReference> & v(
2682 ? pad->directOptionalBaseServices : pad->directMandatoryBaseServices);
2683 for (std::vector<unoidl::AnnotatedReference>::iterator i(v.begin());
2684 i != v.end(); ++i)
2686 if (name == i->name) {
2687 error(
2688 @4, yyscanner,
2689 ("accumulation-based service " + data->currentName
2690 + " duplicate direct base service " + name));
2691 YYERROR;
2694 v.push_back(unoidl::AnnotatedReference(name, annotations($1)));
2698 serviceInterfaceBase:
2699 deprecated_opt flagSection_opt TOK_INTERFACE name ';'
2701 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2702 OUString name(convertName($4));
2703 rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad> pad(
2704 getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
2705 data));
2706 if (($2 & ~unoidl::detail::FLAG_OPTIONAL) != 0) {
2707 error(
2708 @2, yyscanner,
2709 "interface base can only be flagged as [optional]");
2710 YYERROR;
2712 bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
2713 unoidl::detail::SourceProviderEntity const * p;
2714 if (findEntity(@4, yyscanner, data, false, &name, &p, 0, 0)
2715 == FOUND_ERROR)
2717 YYERROR;
2719 bool ifcBase = false;
2720 bool pubBase = false;
2721 if (p != 0) {
2722 switch (p->kind) {
2723 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
2724 ifcBase = true;
2725 pubBase = false;
2726 break;
2727 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
2728 ifcBase = true;
2729 pubBase = true;
2730 break;
2731 default:
2732 if (p->entity.is()
2733 && (p->entity->getSort()
2734 == unoidl::Entity::SORT_INTERFACE_TYPE))
2736 ifcBase = true;
2737 pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
2738 p->entity.get())->isPublished();
2740 break;
2743 if (!ifcBase) {
2744 error(
2745 @4, yyscanner,
2746 ("accumulation-based service " + data->currentName
2747 + " direct base interface " + name
2748 + " does not resolve to an interface type"));
2749 YYERROR;
2751 if (data->publishedContext && !opt && !pubBase) {
2752 error(
2753 @4, yyscanner,
2754 ("published accumulation-based service " + data->currentName
2755 + " direct base interface " + name + " is unpublished"));
2756 YYERROR;
2758 std::vector<unoidl::AnnotatedReference> & v(
2760 ? pad->directOptionalBaseInterfaces
2761 : pad->directMandatoryBaseInterfaces);
2762 for (std::vector<unoidl::AnnotatedReference>::iterator i(v.begin());
2763 i != v.end(); ++i)
2765 if (name == i->name) {
2766 error(
2767 @4, yyscanner,
2768 ("accumulation-based service " + data->currentName
2769 + " duplicate direct base interface " + name));
2770 YYERROR;
2773 v.push_back(unoidl::AnnotatedReference(name, annotations($1)));
2777 serviceProperty:
2778 deprecated_opt flagSection type identifier ';'
2780 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2781 unoidl::detail::SourceProviderType t(*$3);
2782 delete $3;
2783 OUString id(convertName($4));
2784 if (($2 & unoidl::detail::FLAG_PROPERTY) == 0) {
2785 error(
2786 @2, yyscanner,
2787 ("accumulation-based service property must be flagged as"
2788 " [property]"));
2789 YYERROR;
2791 if (($2
2792 & ~(unoidl::detail::FLAG_BOUND | unoidl::detail::FLAG_CONSTRAINED
2793 | unoidl::detail::FLAG_MAYBEAMBIGUOUS
2794 | unoidl::detail::FLAG_MAYBEDEFAULT
2795 | unoidl::detail::FLAG_MAYBEVOID | unoidl::detail::FLAG_OPTIONAL
2796 | unoidl::detail::FLAG_PROPERTY | unoidl::detail::FLAG_READONLY
2797 | unoidl::detail::FLAG_REMOVABLE
2798 | unoidl::detail::FLAG_TRANSIENT))
2799 != 0)
2801 error(
2802 @2, yyscanner,
2803 ("accumulation-based service property can only be flagged as"
2804 " [property, bound, constrained, maybeambiguous, maybedefault,"
2805 " maybevoid, optional, readonly, removable, transient]"));
2806 YYERROR;
2808 int att = 0;
2809 if (($2 & unoidl::detail::FLAG_BOUND) != 0) {
2810 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND;
2812 if (($2 & unoidl::detail::FLAG_CONSTRAINED) != 0) {
2813 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED;
2815 if (($2 & unoidl::detail::FLAG_MAYBEAMBIGUOUS) != 0) {
2816 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS;
2818 if (($2 & unoidl::detail::FLAG_MAYBEDEFAULT) != 0) {
2819 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT;
2821 if (($2 & unoidl::detail::FLAG_MAYBEVOID) != 0) {
2822 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID;
2824 if (($2 & unoidl::detail::FLAG_OPTIONAL) != 0) {
2825 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL;
2827 if (($2 & unoidl::detail::FLAG_READONLY) != 0) {
2828 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY;
2830 if (($2 & unoidl::detail::FLAG_REMOVABLE) != 0) {
2831 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE;
2833 if (($2 & unoidl::detail::FLAG_TRANSIENT) != 0) {
2834 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT;
2836 switch (t.type) {
2837 case unoidl::detail::SourceProviderType::TYPE_VOID:
2838 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
2839 error(
2840 @3, yyscanner,
2841 ("illegal accumulation-based service " + data->currentName
2842 + " direct property " + id + " type"));
2843 YYERROR;
2844 break;
2845 default:
2846 break;
2848 rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>
2849 pad(getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
2850 data));
2851 for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::iterator
2852 i(pad->directProperties.begin());
2853 i != pad->directProperties.end(); ++i)
2855 if (id == i->name) {
2856 error(
2857 @4, yyscanner,
2858 ("accumulation-based service " + data->currentName
2859 + " duplicate direct property " + id));
2860 YYERROR;
2863 pad->directProperties.push_back(
2864 unoidl::AccumulationBasedServiceEntity::Property(
2865 id, t.getName(),
2866 unoidl::AccumulationBasedServiceEntity::Property::Attributes(att),
2867 annotations($1)));
2871 interfaceBasedSingletonDefn:
2872 deprecated_opt published_opt TOK_SINGLETON identifier singleInheritance ';'
2874 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2875 data->publishedContext = $2;
2876 OUString name(convertToFullName(data, $4));
2877 OUString base(convertName($5));
2878 unoidl::detail::SourceProviderEntity const * p;
2879 if (findEntity(@5, yyscanner, data, false, &base, &p, 0, 0)
2880 == FOUND_ERROR)
2882 YYERROR;
2884 bool ifcBase = false;
2885 bool pubBase = false;
2886 if (p != 0) {
2887 switch (p->kind) {
2888 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
2889 ifcBase = true;
2890 pubBase = false;
2891 break;
2892 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
2893 ifcBase = true;
2894 pubBase = true;
2895 break;
2896 default:
2897 if (p->entity.is()
2898 && (p->entity->getSort()
2899 == unoidl::Entity::SORT_INTERFACE_TYPE))
2901 ifcBase = true;
2902 pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
2903 p->entity.get())->isPublished();
2905 break;
2908 if (!ifcBase) {
2909 error(
2910 @5, yyscanner,
2911 ("interface-based singleton " + name + " base " + base
2912 + " does not resolve to an interface type"));
2913 YYERROR;
2915 if ($2 && !pubBase) {
2916 error(
2917 @5, yyscanner,
2918 ("published interface-based singleton " + name + " base " + base
2919 + " is unpublished"));
2920 YYERROR;
2922 if (!data->entities.insert(
2923 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
2924 name,
2925 unoidl::detail::SourceProviderEntity(
2926 unoidl::detail::SourceProviderEntity::KIND_LOCAL,
2927 new unoidl::InterfaceBasedSingletonEntity(
2928 $2, base, annotations($1))))).
2929 second)
2931 error(@4, yyscanner, "multiple entities named " + name);
2932 YYERROR;
2934 clearCurrentState(data);
2938 serviceBasedSingletonDefn:
2939 deprecated_opt published_opt TOK_SINGLETON identifier '{' TOK_SERVICE name ';'
2940 '}' ';'
2942 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2943 data->publishedContext = $2;
2944 OUString name(convertToFullName(data, $4));
2945 OUString base(convertName($7));
2946 unoidl::detail::SourceProviderEntity const * p;
2947 if (findEntity(@7, yyscanner, data, false, &base, &p, 0, 0)
2948 == FOUND_ERROR)
2950 YYERROR;
2952 if (p == 0
2953 || !p->entity.is()
2954 || (p->entity->getSort()
2955 != unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE))
2957 error(
2958 @7, yyscanner,
2959 ("service-based singleton " + name + " base " + base
2960 + " does not resolve to an accumulation-based service"));
2961 YYERROR;
2963 if ($2
2964 && !static_cast<unoidl::AccumulationBasedServiceEntity *>(
2965 p->entity.get())->isPublished())
2967 error(
2968 @7, yyscanner,
2969 ("published service-based singleton " + name + " base " + base
2970 + " is unpublished"));
2971 YYERROR;
2973 if (!data->entities.insert(
2974 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
2975 name,
2976 unoidl::detail::SourceProviderEntity(
2977 unoidl::detail::SourceProviderEntity::KIND_LOCAL,
2978 new unoidl::ServiceBasedSingletonEntity(
2979 $2, base, annotations($1))))).
2980 second)
2982 error(@4, yyscanner, "multiple entities named " + name);
2983 YYERROR;
2985 clearCurrentState(data);
2989 singleInheritance_opt:
2990 singleInheritance
2991 | /* empty */ { $$ = 0; }
2994 singleInheritance: ':' name { $$ = $2; }
2997 exceptionSpec_opt:
2998 exceptionSpec
2999 | /* empty */ { $$ = 0; }
3002 exceptionSpec: TOK_RAISES '(' exceptions ')' { $$ = $3; }
3005 exceptions:
3006 exceptions ',' name
3008 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3009 OUString name(convertName($3));
3010 unoidl::detail::SourceProviderEntity const * p;
3011 if (findEntity(@3, yyscanner, data, false, &name, &p, 0, 0)
3012 == FOUND_ERROR)
3014 delete $1; /* see commented-out %destructor above */
3015 YYERROR;
3017 if (p == 0
3018 || !p->entity.is()
3019 || (p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE))
3021 delete $1; /* see commented-out %destructor above */
3022 error(
3023 @3, yyscanner,
3024 ("exception " + name + " does not resolve to an exception type"));
3025 YYERROR;
3027 if (data->publishedContext
3028 && !(static_cast<unoidl::ExceptionTypeEntity *>(p->entity.get())
3029 ->isPublished()))
3031 delete $1; /* see commented-out %destructor above */
3032 error(
3033 @3, yyscanner,
3034 ("unpublished exception " + name + " used in published context"));
3035 YYERROR;
3037 if (std::find($1->begin(), $1->end(), name) != $1->end()) {
3038 delete $1; /* see commented-out %destructor above */
3039 error(
3040 @3, yyscanner, ("exception " + name + " listed more than once"));
3041 YYERROR;
3043 $1->push_back(name);
3044 $$ = $1;
3046 | name
3048 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3049 OUString name(convertName($1));
3050 unoidl::detail::SourceProviderEntity const * p;
3051 if (findEntity(@1, yyscanner, data, false, &name, &p, 0, 0)
3052 == FOUND_ERROR)
3054 YYERROR;
3056 if (p == 0
3057 || !p->entity.is()
3058 || (p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE))
3060 error(
3061 @1, yyscanner,
3062 ("exception " + name + " does not resolve to an exception type"));
3063 YYERROR;
3065 if (data->publishedContext
3066 && !(static_cast<unoidl::ExceptionTypeEntity *>(p->entity.get())
3067 ->isPublished()))
3069 error(
3070 @1, yyscanner,
3071 ("unpublished exception " + name + " used in published context"));
3072 YYERROR;
3074 $$ = new std::vector<OUString>; $$->push_back(name);
3078 interfaceDecl:
3079 deprecated_opt/*ignored*/ published_opt TOK_INTERFACE identifier ';'
3081 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3082 data->publishedContext = $2;
3083 OUString name(convertToFullName(data, $4));
3084 std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
3085 data->entities.insert(
3086 std::map<OUString, unoidl::detail::SourceProviderEntity>::value_type(
3087 name,
3088 unoidl::detail::SourceProviderEntity(
3090 ? unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL
3091 : unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL))));
3092 if (!p.second) {
3093 switch (p.first->second.kind) {
3094 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
3095 if ($2) {
3096 p.first->second.kind
3097 = unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL;
3099 break;
3100 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
3101 break;
3102 default:
3103 assert(p.first->second.entity.is());
3104 if (p.first->second.entity->getSort()
3105 != unoidl::Entity::SORT_INTERFACE_TYPE)
3107 error(
3108 @4, yyscanner,
3109 "multiple entities named " + data->currentName);
3110 YYERROR;
3112 if ($2
3113 && !static_cast<unoidl::InterfaceTypeEntity *>(
3114 p.first->second.entity.get())->isPublished())
3116 error(
3117 @4, yyscanner,
3118 ("published interface type declaration "
3119 + data->currentName + " has been defined unpublished"));
3120 YYERROR;
3124 clearCurrentState(data);
3128 published_opt:
3129 TOK_PUBLISHED { $$ = true; }
3130 | /* empty */ { $$ = false; }
3133 flagSection_opt:
3134 flagSection
3135 | /* empty */ { $$ = unoidl::detail::SourceProviderFlags(0); }
3138 flagSection: '[' flags ']' { $$ = $2; }
3141 flags:
3142 flags ',' flag
3144 if (($1 & $3) != 0) {
3145 error(@3, yyscanner, "duplicate flag " + flagName($3));
3146 YYERROR;
3148 $$ = unoidl::detail::SourceProviderFlags($1 | $3);
3150 | flag
3153 flag:
3154 TOK_ATTRIBUTE { $$ = unoidl::detail::FLAG_ATTRIBUTE; }
3155 | TOK_BOUND { $$ = unoidl::detail::FLAG_BOUND; }
3156 | TOK_CONSTRAINED { $$ = unoidl::detail::FLAG_CONSTRAINED; }
3157 | TOK_MAYBEAMBIGUOUS { $$ = unoidl::detail::FLAG_MAYBEAMBIGUOUS; }
3158 | TOK_MAYBEDEFAULT { $$ = unoidl::detail::FLAG_MAYBEDEFAULT; }
3159 | TOK_MAYBEVOID { $$ = unoidl::detail::FLAG_MAYBEVOID; }
3160 | TOK_OPTIONAL { $$ = unoidl::detail::FLAG_OPTIONAL; }
3161 | TOK_PROPERTY { $$ = unoidl::detail::FLAG_PROPERTY; }
3162 | TOK_READONLY { $$ = unoidl::detail::FLAG_READONLY; }
3163 | TOK_REMOVABLE { $$ = unoidl::detail::FLAG_REMOVABLE; }
3164 | TOK_TRANSIENT { $$ = unoidl::detail::FLAG_TRANSIENT; }
3167 expr: orExpr
3170 orExpr:
3171 orExpr '|' xorExpr
3173 if (!coerce(@1, yyscanner, &$1, &$3)) {
3174 YYERROR;
3176 switch ($1.type) {
3177 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3178 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival | $3.ival);
3179 break;
3180 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3181 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval | $3.uval);
3182 break;
3183 default:
3184 error(@1, yyscanner, "arguments of non-integer type to \"|\"");
3185 YYERROR;
3186 break;
3189 | xorExpr
3192 xorExpr:
3193 xorExpr '^' andExpr
3195 if (!coerce(@1, yyscanner, &$1, &$3)) {
3196 YYERROR;
3198 switch ($1.type) {
3199 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3200 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival ^ $3.ival);
3201 break;
3202 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3203 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval ^ $3.uval);
3204 break;
3205 default:
3206 error(@1, yyscanner, "arguments of non-integer type to \"^\"");
3207 YYERROR;
3208 break;
3211 | andExpr
3214 andExpr:
3215 andExpr '&' shiftExpr
3217 if (!coerce(@1, yyscanner, &$1, &$3)) {
3218 YYERROR;
3220 switch ($1.type) {
3221 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3222 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival & $3.ival);
3223 break;
3224 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3225 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval & $3.uval);
3226 break;
3227 default:
3228 error(@1, yyscanner, "arguments of non-integer type to \"&\"");
3229 YYERROR;
3230 break;
3233 | shiftExpr
3236 shiftExpr:
3237 shiftExpr TOK_LEFTSHIFT addExpr
3239 int n;
3240 switch ($3.type) {
3241 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3242 if ($3.ival < 0 || $3.ival > 63) {
3243 error(
3244 @3, yyscanner,
3245 ("out-of-range shift argument " + OUString::number($3.ival)
3246 + " to \"<<\" "));
3247 YYERROR;
3249 n = static_cast<int>($3.ival);
3250 break;
3251 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3252 if ($3.uval > 63) {
3253 error(
3254 @3, yyscanner,
3255 ("out-of-range shift argument " + OUString::number($3.uval)
3256 + " to \"<<\" "));
3257 YYERROR;
3259 n = static_cast<int>($3.uval);
3260 break;
3261 default:
3262 error(@3, yyscanner, "right argument of non-integer type to \"<<\"");
3263 YYERROR;
3265 switch ($1.type) {
3266 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3267 if ($1.ival < 0) {
3268 error(
3269 @1, yyscanner,
3270 ("cannot left-shift negative argument "
3271 + OUString::number($1.ival)));
3272 YYERROR;
3274 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival << n);
3275 break;
3276 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3277 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval << n);
3278 break;
3279 default:
3280 error(@1, yyscanner, "left argument of non-integer type to \"<<\"");
3281 YYERROR;
3282 break;
3285 | shiftExpr TOK_RIGHTSHIFT addExpr
3287 int n;
3288 switch ($3.type) {
3289 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3290 if ($3.ival < 0 || $3.ival > 63) {
3291 error(
3292 @3, yyscanner,
3293 ("out-of-range shift argument " + OUString::number($3.ival)
3294 + " to \">>\" "));
3295 YYERROR;
3297 n = static_cast<int>($3.ival);
3298 break;
3299 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3300 if ($3.uval > 63) {
3301 error(
3302 @3, yyscanner,
3303 ("out-of-range shift argument " + OUString::number($3.uval)
3304 + " to \">>\" "));
3305 YYERROR;
3307 n = static_cast<int>($3.uval);
3308 break;
3309 default:
3310 error(@3, yyscanner, "right argument of non-integer type to \">>\"");
3311 YYERROR;
3312 break;
3314 switch ($1.type) {
3315 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3316 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival >> n);
3317 break;
3318 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3319 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval >> n);
3320 break;
3321 default:
3322 error(@1, yyscanner, "left argument of non-integer type to \">>\"");
3323 YYERROR;
3324 break;
3327 | addExpr
3330 addExpr:
3331 addExpr '+' multExpr
3333 if (!coerce(@1, yyscanner, &$1, &$3)) {
3334 YYERROR;
3336 switch ($1.type) {
3337 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3338 error(@1, yyscanner, "arguments of boolean type to binary \"+\"");
3339 YYERROR;
3340 break;
3341 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3342 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival + $3.ival); //TODO: overflow
3343 break;
3344 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3345 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval + $3.uval); //TODO: overflow
3346 break;
3347 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3348 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval + $3.fval);
3349 break;
3352 | addExpr '-' multExpr
3354 if (!coerce(@1, yyscanner, &$1, &$3)) {
3355 YYERROR;
3357 switch ($1.type) {
3358 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3359 error(@1, yyscanner, "arguments of boolean type to binary \"-\"");
3360 YYERROR;
3361 break;
3362 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3363 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival - $3.ival); //TODO: overflow
3364 break;
3365 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3366 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval - $3.uval); //TODO: overflow
3367 break;
3368 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3369 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval - $3.fval);
3370 break;
3373 | multExpr
3376 multExpr:
3377 multExpr '*' unaryExpr
3379 if (!coerce(@1, yyscanner, &$1, &$3)) {
3380 YYERROR;
3382 switch ($1.type) {
3383 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3384 error(@1, yyscanner, "arguments of boolean type to \"*\"");
3385 YYERROR;
3386 break;
3387 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3388 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival * $3.ival); //TODO: overflow
3389 break;
3390 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3391 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval * $3.uval); //TODO: overflow
3392 break;
3393 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3394 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval * $3.fval);
3395 break;
3398 | multExpr '/' unaryExpr
3400 if (!coerce(@1, yyscanner, &$1, &$3)) {
3401 YYERROR;
3403 switch ($1.type) {
3404 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3405 error(@1, yyscanner, "arguments of boolean type to \"/\"");
3406 YYERROR;
3407 break;
3408 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3409 if ($3.ival == 0) {
3410 error(@3, yyscanner, "cannot divide by zero");
3411 YYERROR;
3413 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival / $3.ival);
3414 break;
3415 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3416 if ($3.uval == 0) {
3417 error(@3, yyscanner, "cannot divide by zero");
3418 YYERROR;
3420 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval / $3.uval);
3421 break;
3422 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3423 if ($3.fval == 0) {
3424 error(@3, yyscanner, "cannot divide by zero");
3425 YYERROR;
3427 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval - $3.fval);
3428 break;
3431 | multExpr '%' unaryExpr
3433 if (!coerce(@1, yyscanner, &$1, &$3)) {
3434 YYERROR;
3436 switch ($1.type) {
3437 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3438 if ($3.ival == 0) {
3439 error(@3, yyscanner, "cannot divide by zero");
3440 YYERROR;
3442 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival % $3.ival);
3443 break;
3444 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3445 if ($3.uval == 0) {
3446 error(@3, yyscanner, "cannot divide by zero");
3447 YYERROR;
3449 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval % $3.uval);
3450 break;
3451 default:
3452 error(@1, yyscanner, "arguments of non-integer type to \"%\"");
3453 YYERROR;
3454 break;
3457 | unaryExpr
3460 unaryExpr:
3461 '+' primaryExpr
3463 if ($2.type == unoidl::detail::SourceProviderExpr::TYPE_BOOL) {
3464 error(@2, yyscanner, "argument of boolean type to unary \"+\"");
3465 YYERROR;
3467 $$ = $2;
3469 | '-' primaryExpr
3471 switch ($2.type) {
3472 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3473 error(@2, yyscanner, "argument of boolean type to unary \"-\"");
3474 YYERROR;
3475 break;
3476 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3477 if ($2.ival == SAL_MIN_INT64) {
3478 error(@2, yyscanner, "cannot negate -2^63");
3479 YYERROR;
3481 $$ = unoidl::detail::SourceProviderExpr::Int(-$2.ival);
3482 break;
3483 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3484 if ($2.uval == SAL_CONST_UINT64(0x8000000000000000)) {
3485 $$ = unoidl::detail::SourceProviderExpr::Int(SAL_MIN_INT64);
3486 } else {
3487 if ($2.uval > SAL_MAX_INT64) {
3488 error(
3489 @2, yyscanner,
3490 ("cannot negate out-of-range value "
3491 + OUString::number($2.uval)));
3492 YYERROR;
3494 $$ = unoidl::detail::SourceProviderExpr::Int(
3495 -static_cast<sal_Int64>($2.uval));
3497 break;
3498 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3499 $$ = unoidl::detail::SourceProviderExpr::Float(-$2.fval);
3500 break;
3503 | '~' primaryExpr
3505 switch ($2.type) {
3506 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3507 $$ = unoidl::detail::SourceProviderExpr::Int(~$2.ival);
3508 break;
3509 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3510 $$ = unoidl::detail::SourceProviderExpr::Uint(~$2.uval);
3511 break;
3512 default:
3513 error(@2, yyscanner, "argument of non-integer type to \"~\"");
3514 YYERROR;
3515 break;
3518 | primaryExpr
3521 primaryExpr:
3522 '(' expr ')' { $$ = $2; }
3523 | TOK_FALSE { $$ = unoidl::detail::SourceProviderExpr::Bool(false); }
3524 | TOK_TRUE { $$ = unoidl::detail::SourceProviderExpr::Bool(true); }
3525 | TOK_INTEGER { $$ = unoidl::detail::SourceProviderExpr::Uint($1); }
3526 | TOK_FLOATING { $$ = unoidl::detail::SourceProviderExpr::Float($1); }
3527 | name
3529 OUString name(convertName($1));
3530 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3531 unoidl::ConstantValue v(false); // dummy value
3532 bool found = false;
3533 bool unpub = false;
3534 sal_Int32 i = name.lastIndexOf('.');
3535 if (i == -1) {
3536 rtl::Reference<unoidl::detail::SourceProviderEntityPad> pad(
3537 getCurrentEntity(data)->pad);
3538 unoidl::detail::SourceProviderEnumTypeEntityPad * p1 = dynamic_cast<
3539 unoidl::detail::SourceProviderEnumTypeEntityPad *>(pad.get());
3540 if (p1 != 0) {
3541 for (std::vector<unoidl::EnumTypeEntity::Member>::const_iterator
3542 j(p1->members.begin());
3543 j != p1->members.end(); ++j)
3545 if (j->name == name) {
3546 v = unoidl::ConstantValue(j->value);
3547 found = true;
3548 break;
3551 } else {
3552 unoidl::detail::SourceProviderConstantGroupEntityPad * p2
3553 = dynamic_cast<
3554 unoidl::detail::SourceProviderConstantGroupEntityPad *>(
3555 pad.get());
3556 if (p2 != 0) {
3557 for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
3558 j(p2->members.begin());
3559 j != p2->members.end(); ++j)
3561 if (j->name == name) {
3562 v = j->value;
3563 found = true;
3564 break;
3569 } else {
3570 OUString scope(name.copy(0, i));
3571 unoidl::detail::SourceProviderEntity const * ent;
3572 if (findEntity(@1, yyscanner, data, false, &scope, &ent, 0, 0)
3573 == FOUND_ERROR)
3575 YYERROR;
3577 if (ent != 0) {
3578 OUString id(name.copy(i + 1));
3579 // No need to check for enum members here, as they cannot be
3580 // referenced in expressions by qualified name (TODO: is that true?):
3581 if (ent->entity.is()) {
3582 if (ent->entity->getSort()
3583 == unoidl::Entity::SORT_CONSTANT_GROUP)
3585 std::vector<unoidl::ConstantGroupEntity::Member> const &
3586 mems(
3587 static_cast<unoidl::ConstantGroupEntity *>(
3588 ent->entity.get())->
3589 getMembers());
3590 for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator j(
3591 mems.begin());
3592 j != mems.end(); ++j)
3594 if (j->name == id) {
3595 v = j->value;
3596 found = true;
3597 unpub
3598 = !static_cast<unoidl::ConstantGroupEntity *>(
3599 ent->entity.get())->isPublished();
3600 break;
3604 } else if (ent->pad.is()) {
3605 unoidl::detail::SourceProviderConstantGroupEntityPad * pad
3606 = dynamic_cast<
3607 unoidl::detail::SourceProviderConstantGroupEntityPad *>(
3608 ent->pad.get());
3609 if (pad != 0) {
3610 for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator j(
3611 pad->members.begin());
3612 j != pad->members.end(); ++j)
3614 if (j->name == id) {
3615 v = j->value;
3616 found = true;
3617 unpub = !ent->pad->isPublished();
3618 break;
3625 if (!found) {
3626 error(
3627 @1, yyscanner,
3628 (name
3629 + (" does not resolve to neither a constant nor an unqualified"
3630 " enum member")));
3631 YYERROR;
3633 if (data->publishedContext && unpub) {
3634 error(
3635 @1, yyscanner,
3636 "unpublished value " + name + " used in published context");
3637 YYERROR;
3639 switch (v.type) {
3640 case unoidl::ConstantValue::TYPE_BOOLEAN:
3641 $$ = unoidl::detail::SourceProviderExpr::Bool(v.booleanValue);
3642 break;
3643 case unoidl::ConstantValue::TYPE_BYTE:
3644 $$ = unoidl::detail::SourceProviderExpr::Int(v.byteValue);
3645 break;
3646 case unoidl::ConstantValue::TYPE_SHORT:
3647 $$ = unoidl::detail::SourceProviderExpr::Int(v.shortValue);
3648 break;
3649 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
3650 $$ = unoidl::detail::SourceProviderExpr::Uint(v.unsignedShortValue);
3651 break;
3652 case unoidl::ConstantValue::TYPE_LONG:
3653 $$ = unoidl::detail::SourceProviderExpr::Int(v.longValue);
3654 break;
3655 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
3656 $$ = unoidl::detail::SourceProviderExpr::Uint(v.unsignedLongValue);
3657 break;
3658 case unoidl::ConstantValue::TYPE_HYPER:
3659 $$ = unoidl::detail::SourceProviderExpr::Int(v.hyperValue);
3660 break;
3661 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
3662 $$ = unoidl::detail::SourceProviderExpr::Uint(v.unsignedHyperValue);
3663 break;
3664 case unoidl::ConstantValue::TYPE_FLOAT:
3665 $$ = unoidl::detail::SourceProviderExpr::Float(v.floatValue);
3666 break;
3667 case unoidl::ConstantValue::TYPE_DOUBLE:
3668 $$ = unoidl::detail::SourceProviderExpr::Float(v.doubleValue);
3669 break;
3674 typeArguments:
3675 typeArguments ',' type
3677 unoidl::detail::SourceProviderType t(*$3);
3678 delete $3;
3679 if (!checkTypeArgument(@3, yyscanner, t)) {
3680 delete $1; /* see commented-out %destructor above */
3681 YYERROR;
3683 $1->push_back(t);
3684 $$ = $1;
3686 | type
3688 unoidl::detail::SourceProviderType t(*$1);
3689 delete $1;
3690 if (!checkTypeArgument(@1, yyscanner, t)) {
3691 YYERROR;
3693 $$ = new std::vector<unoidl::detail::SourceProviderType>;
3694 $$->push_back(t);
3698 type:
3699 TOK_VOID
3701 $$ = new unoidl::detail::SourceProviderType(
3702 unoidl::detail::SourceProviderType::TYPE_VOID);
3704 | TOK_BOOLEAN
3706 $$ = new unoidl::detail::SourceProviderType(
3707 unoidl::detail::SourceProviderType::TYPE_BOOLEAN);
3709 | TOK_BYTE
3711 $$ = new unoidl::detail::SourceProviderType(
3712 unoidl::detail::SourceProviderType::TYPE_BYTE);
3714 | TOK_SHORT
3716 $$ = new unoidl::detail::SourceProviderType(
3717 unoidl::detail::SourceProviderType::TYPE_SHORT);
3719 | TOK_UNSIGNED TOK_SHORT
3721 $$ = new unoidl::detail::SourceProviderType(
3722 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT);
3724 | TOK_LONG
3726 $$ = new unoidl::detail::SourceProviderType(
3727 unoidl::detail::SourceProviderType::TYPE_LONG);
3729 | TOK_UNSIGNED TOK_LONG
3731 $$ = new unoidl::detail::SourceProviderType(
3732 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG);
3734 | TOK_HYPER
3736 $$ = new unoidl::detail::SourceProviderType(
3737 unoidl::detail::SourceProviderType::TYPE_HYPER);
3739 | TOK_UNSIGNED TOK_HYPER
3741 $$ = new unoidl::detail::SourceProviderType(
3742 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER);
3744 | TOK_FLOAT
3746 $$ = new unoidl::detail::SourceProviderType(
3747 unoidl::detail::SourceProviderType::TYPE_FLOAT);
3749 | TOK_DOUBLE
3751 $$ = new unoidl::detail::SourceProviderType(
3752 unoidl::detail::SourceProviderType::TYPE_DOUBLE);
3754 | TOK_CHAR
3756 $$ = new unoidl::detail::SourceProviderType(
3757 unoidl::detail::SourceProviderType::TYPE_CHAR);
3759 | TOK_STRING
3761 $$ = new unoidl::detail::SourceProviderType(
3762 unoidl::detail::SourceProviderType::TYPE_STRING);
3764 | TOK_TYPE
3766 $$ = new unoidl::detail::SourceProviderType(
3767 unoidl::detail::SourceProviderType::TYPE_TYPE);
3769 | TOK_ANY
3771 $$ = new unoidl::detail::SourceProviderType(
3772 unoidl::detail::SourceProviderType::TYPE_ANY);
3774 | TOK_SEQUENCE '<' type '>'
3776 switch ($3->type) {
3777 case unoidl::detail::SourceProviderType::TYPE_VOID:
3778 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
3779 case unoidl::detail::SourceProviderType::TYPE_PARAMETER: //TODO?
3780 error(@3, yyscanner, "illegal sequence type component type");
3781 YYERROR;
3782 break;
3783 default:
3784 break;
3786 $$ = new unoidl::detail::SourceProviderType($3);
3787 delete $3;
3789 | name
3791 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3792 OUString name(convertName($1));
3793 bool done = false;
3794 if (name.indexOf('.') == -1 && !data->currentName.isEmpty()) {
3795 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
3796 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
3797 pad = dynamic_cast<
3798 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
3799 ent->pad.get());
3800 if (pad != 0
3801 && (std::find(
3802 pad->typeParameters.begin(), pad->typeParameters.end(),
3803 name)
3804 != pad->typeParameters.end()))
3806 $$ = new unoidl::detail::SourceProviderType(name);
3807 done = true;
3810 if (!done) {
3811 unoidl::detail::SourceProviderEntity const * ent;
3812 unoidl::detail::SourceProviderType t;
3813 switch (findEntity(@1, yyscanner, data, false, &name, &ent, 0, &t)) {
3814 case FOUND_ERROR:
3815 YYERROR;
3816 break;
3817 case FOUND_TYPE:
3818 $$ = new unoidl::detail::SourceProviderType(t);
3819 break;
3820 case FOUND_ENTITY:
3821 if (ent == 0) {
3822 error(@1, yyscanner, "unknown entity " + name);
3823 YYERROR;
3825 bool ok = false;
3826 switch (ent->kind) {
3827 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
3828 if (ent->pad.is()) {
3829 if (data->publishedContext && !ent->pad->isPublished()) {
3830 error(
3831 @1, yyscanner,
3832 ("unpublished entity " + name
3833 + " used in published context"));
3834 YYERROR;
3836 if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
3837 ent->pad.get())
3838 != 0)
3840 $$ = new unoidl::detail::SourceProviderType(
3841 unoidl::detail::SourceProviderType::TYPE_ENUM,
3842 name, ent);
3843 ok = true;
3844 } else if (dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
3845 ent->pad.get())
3846 != 0)
3848 $$ = new unoidl::detail::SourceProviderType(
3849 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
3850 name, ent);
3851 ok = true;
3852 } else if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
3853 ent->pad.get())
3854 != 0)
3856 error(
3857 @1, yyscanner,
3858 (("recursive reference to polymorphic struct type"
3859 " template ")
3860 + name));
3861 YYERROR;
3862 } else if (dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
3863 ent->pad.get())
3864 != 0)
3866 $$ = new unoidl::detail::SourceProviderType(
3867 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
3868 name, ent);
3869 ok = true;
3870 } else if (dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
3871 ent->pad.get())
3872 != 0)
3874 $$ = new unoidl::detail::SourceProviderType(
3875 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
3876 name, ent);
3877 ok = true;
3879 break;
3881 assert(ent->entity.is());
3882 // fall through
3883 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
3884 if (data->publishedContext
3885 && ent->entity->getSort() != unoidl::Entity::SORT_MODULE
3886 && !static_cast<unoidl::PublishableEntity *>(
3887 ent->entity.get())->isPublished())
3889 error(
3890 @1, yyscanner,
3891 ("unpublished entity " + name
3892 + " used in published context"));
3893 YYERROR;
3895 switch (ent->entity->getSort()) {
3896 case unoidl::Entity::SORT_ENUM_TYPE:
3897 $$ = new unoidl::detail::SourceProviderType(
3898 unoidl::detail::SourceProviderType::TYPE_ENUM, name,
3899 ent);
3900 ok = true;
3901 break;
3902 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
3903 $$ = new unoidl::detail::SourceProviderType(
3904 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
3905 name, ent);
3906 ok = true;
3907 break;
3908 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
3909 error(
3910 @1, yyscanner,
3911 ("polymorphic struct type template " + name
3912 + " without type arguments"));
3913 YYERROR;
3914 break;
3915 case unoidl::Entity::SORT_EXCEPTION_TYPE:
3916 $$ = new unoidl::detail::SourceProviderType(
3917 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
3918 name, ent);
3919 ok = true;
3920 break;
3921 case unoidl::Entity::SORT_INTERFACE_TYPE:
3922 $$ = new unoidl::detail::SourceProviderType(
3923 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
3924 name, ent);
3925 ok = true;
3926 break;
3927 case unoidl::Entity::SORT_TYPEDEF:
3928 assert(false && "this cannot happen");
3929 // fall through
3930 default:
3931 break;
3933 break;
3934 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
3935 if (data->publishedContext) {
3936 error(
3937 @1, yyscanner,
3938 ("unpublished entity " + name
3939 + " used in published context"));
3940 YYERROR;
3942 // fall through
3943 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
3944 $$ = new unoidl::detail::SourceProviderType(
3945 unoidl::detail::SourceProviderType::TYPE_INTERFACE, name,
3946 ent);
3947 ok = true;
3948 break;
3949 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
3950 assert(false && "this cannot happen");
3952 if (!ok) {
3953 error(@1, yyscanner, "non-type entity " + name);
3954 YYERROR;
3956 break;
3960 | name '<' typeArguments '>'
3962 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3963 OUString name(convertName($1));
3964 std::vector<unoidl::detail::SourceProviderType> args(*$3);
3965 delete $3;
3966 unoidl::detail::SourceProviderEntity const * ent;
3967 if (findEntity(@1, yyscanner, data, false, &name, &ent, 0, 0)
3968 == FOUND_ERROR)
3970 YYERROR;
3972 if (ent == 0) {
3973 error(@1, yyscanner, "unknown entity " + name);
3974 YYERROR;
3976 bool ok = false;
3977 switch (ent->kind) {
3978 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
3979 if (ent->pad.is()) {
3980 if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
3981 ent->pad.get())
3982 != 0)
3984 error(
3985 @1, yyscanner,
3986 (("recursive reference to polymorphic struct type"
3987 " template ")
3988 + name));
3989 YYERROR;
3991 break;
3993 assert(ent->entity.is());
3994 // fall through
3995 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
3996 if (ent->entity->getSort()
3997 == unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)
3999 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity> e(
4000 static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
4001 ent->entity.get()));
4002 if (args.size() != e->getTypeParameters().size()) {
4003 error(
4004 @1, yyscanner,
4005 ("bad number of polymorphic struct type template " + name
4006 + " type arguments"));
4007 YYERROR;
4009 if (data->publishedContext && !e->isPublished()) {
4010 error(
4011 @1, yyscanner,
4012 ("unpublished polymorphic struct type template " + name
4013 + " used in published context"));
4014 YYERROR;
4016 $$ = new unoidl::detail::SourceProviderType(name, ent, args);
4017 ok = true;
4019 break;
4020 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
4021 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
4022 break;
4023 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
4024 assert(false && "this cannot happen");
4026 if (!ok) {
4027 error(@1, yyscanner, "non-type entity " + name);
4028 YYERROR;
4033 name:
4034 name TOK_COLONS identifier { *$1 += "." + *$3; delete $3; $$ = $1; }
4035 | TOK_COLONS identifier { *$2 = "." + *$2; $$ = $2; }
4036 | identifier
4039 identifier:
4040 TOK_IDENTIFIER
4041 | TOK_GET { $$ = new OString("get"); }
4042 | TOK_PUBLISHED { $$ = new OString("published"); }
4043 | TOK_SET { $$ = new OString("set"); }
4046 deprecated_opt:
4047 TOK_DEPRECATED { $$ = true; }
4048 | /* empty */ { $$ = false; }
4053 namespace unoidl { namespace detail {
4055 OUString SourceProviderType::getName() const {
4056 if (!typedefName.isEmpty()) {
4057 return typedefName;
4059 switch (type) {
4060 case unoidl::detail::SourceProviderType::TYPE_VOID:
4061 return OUString("void");
4062 case unoidl::detail::SourceProviderType::TYPE_BOOLEAN:
4063 return OUString("boolean");
4064 case unoidl::detail::SourceProviderType::TYPE_BYTE:
4065 return OUString("byte");
4066 case unoidl::detail::SourceProviderType::TYPE_SHORT:
4067 return OUString("short");
4068 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
4069 return OUString("unsigned short");
4070 case unoidl::detail::SourceProviderType::TYPE_LONG:
4071 return OUString("long");
4072 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
4073 return OUString("unsigned long");
4074 case unoidl::detail::SourceProviderType::TYPE_HYPER:
4075 return OUString("hyper");
4076 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
4077 return OUString("unsigned hyper");
4078 case unoidl::detail::SourceProviderType::TYPE_FLOAT:
4079 return OUString("float");
4080 case unoidl::detail::SourceProviderType::TYPE_DOUBLE:
4081 return OUString("double");
4082 case unoidl::detail::SourceProviderType::TYPE_CHAR:
4083 return OUString("char");
4084 case unoidl::detail::SourceProviderType::TYPE_STRING:
4085 return OUString("string");
4086 case unoidl::detail::SourceProviderType::TYPE_TYPE:
4087 return OUString("type");
4088 case unoidl::detail::SourceProviderType::TYPE_ANY:
4089 return OUString("any");
4090 case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
4091 assert(subtypes.size() == 1);
4092 return "[]" + subtypes.front().getName();
4093 case unoidl::detail::SourceProviderType::TYPE_ENUM:
4094 case unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT:
4095 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
4096 case unoidl::detail::SourceProviderType::TYPE_INTERFACE:
4097 case unoidl::detail::SourceProviderType::TYPE_PARAMETER:
4098 return name;
4099 case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
4101 OUString n(name + "<");
4102 for (std::vector<SourceProviderType>::const_iterator i(
4103 subtypes.begin());
4104 i != subtypes.end(); ++i)
4106 if (i != subtypes.begin()) {
4107 n += ",";
4109 n += i->getName();
4111 return n + ">";
4113 default:
4114 assert(false && "this cannot happen"); for (;;) { std::abort(); }
4118 bool SourceProviderType::equals(SourceProviderType const & other) const {
4119 if (type != other.type || name != other.name
4120 || subtypes.size() != other.subtypes.size())
4122 return false;
4124 for (std::vector<SourceProviderType>::const_iterator
4125 i(subtypes.begin()), j(other.subtypes.begin());
4126 i != subtypes.end(); ++i, ++j)
4128 if (!i->equals(*j)) {
4129 return false;
4132 return true;
4135 bool SourceProviderInterfaceTypeEntityPad::addDirectBase(
4136 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4137 DirectBase const & base, bool optional)
4139 std::set<OUString> seen;
4140 if (!(checkBaseClashes(
4141 location, yyscanner, data, base.name, base.entity, true, optional,
4142 optional, &seen)
4143 && addBase(
4144 location, yyscanner, data, base.name, base.name, base.entity,
4145 true, optional)))
4147 return false;
4149 if (optional) {
4150 addOptionalBaseMembers(
4151 location, yyscanner, data, base.name, base.entity);
4153 (optional ? directOptionalBases : directMandatoryBases).push_back(base);
4154 return true;
4157 bool SourceProviderInterfaceTypeEntityPad::addDirectMember(
4158 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4159 OUString const & name)
4161 assert(data != 0);
4162 if (!checkMemberClashes(location, yyscanner, data, "", name, true)) {
4163 return false;
4165 allMembers.insert(
4166 std::map<OUString, Member>::value_type(
4167 name, Member(data->currentName)));
4168 return true;
4171 bool SourceProviderInterfaceTypeEntityPad::checkBaseClashes(
4172 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4173 OUString const & name,
4174 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity, bool direct,
4175 bool optional, bool outerOptional, std::set<OUString> * seen) const
4177 assert(data != 0);
4178 assert(entity.is());
4179 assert(seen != 0);
4180 if (direct || optional || seen->insert(name).second) {
4181 std::map<OUString, BaseKind>::const_iterator i(allBases.find(name));
4182 if (i != allBases.end()) {
4183 switch (i->second) {
4184 case BASE_INDIRECT_OPTIONAL:
4185 if (direct && optional) {
4186 error(
4187 location, yyscanner,
4188 ("interface type " + data->currentName
4189 + " duplicate base " + name));
4190 return false;
4192 break;
4193 case BASE_DIRECT_OPTIONAL:
4194 if (direct || !outerOptional) {
4195 error(
4196 location, yyscanner,
4197 ("interface type " + data->currentName
4198 + " duplicate base " + name));
4199 return false;
4201 return true;
4202 case BASE_INDIRECT_MANDATORY:
4203 if (direct) {
4204 error(
4205 location, yyscanner,
4206 ("interface type " + data->currentName
4207 + " duplicate base " + name));
4208 return false;
4210 return true;
4211 case BASE_DIRECT_MANDATORY:
4212 if (direct || (!optional && !outerOptional)) {
4213 error(
4214 location, yyscanner,
4215 ("interface type " + data->currentName
4216 + " duplicate base " + name));
4217 return false;
4219 return true;
4222 if (direct || !optional) {
4223 for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
4224 entity->getDirectMandatoryBases().begin());
4225 j != entity->getDirectMandatoryBases().end(); ++j)
4227 OUString n("." + j->name);
4228 unoidl::detail::SourceProviderEntity const * p;
4229 if (findEntity(location, yyscanner, data, true, &n, &p, 0, 0)
4230 == FOUND_ERROR)
4232 return false;
4234 if (p == 0 || !p->entity.is()
4235 || (p->entity->getSort()
4236 != unoidl::Entity::SORT_INTERFACE_TYPE))
4238 error(
4239 location, yyscanner,
4240 ("inconsistent type manager: interface type "
4241 + data->currentName + " base " + n
4242 + " does not resolve to an existing interface type"));
4243 return false;
4245 if (!checkBaseClashes(
4246 location, yyscanner, data, n,
4247 static_cast<unoidl::InterfaceTypeEntity *>(
4248 p->entity.get()),
4249 false, false, outerOptional, seen))
4251 return false;
4254 for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
4255 entity->getDirectOptionalBases().begin());
4256 j != entity->getDirectOptionalBases().end(); ++j)
4258 OUString n("." + j->name);
4259 unoidl::detail::SourceProviderEntity const * p;
4260 if (findEntity(location, yyscanner, data, true, &n, &p, 0, 0)
4261 == FOUND_ERROR)
4263 return false;
4265 if (p == 0 || !p->entity.is()
4266 || (p->entity->getSort()
4267 != unoidl::Entity::SORT_INTERFACE_TYPE))
4269 error(
4270 location, yyscanner,
4271 ("inconsistent type manager: interface type "
4272 + data->currentName + " base " + n
4273 + " does not resolve to an existing interface type"));
4274 return false;
4276 if (!checkBaseClashes(
4277 location, yyscanner, data, n,
4278 static_cast<unoidl::InterfaceTypeEntity *>(
4279 p->entity.get()),
4280 false, true, outerOptional, seen))
4282 return false;
4285 for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
4286 j(entity->getDirectAttributes().begin());
4287 j != entity->getDirectAttributes().end(); ++j)
4289 if (!checkMemberClashes(
4290 location, yyscanner, data, name, j->name,
4291 !outerOptional))
4293 return false;
4296 for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
4297 j(entity->getDirectMethods().begin());
4298 j != entity->getDirectMethods().end(); ++j)
4300 if (!checkMemberClashes(
4301 location, yyscanner, data, name, j->name,
4302 !outerOptional))
4304 return false;
4309 return true;
4312 bool SourceProviderInterfaceTypeEntityPad::checkMemberClashes(
4313 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4314 OUString const & interfaceName, OUString const & memberName,
4315 bool checkOptional) const
4317 std::map<OUString, Member>::const_iterator i(allMembers.find(memberName));
4318 if (i != allMembers.end()) {
4319 if (!i->second.mandatory.isEmpty()) {
4320 // For a direct member, interfaceName will be empty, so this will
4321 // catch two direct members with the same name:
4322 if (i->second.mandatory != interfaceName) {
4323 error(
4324 location, yyscanner,
4325 ("interface type " + data->currentName
4326 + " duplicate member " + memberName));
4327 return false;
4329 } else if (checkOptional) {
4330 for (std::set<OUString>::const_iterator j(
4331 i->second.optional.begin());
4332 j != i->second.optional.end(); ++j)
4334 if (*j != interfaceName) {
4335 error(
4336 location, yyscanner,
4337 ("interface type " + data->currentName
4338 + " duplicate member " + memberName));
4339 return false;
4344 return true;
4347 bool SourceProviderInterfaceTypeEntityPad::addBase(
4348 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4349 OUString const & directBaseName, OUString const & name,
4350 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity, bool direct,
4351 bool optional)
4353 assert(data != 0);
4354 assert(entity.is());
4355 BaseKind kind = optional
4356 ? direct ? BASE_DIRECT_OPTIONAL : BASE_INDIRECT_OPTIONAL
4357 : direct ? BASE_DIRECT_MANDATORY : BASE_INDIRECT_MANDATORY;
4358 std::pair<std::map<OUString, BaseKind>::iterator, bool> p(
4359 allBases.insert(
4360 std::map<OUString, BaseKind>::value_type(name, kind)));
4361 bool seen = !p.second && p.first->second >= BASE_INDIRECT_MANDATORY;
4362 if (!p.second && kind > p.first->second) {
4363 p.first->second = kind;
4365 if (!optional && !seen) {
4366 for (std::vector<unoidl::AnnotatedReference>::const_iterator i(
4367 entity->getDirectMandatoryBases().begin());
4368 i != entity->getDirectMandatoryBases().end(); ++i)
4370 OUString n("." + i->name);
4371 unoidl::detail::SourceProviderEntity const * q;
4372 if (findEntity(location, yyscanner, data, true, &n, &q, 0, 0)
4373 == FOUND_ERROR)
4375 return false;
4377 if (q == 0 || !q->entity.is()
4378 || q->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4380 error(
4381 location, yyscanner,
4382 ("inconsistent type manager: interface type "
4383 + data->currentName + " base " + n
4384 + " does not resolve to an existing interface type"));
4385 return false;
4387 if (!addBase(
4388 location, yyscanner, data, directBaseName, n,
4389 static_cast<unoidl::InterfaceTypeEntity *>(q->entity.get()),
4390 false, false))
4392 return false;
4395 for (std::vector<unoidl::AnnotatedReference>::const_iterator i(
4396 entity->getDirectOptionalBases().begin());
4397 i != entity->getDirectOptionalBases().end(); ++i)
4399 OUString n("." + i->name);
4400 unoidl::detail::SourceProviderEntity const * q;
4401 if (findEntity(location, yyscanner, data, true, &n, &q, 0, 0)
4402 == FOUND_ERROR)
4404 return false;
4406 if (q == 0 || !q->entity.is()
4407 || q->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4409 error(
4410 location, yyscanner,
4411 ("inconsistent type manager: interface type "
4412 + data->currentName + " base " + n
4413 + " does not resolve to an existing interface type"));
4414 return false;
4416 if (!addBase(
4417 location, yyscanner, data, directBaseName, n,
4418 static_cast<unoidl::InterfaceTypeEntity *>(q->entity.get()),
4419 false, true))
4421 return false;
4424 for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
4425 i(entity->getDirectAttributes().begin());
4426 i != entity->getDirectAttributes().end(); ++i)
4428 allMembers.insert(
4429 std::map<OUString, Member>::value_type(i->name, Member(name)));
4431 for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator i(
4432 entity->getDirectMethods().begin());
4433 i != entity->getDirectMethods().end(); ++i)
4435 allMembers.insert(
4436 std::map<OUString, Member>::value_type(i->name, Member(name)));
4439 return true;
4442 bool SourceProviderInterfaceTypeEntityPad::addOptionalBaseMembers(
4443 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4444 OUString const & name,
4445 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity)
4447 assert(entity.is());
4448 for (std::vector<unoidl::AnnotatedReference>::const_iterator i(
4449 entity->getDirectMandatoryBases().begin());
4450 i != entity->getDirectMandatoryBases().end(); ++i)
4452 OUString n("." + i->name);
4453 unoidl::detail::SourceProviderEntity const * p;
4454 if (findEntity(location, yyscanner, data, true, &n, &p, 0, 0)
4455 == FOUND_ERROR)
4457 return false;
4459 if (p == 0 || !p->entity.is()
4460 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4462 error(
4463 location, yyscanner,
4464 ("inconsistent type manager: interface type "
4465 + data->currentName + " base " + n
4466 + " does not resolve to an existing interface type"));
4467 return false;
4469 if (!addOptionalBaseMembers(
4470 location, yyscanner, data, n,
4471 static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get())))
4473 return false;
4476 for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator i(
4477 entity->getDirectAttributes().begin());
4478 i != entity->getDirectAttributes().end(); ++i)
4480 Member & m(
4481 allMembers.insert(
4482 std::map<OUString, Member>::value_type(
4483 i->name, Member("")))
4484 .first->second);
4485 if (m.mandatory.isEmpty()) {
4486 m.optional.insert(name);
4489 for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator i(
4490 entity->getDirectMethods().begin());
4491 i != entity->getDirectMethods().end(); ++i)
4493 Member & m(
4494 allMembers.insert(
4495 std::map<OUString, Member>::value_type(
4496 i->name, Member("")))
4497 .first->second);
4498 if (m.mandatory.isEmpty()) {
4499 m.optional.insert(name);
4502 return true;
4505 bool parse(OUString const & uri, SourceProviderScannerData * data) {
4506 assert(data != 0);
4507 oslFileHandle handle;
4508 oslFileError e = osl_openFile(uri.pData, &handle, osl_File_OpenFlag_Read);
4509 switch (e) {
4510 case osl_File_E_None:
4511 break;
4512 case osl_File_E_NOENT:
4513 return false;
4514 default:
4515 throw FileFormatException(uri, "cannot open: " + OUString::number(e));
4517 sal_uInt64 size;
4518 e = osl_getFileSize(handle, &size);
4519 if (e != osl_File_E_None) {
4520 oslFileError e2 = osl_closeFile(handle);
4521 SAL_WARN_IF(
4522 e2 != osl_File_E_None, "unoidl",
4523 "cannot close " << uri << ": " << +e2);
4524 throw FileFormatException(
4525 uri, "cannot get size: " + OUString::number(e));
4527 void * address;
4528 e = osl_mapFile(handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
4529 if (e != osl_File_E_None) {
4530 oslFileError e2 = osl_closeFile(handle);
4531 SAL_WARN_IF(
4532 e2 != osl_File_E_None, "unoidl",
4533 "cannot close " << uri << ": " << +e2);
4534 throw FileFormatException(uri, "cannot mmap: " + OUString::number(e));
4536 try {
4537 data->setSource(address, size);
4538 yyscan_t yyscanner;
4539 if (yylex_init_extra(data, &yyscanner) != 0) {
4540 // Checking errno for the specific EINVAL, ENOMEM documented for
4541 // yylex_init_extra would not work as those values are not defined
4542 // by the C++ Standard:
4543 int e2 = errno;
4544 throw FileFormatException(
4545 uri,
4546 "yylex_init_extra failed with errno " + OUString::number(e2));
4548 int e2 = yyparse(yyscanner);
4549 yylex_destroy(yyscanner);
4550 switch (e2) {
4551 case 0:
4552 break;
4553 default:
4554 assert(false);
4555 // fall through
4556 case 1:
4557 throw FileFormatException(
4558 uri,
4559 ("cannot parse"
4560 + (data->errorLine == 0
4561 ? OUString() : " line " + OUString::number(data->errorLine))
4562 + (data->parserError.isEmpty()
4563 ? OUString()
4564 : (", "
4565 + OStringToOUString(
4566 data->parserError, osl_getThreadTextEncoding())))
4567 + (data->errorMessage.isEmpty()
4568 ? OUString() : ": \"" + data->errorMessage + "\"")));
4569 case 2:
4570 throw std::bad_alloc();
4572 } catch (...) {
4573 e = osl_unmapMappedFile(handle, address, size);
4574 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
4575 e = osl_closeFile(handle);
4576 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
4577 throw;
4579 e = osl_unmapMappedFile(handle, address, size);
4580 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
4581 e = osl_closeFile(handle);
4582 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
4583 return true;
4588 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */