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