LCOV - code coverage report
Current view: top level - unoidl/source - sourceprovider-parser.y (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1665 2398 69.4 %
Date: 2015-06-13 12:38:46 Functions: 29 30 96.7 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11