Use o3tl::convert in Math
[LibreOffice.git] / unoidl / source / sourceprovider-parser.y
blob0175b5379897be61597f6d478bff5a3e270da023
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 <o3tl/unreachable.hxx>
20 #include <rtl/ustrbuf.hxx>
21 #include <unoidl/unoidl.hxx>
23 #include <algorithm>
24 #include <cassert>
25 #include <cerrno>
26 #include <cstddef>
27 #include <cstdlib>
28 #include <limits>
29 #include <new>
30 #include <utility>
31 #include <vector>
33 #include "sourceprovider-parser-requires.hxx"
37 %union {
38 sal_uInt64 ival;
39 double fval;
40 OString * sval;
42 bool bval;
43 std::vector<OUString> * excns;
44 unoidl::detail::SourceProviderAccessDecls decls;
45 unoidl::InterfaceTypeEntity::Method::Parameter::Direction dir;
46 unoidl::detail::SourceProviderFlags flags;
47 unoidl::detail::SourceProviderExpr expr;
48 unoidl::detail::SourceProviderType * type;
49 std::vector<unoidl::detail::SourceProviderType> * types;
52 /* TODO: %destructor { delete $$; } <sval> <excns> <type> <types> */
54 %lex-param {yyscan_t yyscanner}
55 %parse-param {yyscan_t yyscanner}
59 #include <osl/file.h>
60 #include <osl/thread.h>
61 #include <sal/log.hxx>
63 #include "sourceprovider-scanner.hxx"
65 #define YYLLOC_DEFAULT(Current, Rhs, N) \
66 do { (Current) = YYRHSLOC((Rhs), (N) ? 1 : 0); } while (0)
68 static void yyerror(YYLTYPE * locp, yyscan_t yyscanner, char const * msg) {
69 assert(locp != nullptr);
70 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
71 data->errorLine = *locp;
72 data->parserError = OString(msg);
75 namespace {
77 void error(YYLTYPE location, yyscan_t yyscanner, OUString const & message) {
78 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
79 data->errorLine = location;
80 data->errorMessage = message;
83 OUString flagName(unoidl::detail::SourceProviderFlags flag) {
84 switch (flag) {
85 case unoidl::detail::FLAG_ATTRIBUTE:
86 return "attribute";
87 case unoidl::detail::FLAG_BOUND:
88 return "bound";
89 case unoidl::detail::FLAG_CONSTRAINED:
90 return "constrained";
91 case unoidl::detail::FLAG_MAYBEAMBIGUOUS:
92 return "maybeambiguous";
93 case unoidl::detail::FLAG_MAYBEDEFAULT:
94 return "maybedefault";
95 case unoidl::detail::FLAG_MAYBEVOID:
96 return "maybevoid";
97 case unoidl::detail::FLAG_OPTIONAL:
98 return "optional";
99 case unoidl::detail::FLAG_PROPERTY:
100 return "property";
101 case unoidl::detail::FLAG_READONLY:
102 return "readonly";
103 case unoidl::detail::FLAG_REMOVABLE:
104 return "removable";
105 case unoidl::detail::FLAG_TRANSIENT:
106 return "transient";
107 default:
108 assert(false && "this cannot happen"); for (;;) { std::abort(); }
112 OUString convertName(OString const * name) {
113 assert(name != nullptr);
114 OUString s(OStringToOUString(*name, RTL_TEXTENCODING_ASCII_US));
115 delete name;
116 return s;
119 OUString convertToFullName(
120 unoidl::detail::SourceProviderScannerData const * data,
121 OString const * identifier)
123 assert(data != nullptr);
124 OUString pref;
125 if (!data->modules.empty()) {
126 pref = data->modules.back() + ".";
128 return pref + convertName(identifier);
131 void convertToCurrentName(
132 unoidl::detail::SourceProviderScannerData * data,
133 OString const * identifier)
135 assert(data != nullptr);
136 assert(data->currentName.isEmpty());
137 data->currentName = convertToFullName(data, identifier);
138 assert(!data->currentName.isEmpty());
141 void clearCurrentState(unoidl::detail::SourceProviderScannerData * data) {
142 assert(data != nullptr);
143 data->currentName.clear();
144 data->publishedContext = false;
147 unoidl::detail::SourceProviderEntity * getCurrentEntity(
148 unoidl::detail::SourceProviderScannerData * data)
150 assert(data != nullptr);
151 assert(!data->currentName.isEmpty());
152 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
153 data->entities.find(data->currentName));
154 assert(i != data->entities.end());
155 assert(i->second.kind == unoidl::detail::SourceProviderEntity::KIND_LOCAL);
156 assert(i->second.pad.is());
157 return &i->second;
160 template<typename T> rtl::Reference<T> getCurrentPad(
161 unoidl::detail::SourceProviderScannerData * data)
163 rtl::Reference<T> pad(dynamic_cast<T *>(getCurrentEntity(data)->pad.get()));
164 assert(pad.is());
165 return pad;
168 bool nameHasSameIdentifierAs(OUString const & name, OUString const & identifier)
170 sal_Int32 i = name.lastIndexOf('.') + 1;
171 return identifier.getLength() == name.getLength() - i
172 && name.match(identifier, i);
175 bool coerce(
176 YYLTYPE location, yyscan_t yyscanner,
177 unoidl::detail::SourceProviderExpr * lhs,
178 unoidl::detail::SourceProviderExpr * rhs)
180 assert(lhs != nullptr);
181 assert(rhs != nullptr);
182 bool ok = bool(); // avoid warnings
183 switch (lhs->type) {
184 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
185 ok = rhs->type != unoidl::detail::SourceProviderExpr::TYPE_BOOL;
186 break;
187 case unoidl::detail::SourceProviderExpr::TYPE_INT:
188 switch (rhs->type) {
189 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
190 ok = false;
191 break;
192 case unoidl::detail::SourceProviderExpr::TYPE_INT:
193 ok = true;
194 break;
195 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
196 if (lhs->ival >= 0) {
197 lhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
198 ok = true;
199 } else if (rhs->uval <= SAL_MAX_INT64) {
200 rhs->type = unoidl::detail::SourceProviderExpr::TYPE_INT;
201 ok = true;
202 } else {
203 ok = false;
205 break;
206 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
208 auto tmp = lhs->ival;
209 lhs->fval = tmp;
210 ok = true;
212 break;
214 break;
215 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
216 switch (rhs->type) {
217 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
218 ok = false;
219 break;
220 case unoidl::detail::SourceProviderExpr::TYPE_INT:
221 if (rhs->ival >= 0) {
222 rhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
223 ok = true;
224 } else if (lhs->uval <= SAL_MAX_INT64) {
225 lhs->type = unoidl::detail::SourceProviderExpr::TYPE_INT;
226 ok = true;
227 } else {
228 ok = false;
230 break;
231 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
232 ok = true;
233 break;
234 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
236 auto nTmp = lhs->uval;
237 lhs->fval = nTmp;
238 ok = true;
240 break;
242 break;
243 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
244 switch (rhs->type) {
245 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
246 ok = false;
247 break;
248 case unoidl::detail::SourceProviderExpr::TYPE_INT:
250 auto tmp = rhs->ival;
251 rhs->fval = tmp;
252 ok = true;
254 break;
255 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
257 auto tmp = rhs->uval;
258 rhs->fval = tmp;
259 ok = true;
261 break;
262 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
263 ok = true;
264 break;
266 break;
268 if (!ok) {
269 error(location, yyscanner, "cannot coerce binary expression arguments");
271 return ok;
274 unoidl::detail::SourceProviderEntity * findEntity_(
275 unoidl::detail::SourceProviderScannerData * data, OUString * name)
277 assert(data != nullptr);
278 assert(name != nullptr);
279 OUString n;
280 if (!name->startsWith(".", &n)) {
281 for (auto i(data->modules.rbegin()); i != data->modules.rend(); ++i) {
282 n = *i + "." + *name;
283 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator j(
284 data->entities.find(n));
285 if (j != data->entities.end()) {
286 *name = n;
287 return &j->second;
289 rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
290 if (ent.is()) {
291 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator
292 k(data->entities.emplace(
294 unoidl::detail::SourceProviderEntity(
295 unoidl::detail::SourceProviderEntity::KIND_EXTERNAL,
296 ent)).
297 first);
298 *name = n;
299 return &k->second;
302 n = *name;
304 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
305 data->entities.find(n));
306 if (i != data->entities.end()) {
307 *name = n;
308 return &i->second;
310 rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
311 if (ent.is()) {
312 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator
313 j(data->entities.emplace(
315 unoidl::detail::SourceProviderEntity(
316 unoidl::detail::SourceProviderEntity::KIND_EXTERNAL,
317 ent)).
318 first);
319 *name = n;
320 return &j->second;
322 return nullptr;
325 enum Found { FOUND_ERROR, FOUND_TYPE, FOUND_ENTITY };
327 Found findEntity(
328 YYLTYPE location, yyscan_t yyscanner,
329 unoidl::detail::SourceProviderScannerData * data,
330 bool resolveInterfaceDefinitions, OUString * name,
331 unoidl::detail::SourceProviderEntity const ** entity, bool * typedefed,
332 unoidl::detail::SourceProviderType * typedefedType)
334 //TODO: avoid recursion
335 assert(data != nullptr);
336 assert(name != nullptr);
337 assert(entity != nullptr);
338 unoidl::detail::SourceProviderEntity * e = findEntity_(data, name);
339 OUString n(*name);
340 OUString typeNucleus;
341 std::size_t rank = 0;
342 std::vector<unoidl::detail::SourceProviderType> args;
343 for (;;) {
344 if (e != nullptr) {
345 switch (e->kind) {
346 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
347 if (e->pad.is()) {
348 break;
350 assert(e->entity.is());
351 [[fallthrough]];
352 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
353 if (e->entity->getSort() == unoidl::Entity::SORT_TYPEDEF) {
354 if (typedefed != nullptr) {
355 *typedefed = true;
357 if (data->publishedContext
358 && !static_cast<unoidl::TypedefEntity *>(
359 e->entity.get())->isPublished())
361 error(
362 location, yyscanner,
363 ("type " + *name + " based on unpublished typedef "
364 + n + " used in published context"));
365 return FOUND_ERROR;
367 OUString t(
368 static_cast<unoidl::TypedefEntity *>(e->entity.get())
369 ->getType());
370 typeNucleus = t;
371 while (typeNucleus.startsWith("[]", &typeNucleus)) {
372 if (!args.empty()) {
373 error(
374 location, yyscanner,
375 ("inconsistent type manager: bad type " + *name
376 + (" based on instantiated polymorphic struct"
377 " type based on sequence type named ")
378 + t));
379 return FOUND_ERROR;
381 if (rank == std::numeric_limits<std::size_t>::max()) {
382 error(
383 location, yyscanner,
384 ("bad type " + *name
385 + " based on sequence type of too high rank"));
386 return FOUND_ERROR;
388 ++rank;
390 sal_Int32 i = typeNucleus.indexOf('<');
391 if (i != -1) {
392 if (!args.empty()) {
393 error(
394 location, yyscanner,
395 ("inconsistent type manager: bad type " + *name
396 + (" based on instantiated polymorphic struct"
397 " type based on instantiated polymorphic"
398 " struct type named ")
399 + t));
400 return FOUND_ERROR;
402 OUString tmpl(typeNucleus.copy(0, i));
403 do {
404 ++i; // skip '<' or ','
405 sal_Int32 j = i;
406 for (sal_Int32 level = 0;
407 j != typeNucleus.getLength(); ++j)
409 sal_Unicode c = typeNucleus[j];
410 if (c == ',') {
411 if (level == 0) {
412 break;
414 } else if (c == '<') {
415 ++level;
416 } else if (c == '>') {
417 if (level == 0) {
418 break;
420 --level;
423 if (j != typeNucleus.getLength()) {
424 OUString argName(typeNucleus.copy(i, j - i));
425 unoidl::detail::SourceProviderEntity const *
426 argEnt;
427 unoidl::detail::SourceProviderType argType;
428 switch (
429 findEntity(
430 location, yyscanner, data, false,
431 &argName, &argEnt, nullptr, &argType))
433 case FOUND_ERROR:
434 return FOUND_ERROR;
435 case FOUND_TYPE:
436 break;
437 case FOUND_ENTITY:
438 if (argEnt == nullptr) {
439 error(
440 location, yyscanner,
441 (("inconsistent type manager: bad"
442 " instantiated polymorphic struct"
443 " type template type argument ")
444 + argName));
445 return FOUND_ERROR;
446 } else {
447 unoidl::detail::SourceProviderType::Type
448 argT
449 = unoidl::detail::SourceProviderType::Type();
450 // avoid warnings
451 switch (argEnt->kind) {
452 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
453 if (e->pad.is()) {
454 error(
455 location, yyscanner,
456 (("inconsistent type"
457 " manager: bad"
458 " instantiated"
459 " polymorphic struct type"
460 " template type"
461 " argument ")
462 + argName));
463 return FOUND_ERROR;
465 assert(e->entity.is());
466 [[fallthrough]];
467 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
468 switch (e->entity->getSort()) {
469 case unoidl::Entity::SORT_ENUM_TYPE:
470 argT = unoidl::detail::SourceProviderType::TYPE_ENUM;
471 break;
472 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
473 argT = unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT;
474 break;
475 case unoidl::Entity::SORT_INTERFACE_TYPE:
476 argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
477 break;
478 default:
479 error(
480 location, yyscanner,
481 (("inconsistent type"
482 "manager: bad"
483 " instantiated"
484 " polymorphic struct type"
485 " template type"
486 " argument ")
487 + argName));
488 return FOUND_ERROR;
490 break;
491 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
492 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
493 argT = unoidl::detail::SourceProviderType::TYPE_INTERFACE;
494 break;
495 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
496 assert(false && "this cannot happen");
498 argType
499 = unoidl::detail::SourceProviderType(
500 argT, argName, argEnt);
502 break;
504 args.push_back(argType);
506 i = j;
507 } while (i != typeNucleus.getLength()
508 && typeNucleus[i] != '>');
509 if (i != typeNucleus.getLength() - 1
510 || typeNucleus[i] != '>')
512 error(
513 location, yyscanner,
514 ("inconsistent type manager: bad type name \""
515 + t + "\""));
516 return FOUND_ERROR;
518 assert(!args.empty());
519 typeNucleus = tmpl;
521 if (typeNucleus.isEmpty()) {
522 error(
523 location, yyscanner,
524 ("inconsistent type manager: bad type name \"" + t
525 + "\""));
526 return FOUND_ERROR;
528 if (typeNucleus == "void") {
529 error(
530 location, yyscanner,
531 ("inconsistent type manager: bad type " + *name
532 + " based on void"));
533 return FOUND_ERROR;
535 if (typeNucleus == "boolean" || typeNucleus == "byte"
536 || typeNucleus == "short"
537 || typeNucleus == "unsigned short"
538 || typeNucleus == "long"
539 || typeNucleus == "unsigned long"
540 || typeNucleus == "hyper"
541 || typeNucleus == "unsigned hyper"
542 || typeNucleus == "float" || typeNucleus == "double"
543 || typeNucleus == "char" || typeNucleus == "string"
544 || typeNucleus == "type" || typeNucleus == "any")
546 if (!args.empty()) {
547 error(
548 location, yyscanner,
549 ("inconsistent type manager: bad type " + *name
550 + (" based on instantiated polymorphic struct"
551 " type based on ")
552 + typeNucleus));
553 return FOUND_ERROR;
555 break;
557 n = "." + typeNucleus;
558 typeNucleus.clear();
559 e = findEntity_(data, &n);
560 continue;
562 break;
563 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
564 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
565 if (resolveInterfaceDefinitions) {
566 rtl::Reference<unoidl::Entity> ent(
567 data->manager->findEntity(n));
568 // Do not allow ent to be of SORT_TYPEDEF:
569 if (!ent.is()
570 || (ent->getSort()
571 != unoidl::Entity::SORT_INTERFACE_TYPE))
573 error(
574 location, yyscanner,
575 (*name + " is based on interface declaration " + n
576 + " that is not an interface type entity"));
577 return FOUND_ERROR;
579 e->kind
580 = unoidl::detail::SourceProviderEntity::KIND_EXTERNAL;
581 e->entity = ent;
583 break;
584 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
585 error(
586 location, yyscanner,
587 *name + " is based on module entity " + n);
588 return FOUND_ERROR;
591 if (!typeNucleus.isEmpty() || rank != 0 || !args.empty()) {
592 if (typeNucleus.isEmpty() && e == nullptr) {
593 // Found a type name based on an unknown entity:
594 *entity = nullptr;
595 return FOUND_ENTITY;
597 unoidl::detail::SourceProviderType t;
598 if (args.empty()) {
599 if (typeNucleus == "boolean") {
600 t = unoidl::detail::SourceProviderType(
601 unoidl::detail::SourceProviderType::TYPE_BOOLEAN);
602 } else if (typeNucleus == "byte") {
603 t = unoidl::detail::SourceProviderType(
604 unoidl::detail::SourceProviderType::TYPE_BYTE);
605 } else if (typeNucleus == "short") {
606 t = unoidl::detail::SourceProviderType(
607 unoidl::detail::SourceProviderType::TYPE_SHORT);
608 } else if (typeNucleus == "unsigned short") {
609 t = unoidl::detail::SourceProviderType(
610 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT);
611 } else if (typeNucleus == "long") {
612 t = unoidl::detail::SourceProviderType(
613 unoidl::detail::SourceProviderType::TYPE_LONG);
614 } else if (typeNucleus == "unsigned long") {
615 t = unoidl::detail::SourceProviderType(
616 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG);
617 } else if (typeNucleus == "hyper") {
618 t = unoidl::detail::SourceProviderType(
619 unoidl::detail::SourceProviderType::TYPE_HYPER);
620 } else if (typeNucleus == "unsigned hyper") {
621 t = unoidl::detail::SourceProviderType(
622 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER);
623 } else if (typeNucleus == "float") {
624 t = unoidl::detail::SourceProviderType(
625 unoidl::detail::SourceProviderType::TYPE_FLOAT);
626 } else if (typeNucleus == "double") {
627 t = unoidl::detail::SourceProviderType(
628 unoidl::detail::SourceProviderType::TYPE_DOUBLE);
629 } else if (typeNucleus == "char") {
630 t = unoidl::detail::SourceProviderType(
631 unoidl::detail::SourceProviderType::TYPE_CHAR);
632 } else if (typeNucleus == "string") {
633 t = unoidl::detail::SourceProviderType(
634 unoidl::detail::SourceProviderType::TYPE_STRING);
635 } else if (typeNucleus == "type") {
636 t = unoidl::detail::SourceProviderType(
637 unoidl::detail::SourceProviderType::TYPE_TYPE);
638 } else if (typeNucleus == "any") {
639 t = unoidl::detail::SourceProviderType(
640 unoidl::detail::SourceProviderType::TYPE_ANY);
641 } else {
642 assert(typeNucleus.isEmpty());
643 assert(e != nullptr);
644 switch (e->kind) {
645 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
646 if (e->pad.is()) {
647 if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
648 e->pad.get())
649 != nullptr)
651 t = unoidl::detail::SourceProviderType(
652 unoidl::detail::SourceProviderType::TYPE_ENUM,
653 n, e);
654 } else if (dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
655 e->pad.get())
656 != nullptr)
658 t = unoidl::detail::SourceProviderType(
659 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
660 n, e);
661 } else if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
662 e->pad.get())
663 != nullptr)
665 error(
666 location, yyscanner,
667 ("bad type " + *name
668 + (" based on recursive reference to"
669 " polymorphic struct type template ")
670 + n));
671 return FOUND_ERROR;
672 } else if (dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
673 e->pad.get())
674 != nullptr)
676 t = unoidl::detail::SourceProviderType(
677 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
678 n, e);
679 } else if (dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
680 e->pad.get())
681 != nullptr)
683 t = unoidl::detail::SourceProviderType(
684 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
685 n, e);
686 } else {
687 error(
688 location, yyscanner,
689 ("bad type " + *name
690 + " based on non-type entity " + n));
691 return FOUND_ERROR;
693 break;
695 assert(e->entity.is());
696 [[fallthrough]];
697 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
698 switch (e->entity->getSort()) {
699 case unoidl::Entity::SORT_ENUM_TYPE:
700 t = unoidl::detail::SourceProviderType(
701 unoidl::detail::SourceProviderType::TYPE_ENUM,
702 n, e);
703 break;
704 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
705 t = unoidl::detail::SourceProviderType(
706 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
707 n, e);
708 break;
709 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
710 error(
711 location, yyscanner,
712 ("bad type " + *name
713 + " based on polymorphic struct type template "
714 + n + " without type arguments"));
715 return FOUND_ERROR;
716 case unoidl::Entity::SORT_EXCEPTION_TYPE:
717 t = unoidl::detail::SourceProviderType(
718 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
719 n, e);
720 break;
721 case unoidl::Entity::SORT_INTERFACE_TYPE:
722 t = unoidl::detail::SourceProviderType(
723 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
724 n, e);
725 break;
726 default:
727 error(
728 location, yyscanner,
729 ("bad type " + *name
730 + " based on non-type entity " + n));
731 return FOUND_ERROR;
733 break;
734 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
735 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
736 t = unoidl::detail::SourceProviderType(
737 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
738 n, e);
739 break;
740 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
741 assert(false && "this cannot happen");
744 } else {
745 assert(typeNucleus.isEmpty());
746 assert(e != nullptr);
747 switch (e->kind) {
748 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
749 if (e->pad.is()) {
750 error(
751 location, yyscanner,
752 ("bad type " + *name
753 + (" based on instantiated polymorphic struct type"
754 " based on ")
756 + (" that is either not a polymorphic struct type"
757 " template or a recursive reference to a"
758 " polymorphic struct type template")));
759 return FOUND_ERROR;
761 assert(e->entity.is());
762 [[fallthrough]];
763 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
764 if (e->entity->getSort()
765 == unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)
767 if (args.size()
768 != (static_cast<
769 unoidl::PolymorphicStructTypeTemplateEntity *>(
770 e->entity.get())
771 ->getTypeParameters().size()))
773 error(
774 location, yyscanner,
775 ("bad type " + *name
776 + (" based on instantiated polymorphic struct"
777 " type with ")
778 + OUString::number(args.size())
779 + (" type arguments based on polymorphic"
780 " struct type template ")
781 + n + " with "
782 + OUString::number(
783 static_cast<
784 unoidl::PolymorphicStructTypeTemplateEntity *>(
785 e->entity.get())
786 ->getTypeParameters().size())
787 + " type parameters"));
788 return FOUND_ERROR;
790 t = unoidl::detail::SourceProviderType(n, e, std::move(args));
791 break;
793 [[fallthrough]];
794 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
795 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
796 error(
797 location, yyscanner,
798 ("bad type " + *name
799 + (" based on instantiated polymorphic struct type"
800 " based on ")
802 + " that is not a polymorphic struct type template"));
803 return FOUND_ERROR;
804 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
805 assert(false && "this cannot happen");
808 if (typedefedType != nullptr) {
809 for (std::size_t i = 0; i != rank; ++i) {
810 t = unoidl::detail::SourceProviderType(&t);
812 *typedefedType = t;
813 typedefedType->typedefName = *name;
815 *entity = nullptr;
816 return FOUND_TYPE;
818 *entity = e;
819 return FOUND_ENTITY;
824 bool checkTypeArgument(
825 YYLTYPE location, yyscan_t yyscanner,
826 unoidl::detail::SourceProviderType const & type)
828 switch (type.type) {
829 case unoidl::detail::SourceProviderType::TYPE_VOID:
830 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
831 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
832 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
833 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
834 case unoidl::detail::SourceProviderType::TYPE_PARAMETER: //TODO?
835 error(
836 location, yyscanner,
837 "bad instantiated polymorphic struct type argument");
838 return false;
839 case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
840 return checkTypeArgument(location, yyscanner, type.subtypes.front());
841 default:
842 return true;
846 bool checkInstantiatedPolymorphicStructTypeArgument(
847 unoidl::detail::SourceProviderType const & type, OUString const & name)
849 if (type.type
850 == unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT)
852 for (auto & i: type.subtypes) {
853 if (checkInstantiatedPolymorphicStructTypeArgument(i, name)
854 || i.getName() == name) // no need to worry about typedef
856 return true;
860 return false;
863 std::vector<OUString> annotations(bool deprecated) {
864 std::vector<OUString> ann;
865 if (deprecated) {
866 ann.push_back("deprecated");
868 return ann;
875 %token TOK_ELLIPSIS
876 %token TOK_COLONS
877 %token TOK_LEFTSHIFT
878 %token TOK_RIGHTSHIFT
880 %token TOK_FALSE
881 %token TOK_TRUE
882 %token TOK_ANY
883 %token TOK_ATTRIBUTE
884 %token TOK_BOOLEAN
885 %token TOK_BOUND
886 %token TOK_BYTE
887 %token TOK_CHAR
888 %token TOK_CONST
889 %token TOK_CONSTANTS
890 %token TOK_CONSTRAINED
891 %token TOK_DOUBLE
892 %token TOK_ENUM
893 %token TOK_EXCEPTION
894 %token TOK_FLOAT
895 %token TOK_GET
896 %token TOK_HYPER
897 %token TOK_IN
898 %token TOK_INOUT
899 %token TOK_INTERFACE
900 %token TOK_LONG
901 %token TOK_MAYBEAMBIGUOUS
902 %token TOK_MAYBEDEFAULT
903 %token TOK_MAYBEVOID
904 %token TOK_MODULE
905 %token TOK_OPTIONAL
906 %token TOK_OUT
907 %token TOK_PROPERTY
908 %token TOK_PUBLISHED
909 %token TOK_RAISES
910 %token TOK_READONLY
911 %token TOK_REMOVABLE
912 %token TOK_SEQUENCE
913 %token TOK_SERVICE
914 %token TOK_SET
915 %token TOK_SHORT
916 %token TOK_SINGLETON
917 %token TOK_STRING
918 %token TOK_STRUCT
919 %token TOK_TRANSIENT
920 %token TOK_TYPE
921 %token TOK_TYPEDEF
922 %token TOK_UNSIGNED
923 %token TOK_VOID
925 %token<sval> TOK_IDENTIFIER
926 %token<ival> TOK_INTEGER
927 %token<fval> TOK_FLOATING
929 %token TOK_DEPRECATED
931 %token TOK_ERROR
933 %type<sval> identifier name singleInheritance singleInheritance_opt
934 %type<bval> ctors_opt deprecated_opt ellipsis_opt published_opt
935 %type<decls> attributeAccessDecl attributeAccessDecls
936 %type<dir> direction
937 %type<excns> exceptionSpec exceptionSpec_opt exceptions
938 %type<flags> flag flagSection flagSection_opt flags
939 %type<expr> addExpr andExpr expr multExpr orExpr primaryExpr shiftExpr unaryExpr
940 xorExpr
941 %type<type> type
942 %type<types> typeArguments
944 %initial-action { yylloc = 1; }
948 definitions:
949 definitions definition
950 | /* empty */
953 definition:
954 moduleDecl
955 | enumDefn
956 | plainStructDefn
957 | polymorphicStructTemplateDefn
958 | exceptionDefn
959 | interfaceDefn
960 | typedefDefn
961 | constantGroupDefn
962 | singleInterfaceBasedServiceDefn
963 | accumulationBasedServiceDefn
964 | interfaceBasedSingletonDefn
965 | serviceBasedSingletonDefn
966 | interfaceDecl
969 moduleDecl:
970 TOK_MODULE identifier
972 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
973 OUString name(convertToFullName(data, $2));
974 data->modules.push_back(name);
975 std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
976 data->entities.emplace(
977 name,
978 unoidl::detail::SourceProviderEntity(
979 unoidl::detail::SourceProviderEntity::KIND_MODULE)));
980 if (!p.second
981 && (p.first->second.kind
982 != unoidl::detail::SourceProviderEntity::KIND_MODULE))
984 error(@2, yyscanner, "multiple entities named " + name);
985 YYERROR;
988 '{' definitions '}' ';' { yyget_extra(yyscanner)->modules.pop_back(); }
991 enumDefn:
992 deprecated_opt published_opt TOK_ENUM identifier
994 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
995 data->publishedContext = $2;
996 convertToCurrentName(data, $4);
997 if (!data->entities.emplace(
998 data->currentName,
999 unoidl::detail::SourceProviderEntity(
1000 new unoidl::detail::SourceProviderEnumTypeEntityPad(
1001 $2))).
1002 second)
1004 error(@4, yyscanner, "multiple entities named " + data->currentName);
1005 YYERROR;
1008 '{' enumMembers '}' ';'
1010 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1011 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1012 unoidl::detail::SourceProviderEnumTypeEntityPad * pad =
1013 dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
1014 ent->pad.get());
1015 assert(pad != nullptr);
1016 ent->entity = new unoidl::EnumTypeEntity(
1017 pad->isPublished(), std::move(pad->members), annotations($1));
1018 ent->pad.clear();
1019 clearCurrentState(data);
1023 enumMembers:
1024 | enumMembers ',' enumMember
1025 | enumMember
1028 enumMember:
1029 deprecated_opt identifier
1031 OUString id(convertName($2));
1032 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1033 rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
1034 getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
1035 sal_Int32 v;
1036 if (pad->members.empty()) {
1037 v = 0;
1038 } else {
1039 v = pad->members.back().value;
1040 if (v == SAL_MAX_INT32) {
1041 error(
1042 @2, yyscanner,
1043 ("enum " + data->currentName + " member " + id
1044 + " would have out-of-range value 2^31"));
1045 YYERROR;
1047 ++v;
1049 pad->members.emplace_back(id, v, annotations($1));
1051 | deprecated_opt identifier '=' expr
1053 OUString id(convertName($2));
1054 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1055 rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
1056 getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
1057 sal_Int32 v;
1058 switch ($4.type) {
1059 case unoidl::detail::SourceProviderExpr::TYPE_INT:
1060 if ($4.ival < SAL_MIN_INT32 || $4.ival > SAL_MAX_INT32) {
1061 error(
1062 @4, yyscanner,
1063 ("out-of-range enum " + data->currentName + " member " + id
1064 + " value " + OUString::number($4.ival)));
1065 YYERROR;
1067 v = static_cast<sal_Int32>($4.ival);
1068 break;
1069 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
1070 if ($4.uval > SAL_MAX_INT32) {
1071 error(
1072 @4, yyscanner,
1073 ("out-of-range enum " + data->currentName + " member " + id
1074 + " value " + OUString::number($4.uval)));
1075 YYERROR;
1077 v = static_cast<sal_Int32>($4.uval);
1078 break;
1079 default:
1080 error(
1081 @4, yyscanner,
1082 ("non-integer enum " + data->currentName + " member " + id
1083 + " value"));
1084 YYERROR;
1085 break;
1087 pad->members.emplace_back(id, v, annotations($1));
1091 plainStructDefn:
1092 deprecated_opt published_opt TOK_STRUCT identifier singleInheritance_opt
1094 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1095 data->publishedContext = $2;
1096 convertToCurrentName(data, $4);
1097 OUString baseName;
1098 rtl::Reference<unoidl::PlainStructTypeEntity> baseEnt;
1099 if ($5 != nullptr) {
1100 baseName = convertName($5);
1101 unoidl::detail::SourceProviderEntity const * p;
1102 if (findEntity(
1103 @5, yyscanner, data, false, &baseName, &p, nullptr, nullptr)
1104 == FOUND_ERROR)
1106 YYERROR;
1108 if (p == nullptr || !p->entity.is()
1109 || p->entity->getSort() != unoidl::Entity::SORT_PLAIN_STRUCT_TYPE)
1111 error(
1112 @5, yyscanner,
1113 ("plain struct type " + data->currentName + " base "
1114 + baseName
1115 + " does not resolve to an existing plain struct type"));
1116 YYERROR;
1118 baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
1119 p->entity.get());
1120 if ($2 && !baseEnt->isPublished()) {
1121 error(
1122 @5, yyscanner,
1123 ("published plain struct type " + data->currentName + " base "
1124 + baseName + " is unpublished"));
1125 YYERROR;
1128 if (!data->entities.emplace(
1129 data->currentName,
1130 unoidl::detail::SourceProviderEntity(
1131 new unoidl::detail::SourceProviderPlainStructTypeEntityPad(
1132 $2, baseName, baseEnt))).
1133 second)
1135 error(@4, yyscanner, "multiple entities named " + data->currentName);
1136 YYERROR;
1139 '{' structMembers '}' ';'
1141 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1142 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1143 unoidl::detail::SourceProviderPlainStructTypeEntityPad * pad =
1144 dynamic_cast<
1145 unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
1146 ent->pad.get());
1147 assert(pad != nullptr);
1148 ent->entity = new unoidl::PlainStructTypeEntity(
1149 pad->isPublished(), pad->baseName, std::move(pad->members), annotations($1));
1150 ent->pad.clear();
1151 clearCurrentState(data);
1155 polymorphicStructTemplateDefn:
1156 deprecated_opt published_opt TOK_STRUCT identifier '<'
1158 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1159 data->publishedContext = $2;
1160 convertToCurrentName(data, $4);
1161 if (!data->entities.emplace(
1162 data->currentName,
1163 unoidl::detail::SourceProviderEntity(
1164 new unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad(
1165 $2))).
1166 second)
1168 error(@4, yyscanner, "multiple entities named " + data->currentName);
1169 YYERROR;
1172 typeParameters '>' '{' structMembers '}' ';'
1174 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1175 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1176 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
1177 pad = dynamic_cast<
1178 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
1179 ent->pad.get());
1180 assert(pad != nullptr);
1181 ent->entity = new unoidl::PolymorphicStructTypeTemplateEntity(
1182 pad->isPublished(), std::move(pad->typeParameters), std::move(pad->members),
1183 annotations($1));
1184 ent->pad.clear();
1185 clearCurrentState(data);
1189 typeParameters:
1190 typeParameters ',' identifier
1192 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1193 rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
1194 pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
1195 data));
1196 OUString id(convertName($3));
1197 if (std::find(pad->typeParameters.begin(), pad->typeParameters.end(), id)
1198 != pad->typeParameters.end())
1200 error(
1201 @3, yyscanner,
1202 ("polymorphic struct type template " + data->currentName
1203 + " type parameter " + id
1204 + " has same identifier as another type parameter"));
1205 YYERROR;
1207 pad->typeParameters.push_back(id);
1209 | identifier
1211 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1212 rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
1213 pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
1214 data));
1215 OUString id(convertName($1));
1216 assert(pad->typeParameters.empty());
1217 pad->typeParameters.push_back(id);
1221 exceptionDefn:
1222 deprecated_opt published_opt TOK_EXCEPTION identifier singleInheritance_opt
1224 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1225 data->publishedContext = $2;
1226 convertToCurrentName(data, $4);
1227 OUString baseName;
1228 rtl::Reference<unoidl::ExceptionTypeEntity> baseEnt;
1229 if ($5 != nullptr) {
1230 baseName = convertName($5);
1231 unoidl::detail::SourceProviderEntity const * p;
1232 if (findEntity(
1233 @5, yyscanner, data, false, &baseName, &p, nullptr, nullptr)
1234 == FOUND_ERROR)
1236 YYERROR;
1238 if (p == nullptr || !p->entity.is()
1239 || p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE)
1241 error(
1242 @5, yyscanner,
1243 ("exception type " + data->currentName + " base " + baseName
1244 + " does not resolve to an existing exception type"));
1245 YYERROR;
1247 baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
1248 p->entity.get());
1249 if ($2 && !baseEnt->isPublished()) {
1250 error(
1251 @5, yyscanner,
1252 ("published exception type " + data->currentName + " base "
1253 + baseName + " is unpublished"));
1254 YYERROR;
1257 if (!data->entities.emplace(
1258 data->currentName,
1259 unoidl::detail::SourceProviderEntity(
1260 new unoidl::detail::SourceProviderExceptionTypeEntityPad(
1261 $2, baseName, baseEnt))).
1262 second)
1264 error(@4, yyscanner, "multiple entities named " + data->currentName);
1265 YYERROR;
1268 '{' structMembers '}' ';'
1270 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1271 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1272 unoidl::detail::SourceProviderExceptionTypeEntityPad * pad =
1273 dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
1274 ent->pad.get());
1275 assert(pad != nullptr);
1276 ent->entity = new unoidl::ExceptionTypeEntity(
1277 pad->isPublished(), pad->baseName, std::move(pad->members), annotations($1));
1278 ent->pad.clear();
1279 clearCurrentState(data);
1283 structMembers:
1284 structMembers structMember
1285 | /* empty */
1288 structMember:
1289 deprecated_opt type identifier ';'
1291 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1292 unoidl::detail::SourceProviderType t(*$2);
1293 delete $2;
1294 OUString id(convertName($3));
1295 switch (t.type) {
1296 case unoidl::detail::SourceProviderType::TYPE_VOID:
1297 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1298 error(
1299 @2, yyscanner,
1300 ("illegal struct/exception type " + data->currentName
1301 + " direct member " + id + " type"));
1302 YYERROR;
1303 break;
1304 default:
1305 break;
1307 if (t.type != unoidl::detail::SourceProviderType::TYPE_PARAMETER
1308 && t.getName() == data->currentName) // no need to worry about typedef
1310 error(
1311 @2, yyscanner,
1312 ("struct/exception type " + data->currentName + " direct member "
1313 + id + " has same type as the type itself"));
1314 YYERROR;
1316 if (checkInstantiatedPolymorphicStructTypeArgument(t, data->currentName))
1318 error(
1319 @2, yyscanner,
1320 ("struct/exception type " + data->currentName + " direct member "
1321 + id
1322 + (" has instantiated polymorphic struct type that uses the type"
1323 " itself as an argument")));
1324 YYERROR;
1326 if (nameHasSameIdentifierAs(data->currentName, id)) {
1327 error(
1328 @3, yyscanner,
1329 ("struct/exception type " + data->currentName + " direct member "
1330 + id + " has same unqualified identifier as the type itself"));
1331 YYERROR;
1333 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1334 unoidl::detail::SourceProviderPlainStructTypeEntityPad * p1 =
1335 dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
1336 ent->pad.get());
1337 if (p1 != nullptr) {
1338 for (const auto & i: p1->members) {
1339 if (id == i.name) {
1340 error(
1341 @3, yyscanner,
1342 ("plain struct type " + data->currentName
1343 + " direct member " + id
1344 + " has same identifier as another direct member"));
1345 YYERROR;
1348 if (p1->baseEntity.is()) {
1349 OUString baseName(p1->baseName);
1350 for (auto baseEnt(p1->baseEntity);;) {
1351 if (nameHasSameIdentifierAs(baseName, id)) {
1352 error(
1353 @3, yyscanner,
1354 ("plain struct type " + data->currentName
1355 + " direct member " + id
1356 + " has same unqalified identifier as base "
1357 + baseName));
1358 YYERROR;
1360 for (auto & i: baseEnt->getDirectMembers()) {
1361 if (id == i.name) {
1362 error(
1363 @3, yyscanner,
1364 ("plain struct type " + data->currentName
1365 + " direct member " + id
1366 + " has same identifier as a member of base "
1367 + baseName));
1368 YYERROR;
1371 baseName = baseEnt->getDirectBase();
1372 if (baseName.isEmpty()) {
1373 break;
1375 unoidl::detail::SourceProviderEntity const * p;
1376 if (findEntity(
1377 @2, yyscanner, data, false, &baseName, &p, nullptr,
1378 nullptr)
1379 == FOUND_ERROR)
1381 YYERROR;
1383 if (p == nullptr || !p->entity.is()
1384 || (p->entity->getSort()
1385 != unoidl::Entity::SORT_PLAIN_STRUCT_TYPE))
1387 error(
1388 @2, yyscanner,
1389 ("inconsistent type manager: plain struct type "
1390 + data->currentName + " base " + baseName
1391 + (" does not resolve to an existing plain struct"
1392 " type")));
1393 YYERROR;
1395 baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
1396 p->entity.get());
1399 p1->members.emplace_back(id, t.getName(), annotations($1));
1400 } else {
1401 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
1402 p2 = dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
1403 ent->pad.get());
1404 if (p2 != nullptr) {
1405 for (const auto & i: p2->members) {
1406 if (id == i.name) {
1407 error(
1408 @3, yyscanner,
1409 ("polymorphic struct type template "
1410 + data->currentName + " direct member " + id
1411 + " has same identifier as another direct member"));
1412 YYERROR;
1415 p2->members.emplace_back(
1416 id, t.getName(),
1417 t.type == unoidl::detail::SourceProviderType::TYPE_PARAMETER,
1418 annotations($1));
1419 } else {
1420 unoidl::detail::SourceProviderExceptionTypeEntityPad * p3
1421 = dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
1422 ent->pad.get());
1423 assert(p3 != nullptr);
1424 for (const auto & i: p3->members) {
1425 if (id == i.name) {
1426 error(
1427 @3, yyscanner,
1428 ("exception type " + data->currentName
1429 + " direct member " + id
1430 + " has same identifier as another direct member"));
1431 YYERROR;
1434 if (p3->baseEntity.is()) {
1435 OUString baseName(p3->baseName);
1436 for (auto baseEnt(p3->baseEntity);;) {
1437 if (nameHasSameIdentifierAs(baseName, id)) {
1438 error(
1439 @3, yyscanner,
1440 ("exception type " + data->currentName
1441 + " direct member " + id
1442 + " has same unqalified identifier as base "
1443 + baseName));
1444 YYERROR;
1446 for (auto & i: baseEnt->getDirectMembers()) {
1447 if (id == i.name) {
1448 error(
1449 @3, yyscanner,
1450 ("exception type " + data->currentName
1451 + " direct member " + id
1452 + " has same identifier as a member of base "
1453 + baseName));
1454 YYERROR;
1457 baseName = baseEnt->getDirectBase();
1458 if (baseName.isEmpty()) {
1459 break;
1461 unoidl::detail::SourceProviderEntity const * p;
1462 if (findEntity(
1463 @2, yyscanner, data, false, &baseName, &p,
1464 nullptr, nullptr)
1465 == FOUND_ERROR)
1467 YYERROR;
1469 if (p == nullptr || !p->entity.is()
1470 || (p->entity->getSort()
1471 != unoidl::Entity::SORT_EXCEPTION_TYPE))
1473 error(
1474 @2, yyscanner,
1475 ("inconsistent type manager: exception type "
1476 + data->currentName + " base " + baseName
1477 + (" does not resolve to an existing exception"
1478 " type")));
1479 YYERROR;
1481 baseEnt = static_cast<unoidl::ExceptionTypeEntity *>(
1482 p->entity.get());
1485 p3->members.emplace_back(id, t.getName(), annotations($1));
1491 interfaceDefn:
1492 deprecated_opt published_opt TOK_INTERFACE identifier singleInheritance_opt
1494 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1495 data->publishedContext = $2;
1496 convertToCurrentName(data, $4);
1497 OUString baseName;
1498 rtl::Reference<unoidl::InterfaceTypeEntity> baseEnt;
1499 if ($5 != nullptr) {
1500 baseName = convertName($5);
1501 unoidl::detail::SourceProviderEntity const * p;
1502 if (findEntity(
1503 @5, yyscanner, data, true, &baseName, &p, nullptr, nullptr)
1504 == FOUND_ERROR)
1506 YYERROR;
1508 if (p == nullptr || !p->entity.is()
1509 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1511 error(
1512 @5, yyscanner,
1513 ("interface type " + data->currentName + " direct base "
1514 + baseName
1515 + " does not resolve to an existing interface type"));
1516 YYERROR;
1518 baseEnt = static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get());
1519 if ($2 && !baseEnt->isPublished()) {
1520 error(
1521 @5, yyscanner,
1522 ("published interface type " + data->currentName
1523 + " direct base " + baseName + " is unpublished"));
1524 YYERROR;
1527 std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
1528 data->entities.find(data->currentName));
1529 if (i != data->entities.end()) {
1530 switch (i->second.kind) {
1531 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
1532 break;
1533 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
1534 if (!$2) {
1535 error(
1536 @4, yyscanner,
1537 ("unpublished interface type " + data->currentName
1538 + " has been declared published"));
1539 YYERROR;
1541 break;
1542 default:
1543 error(
1544 @4, yyscanner,
1545 "multiple entities named " + data->currentName);
1546 YYERROR;
1547 break;
1550 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1551 new unoidl::detail::SourceProviderInterfaceTypeEntityPad(
1552 $2, baseEnt.is()));
1553 if (baseEnt.is()
1554 && !pad->addDirectBase(
1555 @4, yyscanner, data,
1556 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1557 baseName, baseEnt, std::vector<OUString>()),
1558 false))
1560 YYERROR;
1562 data->entities[data->currentName] = unoidl::detail::SourceProviderEntity(
1563 pad);
1565 '{' interfaceMembers '}' ';'
1567 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1568 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1569 unoidl::detail::SourceProviderInterfaceTypeEntityPad * pad =
1570 dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
1571 ent->pad.get());
1572 assert(pad != nullptr);
1573 if (pad->directMandatoryBases.empty()
1574 && data->currentName != "com.sun.star.uno.XInterface")
1576 OUString base(".com.sun.star.uno.XInterface");
1577 unoidl::detail::SourceProviderEntity const * p;
1578 if (findEntity(@4, yyscanner, data, true, &base, &p, nullptr, nullptr)
1579 == FOUND_ERROR)
1581 YYERROR;
1583 if (p == nullptr || !p->entity.is()
1584 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1586 error(
1587 @3, yyscanner,
1588 ("interface type " + data->currentName
1589 + " implicit direct base " + base
1590 + " does not resolve to an existing interface type"));
1591 YYERROR;
1593 if (!pad->addDirectBase(
1594 @3, yyscanner, data,
1595 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1596 base,
1597 static_cast<unoidl::InterfaceTypeEntity *>(
1598 p->entity.get()),
1599 std::vector<OUString>()),
1600 false))
1602 YYERROR;
1605 std::vector<unoidl::AnnotatedReference> mbases;
1606 for (auto & i: pad->directMandatoryBases) {
1607 mbases.emplace_back(i.name, std::move(i.annotations));
1609 std::vector<unoidl::AnnotatedReference> obases;
1610 for (auto & i: pad->directOptionalBases) {
1611 obases.emplace_back(i.name, std::move(i.annotations));
1613 ent->entity = new unoidl::InterfaceTypeEntity(
1614 pad->isPublished(), std::move(mbases), std::move(obases), std::move(pad->directAttributes),
1615 std::move(pad->directMethods), annotations($1));
1616 ent->pad.clear();
1617 clearCurrentState(data);
1621 interfaceMembers:
1622 interfaceMembers interfaceMember
1623 | /* empty */
1626 interfaceMember:
1627 interfaceBase
1628 | interfaceAttribute
1629 | interfaceMethod
1632 interfaceBase:
1633 deprecated_opt flagSection_opt TOK_INTERFACE name ';'
1635 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1636 OUString name(convertName($4));
1637 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1638 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1639 data));
1640 if (pad->singleBase) {
1641 error(
1642 @3, yyscanner,
1643 "single-inheritance interface cannot have additional bases");
1644 YYERROR;
1646 if (($2 & ~unoidl::detail::FLAG_OPTIONAL) != 0) {
1647 error(
1648 @2, yyscanner,
1649 "interface base can only be flagged as [optional]");
1650 YYERROR;
1652 bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
1653 OUString orgName(name);
1654 unoidl::detail::SourceProviderEntity const * p;
1655 bool typedefed = false;
1656 if (findEntity(@4, yyscanner, data, true, &name, &p, &typedefed, nullptr)
1657 == FOUND_ERROR)
1659 YYERROR;
1661 if (p == nullptr || !p->entity.is()
1662 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
1664 error(
1665 @4, yyscanner,
1666 ("interface type " + data->currentName + " direct base " + name
1667 + " does not resolve to an existing interface type"));
1668 YYERROR;
1670 if (typedefed) {
1671 error(
1672 @4, yyscanner,
1673 ("interface type " + data->currentName + " direct base " + orgName
1674 + " is a typedef"));
1675 YYERROR;
1677 rtl::Reference<unoidl::InterfaceTypeEntity> ent(
1678 static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get()));
1679 if (data->publishedContext && !ent->isPublished()) {
1680 error(
1681 @4, yyscanner,
1682 ("published interface type " + data->currentName + " direct base "
1683 + name + " is unpublished"));
1684 YYERROR;
1686 if (!pad->addDirectBase(
1687 @4, yyscanner, data,
1688 unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
1689 name, ent, annotations($1)),
1690 opt))
1692 YYERROR;
1697 interfaceAttribute:
1698 deprecated_opt flagSection type identifier
1700 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1701 unoidl::detail::SourceProviderType t(*$3);
1702 delete $3;
1703 OUString id(convertName($4));
1704 if (($2 & unoidl::detail::FLAG_ATTRIBUTE) == 0) {
1705 error(
1706 @2, yyscanner,
1707 "interface attribute must be flagged as [attribute]");
1708 YYERROR;
1710 if (($2
1711 & ~(unoidl::detail::FLAG_ATTRIBUTE | unoidl::detail::FLAG_BOUND
1712 | unoidl::detail::FLAG_READONLY))
1713 != 0)
1715 error(
1716 @2, yyscanner,
1717 ("interface attribute can only be flagged as [attribute,"
1718 " bound, readonly]"));
1719 YYERROR;
1721 switch (t.type) {
1722 case unoidl::detail::SourceProviderType::TYPE_VOID:
1723 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1724 error(
1725 @3, yyscanner,
1726 ("illegal interface type " + data->currentName
1727 + " direct attribute " + id + " type"));
1728 YYERROR;
1729 break;
1730 default:
1731 break;
1733 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1734 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1735 data));
1736 if (!pad->addDirectMember(@4, yyscanner, data, id)) {
1737 YYERROR;
1739 pad->directAttributes.emplace_back(
1740 id, t.getName(), ($2 & unoidl::detail::FLAG_BOUND) != 0,
1741 ($2 & unoidl::detail::FLAG_READONLY) != 0,
1742 std::vector<OUString>(), std::vector<OUString>(), annotations($1));
1744 attributeAccessDecls_opt ';'
1747 attributeAccessDecls_opt:
1748 '{' attributeAccessDecls '}'
1749 | /* empty */
1752 attributeAccessDecls:
1753 attributeAccessDecls attributeAccessDecl
1755 if (($1 & $2) != 0) {
1756 error(
1757 @2, yyscanner, "duplicate get/set attribute access declaration");
1758 YYERROR;
1760 $$ = unoidl::detail::SourceProviderAccessDecls($1 | $2);
1762 | /* empty */ { $$ = unoidl::detail::SourceProviderAccessDecls(0); }
1765 attributeAccessDecl:
1766 TOK_GET exceptionSpec ';'
1768 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1769 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1770 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1771 data));
1772 assert(!pad->directAttributes.empty());
1773 pad->directAttributes.back().getExceptions = *$2;
1774 delete $2;
1775 $$ = unoidl::detail::ACCESS_DECL_GET;
1777 | TOK_SET exceptionSpec ';'
1779 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1780 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1781 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1782 data));
1783 assert(!pad->directAttributes.empty());
1784 pad->directAttributes.back().setExceptions = *$2;
1785 delete $2;
1786 if (pad->directAttributes.back().readOnly) {
1787 error(
1788 @1, yyscanner,
1789 ("interface type " + data->currentName
1790 + " direct read-only attribute "
1791 + pad->directAttributes.back().name
1792 + " cannot have set access declaration"));
1793 YYERROR;
1795 $$ = unoidl::detail::ACCESS_DECL_SET;
1799 interfaceMethod:
1800 deprecated_opt type identifier
1802 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1803 unoidl::detail::SourceProviderType t(*$2);
1804 delete $2;
1805 OUString id(convertName($3));
1806 if (t.type == unoidl::detail::SourceProviderType::TYPE_EXCEPTION) {
1807 error(
1808 @3, yyscanner,
1809 ("illegal interface type " + data->currentName
1810 + " direct method " + id + " return type"));
1811 YYERROR;
1813 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
1814 getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1815 data));
1816 if (!pad->addDirectMember(@3, yyscanner, data, id)) {
1817 YYERROR;
1819 pad->directMethods.emplace_back(
1820 id, t.getName(),
1821 std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>(),
1822 std::vector<OUString>(), annotations($1));
1824 '(' methodParams_opt ')' exceptionSpec_opt ';'
1826 if ($8 != nullptr) {
1827 unoidl::detail::SourceProviderScannerData * data
1828 = yyget_extra(yyscanner);
1829 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1830 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1831 data));
1832 assert(!pad->directMethods.empty());
1833 pad->directMethods.back().exceptions = *$8;
1834 delete $8;
1839 methodParams_opt:
1840 methodParams
1841 | /* empty */
1844 methodParams:
1845 methodParams ',' methodParam
1846 | methodParam
1849 methodParam:
1850 '[' direction ']' type identifier
1852 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1853 unoidl::detail::SourceProviderType t(*$4);
1854 delete $4;
1855 OUString id(convertName($5));
1856 rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
1857 pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
1858 data));
1859 assert(!pad->directMethods.empty());
1860 switch (t.type) {
1861 case unoidl::detail::SourceProviderType::TYPE_VOID:
1862 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1863 error(
1864 @4, yyscanner,
1865 ("illegal interface type " + data->currentName
1866 + " direct method " + pad->directMethods.back().name
1867 + " parameter " + id + " type"));
1868 YYERROR;
1869 break;
1870 default:
1871 break;
1873 for (const auto & i: pad->directMethods.back().parameters) {
1874 if (id == i.name) {
1875 error(
1876 @5, yyscanner,
1877 ("interface type " + data->currentName + " direct method "
1878 + pad->directMethods.back().name + " parameter " + id
1879 + " has same identifier as another parameter"));
1880 YYERROR;
1883 pad->directMethods.back().parameters.emplace_back(id, t.getName(), $2);
1887 direction:
1888 TOK_IN { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN; }
1889 | TOK_OUT
1890 { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT; }
1891 | TOK_INOUT
1892 { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT; }
1895 typedefDefn:
1896 deprecated_opt published_opt TOK_TYPEDEF type identifier ';'
1898 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1899 data->publishedContext = $2;
1900 unoidl::detail::SourceProviderType t(*$4);
1901 delete $4;
1902 OUString name(convertToFullName(data, $5));
1903 // There is no good reason to forbid typedefs to VOID, to instantiated
1904 // polymorphic struct types, and to exception types, but some old client
1905 // code of registry data expects this typedef restriction (like the
1906 // assert(false) default in handleTypedef in
1907 // codemaker/source/javamaker/javatype.cxx), so forbid them for now:
1908 switch (t.type) {
1909 case unoidl::detail::SourceProviderType::TYPE_VOID:
1910 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
1911 case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
1912 error(@4, yyscanner, "bad typedef type");
1913 YYERROR;
1914 break;
1915 case unoidl::detail::SourceProviderType::TYPE_ENUM:
1916 case unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT:
1917 case unoidl::detail::SourceProviderType::TYPE_INTERFACE:
1918 if ($2) {
1919 bool unpub = false;
1920 switch (t.entity->kind) {
1921 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
1922 unpub = true;
1923 break;
1924 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
1925 break;
1926 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
1927 O3TL_UNREACHABLE;
1928 default:
1929 assert(t.entity->entity.is() || t.entity->pad.is());
1930 unpub
1931 = !(t.entity->entity.is()
1932 ? static_cast<unoidl::PublishableEntity *>(
1933 t.entity->entity.get())->isPublished()
1934 : t.entity->pad->isPublished());
1935 break;
1937 if (unpub) {
1938 error(
1939 @4, yyscanner,
1940 "published typedef " + name + " type is unpublished");
1941 YYERROR;
1944 break;
1945 case unoidl::detail::SourceProviderType::TYPE_PARAMETER:
1946 O3TL_UNREACHABLE;
1947 default:
1948 break;
1950 if (!data->entities.emplace(
1951 name,
1952 unoidl::detail::SourceProviderEntity(
1953 unoidl::detail::SourceProviderEntity::KIND_LOCAL,
1954 new unoidl::TypedefEntity(
1955 $2, t.getName(), annotations($1)))).
1956 second)
1958 error(@5, yyscanner, "multiple entities named " + name);
1959 YYERROR;
1961 clearCurrentState(data);
1965 constantGroupDefn:
1966 deprecated_opt published_opt TOK_CONSTANTS identifier
1968 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1969 data->publishedContext = $2;
1970 convertToCurrentName(data, $4);
1971 if (!data->entities.emplace(
1972 data->currentName,
1973 unoidl::detail::SourceProviderEntity(
1974 new unoidl::detail::SourceProviderConstantGroupEntityPad(
1975 $2))).
1976 second)
1978 error(@4, yyscanner, "multiple entities named " + data->currentName);
1979 YYERROR;
1982 '{' constants '}' ';'
1984 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
1985 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
1986 unoidl::detail::SourceProviderConstantGroupEntityPad * pad =
1987 dynamic_cast<unoidl::detail::SourceProviderConstantGroupEntityPad *>(
1988 ent->pad.get());
1989 assert(pad != nullptr);
1990 ent->entity = new unoidl::ConstantGroupEntity(
1991 pad->isPublished(), std::move(pad->members), annotations($1));
1992 ent->pad.clear();
1993 clearCurrentState(data);
1997 constants:
1998 constants constant
1999 | /* empty */
2002 constant:
2003 deprecated_opt TOK_CONST type identifier '=' expr ';'
2005 OUString id(convertName($4));
2006 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2007 rtl::Reference<unoidl::detail::SourceProviderConstantGroupEntityPad> pad(
2008 getCurrentPad<unoidl::detail::SourceProviderConstantGroupEntityPad>(
2009 data));
2010 unoidl::detail::SourceProviderType t(*$3);
2011 delete $3;
2012 unoidl::ConstantValue v(false); // dummy value
2013 switch (t.type) {
2014 case unoidl::detail::SourceProviderType::TYPE_BOOLEAN:
2015 if ($6.type != unoidl::detail::SourceProviderExpr::TYPE_BOOL) {
2016 error(
2017 @6, yyscanner,
2018 ("bad value of boolean-typed constant " + data->currentName
2019 + "." + id));
2020 YYERROR;
2022 v = unoidl::ConstantValue($6.bval);
2023 break;
2024 case unoidl::detail::SourceProviderType::TYPE_BYTE:
2025 switch ($6.type) {
2026 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2027 if ($6.ival < SAL_MIN_INT8 || $6.ival > SAL_MAX_INT8) {
2028 error(
2029 @6, yyscanner,
2030 ("out-of-range byte-typed constant " + data->currentName
2031 + "." + id + " value " + OUString::number($6.ival)));
2032 YYERROR;
2034 v = unoidl::ConstantValue(static_cast<sal_Int8>($6.ival));
2035 break;
2036 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2037 if ($6.uval > SAL_MAX_INT8) {
2038 error(
2039 @6, yyscanner,
2040 ("out-of-range byte-typed constant " + data->currentName
2041 + "." + id + " value " + OUString::number($6.uval)));
2042 YYERROR;
2044 v = unoidl::ConstantValue(static_cast<sal_Int8>($6.uval));
2045 break;
2046 default:
2047 error(
2048 @6, yyscanner,
2049 ("bad value of byte-typed constant " + data->currentName + "."
2050 + id));
2051 YYERROR;
2052 break;
2054 break;
2055 case unoidl::detail::SourceProviderType::TYPE_SHORT:
2056 switch ($6.type) {
2057 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2058 if ($6.ival < SAL_MIN_INT16 || $6.ival > SAL_MAX_INT16) {
2059 error(
2060 @6, yyscanner,
2061 ("out-of-range short-typed constant " + data->currentName
2062 + "." + id + " value " + OUString::number($6.ival)));
2063 YYERROR;
2065 v = unoidl::ConstantValue(static_cast<sal_Int16>($6.ival));
2066 break;
2067 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2068 if ($6.uval > SAL_MAX_INT16) {
2069 error(
2070 @6, yyscanner,
2071 ("out-of-range short-typed constant " + data->currentName
2072 + "." + id + " value " + OUString::number($6.uval)));
2073 YYERROR;
2075 v = unoidl::ConstantValue(static_cast<sal_Int16>($6.uval));
2076 break;
2077 default:
2078 error(
2079 @6, yyscanner,
2080 ("bad value of short-typed constant " + data->currentName
2081 + "." + id));
2082 YYERROR;
2083 break;
2085 break;
2086 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
2087 switch ($6.type) {
2088 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2089 if ($6.ival < 0 || $6.ival > SAL_MAX_UINT16) {
2090 error(
2091 @6, yyscanner,
2092 ("out-of-range unsigned-short-typed constant "
2093 + data->currentName + "." + id + " value "
2094 + OUString::number($6.ival)));
2095 YYERROR;
2097 v = unoidl::ConstantValue(static_cast<sal_uInt16>($6.ival));
2098 break;
2099 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2100 if ($6.uval > SAL_MAX_UINT16) {
2101 error(
2102 @6, yyscanner,
2103 ("out-of-range unsigned-short-typed constant "
2104 + data->currentName + "." + id + " value "
2105 + OUString::number($6.uval)));
2106 YYERROR;
2108 v = unoidl::ConstantValue(static_cast<sal_uInt16>($6.uval));
2109 break;
2110 default:
2111 error(
2112 @6, yyscanner,
2113 ("bad value of unsigned-short-typed constant "
2114 + data->currentName + "." + id));
2115 YYERROR;
2116 break;
2118 break;
2119 case unoidl::detail::SourceProviderType::TYPE_LONG:
2120 switch ($6.type) {
2121 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2122 if ($6.ival < SAL_MIN_INT32 || $6.ival > SAL_MAX_INT32) {
2123 error(
2124 @6, yyscanner,
2125 ("out-of-range long-typed constant " + data->currentName
2126 + "." + id + " value " + OUString::number($6.ival)));
2127 YYERROR;
2129 v = unoidl::ConstantValue(static_cast<sal_Int32>($6.ival));
2130 break;
2131 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2132 if ($6.uval > SAL_MAX_INT32) {
2133 error(
2134 @6, yyscanner,
2135 ("out-of-range long-typed constant " + data->currentName
2136 + "." + id + " value " + OUString::number($6.uval)));
2137 YYERROR;
2139 v = unoidl::ConstantValue(static_cast<sal_Int32>($6.uval));
2140 break;
2141 default:
2142 error(
2143 @6, yyscanner,
2144 ("bad value of long-typed constant " + data->currentName
2145 + "." + id));
2146 YYERROR;
2147 break;
2149 break;
2150 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
2151 switch ($6.type) {
2152 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2153 if ($6.ival < 0 || $6.ival > SAL_MAX_UINT32) {
2154 error(
2155 @6, yyscanner,
2156 ("out-of-range unsigned-long-typed constant "
2157 + data->currentName + "." + id + " value "
2158 + OUString::number($6.ival)));
2159 YYERROR;
2161 v = unoidl::ConstantValue(static_cast<sal_uInt32>($6.ival));
2162 break;
2163 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2164 if ($6.uval > SAL_MAX_UINT32) {
2165 error(
2166 @6, yyscanner,
2167 ("out-of-range unsigned-long-typed constant "
2168 + data->currentName + "." + id + " value "
2169 + OUString::number($6.uval)));
2170 YYERROR;
2172 v = unoidl::ConstantValue(static_cast<sal_uInt32>($6.uval));
2173 break;
2174 default:
2175 error(
2176 @6, yyscanner,
2177 ("bad value of unsigned-long-typed constant "
2178 + data->currentName + "." + id));
2179 YYERROR;
2180 break;
2182 break;
2183 case unoidl::detail::SourceProviderType::TYPE_HYPER:
2184 switch ($6.type) {
2185 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2186 v = unoidl::ConstantValue($6.ival);
2187 break;
2188 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2189 if ($6.uval > SAL_MAX_INT64) {
2190 error(
2191 @6, yyscanner,
2192 ("out-of-range hyper-typed constant " + data->currentName
2193 + "." + id + " value " + OUString::number($6.uval)));
2194 YYERROR;
2196 v = unoidl::ConstantValue(static_cast<sal_Int64>($6.uval));
2197 break;
2198 default:
2199 error(
2200 @6, yyscanner,
2201 ("bad value of hyper-typed constant " + data->currentName
2202 + "." + id));
2203 YYERROR;
2204 break;
2206 break;
2207 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
2208 switch ($6.type) {
2209 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2210 if ($6.ival < 0) {
2211 error(
2212 @6, yyscanner,
2213 ("out-of-range unsigned-hyper-typed constant "
2214 + data->currentName + "." + id + " value "
2215 + OUString::number($6.ival)));
2216 YYERROR;
2218 v = unoidl::ConstantValue(static_cast<sal_uInt64>($6.ival));
2219 break;
2220 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2221 v = unoidl::ConstantValue($6.uval);
2222 break;
2223 default:
2224 error(
2225 @6, yyscanner,
2226 ("bad value of unsigned-hyper-typed constant "
2227 + data->currentName + "." + id));
2228 YYERROR;
2229 break;
2231 break;
2232 case unoidl::detail::SourceProviderType::TYPE_FLOAT:
2233 switch ($6.type) {
2234 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
2235 error(
2236 @6, yyscanner,
2237 ("bad boolean value of float-typed constant "
2238 + data->currentName + "." + id));
2239 YYERROR;
2240 break;
2241 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2242 v = unoidl::ConstantValue(static_cast<float>($6.ival));
2243 break;
2244 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2245 v = unoidl::ConstantValue(static_cast<float>($6.uval));
2246 break;
2247 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
2248 v = unoidl::ConstantValue(static_cast<float>($6.fval));
2249 break;
2251 break;
2252 case unoidl::detail::SourceProviderType::TYPE_DOUBLE:
2253 switch ($6.type) {
2254 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
2255 error(
2256 @6, yyscanner,
2257 ("bad boolean value of double-typed constant "
2258 + data->currentName + "." + id));
2259 YYERROR;
2260 break;
2261 case unoidl::detail::SourceProviderExpr::TYPE_INT:
2262 v = unoidl::ConstantValue(static_cast<double>($6.ival));
2263 break;
2264 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
2265 v = unoidl::ConstantValue(static_cast<double>($6.uval));
2266 break;
2267 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
2268 v = unoidl::ConstantValue($6.fval);
2269 break;
2271 break;
2272 default:
2273 error(
2274 @3, yyscanner,
2275 "bad type for constant " + data->currentName + "." + id);
2276 YYERROR;
2277 break;
2279 pad->members.emplace_back(id, v, annotations($1));
2283 singleInterfaceBasedServiceDefn:
2284 deprecated_opt published_opt TOK_SERVICE identifier singleInheritance
2286 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2287 data->publishedContext = $2;
2288 convertToCurrentName(data, $4);
2289 OUString base(convertName($5));
2290 unoidl::detail::SourceProviderEntity const * p;
2291 if (findEntity(@5, yyscanner, data, false, &base, &p, nullptr, nullptr)
2292 == FOUND_ERROR)
2294 YYERROR;
2296 bool ifcBase = false;
2297 bool pubBase = false;
2298 if (p != nullptr) {
2299 switch (p->kind) {
2300 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
2301 ifcBase = true;
2302 pubBase = false;
2303 break;
2304 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
2305 ifcBase = true;
2306 pubBase = true;
2307 break;
2308 default:
2309 if (p->entity.is()
2310 && (p->entity->getSort()
2311 == unoidl::Entity::SORT_INTERFACE_TYPE))
2313 ifcBase = true;
2314 pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
2315 p->entity.get())->isPublished();
2317 break;
2320 if (!ifcBase) {
2321 error(
2322 @5, yyscanner,
2323 ("single-interface--based service " + data->currentName + " base "
2324 + base + " does not resolve to an interface type"));
2325 YYERROR;
2327 if ($2 && !pubBase) {
2328 error(
2329 @5, yyscanner,
2330 ("published single-interface--based service " + data->currentName
2331 + " base " + base + " is unpublished"));
2332 YYERROR;
2334 if (!data->entities.emplace(
2335 data->currentName,
2336 unoidl::detail::SourceProviderEntity(
2337 new unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad(
2338 $2, base))).
2339 second)
2341 error(@4, yyscanner, "multiple entities named " + data->currentName);
2342 YYERROR;
2345 ctors_opt ';'
2347 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2348 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
2349 unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad * pad =
2350 dynamic_cast<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad *>(
2351 ent->pad.get());
2352 assert(pad != nullptr);
2353 std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor> ctors;
2354 if ($7) {
2355 for (const auto & i: pad->constructors) {
2356 std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter> parms;
2357 for (auto & j: i.parameters) {
2358 parms.emplace_back(j.name, j.type.getName(), j.rest);
2360 ctors.push_back(
2361 unoidl::SingleInterfaceBasedServiceEntity::Constructor(
2362 i.name, std::vector(parms), std::vector(i.exceptions), std::vector(i.annotations)));
2364 } else {
2365 assert(pad->constructors.empty());
2366 ctors.push_back(
2367 unoidl::SingleInterfaceBasedServiceEntity::Constructor());
2369 ent->entity = new unoidl::SingleInterfaceBasedServiceEntity(
2370 pad->isPublished(), pad->base, std::move(ctors), annotations($1));
2371 ent->pad.clear();
2372 clearCurrentState(data);
2376 ctors_opt:
2377 '{' ctors '}' { $$ = true; }
2378 | /* empty */ { $$ = false; }
2381 ctors:
2382 ctors ctor
2383 | /* empty */
2386 ctor:
2387 deprecated_opt identifier
2389 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2390 OUString id(convertName($2));
2391 rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
2392 pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
2393 data));
2394 for (const auto & i: pad->constructors) {
2395 if (id == i.name) {
2396 error(
2397 @2, yyscanner,
2398 ("single-interface--based service " + data->currentName
2399 + " constructor " + id
2400 + " has same identifier as another constructor"));
2401 YYERROR;
2404 pad->constructors.push_back(
2405 unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor(
2406 id, annotations($1)));
2408 '(' ctorParams_opt ')' exceptionSpec_opt ';'
2410 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2411 rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
2412 pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
2413 data));
2414 assert(!pad->constructors.empty());
2415 if ($7 != nullptr) {
2416 pad->constructors.back().exceptions = *$7;
2417 delete $7;
2419 for (auto i(pad->constructors.begin()); i != pad->constructors.end() - 1;
2420 ++i)
2422 if (i->parameters.size()
2423 == pad->constructors.back().parameters.size())
2425 bool same = true;
2426 for (auto
2427 j(i->parameters.begin()),
2428 k(pad->constructors.back().parameters.begin());
2429 j != i->parameters.end(); ++j, ++k)
2431 if (!j->type.equals(k->type) || j->rest != k->rest) {
2432 same = false;
2433 break;
2436 if (same) {
2437 error(
2438 @2, yyscanner,
2439 ("single-interface--based service " + data->currentName
2440 + " constructor " + pad->constructors.back().name
2441 + " has similar paramete list to constructor "
2442 + i->name));
2443 YYERROR;
2450 ctorParams_opt:
2451 ctorParams
2452 | /* empty */
2455 ctorParams:
2456 ctorParams ',' ctorParam
2457 | ctorParam
2460 ctorParam:
2461 '[' direction ']' type ellipsis_opt identifier
2463 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2464 unoidl::detail::SourceProviderType t(*$4);
2465 delete $4;
2466 OUString id(convertName($6));
2467 rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
2468 pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
2469 data));
2470 assert(!pad->constructors.empty());
2471 if ($2 != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN) {
2472 error(
2473 @4, yyscanner,
2474 ("single-interface--based service " + data->currentName
2475 + " constructor " + pad->constructors.back().name + " parameter "
2476 + id + " direction must be [in]"));
2477 YYERROR;
2479 switch (t.type) {
2480 case unoidl::detail::SourceProviderType::TYPE_VOID:
2481 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
2482 error(
2483 @4, yyscanner,
2484 ("illegal single-interface--based service " + data->currentName
2485 + " constructor " + pad->constructors.back().name + " parameter "
2486 + id + " type"));
2487 YYERROR;
2488 break;
2489 default:
2490 break;
2492 if ($5) {
2493 if (t.type != unoidl::detail::SourceProviderType::TYPE_ANY) {
2494 error(
2495 @4, yyscanner,
2496 ("illegal single-interface--based service "
2497 + data->currentName + " constructor "
2498 + pad->constructors.back().name + " rest parameter " + id
2499 + " non-any type"));
2500 YYERROR;
2502 if (!pad->constructors.back().parameters.empty()) {
2503 error(
2504 @5, yyscanner,
2505 ("single-interface--based service " + data->currentName
2506 + " constructor " + pad->constructors.back().name
2507 + " rest parameter " + id + " must be first parameter"));
2508 YYERROR;
2510 } else if (!pad->constructors.back().parameters.empty()
2511 && pad->constructors.back().parameters.back().rest)
2513 error(
2514 @1, yyscanner,
2515 ("single-interface--based service " + data->currentName
2516 + " constructor " + pad->constructors.back().name
2517 + " rest parameter must be last parameter"));
2518 YYERROR;
2520 for (const auto & i: pad->constructors.back().parameters) {
2521 if (id == i.name) {
2522 error(
2523 @6, yyscanner,
2524 ("single-interface--based service " + data->currentName
2525 + " constructor " + pad->constructors.back().name
2526 + " parameter " + id
2527 + " has same identifier as another parameter"));
2528 YYERROR;
2531 pad->constructors.back().parameters.push_back(
2532 unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter(
2533 id, t, $5));
2537 ellipsis_opt:
2538 TOK_ELLIPSIS { $$ = true; }
2539 | /* empty */ { $$ = false; }
2541 accumulationBasedServiceDefn:
2542 deprecated_opt published_opt TOK_SERVICE identifier
2544 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2545 data->publishedContext = $2;
2546 convertToCurrentName(data, $4);
2547 if (!data->entities.emplace(
2548 data->currentName,
2549 unoidl::detail::SourceProviderEntity(
2550 new unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad(
2551 $2))).
2552 second)
2554 error(@4, yyscanner, "multiple entities named " + data->currentName);
2555 YYERROR;
2558 '{' serviceMembers '}' ';'
2560 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2561 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
2562 unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad * pad =
2563 dynamic_cast<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad *>(
2564 ent->pad.get());
2565 assert(pad != nullptr);
2566 ent->entity = new unoidl::AccumulationBasedServiceEntity(
2567 pad->isPublished(), std::move(pad->directMandatoryBaseServices),
2568 std::move(pad->directOptionalBaseServices), std::move(pad->directMandatoryBaseInterfaces),
2569 std::move(pad->directOptionalBaseInterfaces), std::move(pad->directProperties),
2570 annotations($1));
2571 ent->pad.clear();
2572 clearCurrentState(data);
2576 serviceMembers:
2577 serviceMembers serviceMember
2578 | /* empty */
2581 serviceMember:
2582 serviceBase
2583 | serviceInterfaceBase
2584 | serviceProperty
2587 serviceBase:
2588 deprecated_opt flagSection_opt TOK_SERVICE name ';'
2590 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2591 OUString name(convertName($4));
2592 rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad> pad(
2593 getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
2594 data));
2595 if (($2 & ~unoidl::detail::FLAG_OPTIONAL) != 0) {
2596 error(
2597 @2, yyscanner,
2598 "service base can only be flagged as [optional]");
2599 YYERROR;
2601 bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
2602 unoidl::detail::SourceProviderEntity const * p;
2603 if (findEntity(@4, yyscanner, data, false, &name, &p, nullptr, nullptr)
2604 == FOUND_ERROR)
2606 YYERROR;
2608 if (p == nullptr || !p->entity.is()
2609 || (p->entity->getSort()
2610 != unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE))
2612 error(
2613 @4, yyscanner,
2614 ("accumulation-based service " + data->currentName
2615 + " direct base service " + name
2616 + " does not resolve to an accumulation-based service"));
2617 YYERROR;
2619 if (data->publishedContext
2620 && !static_cast<unoidl::AccumulationBasedServiceEntity *>(
2621 p->entity.get())->isPublished())
2623 error(
2624 @4, yyscanner,
2625 ("published accumulation-based service " + data->currentName
2626 + " direct base service " + name + " is unpublished"));
2627 YYERROR;
2629 std::vector<unoidl::AnnotatedReference> & v(
2631 ? pad->directOptionalBaseServices : pad->directMandatoryBaseServices);
2632 for (const auto & i: v) {
2633 if (name == i.name) {
2634 error(
2635 @4, yyscanner,
2636 ("accumulation-based service " + data->currentName
2637 + " duplicate direct base service " + name));
2638 YYERROR;
2641 v.emplace_back(name, annotations($1));
2645 serviceInterfaceBase:
2646 deprecated_opt flagSection_opt TOK_INTERFACE name ';'
2648 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2649 OUString name(convertName($4));
2650 rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad> pad(
2651 getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
2652 data));
2653 if (($2 & ~unoidl::detail::FLAG_OPTIONAL) != 0) {
2654 error(
2655 @2, yyscanner,
2656 "interface base can only be flagged as [optional]");
2657 YYERROR;
2659 bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
2660 unoidl::detail::SourceProviderEntity const * p;
2661 if (findEntity(@4, yyscanner, data, false, &name, &p, nullptr, nullptr)
2662 == FOUND_ERROR)
2664 YYERROR;
2666 bool ifcBase = false;
2667 bool pubBase = false;
2668 if (p != nullptr) {
2669 switch (p->kind) {
2670 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
2671 ifcBase = true;
2672 pubBase = false;
2673 break;
2674 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
2675 ifcBase = true;
2676 pubBase = true;
2677 break;
2678 default:
2679 if (p->entity.is()
2680 && (p->entity->getSort()
2681 == unoidl::Entity::SORT_INTERFACE_TYPE))
2683 ifcBase = true;
2684 pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
2685 p->entity.get())->isPublished();
2687 break;
2690 if (!ifcBase) {
2691 error(
2692 @4, yyscanner,
2693 ("accumulation-based service " + data->currentName
2694 + " direct base interface " + name
2695 + " does not resolve to an interface type"));
2696 YYERROR;
2698 if (data->publishedContext && !opt && !pubBase) {
2699 error(
2700 @4, yyscanner,
2701 ("published accumulation-based service " + data->currentName
2702 + " direct base interface " + name + " is unpublished"));
2703 YYERROR;
2705 std::vector<unoidl::AnnotatedReference> & v(
2707 ? pad->directOptionalBaseInterfaces
2708 : pad->directMandatoryBaseInterfaces);
2709 for (const auto & i: v) {
2710 if (name == i.name) {
2711 error(
2712 @4, yyscanner,
2713 ("accumulation-based service " + data->currentName
2714 + " duplicate direct base interface " + name));
2715 YYERROR;
2718 v.emplace_back(name, annotations($1));
2722 serviceProperty:
2723 deprecated_opt flagSection type identifier ';'
2725 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2726 unoidl::detail::SourceProviderType t(*$3);
2727 delete $3;
2728 OUString id(convertName($4));
2729 if (($2 & unoidl::detail::FLAG_PROPERTY) == 0) {
2730 error(
2731 @2, yyscanner,
2732 ("accumulation-based service property must be flagged as"
2733 " [property]"));
2734 YYERROR;
2736 if (($2
2737 & ~(unoidl::detail::FLAG_BOUND | unoidl::detail::FLAG_CONSTRAINED
2738 | unoidl::detail::FLAG_MAYBEAMBIGUOUS
2739 | unoidl::detail::FLAG_MAYBEDEFAULT
2740 | unoidl::detail::FLAG_MAYBEVOID | unoidl::detail::FLAG_OPTIONAL
2741 | unoidl::detail::FLAG_PROPERTY | unoidl::detail::FLAG_READONLY
2742 | unoidl::detail::FLAG_REMOVABLE
2743 | unoidl::detail::FLAG_TRANSIENT))
2744 != 0)
2746 error(
2747 @2, yyscanner,
2748 ("accumulation-based service property can only be flagged as"
2749 " [property, bound, constrained, maybeambiguous, maybedefault,"
2750 " maybevoid, optional, readonly, removable, transient]"));
2751 YYERROR;
2753 int att = 0;
2754 if (($2 & unoidl::detail::FLAG_BOUND) != 0) {
2755 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND;
2757 if (($2 & unoidl::detail::FLAG_CONSTRAINED) != 0) {
2758 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED;
2760 if (($2 & unoidl::detail::FLAG_MAYBEAMBIGUOUS) != 0) {
2761 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS;
2763 if (($2 & unoidl::detail::FLAG_MAYBEDEFAULT) != 0) {
2764 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT;
2766 if (($2 & unoidl::detail::FLAG_MAYBEVOID) != 0) {
2767 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID;
2769 if (($2 & unoidl::detail::FLAG_OPTIONAL) != 0) {
2770 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL;
2772 if (($2 & unoidl::detail::FLAG_READONLY) != 0) {
2773 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY;
2775 if (($2 & unoidl::detail::FLAG_REMOVABLE) != 0) {
2776 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE;
2778 if (($2 & unoidl::detail::FLAG_TRANSIENT) != 0) {
2779 att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT;
2781 switch (t.type) {
2782 case unoidl::detail::SourceProviderType::TYPE_VOID:
2783 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
2784 error(
2785 @3, yyscanner,
2786 ("illegal accumulation-based service " + data->currentName
2787 + " direct property " + id + " type"));
2788 YYERROR;
2789 break;
2790 default:
2791 break;
2793 rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>
2794 pad(getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
2795 data));
2796 for (const auto & i: pad->directProperties) {
2797 if (id == i.name) {
2798 error(
2799 @4, yyscanner,
2800 ("accumulation-based service " + data->currentName
2801 + " duplicate direct property " + id));
2802 YYERROR;
2805 pad->directProperties.emplace_back(
2806 id, t.getName(),
2807 unoidl::AccumulationBasedServiceEntity::Property::Attributes(att),
2808 annotations($1));
2812 interfaceBasedSingletonDefn:
2813 deprecated_opt published_opt TOK_SINGLETON identifier singleInheritance ';'
2815 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2816 data->publishedContext = $2;
2817 OUString name(convertToFullName(data, $4));
2818 OUString base(convertName($5));
2819 unoidl::detail::SourceProviderEntity const * p;
2820 if (findEntity(@5, yyscanner, data, false, &base, &p, nullptr, nullptr)
2821 == FOUND_ERROR)
2823 YYERROR;
2825 bool ifcBase = false;
2826 bool pubBase = false;
2827 if (p != nullptr) {
2828 switch (p->kind) {
2829 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
2830 ifcBase = true;
2831 pubBase = false;
2832 break;
2833 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
2834 ifcBase = true;
2835 pubBase = true;
2836 break;
2837 default:
2838 if (p->entity.is()
2839 && (p->entity->getSort()
2840 == unoidl::Entity::SORT_INTERFACE_TYPE))
2842 ifcBase = true;
2843 pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
2844 p->entity.get())->isPublished();
2846 break;
2849 if (!ifcBase) {
2850 error(
2851 @5, yyscanner,
2852 ("interface-based singleton " + name + " base " + base
2853 + " does not resolve to an interface type"));
2854 YYERROR;
2856 if ($2 && !pubBase) {
2857 error(
2858 @5, yyscanner,
2859 ("published interface-based singleton " + name + " base " + base
2860 + " is unpublished"));
2861 YYERROR;
2863 if (!data->entities.emplace(
2864 name,
2865 unoidl::detail::SourceProviderEntity(
2866 unoidl::detail::SourceProviderEntity::KIND_LOCAL,
2867 new unoidl::InterfaceBasedSingletonEntity(
2868 $2, base, annotations($1)))).
2869 second)
2871 error(@4, yyscanner, "multiple entities named " + name);
2872 YYERROR;
2874 clearCurrentState(data);
2878 serviceBasedSingletonDefn:
2879 deprecated_opt published_opt TOK_SINGLETON identifier '{' TOK_SERVICE name ';'
2880 '}' ';'
2882 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2883 data->publishedContext = $2;
2884 OUString name(convertToFullName(data, $4));
2885 OUString base(convertName($7));
2886 unoidl::detail::SourceProviderEntity const * p;
2887 if (findEntity(@7, yyscanner, data, false, &base, &p, nullptr, nullptr)
2888 == FOUND_ERROR)
2890 YYERROR;
2892 if (p == nullptr
2893 || !p->entity.is()
2894 || (p->entity->getSort()
2895 != unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE))
2897 error(
2898 @7, yyscanner,
2899 ("service-based singleton " + name + " base " + base
2900 + " does not resolve to an accumulation-based service"));
2901 YYERROR;
2903 if ($2
2904 && !static_cast<unoidl::AccumulationBasedServiceEntity *>(
2905 p->entity.get())->isPublished())
2907 error(
2908 @7, yyscanner,
2909 ("published service-based singleton " + name + " base " + base
2910 + " is unpublished"));
2911 YYERROR;
2913 if (!data->entities.emplace(
2914 name,
2915 unoidl::detail::SourceProviderEntity(
2916 unoidl::detail::SourceProviderEntity::KIND_LOCAL,
2917 new unoidl::ServiceBasedSingletonEntity(
2918 $2, base, annotations($1)))).
2919 second)
2921 error(@4, yyscanner, "multiple entities named " + name);
2922 YYERROR;
2924 clearCurrentState(data);
2928 singleInheritance_opt:
2929 singleInheritance
2930 | /* empty */ { $$ = nullptr; }
2933 singleInheritance: ':' name { $$ = $2; }
2936 exceptionSpec_opt:
2937 exceptionSpec
2938 | /* empty */ { $$ = nullptr; }
2941 exceptionSpec: TOK_RAISES '(' exceptions ')' { $$ = $3; }
2944 exceptions:
2945 exceptions ',' name
2947 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2948 OUString name(convertName($3));
2949 unoidl::detail::SourceProviderEntity const * p;
2950 if (findEntity(@3, yyscanner, data, false, &name, &p, nullptr, nullptr)
2951 == FOUND_ERROR)
2953 delete $1; /* see commented-out %destructor above */
2954 YYERROR;
2956 if (p == nullptr
2957 || !p->entity.is()
2958 || (p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE))
2960 delete $1; /* see commented-out %destructor above */
2961 error(
2962 @3, yyscanner,
2963 ("exception " + name + " does not resolve to an exception type"));
2964 YYERROR;
2966 if (data->publishedContext
2967 && !(static_cast<unoidl::ExceptionTypeEntity *>(p->entity.get())
2968 ->isPublished()))
2970 delete $1; /* see commented-out %destructor above */
2971 error(
2972 @3, yyscanner,
2973 ("unpublished exception " + name + " used in published context"));
2974 YYERROR;
2976 if (std::find($1->begin(), $1->end(), name) != $1->end()) {
2977 delete $1; /* see commented-out %destructor above */
2978 error(
2979 @3, yyscanner, ("exception " + name + " listed more than once"));
2980 YYERROR;
2982 $1->push_back(name);
2983 $$ = $1;
2985 | name
2987 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
2988 OUString name(convertName($1));
2989 unoidl::detail::SourceProviderEntity const * p;
2990 if (findEntity(@1, yyscanner, data, false, &name, &p, nullptr, nullptr)
2991 == FOUND_ERROR)
2993 YYERROR;
2995 if (p == nullptr
2996 || !p->entity.is()
2997 || (p->entity->getSort() != unoidl::Entity::SORT_EXCEPTION_TYPE))
2999 error(
3000 @1, yyscanner,
3001 ("exception " + name + " does not resolve to an exception type"));
3002 YYERROR;
3004 if (data->publishedContext
3005 && !(static_cast<unoidl::ExceptionTypeEntity *>(p->entity.get())
3006 ->isPublished()))
3008 error(
3009 @1, yyscanner,
3010 ("unpublished exception " + name + " used in published context"));
3011 YYERROR;
3013 $$ = new std::vector<OUString>; $$->push_back(name);
3017 interfaceDecl:
3018 deprecated_opt/*ignored*/ published_opt TOK_INTERFACE identifier ';'
3020 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3021 data->publishedContext = $2;
3022 OUString name(convertToFullName(data, $4));
3023 std::pair<std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator, bool> p(
3024 data->entities.emplace(
3025 name,
3026 unoidl::detail::SourceProviderEntity(
3028 ? unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL
3029 : unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL)));
3030 if (!p.second) {
3031 switch (p.first->second.kind) {
3032 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
3033 if ($2) {
3034 p.first->second.kind
3035 = unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL;
3037 break;
3038 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
3039 break;
3040 default:
3041 assert(p.first->second.entity.is());
3042 if (p.first->second.entity->getSort()
3043 != unoidl::Entity::SORT_INTERFACE_TYPE)
3045 error(
3046 @4, yyscanner,
3047 "multiple entities named " + data->currentName);
3048 YYERROR;
3050 if ($2
3051 && !static_cast<unoidl::InterfaceTypeEntity *>(
3052 p.first->second.entity.get())->isPublished())
3054 error(
3055 @4, yyscanner,
3056 ("published interface type declaration "
3057 + data->currentName + " has been defined unpublished"));
3058 YYERROR;
3062 clearCurrentState(data);
3066 published_opt:
3067 TOK_PUBLISHED { $$ = true; }
3068 | /* empty */ { $$ = false; }
3071 flagSection_opt:
3072 flagSection
3073 | /* empty */ { $$ = unoidl::detail::SourceProviderFlags(0); }
3076 flagSection: '[' flags ']' { $$ = $2; }
3079 flags:
3080 flags ',' flag
3082 if (($1 & $3) != 0) {
3083 error(@3, yyscanner, "duplicate flag " + flagName($3));
3084 YYERROR;
3086 $$ = unoidl::detail::SourceProviderFlags($1 | $3);
3088 | flag
3091 flag:
3092 TOK_ATTRIBUTE { $$ = unoidl::detail::FLAG_ATTRIBUTE; }
3093 | TOK_BOUND { $$ = unoidl::detail::FLAG_BOUND; }
3094 | TOK_CONSTRAINED { $$ = unoidl::detail::FLAG_CONSTRAINED; }
3095 | TOK_MAYBEAMBIGUOUS { $$ = unoidl::detail::FLAG_MAYBEAMBIGUOUS; }
3096 | TOK_MAYBEDEFAULT { $$ = unoidl::detail::FLAG_MAYBEDEFAULT; }
3097 | TOK_MAYBEVOID { $$ = unoidl::detail::FLAG_MAYBEVOID; }
3098 | TOK_OPTIONAL { $$ = unoidl::detail::FLAG_OPTIONAL; }
3099 | TOK_PROPERTY { $$ = unoidl::detail::FLAG_PROPERTY; }
3100 | TOK_READONLY { $$ = unoidl::detail::FLAG_READONLY; }
3101 | TOK_REMOVABLE { $$ = unoidl::detail::FLAG_REMOVABLE; }
3102 | TOK_TRANSIENT { $$ = unoidl::detail::FLAG_TRANSIENT; }
3105 expr: orExpr
3108 orExpr:
3109 orExpr '|' xorExpr
3111 if (!coerce(@1, yyscanner, &$1, &$3)) {
3112 YYERROR;
3114 switch ($1.type) {
3115 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3116 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival | $3.ival);
3117 break;
3118 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3119 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval | $3.uval);
3120 break;
3121 default:
3122 error(@1, yyscanner, "arguments of non-integer type to \"|\"");
3123 YYERROR;
3124 break;
3127 | xorExpr
3130 xorExpr:
3131 xorExpr '^' andExpr
3133 if (!coerce(@1, yyscanner, &$1, &$3)) {
3134 YYERROR;
3136 switch ($1.type) {
3137 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3138 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival ^ $3.ival);
3139 break;
3140 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3141 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval ^ $3.uval);
3142 break;
3143 default:
3144 error(@1, yyscanner, "arguments of non-integer type to \"^\"");
3145 YYERROR;
3146 break;
3149 | andExpr
3152 andExpr:
3153 andExpr '&' shiftExpr
3155 if (!coerce(@1, yyscanner, &$1, &$3)) {
3156 YYERROR;
3158 switch ($1.type) {
3159 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3160 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival & $3.ival);
3161 break;
3162 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3163 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval & $3.uval);
3164 break;
3165 default:
3166 error(@1, yyscanner, "arguments of non-integer type to \"&\"");
3167 YYERROR;
3168 break;
3171 | shiftExpr
3174 shiftExpr:
3175 shiftExpr TOK_LEFTSHIFT addExpr
3177 int n;
3178 switch ($3.type) {
3179 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3180 if ($3.ival < 0 || $3.ival > 63) {
3181 error(
3182 @3, yyscanner,
3183 ("out-of-range shift argument " + OUString::number($3.ival)
3184 + " to \"<<\" "));
3185 YYERROR;
3187 n = static_cast<int>($3.ival);
3188 break;
3189 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3190 if ($3.uval > 63) {
3191 error(
3192 @3, yyscanner,
3193 ("out-of-range shift argument " + OUString::number($3.uval)
3194 + " to \"<<\" "));
3195 YYERROR;
3197 n = static_cast<int>($3.uval);
3198 break;
3199 default:
3200 error(@3, yyscanner, "right argument of non-integer type to \"<<\"");
3201 YYERROR;
3203 switch ($1.type) {
3204 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3205 if ($1.ival < 0) {
3206 error(
3207 @1, yyscanner,
3208 ("cannot left-shift negative argument "
3209 + OUString::number($1.ival)));
3210 YYERROR;
3212 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival << n);
3213 break;
3214 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3215 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval << n);
3216 break;
3217 default:
3218 error(@1, yyscanner, "left argument of non-integer type to \"<<\"");
3219 YYERROR;
3220 break;
3223 | shiftExpr TOK_RIGHTSHIFT addExpr
3225 int n;
3226 switch ($3.type) {
3227 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3228 if ($3.ival < 0 || $3.ival > 63) {
3229 error(
3230 @3, yyscanner,
3231 ("out-of-range shift argument " + OUString::number($3.ival)
3232 + " to \">>\" "));
3233 YYERROR;
3235 n = static_cast<int>($3.ival);
3236 break;
3237 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3238 if ($3.uval > 63) {
3239 error(
3240 @3, yyscanner,
3241 ("out-of-range shift argument " + OUString::number($3.uval)
3242 + " to \">>\" "));
3243 YYERROR;
3245 n = static_cast<int>($3.uval);
3246 break;
3247 default:
3248 error(@3, yyscanner, "right argument of non-integer type to \">>\"");
3249 YYERROR;
3250 break;
3252 switch ($1.type) {
3253 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3254 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival >> n);
3255 break;
3256 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3257 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval >> n);
3258 break;
3259 default:
3260 error(@1, yyscanner, "left argument of non-integer type to \">>\"");
3261 YYERROR;
3262 break;
3265 | addExpr
3268 addExpr:
3269 addExpr '+' multExpr
3271 if (!coerce(@1, yyscanner, &$1, &$3)) {
3272 YYERROR;
3274 switch ($1.type) {
3275 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3276 error(@1, yyscanner, "arguments of boolean type to binary \"+\"");
3277 YYERROR;
3278 break;
3279 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3280 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival + $3.ival); //TODO: overflow
3281 break;
3282 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3283 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval + $3.uval); //TODO: overflow
3284 break;
3285 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3286 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval + $3.fval);
3287 break;
3290 | addExpr '-' multExpr
3292 if (!coerce(@1, yyscanner, &$1, &$3)) {
3293 YYERROR;
3295 switch ($1.type) {
3296 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3297 error(@1, yyscanner, "arguments of boolean type to binary \"-\"");
3298 YYERROR;
3299 break;
3300 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3301 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival - $3.ival); //TODO: overflow
3302 break;
3303 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3304 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval - $3.uval); //TODO: overflow
3305 break;
3306 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3307 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval - $3.fval);
3308 break;
3311 | multExpr
3314 multExpr:
3315 multExpr '*' unaryExpr
3317 if (!coerce(@1, yyscanner, &$1, &$3)) {
3318 YYERROR;
3320 switch ($1.type) {
3321 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3322 error(@1, yyscanner, "arguments of boolean type to \"*\"");
3323 YYERROR;
3324 break;
3325 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3326 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival * $3.ival); //TODO: overflow
3327 break;
3328 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3329 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval * $3.uval); //TODO: overflow
3330 break;
3331 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3332 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval * $3.fval);
3333 break;
3336 | multExpr '/' unaryExpr
3338 if (!coerce(@1, yyscanner, &$1, &$3)) {
3339 YYERROR;
3341 switch ($1.type) {
3342 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3343 error(@1, yyscanner, "arguments of boolean type to \"/\"");
3344 YYERROR;
3345 break;
3346 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3347 if ($3.ival == 0) {
3348 error(@3, yyscanner, "cannot divide by zero");
3349 YYERROR;
3351 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival / $3.ival);
3352 break;
3353 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3354 if ($3.uval == 0) {
3355 error(@3, yyscanner, "cannot divide by zero");
3356 YYERROR;
3358 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval / $3.uval);
3359 break;
3360 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3361 if ($3.fval == 0) {
3362 error(@3, yyscanner, "cannot divide by zero");
3363 YYERROR;
3365 $$ = unoidl::detail::SourceProviderExpr::Float($1.fval - $3.fval);
3366 break;
3369 | multExpr '%' unaryExpr
3371 if (!coerce(@1, yyscanner, &$1, &$3)) {
3372 YYERROR;
3374 switch ($1.type) {
3375 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3376 if ($3.ival == 0) {
3377 error(@3, yyscanner, "cannot divide by zero");
3378 YYERROR;
3380 $$ = unoidl::detail::SourceProviderExpr::Int($1.ival % $3.ival);
3381 break;
3382 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3383 if ($3.uval == 0) {
3384 error(@3, yyscanner, "cannot divide by zero");
3385 YYERROR;
3387 $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval % $3.uval);
3388 break;
3389 default:
3390 error(@1, yyscanner, "arguments of non-integer type to \"%\"");
3391 YYERROR;
3392 break;
3395 | unaryExpr
3398 unaryExpr:
3399 '+' primaryExpr
3401 if ($2.type == unoidl::detail::SourceProviderExpr::TYPE_BOOL) {
3402 error(@2, yyscanner, "argument of boolean type to unary \"+\"");
3403 YYERROR;
3405 $$ = $2;
3407 | '-' primaryExpr
3409 switch ($2.type) {
3410 case unoidl::detail::SourceProviderExpr::TYPE_BOOL:
3411 error(@2, yyscanner, "argument of boolean type to unary \"-\"");
3412 YYERROR;
3413 break;
3414 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3415 if ($2.ival == SAL_MIN_INT64) {
3416 error(@2, yyscanner, "cannot negate -2^63");
3417 YYERROR;
3419 $$ = unoidl::detail::SourceProviderExpr::Int(-$2.ival);
3420 break;
3421 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3422 if ($2.uval == SAL_CONST_UINT64(0x8000000000000000)) {
3423 $$ = unoidl::detail::SourceProviderExpr::Int(SAL_MIN_INT64);
3424 } else {
3425 if ($2.uval > SAL_MAX_INT64) {
3426 error(
3427 @2, yyscanner,
3428 ("cannot negate out-of-range value "
3429 + OUString::number($2.uval)));
3430 YYERROR;
3432 $$ = unoidl::detail::SourceProviderExpr::Int(
3433 -static_cast<sal_Int64>($2.uval));
3435 break;
3436 case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
3437 $$ = unoidl::detail::SourceProviderExpr::Float(-$2.fval);
3438 break;
3441 | '~' primaryExpr
3443 switch ($2.type) {
3444 case unoidl::detail::SourceProviderExpr::TYPE_INT:
3445 $$ = unoidl::detail::SourceProviderExpr::Int(~$2.ival);
3446 break;
3447 case unoidl::detail::SourceProviderExpr::TYPE_UINT:
3448 $$ = unoidl::detail::SourceProviderExpr::Uint(~$2.uval);
3449 break;
3450 default:
3451 error(@2, yyscanner, "argument of non-integer type to \"~\"");
3452 YYERROR;
3453 break;
3456 | primaryExpr
3459 primaryExpr:
3460 '(' expr ')' { $$ = $2; }
3461 | TOK_FALSE { $$ = unoidl::detail::SourceProviderExpr::Bool(false); }
3462 | TOK_TRUE { $$ = unoidl::detail::SourceProviderExpr::Bool(true); }
3463 | TOK_INTEGER { $$ = unoidl::detail::SourceProviderExpr::Uint($1); }
3464 | TOK_FLOATING { $$ = unoidl::detail::SourceProviderExpr::Float($1); }
3465 | name
3467 OUString name(convertName($1));
3468 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3469 unoidl::ConstantValue v(false); // dummy value
3470 bool found = false;
3471 bool unpub = false;
3472 sal_Int32 i = name.lastIndexOf('.');
3473 if (i == -1) {
3474 rtl::Reference<unoidl::detail::SourceProviderEntityPad> pad(
3475 getCurrentEntity(data)->pad);
3476 unoidl::detail::SourceProviderEnumTypeEntityPad * p1 = dynamic_cast<
3477 unoidl::detail::SourceProviderEnumTypeEntityPad *>(pad.get());
3478 if (p1 != nullptr) {
3479 for (const auto & j: p1->members) {
3480 if (j.name == name) {
3481 v = unoidl::ConstantValue(j.value);
3482 found = true;
3483 break;
3486 } else {
3487 unoidl::detail::SourceProviderConstantGroupEntityPad * p2
3488 = dynamic_cast<
3489 unoidl::detail::SourceProviderConstantGroupEntityPad *>(
3490 pad.get());
3491 if (p2 != nullptr) {
3492 for (const auto & j: p2->members) {
3493 if (j.name == name) {
3494 v = j.value;
3495 found = true;
3496 break;
3501 } else {
3502 OUString scope(name.copy(0, i));
3503 unoidl::detail::SourceProviderEntity const * ent;
3504 if (findEntity(
3505 @1, yyscanner, data, false, &scope, &ent, nullptr, nullptr)
3506 == FOUND_ERROR)
3508 YYERROR;
3510 if (ent != nullptr) {
3511 OUString id(name.copy(i + 1));
3512 // No need to check for enum members here, as they cannot be
3513 // referenced in expressions by qualified name (TODO: is that true?):
3514 if (ent->entity.is()) {
3515 if (ent->entity->getSort()
3516 == unoidl::Entity::SORT_CONSTANT_GROUP)
3518 std::vector<unoidl::ConstantGroupEntity::Member> const &
3519 mems(
3520 static_cast<unoidl::ConstantGroupEntity *>(
3521 ent->entity.get())->
3522 getMembers());
3523 for (auto & j: mems) {
3524 if (j.name == id) {
3525 v = j.value;
3526 found = true;
3527 unpub
3528 = !static_cast<unoidl::ConstantGroupEntity *>(
3529 ent->entity.get())->isPublished();
3530 break;
3534 } else if (ent->pad.is()) {
3535 unoidl::detail::SourceProviderConstantGroupEntityPad * pad
3536 = dynamic_cast<
3537 unoidl::detail::SourceProviderConstantGroupEntityPad *>(
3538 ent->pad.get());
3539 if (pad != nullptr) {
3540 for (const auto & j: pad->members) {
3541 if (j.name == id) {
3542 v = j.value;
3543 found = true;
3544 unpub = !ent->pad->isPublished();
3545 break;
3552 if (!found) {
3553 error(
3554 @1, yyscanner,
3555 (name
3556 + (" does not resolve to neither a constant nor an unqualified"
3557 " enum member")));
3558 YYERROR;
3560 if (data->publishedContext && unpub) {
3561 error(
3562 @1, yyscanner,
3563 "unpublished value " + name + " used in published context");
3564 YYERROR;
3566 switch (v.type) {
3567 case unoidl::ConstantValue::TYPE_BOOLEAN:
3568 $$ = unoidl::detail::SourceProviderExpr::Bool(v.booleanValue);
3569 break;
3570 case unoidl::ConstantValue::TYPE_BYTE:
3571 $$ = unoidl::detail::SourceProviderExpr::Int(v.byteValue);
3572 break;
3573 case unoidl::ConstantValue::TYPE_SHORT:
3574 $$ = unoidl::detail::SourceProviderExpr::Int(v.shortValue);
3575 break;
3576 case unoidl::ConstantValue::TYPE_UNSIGNED_SHORT:
3577 $$ = unoidl::detail::SourceProviderExpr::Uint(v.unsignedShortValue);
3578 break;
3579 case unoidl::ConstantValue::TYPE_LONG:
3580 $$ = unoidl::detail::SourceProviderExpr::Int(v.longValue);
3581 break;
3582 case unoidl::ConstantValue::TYPE_UNSIGNED_LONG:
3583 $$ = unoidl::detail::SourceProviderExpr::Uint(v.unsignedLongValue);
3584 break;
3585 case unoidl::ConstantValue::TYPE_HYPER:
3586 $$ = unoidl::detail::SourceProviderExpr::Int(v.hyperValue);
3587 break;
3588 case unoidl::ConstantValue::TYPE_UNSIGNED_HYPER:
3589 $$ = unoidl::detail::SourceProviderExpr::Uint(v.unsignedHyperValue);
3590 break;
3591 case unoidl::ConstantValue::TYPE_FLOAT:
3592 $$ = unoidl::detail::SourceProviderExpr::Float(v.floatValue);
3593 break;
3594 case unoidl::ConstantValue::TYPE_DOUBLE:
3595 $$ = unoidl::detail::SourceProviderExpr::Float(v.doubleValue);
3596 break;
3601 typeArguments:
3602 typeArguments ',' type
3604 unoidl::detail::SourceProviderType t(*$3);
3605 delete $3;
3606 if (!checkTypeArgument(@3, yyscanner, t)) {
3607 delete $1; /* see commented-out %destructor above */
3608 YYERROR;
3610 $1->push_back(t);
3611 $$ = $1;
3613 | type
3615 unoidl::detail::SourceProviderType t(*$1);
3616 delete $1;
3617 if (!checkTypeArgument(@1, yyscanner, t)) {
3618 YYERROR;
3620 $$ = new std::vector<unoidl::detail::SourceProviderType>;
3621 $$->push_back(t);
3625 type:
3626 TOK_VOID
3628 $$ = new unoidl::detail::SourceProviderType(
3629 unoidl::detail::SourceProviderType::TYPE_VOID);
3631 | TOK_BOOLEAN
3633 $$ = new unoidl::detail::SourceProviderType(
3634 unoidl::detail::SourceProviderType::TYPE_BOOLEAN);
3636 | TOK_BYTE
3638 $$ = new unoidl::detail::SourceProviderType(
3639 unoidl::detail::SourceProviderType::TYPE_BYTE);
3641 | TOK_SHORT
3643 $$ = new unoidl::detail::SourceProviderType(
3644 unoidl::detail::SourceProviderType::TYPE_SHORT);
3646 | TOK_UNSIGNED TOK_SHORT
3648 $$ = new unoidl::detail::SourceProviderType(
3649 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT);
3651 | TOK_LONG
3653 $$ = new unoidl::detail::SourceProviderType(
3654 unoidl::detail::SourceProviderType::TYPE_LONG);
3656 | TOK_UNSIGNED TOK_LONG
3658 $$ = new unoidl::detail::SourceProviderType(
3659 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG);
3661 | TOK_HYPER
3663 $$ = new unoidl::detail::SourceProviderType(
3664 unoidl::detail::SourceProviderType::TYPE_HYPER);
3666 | TOK_UNSIGNED TOK_HYPER
3668 $$ = new unoidl::detail::SourceProviderType(
3669 unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER);
3671 | TOK_FLOAT
3673 $$ = new unoidl::detail::SourceProviderType(
3674 unoidl::detail::SourceProviderType::TYPE_FLOAT);
3676 | TOK_DOUBLE
3678 $$ = new unoidl::detail::SourceProviderType(
3679 unoidl::detail::SourceProviderType::TYPE_DOUBLE);
3681 | TOK_CHAR
3683 $$ = new unoidl::detail::SourceProviderType(
3684 unoidl::detail::SourceProviderType::TYPE_CHAR);
3686 | TOK_STRING
3688 $$ = new unoidl::detail::SourceProviderType(
3689 unoidl::detail::SourceProviderType::TYPE_STRING);
3691 | TOK_TYPE
3693 $$ = new unoidl::detail::SourceProviderType(
3694 unoidl::detail::SourceProviderType::TYPE_TYPE);
3696 | TOK_ANY
3698 $$ = new unoidl::detail::SourceProviderType(
3699 unoidl::detail::SourceProviderType::TYPE_ANY);
3701 | TOK_SEQUENCE '<' type '>'
3703 switch ($3->type) {
3704 case unoidl::detail::SourceProviderType::TYPE_VOID:
3705 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
3706 case unoidl::detail::SourceProviderType::TYPE_PARAMETER: //TODO?
3707 error(@3, yyscanner, "illegal sequence type component type");
3708 YYERROR;
3709 break;
3710 default:
3711 break;
3713 $$ = new unoidl::detail::SourceProviderType($3);
3714 delete $3;
3716 | name
3718 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3719 OUString name(convertName($1));
3720 bool done = false;
3721 if (name.indexOf('.') == -1 && !data->currentName.isEmpty()) {
3722 unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
3723 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
3724 pad = dynamic_cast<
3725 unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
3726 ent->pad.get());
3727 if (pad != nullptr
3728 && (std::find(
3729 pad->typeParameters.begin(), pad->typeParameters.end(),
3730 name)
3731 != pad->typeParameters.end()))
3733 $$ = new unoidl::detail::SourceProviderType(name);
3734 done = true;
3737 if (!done) {
3738 unoidl::detail::SourceProviderEntity const * ent;
3739 unoidl::detail::SourceProviderType t;
3740 switch (findEntity(
3741 @1, yyscanner, data, false, &name, &ent, nullptr, &t))
3743 case FOUND_ERROR:
3744 YYERROR;
3745 break;
3746 case FOUND_TYPE:
3747 $$ = new unoidl::detail::SourceProviderType(t);
3748 break;
3749 case FOUND_ENTITY:
3750 if (ent == nullptr) {
3751 error(@1, yyscanner, "unknown entity " + name);
3752 YYERROR;
3754 bool ok = false;
3755 switch (ent->kind) {
3756 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
3757 if (ent->pad.is()) {
3758 if (data->publishedContext && !ent->pad->isPublished()) {
3759 error(
3760 @1, yyscanner,
3761 ("unpublished entity " + name
3762 + " used in published context"));
3763 YYERROR;
3765 if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
3766 ent->pad.get())
3767 != nullptr)
3769 $$ = new unoidl::detail::SourceProviderType(
3770 unoidl::detail::SourceProviderType::TYPE_ENUM,
3771 name, ent);
3772 ok = true;
3773 } else if (dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
3774 ent->pad.get())
3775 != nullptr)
3777 $$ = new unoidl::detail::SourceProviderType(
3778 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
3779 name, ent);
3780 ok = true;
3781 } else if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
3782 ent->pad.get())
3783 != nullptr)
3785 error(
3786 @1, yyscanner,
3787 (("recursive reference to polymorphic struct type"
3788 " template ")
3789 + name));
3790 YYERROR;
3791 } else if (dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
3792 ent->pad.get())
3793 != nullptr)
3795 $$ = new unoidl::detail::SourceProviderType(
3796 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
3797 name, ent);
3798 ok = true;
3799 } else if (dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
3800 ent->pad.get())
3801 != nullptr)
3803 $$ = new unoidl::detail::SourceProviderType(
3804 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
3805 name, ent);
3806 ok = true;
3808 break;
3810 assert(ent->entity.is());
3811 [[fallthrough]];
3812 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
3813 if (data->publishedContext
3814 && ent->entity->getSort() != unoidl::Entity::SORT_MODULE
3815 && !static_cast<unoidl::PublishableEntity *>(
3816 ent->entity.get())->isPublished())
3818 error(
3819 @1, yyscanner,
3820 ("unpublished entity " + name
3821 + " used in published context"));
3822 YYERROR;
3824 switch (ent->entity->getSort()) {
3825 case unoidl::Entity::SORT_ENUM_TYPE:
3826 $$ = new unoidl::detail::SourceProviderType(
3827 unoidl::detail::SourceProviderType::TYPE_ENUM, name,
3828 ent);
3829 ok = true;
3830 break;
3831 case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
3832 $$ = new unoidl::detail::SourceProviderType(
3833 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
3834 name, ent);
3835 ok = true;
3836 break;
3837 case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
3838 error(
3839 @1, yyscanner,
3840 ("polymorphic struct type template " + name
3841 + " without type arguments"));
3842 YYERROR;
3843 break;
3844 case unoidl::Entity::SORT_EXCEPTION_TYPE:
3845 $$ = new unoidl::detail::SourceProviderType(
3846 unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
3847 name, ent);
3848 ok = true;
3849 break;
3850 case unoidl::Entity::SORT_INTERFACE_TYPE:
3851 $$ = new unoidl::detail::SourceProviderType(
3852 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
3853 name, ent);
3854 ok = true;
3855 break;
3856 case unoidl::Entity::SORT_TYPEDEF:
3857 O3TL_UNREACHABLE;
3858 default:
3859 break;
3861 break;
3862 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
3863 if (data->publishedContext) {
3864 error(
3865 @1, yyscanner,
3866 ("unpublished entity " + name
3867 + " used in published context"));
3868 YYERROR;
3870 [[fallthrough]];
3871 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
3872 $$ = new unoidl::detail::SourceProviderType(
3873 unoidl::detail::SourceProviderType::TYPE_INTERFACE, name,
3874 ent);
3875 ok = true;
3876 break;
3877 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
3878 assert(false && "this cannot happen");
3880 if (!ok) {
3881 error(@1, yyscanner, "non-type entity " + name);
3882 YYERROR;
3884 break;
3888 | name '<' typeArguments '>'
3890 unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
3891 OUString name(convertName($1));
3892 std::vector<unoidl::detail::SourceProviderType> args(*$3);
3893 delete $3;
3894 unoidl::detail::SourceProviderEntity const * ent;
3895 if (findEntity(@1, yyscanner, data, false, &name, &ent, nullptr, nullptr)
3896 == FOUND_ERROR)
3898 YYERROR;
3900 if (ent == nullptr) {
3901 error(@1, yyscanner, "unknown entity " + name);
3902 YYERROR;
3904 bool ok = false;
3905 switch (ent->kind) {
3906 case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
3907 if (ent->pad.is()) {
3908 if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
3909 ent->pad.get())
3910 != nullptr)
3912 error(
3913 @1, yyscanner,
3914 (("recursive reference to polymorphic struct type"
3915 " template ")
3916 + name));
3917 YYERROR;
3919 break;
3921 assert(ent->entity.is());
3922 [[fallthrough]];
3923 case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
3924 if (ent->entity->getSort()
3925 == unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE)
3927 rtl::Reference<unoidl::PolymorphicStructTypeTemplateEntity> e(
3928 static_cast<unoidl::PolymorphicStructTypeTemplateEntity *>(
3929 ent->entity.get()));
3930 if (args.size() != e->getTypeParameters().size()) {
3931 error(
3932 @1, yyscanner,
3933 ("bad number of polymorphic struct type template " + name
3934 + " type arguments"));
3935 YYERROR;
3937 if (data->publishedContext && !e->isPublished()) {
3938 error(
3939 @1, yyscanner,
3940 ("unpublished polymorphic struct type template " + name
3941 + " used in published context"));
3942 YYERROR;
3944 $$ = new unoidl::detail::SourceProviderType(name, ent, std::move(args));
3945 ok = true;
3947 break;
3948 case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
3949 case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
3950 break;
3951 case unoidl::detail::SourceProviderEntity::KIND_MODULE:
3952 assert(false && "this cannot happen");
3954 if (!ok) {
3955 error(@1, yyscanner, "non-type entity " + name);
3956 YYERROR;
3961 name:
3962 name TOK_COLONS identifier { *$1 += "." + *$3; delete $3; $$ = $1; }
3963 | TOK_COLONS identifier { *$2 = "." + *$2; $$ = $2; }
3964 | identifier
3967 identifier:
3968 TOK_IDENTIFIER
3969 | TOK_GET { $$ = new OString("get"); }
3970 | TOK_PUBLISHED { $$ = new OString("published"); }
3971 | TOK_SET { $$ = new OString("set"); }
3974 deprecated_opt:
3975 TOK_DEPRECATED { $$ = true; }
3976 | /* empty */ { $$ = false; }
3981 namespace unoidl::detail {
3983 OUString SourceProviderType::getName() const {
3984 if (!typedefName.isEmpty()) {
3985 return typedefName;
3987 switch (type) {
3988 case unoidl::detail::SourceProviderType::TYPE_VOID:
3989 return "void";
3990 case unoidl::detail::SourceProviderType::TYPE_BOOLEAN:
3991 return "boolean";
3992 case unoidl::detail::SourceProviderType::TYPE_BYTE:
3993 return "byte";
3994 case unoidl::detail::SourceProviderType::TYPE_SHORT:
3995 return "short";
3996 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
3997 return "unsigned short";
3998 case unoidl::detail::SourceProviderType::TYPE_LONG:
3999 return "long";
4000 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
4001 return "unsigned long";
4002 case unoidl::detail::SourceProviderType::TYPE_HYPER:
4003 return "hyper";
4004 case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
4005 return "unsigned hyper";
4006 case unoidl::detail::SourceProviderType::TYPE_FLOAT:
4007 return "float";
4008 case unoidl::detail::SourceProviderType::TYPE_DOUBLE:
4009 return "double";
4010 case unoidl::detail::SourceProviderType::TYPE_CHAR:
4011 return "char";
4012 case unoidl::detail::SourceProviderType::TYPE_STRING:
4013 return "string";
4014 case unoidl::detail::SourceProviderType::TYPE_TYPE:
4015 return "type";
4016 case unoidl::detail::SourceProviderType::TYPE_ANY:
4017 return "any";
4018 case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
4019 assert(subtypes.size() == 1);
4020 return "[]" + subtypes.front().getName();
4021 case unoidl::detail::SourceProviderType::TYPE_ENUM:
4022 case unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT:
4023 case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
4024 case unoidl::detail::SourceProviderType::TYPE_INTERFACE:
4025 case unoidl::detail::SourceProviderType::TYPE_PARAMETER:
4026 return name;
4027 case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
4029 OUStringBuffer n(512);
4030 n.append(name + "<");
4031 for (auto i(subtypes.begin()); i != subtypes.end(); ++i) {
4032 if (i != subtypes.begin()) {
4033 n.append(",");
4035 n.append(i->getName());
4037 return n.append(">").makeStringAndClear();
4039 default:
4040 assert(false && "this cannot happen"); for (;;) { std::abort(); }
4044 bool SourceProviderType::equals(SourceProviderType const & other) const {
4045 if (type != other.type || name != other.name
4046 || subtypes.size() != other.subtypes.size())
4048 return false;
4050 for (auto i(subtypes.begin()), j(other.subtypes.begin());
4051 i != subtypes.end(); ++i, ++j)
4053 if (!i->equals(*j)) {
4054 return false;
4057 return true;
4060 bool SourceProviderInterfaceTypeEntityPad::addDirectBase(
4061 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4062 DirectBase const & base, bool optional)
4064 std::set<OUString> seen;
4065 if (!(checkBaseClashes(
4066 location, yyscanner, data, base.name, base.entity, true, optional,
4067 optional, &seen)
4068 && addBase(
4069 location, yyscanner, data, base.name, base.name, base.entity,
4070 true, optional)))
4072 return false;
4074 if (optional) {
4075 addOptionalBaseMembers(
4076 location, yyscanner, data, base.name, base.entity);
4078 (optional ? directOptionalBases : directMandatoryBases).push_back(base);
4079 return true;
4082 bool SourceProviderInterfaceTypeEntityPad::addDirectMember(
4083 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4084 OUString const & name)
4086 assert(data != nullptr);
4087 if (!checkMemberClashes(location, yyscanner, data, u"", name, true)) {
4088 return false;
4090 allMembers.emplace(name, Member(data->currentName));
4091 return true;
4094 bool SourceProviderInterfaceTypeEntityPad::checkBaseClashes(
4095 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4096 OUString const & name,
4097 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity, bool direct,
4098 bool optional, bool outerOptional, std::set<OUString> * seen) const
4100 assert(data != nullptr);
4101 assert(entity.is());
4102 assert(seen != nullptr);
4103 if (direct || optional || seen->insert(name).second) {
4104 std::map<OUString, BaseKind>::const_iterator i(allBases.find(name));
4105 if (i != allBases.end()) {
4106 switch (i->second) {
4107 case BASE_INDIRECT_OPTIONAL:
4108 if (direct && optional) {
4109 error(
4110 location, yyscanner,
4111 ("interface type " + data->currentName
4112 + " duplicate base " + name));
4113 return false;
4115 break;
4116 case BASE_DIRECT_OPTIONAL:
4117 if (direct || !outerOptional) {
4118 error(
4119 location, yyscanner,
4120 ("interface type " + data->currentName
4121 + " duplicate base " + name));
4122 return false;
4124 return true;
4125 case BASE_INDIRECT_MANDATORY:
4126 if (direct) {
4127 error(
4128 location, yyscanner,
4129 ("interface type " + data->currentName
4130 + " duplicate base " + name));
4131 return false;
4133 return true;
4134 case BASE_DIRECT_MANDATORY:
4135 if (direct || (!optional && !outerOptional)) {
4136 error(
4137 location, yyscanner,
4138 ("interface type " + data->currentName
4139 + " duplicate base " + name));
4140 return false;
4142 return true;
4145 if (direct || !optional) {
4146 for (auto & j: entity->getDirectMandatoryBases()) {
4147 OUString n("." + j.name);
4148 unoidl::detail::SourceProviderEntity const * p;
4149 if (findEntity(
4150 location, yyscanner, data, true, &n, &p, nullptr,
4151 nullptr)
4152 == FOUND_ERROR)
4154 return false;
4156 if (p == nullptr || !p->entity.is()
4157 || (p->entity->getSort()
4158 != unoidl::Entity::SORT_INTERFACE_TYPE))
4160 error(
4161 location, yyscanner,
4162 ("inconsistent type manager: interface type "
4163 + data->currentName + " base " + n
4164 + " does not resolve to an existing interface type"));
4165 return false;
4167 if (!checkBaseClashes(
4168 location, yyscanner, data, n,
4169 static_cast<unoidl::InterfaceTypeEntity *>(
4170 p->entity.get()),
4171 false, false, outerOptional, seen))
4173 return false;
4176 for (auto & j: entity->getDirectOptionalBases()) {
4177 OUString n("." + j.name);
4178 unoidl::detail::SourceProviderEntity const * p;
4179 if (findEntity(
4180 location, yyscanner, data, true, &n, &p, nullptr,
4181 nullptr)
4182 == FOUND_ERROR)
4184 return false;
4186 if (p == nullptr || !p->entity.is()
4187 || (p->entity->getSort()
4188 != unoidl::Entity::SORT_INTERFACE_TYPE))
4190 error(
4191 location, yyscanner,
4192 ("inconsistent type manager: interface type "
4193 + data->currentName + " base " + n
4194 + " does not resolve to an existing interface type"));
4195 return false;
4197 if (!checkBaseClashes(
4198 location, yyscanner, data, n,
4199 static_cast<unoidl::InterfaceTypeEntity *>(
4200 p->entity.get()),
4201 false, true, outerOptional, seen))
4203 return false;
4206 for (auto & j: entity->getDirectAttributes()) {
4207 if (!checkMemberClashes(
4208 location, yyscanner, data, name, j.name,
4209 !outerOptional))
4211 return false;
4214 for (auto & j: entity->getDirectMethods()) {
4215 if (!checkMemberClashes(
4216 location, yyscanner, data, name, j.name,
4217 !outerOptional))
4219 return false;
4224 return true;
4227 bool SourceProviderInterfaceTypeEntityPad::checkMemberClashes(
4228 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4229 std::u16string_view interfaceName, OUString const & memberName,
4230 bool checkOptional) const
4232 std::map<OUString, Member>::const_iterator i(allMembers.find(memberName));
4233 if (i != allMembers.end()) {
4234 if (!i->second.mandatory.isEmpty()) {
4235 // For a direct member, interfaceName will be empty, so this will
4236 // catch two direct members with the same name:
4237 if (i->second.mandatory != interfaceName) {
4238 error(
4239 location, yyscanner,
4240 ("interface type " + data->currentName
4241 + " duplicate member " + memberName));
4242 return false;
4244 } else if (checkOptional) {
4245 for (auto & j: i->second.optional) {
4246 if (j != interfaceName) {
4247 error(
4248 location, yyscanner,
4249 ("interface type " + data->currentName
4250 + " duplicate member " + memberName));
4251 return false;
4256 return true;
4259 bool SourceProviderInterfaceTypeEntityPad::addBase(
4260 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4261 OUString const & directBaseName, OUString const & name,
4262 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity, bool direct,
4263 bool optional)
4265 assert(data != nullptr);
4266 assert(entity.is());
4267 BaseKind kind = optional
4268 ? direct ? BASE_DIRECT_OPTIONAL : BASE_INDIRECT_OPTIONAL
4269 : direct ? BASE_DIRECT_MANDATORY : BASE_INDIRECT_MANDATORY;
4270 std::pair<std::map<OUString, BaseKind>::iterator, bool> p(
4271 allBases.emplace(name, kind));
4272 bool seen = !p.second && p.first->second >= BASE_INDIRECT_MANDATORY;
4273 if (!p.second && kind > p.first->second) {
4274 p.first->second = kind;
4276 if (!optional && !seen) {
4277 for (auto & i: entity->getDirectMandatoryBases()) {
4278 OUString n("." + i.name);
4279 unoidl::detail::SourceProviderEntity const * q;
4280 if (findEntity(
4281 location, yyscanner, data, true, &n, &q, nullptr, nullptr)
4282 == FOUND_ERROR)
4284 return false;
4286 if (q == nullptr || !q->entity.is()
4287 || q->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4289 error(
4290 location, yyscanner,
4291 ("inconsistent type manager: interface type "
4292 + data->currentName + " base " + n
4293 + " does not resolve to an existing interface type"));
4294 return false;
4296 if (!addBase(
4297 location, yyscanner, data, directBaseName, n,
4298 static_cast<unoidl::InterfaceTypeEntity *>(q->entity.get()),
4299 false, false))
4301 return false;
4304 for (auto & i: entity->getDirectOptionalBases())
4306 OUString n("." + i.name);
4307 unoidl::detail::SourceProviderEntity const * q;
4308 if (findEntity(
4309 location, yyscanner, data, true, &n, &q, nullptr, nullptr)
4310 == FOUND_ERROR)
4312 return false;
4314 if (q == nullptr || !q->entity.is()
4315 || q->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4317 error(
4318 location, yyscanner,
4319 ("inconsistent type manager: interface type "
4320 + data->currentName + " base " + n
4321 + " does not resolve to an existing interface type"));
4322 return false;
4324 if (!addBase(
4325 location, yyscanner, data, directBaseName, n,
4326 static_cast<unoidl::InterfaceTypeEntity *>(q->entity.get()),
4327 false, true))
4329 return false;
4332 for (auto & i: entity->getDirectAttributes()) {
4333 allMembers.emplace(i.name, Member(name));
4335 for (auto & i: entity->getDirectMethods()) {
4336 allMembers.emplace(i.name, Member(name));
4339 return true;
4342 bool SourceProviderInterfaceTypeEntityPad::addOptionalBaseMembers(
4343 YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
4344 OUString const & name,
4345 rtl::Reference<unoidl::InterfaceTypeEntity> const & entity)
4347 assert(entity.is());
4348 for (auto & i: entity->getDirectMandatoryBases()) {
4349 OUString n("." + i.name);
4350 unoidl::detail::SourceProviderEntity const * p;
4351 if (findEntity(
4352 location, yyscanner, data, true, &n, &p, nullptr, nullptr)
4353 == FOUND_ERROR)
4355 return false;
4357 if (p == nullptr || !p->entity.is()
4358 || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
4360 error(
4361 location, yyscanner,
4362 ("inconsistent type manager: interface type "
4363 + data->currentName + " base " + n
4364 + " does not resolve to an existing interface type"));
4365 return false;
4367 if (!addOptionalBaseMembers(
4368 location, yyscanner, data, n,
4369 static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get())))
4371 return false;
4374 for (auto & i: entity->getDirectAttributes()) {
4375 Member & m(
4376 allMembers.emplace(i.name, Member(""))
4377 .first->second);
4378 if (m.mandatory.isEmpty()) {
4379 m.optional.insert(name);
4382 for (auto & i: entity->getDirectMethods()) {
4383 Member & m(
4384 allMembers.emplace(i.name, Member(""))
4385 .first->second);
4386 if (m.mandatory.isEmpty()) {
4387 m.optional.insert(name);
4390 return true;
4393 bool parse(OUString const & uri, SourceProviderScannerData * data) {
4394 assert(data != nullptr);
4395 oslFileHandle handle;
4396 oslFileError e = osl_openFile(uri.pData, &handle, osl_File_OpenFlag_Read);
4397 switch (e) {
4398 case osl_File_E_None:
4399 break;
4400 case osl_File_E_NOENT:
4401 return false;
4402 default:
4403 throw FileFormatException(uri, "cannot open: " + OUString::number(e));
4405 sal_uInt64 size;
4406 e = osl_getFileSize(handle, &size);
4407 if (e != osl_File_E_None) {
4408 oslFileError e2 = osl_closeFile(handle);
4409 SAL_WARN_IF(
4410 e2 != osl_File_E_None, "unoidl",
4411 "cannot close " << uri << ": " << +e2);
4412 throw FileFormatException(
4413 uri, "cannot get size: " + OUString::number(e));
4415 void * address;
4416 e = osl_mapFile(handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
4417 if (e != osl_File_E_None) {
4418 oslFileError e2 = osl_closeFile(handle);
4419 SAL_WARN_IF(
4420 e2 != osl_File_E_None, "unoidl",
4421 "cannot close " << uri << ": " << +e2);
4422 throw FileFormatException(uri, "cannot mmap: " + OUString::number(e));
4424 try {
4425 data->setSource(address, size);
4426 yyscan_t yyscanner;
4427 if (yylex_init_extra(data, &yyscanner) != 0) {
4428 // Checking errno for the specific EINVAL, ENOMEM documented for
4429 // yylex_init_extra would not work as those values are not defined
4430 // by the C++ Standard:
4431 int e2 = errno;
4432 throw FileFormatException(
4433 uri,
4434 "yylex_init_extra failed with errno " + OUString::number(e2));
4436 int e2 = yyparse(yyscanner);
4437 yylex_destroy(yyscanner);
4438 switch (e2) {
4439 case 0:
4440 break;
4441 default:
4442 O3TL_UNREACHABLE;
4443 case 1:
4444 throw FileFormatException(
4445 uri,
4446 ("cannot parse"
4447 + (data->errorLine == 0
4448 ? OUString() : " line " + OUString::number(data->errorLine))
4449 + (data->parserError.isEmpty()
4450 ? OUString()
4451 : (", "
4452 + OStringToOUString(
4453 data->parserError, osl_getThreadTextEncoding())))
4454 + (data->errorMessage.isEmpty()
4455 ? OUString() : ": \"" + data->errorMessage + "\"")));
4456 case 2:
4457 throw std::bad_alloc();
4459 } catch (...) {
4460 e = osl_unmapMappedFile(handle, address, size);
4461 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
4462 e = osl_closeFile(handle);
4463 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
4464 throw;
4466 e = osl_unmapMappedFile(handle, address, size);
4467 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
4468 e = osl_closeFile(handle);
4469 SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
4470 return true;
4475 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */