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

Generated by: LCOV version 1.10