LCOV - code coverage report
Current view: top level - unoidl/source - sourceprovider-parser.y (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1554 2276 68.3 %
Date: 2014-11-03 Functions: 29 30 96.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  */
       9             : 
      10             : /*TODO: check Exception, RuntimeException, XInterface defns */
      11             : 
      12             : %locations
      13             : %pure-parser
      14             : 
      15             : %{
      16             : 
      17             : #include "sal/config.h"
      18             : 
      19             : #include <algorithm>
      20             : #include <cassert>
      21             : #include <cerrno>
      22             : #include <cstddef>
      23             : #include <cstdlib>
      24             : #include <limits>
      25             : #include <new>
      26             : #include <utility>
      27             : #include <vector>
      28             : 
      29             : #include <sourceprovider-parser-requires.hxx>
      30             : 
      31             : %}
      32             : 
      33             : %union {
      34             :     sal_uInt64 ival;
      35             :     double fval;
      36             :     OString * sval;
      37             : 
      38             :     bool bval;
      39             :     std::vector<OUString> * excns;
      40             :     unoidl::detail::SourceProviderAccessDecls decls;
      41             :     unoidl::InterfaceTypeEntity::Method::Parameter::Direction dir;
      42             :     unoidl::detail::SourceProviderFlags flags;
      43             :     unoidl::detail::SourceProviderExpr expr;
      44             :     unoidl::detail::SourceProviderType * type;
      45             :     std::vector<unoidl::detail::SourceProviderType> * types;
      46             : }
      47             : 
      48             : /* TODO: %destructor { delete $$; } <sval> <excns> <type> <types> */
      49             : 
      50             : %lex-param {yyscan_t yyscanner}
      51             : %parse-param {yyscan_t yyscanner}
      52             : 
      53             : %{
      54             : 
      55             : #include "osl/file.h"
      56             : #include "osl/thread.h"
      57             : 
      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          46 : void yyerror(YYLTYPE * locp, yyscan_t yyscanner, char const * msg) {
      64             :     assert(locp != 0);
      65          46 :     unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
      66          46 :     data->errorLine = *locp;
      67          46 :     data->parserError = OString(msg);
      68          46 : }
      69             : 
      70             : namespace {
      71             : 
      72         324 : void error(YYLTYPE location, yyscan_t yyscanner, OUString const & message) {
      73         324 :     unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
      74         324 :     data->errorLine = location;
      75         324 :     data->errorMessage = message;
      76         324 : }
      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 && "this cannot happen"); for (;;) { std::abort(); }
     104             :     }
     105             : }
     106             : 
     107      105805 : OUString convertName(OString const * name) {
     108             :     assert(name != 0);
     109      105805 :     OUString s(OStringToOUString(*name, RTL_TEXTENCODING_ASCII_US));
     110      105805 :     delete name;
     111      105805 :     return s;
     112             : }
     113             : 
     114       33934 : OUString convertToFullName(
     115             :     unoidl::detail::SourceProviderScannerData const * data,
     116             :     OString const * identifier)
     117             : {
     118             :     assert(data != 0);
     119       33934 :     OUString pref;
     120       33934 :     if (!data->modules.empty()) {
     121       27009 :         pref = data->modules.back() + ".";
     122             :     }
     123       33934 :     return pref + convertName(identifier);
     124             : }
     125             : 
     126        9580 : void convertToCurrentName(
     127             :     unoidl::detail::SourceProviderScannerData * data,
     128             :     OString const * identifier)
     129             : {
     130             :     assert(data != 0);
     131             :     assert(data->currentName.isEmpty());
     132        9580 :     data->currentName = convertToFullName(data, identifier);
     133             :     assert(!data->currentName.isEmpty());
     134        9580 : }
     135             : 
     136       10604 : void clearCurrentState(unoidl::detail::SourceProviderScannerData * data) {
     137             :     assert(data != 0);
     138       10604 :     data->currentName = "";
     139       10604 :     data->publishedContext = false;
     140       10604 : }
     141             : 
     142       70407 : 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       70407 :         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       70407 :     return &i->second;
     153             : }
     154             : 
     155       56347 : template<typename T> rtl::Reference<T> getCurrentPad(
     156             :     unoidl::detail::SourceProviderScannerData * data)
     157             : {
     158       56347 :     rtl::Reference<T> pad(dynamic_cast<T *>(getCurrentEntity(data)->pad.get()));
     159             :     assert(pad.is());
     160       56347 :     return pad;
     161             : }
     162             : 
     163        3684 : bool nameHasSameIdentifierAs(OUString const & name, OUString const & identifier)
     164             : {
     165        3684 :     sal_Int32 i = name.lastIndexOf('.') + 1;
     166        3684 :     return identifier.getLength() == name.getLength() - i
     167        3684 :         && name.match(identifier, i);
     168             : }
     169             : 
     170          76 : 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          76 :     bool ok = bool(); // avoid warnings
     178          76 :     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          76 :         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          16 :             ok = true;
     189          16 :             break;
     190             :         case unoidl::detail::SourceProviderExpr::TYPE_UINT:
     191          60 :             if (lhs->ival >= 0) {
     192          60 :                 lhs->type = unoidl::detail::SourceProviderExpr::TYPE_UINT;
     193          60 :                 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          60 :             break;
     201             :         case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
     202           0 :             lhs->fval = lhs->ival;
     203           0 :             ok = true;
     204           0 :             break;
     205             :         }
     206          76 :         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          76 :     if (!ok) {
     252           0 :         error(location, yyscanner, "cannot coerce binary expression arguments");
     253             :     }
     254          76 :     return ok;
     255             : }
     256             : 
     257       28975 : unoidl::detail::SourceProviderEntity * findEntity_(
     258             :     unoidl::detail::SourceProviderScannerData * data, OUString * name)
     259             : {
     260             :     assert(data != 0);
     261             :     assert(name != 0);
     262       28975 :     OUString n;
     263       28975 :     if (!name->startsWith(".", &n)) {
     264      151776 :         for (std::vector<OUString>::reverse_iterator i(data->modules.rbegin());
     265      101184 :              i != data->modules.rend(); ++i)
     266             :         {
     267       40847 :             n = *i + "." + *name;
     268             :             std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator j(
     269       40847 :                 data->entities.find(n));
     270       40847 :             if (j != data->entities.end()) {
     271        1961 :                 *name = n;
     272        5400 :                 return &j->second;
     273             :             }
     274       38886 :             rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
     275       38886 :             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        2956 :                                   ent))).
     283        1478 :                       first);
     284        1478 :                 *name = n;
     285        1478 :                 return &k->second;
     286             :             }
     287       37408 :         }
     288        9745 :         n = *name;
     289             :     }
     290             :     std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
     291       25536 :         data->entities.find(n));
     292       25536 :     if (i != data->entities.end()) {
     293       16060 :         *name = n;
     294       16060 :         return &i->second;
     295             :     }
     296       18952 :     rtl::Reference<unoidl::Entity> ent(data->manager->findEntity(n));
     297        9476 :     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       18944 :                           ent))).
     305        9472 :               first);
     306        9472 :         *name = n;
     307        9472 :         return &j->second;
     308             :     }
     309       28979 :     return 0;
     310             : }
     311             : 
     312             : enum Found { FOUND_ERROR, FOUND_TYPE, FOUND_ENTITY };
     313             : 
     314       28812 : 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       28812 :     unoidl::detail::SourceProviderEntity * e = findEntity_(data, name);
     326       28812 :     OUString n(*name);
     327       57624 :     OUString typeNucleus;
     328       28812 :     std::size_t rank = 0;
     329       57624 :     std::vector<unoidl::detail::SourceProviderType> args;
     330             :     for (;;) {
     331       28975 :         if (e != 0) {
     332       28971 :             switch (e->kind) {
     333             :             case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
     334        6136 :                 if (e->pad.is()) {
     335         208 :                     break;
     336             :                 }
     337             :                 assert(e->entity.is());
     338             :                 // fall through
     339             :             case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
     340       27412 :                 if (e->entity->getSort() == unoidl::Entity::SORT_TYPEDEF) {
     341         564 :                     if (typedefed != 0) {
     342           4 :                         *typedefed = true;
     343             :                     }
     344         564 :                     if (data->publishedContext
     345         884 :                         && !static_cast<unoidl::TypedefEntity *>(
     346         320 :                             e->entity.get())->isPublished())
     347             :                     {
     348             :                         error(
     349             :                             location, yyscanner,
     350          12 :                             ("type " + *name + " based on unpublished typedef "
     351           6 :                              + n + " used in published context"));
     352          12 :                         return FOUND_ERROR;
     353             :                     }
     354             :                     OUString t(
     355         558 :                         static_cast<unoidl::TypedefEntity *>(e->entity.get())
     356         558 :                         ->getType());
     357         558 :                     typeNucleus = t;
     358        1238 :                     while (typeNucleus.startsWith("[]", &typeNucleus)) {
     359         122 :                         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         122 :                         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         122 :                         ++rank;
     376             :                     }
     377         558 :                     sal_Int32 i = typeNucleus.indexOf('<');
     378         558 :                     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         558 :                     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         558 :                     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        1671 :                     if (typeNucleus == "boolean" || typeNucleus == "byte"
     523         551 :                         || typeNucleus == "short"
     524         548 :                         || typeNucleus == "unsigned short"
     525         539 :                         || typeNucleus == "long"
     526         224 :                         || typeNucleus == "unsigned long"
     527         221 :                         || typeNucleus == "hyper"
     528         218 :                         || typeNucleus == "unsigned hyper"
     529         215 :                         || typeNucleus == "float" || typeNucleus == "double"
     530         179 :                         || typeNucleus == "char" || typeNucleus == "string"
     531         730 :                         || typeNucleus == "type" || typeNucleus == "any")
     532             :                     {
     533         395 :                         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         395 :                         break;
     543             :                     }
     544         163 :                     n = "." + typeNucleus;
     545             :                     typeNucleus = "",
     546         163 :                     e = findEntity_(data, &n);
     547         163 :                     continue;
     548             :                 }
     549       26848 :                 break;
     550             :             case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
     551             :             case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
     552        1351 :                 if (resolveInterfaceDefinitions) {
     553             :                     rtl::Reference<unoidl::Entity> ent(
     554          14 :                         data->manager->findEntity(n));
     555             :                     // Do not allow ent to be of SORT_TYPEDEF:
     556          28 :                     if (!ent.is()
     557          14 :                         || (ent->getSort()
     558             :                             != unoidl::Entity::SORT_INTERFACE_TYPE))
     559             :                     {
     560             :                         error(
     561             :                             location, yyscanner,
     562          12 :                             (*name + " is based on interface declaration " + n
     563           6 :                              + " that is not an interface type entity"));
     564           6 :                         return FOUND_ERROR;
     565             :                     }
     566             :                     e->kind
     567           8 :                         = unoidl::detail::SourceProviderEntity::KIND_EXTERNAL;
     568           8 :                     e->entity = ent;
     569             :                 }
     570        1345 :                 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       28800 :         if (!typeNucleus.isEmpty() || rank != 0 || !args.empty()) {
     579         474 :             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         474 :             unoidl::detail::SourceProviderType t;
     585         474 :             if (args.empty()) {
     586         474 :                 if (typeNucleus == "boolean") {
     587           6 :                     t = unoidl::detail::SourceProviderType(
     588           3 :                         unoidl::detail::SourceProviderType::TYPE_BOOLEAN);
     589         471 :                 } else if (typeNucleus == "byte") {
     590           8 :                     t = unoidl::detail::SourceProviderType(
     591           4 :                         unoidl::detail::SourceProviderType::TYPE_BYTE);
     592         467 :                 } else if (typeNucleus == "short") {
     593           6 :                     t = unoidl::detail::SourceProviderType(
     594           3 :                         unoidl::detail::SourceProviderType::TYPE_SHORT);
     595         464 :                 } else if (typeNucleus == "unsigned short") {
     596          18 :                     t = unoidl::detail::SourceProviderType(
     597           9 :                         unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT);
     598         455 :                 } else if (typeNucleus == "long") {
     599         630 :                     t = unoidl::detail::SourceProviderType(
     600         315 :                         unoidl::detail::SourceProviderType::TYPE_LONG);
     601         140 :                 } else if (typeNucleus == "unsigned long") {
     602           6 :                     t = unoidl::detail::SourceProviderType(
     603           3 :                         unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG);
     604         137 :                 } else if (typeNucleus == "hyper") {
     605           6 :                     t = unoidl::detail::SourceProviderType(
     606           3 :                         unoidl::detail::SourceProviderType::TYPE_HYPER);
     607         134 :                 } else if (typeNucleus == "unsigned hyper") {
     608           6 :                     t = unoidl::detail::SourceProviderType(
     609           3 :                         unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER);
     610         131 :                 } else if (typeNucleus == "float") {
     611           6 :                     t = unoidl::detail::SourceProviderType(
     612           3 :                         unoidl::detail::SourceProviderType::TYPE_FLOAT);
     613         128 :                 } else if (typeNucleus == "double") {
     614          66 :                     t = unoidl::detail::SourceProviderType(
     615          33 :                         unoidl::detail::SourceProviderType::TYPE_DOUBLE);
     616          95 :                 } else if (typeNucleus == "char") {
     617           6 :                     t = unoidl::detail::SourceProviderType(
     618           3 :                         unoidl::detail::SourceProviderType::TYPE_CHAR);
     619          92 :                 } else if (typeNucleus == "string") {
     620           8 :                     t = unoidl::detail::SourceProviderType(
     621           4 :                         unoidl::detail::SourceProviderType::TYPE_STRING);
     622          88 :                 } else if (typeNucleus == "type") {
     623           6 :                     t = unoidl::detail::SourceProviderType(
     624           3 :                         unoidl::detail::SourceProviderType::TYPE_TYPE);
     625          85 :                 } else if (typeNucleus == "any") {
     626          12 :                     t = unoidl::detail::SourceProviderType(
     627           6 :                         unoidl::detail::SourceProviderType::TYPE_ANY);
     628             :                 } else {
     629             :                     assert(typeNucleus.isEmpty());
     630             :                     assert(e != 0);
     631          79 :                     switch (e->kind) {
     632             :                     case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
     633          10 :                         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          79 :                         switch (e->entity->getSort()) {
     686             :                         case unoidl::Entity::SORT_ENUM_TYPE:
     687           8 :                             t = unoidl::detail::SourceProviderType(
     688             :                                 unoidl::detail::SourceProviderType::TYPE_ENUM,
     689           4 :                                 n, e);
     690           4 :                             break;
     691             :                         case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
     692         146 :                             t = unoidl::detail::SourceProviderType(
     693             :                                 unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
     694          73 :                                 n, e);
     695          73 :                             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           4 :                             t = unoidl::detail::SourceProviderType(
     710             :                                 unoidl::detail::SourceProviderType::TYPE_INTERFACE,
     711           2 :                                 n, e);
     712           2 :                             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          79 :                         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         474 :             if (typedefedType != 0) {
     796         592 :                 for (std::size_t i = 0; i != rank; ++i) {
     797         122 :                     t = unoidl::detail::SourceProviderType(&t);
     798             :                 }
     799         470 :                 *typedefedType = t;
     800         470 :                 typedefedType->typedefName = *name;
     801             :             }
     802         474 :             *entity = 0;
     803         474 :             return FOUND_TYPE;
     804             :         }
     805       28326 :         *entity = e;
     806       28326 :         return FOUND_ENTITY;
     807       28975 :     }
     808             : }
     809             : 
     810             : 
     811         272 : bool checkTypeArgument(
     812             :     YYLTYPE location, yyscan_t yyscanner,
     813             :     unoidl::detail::SourceProviderType const & type)
     814             : {
     815         272 :     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          18 :             "bad instantiated polymorphic struct type argument");
     825          18 :         return false;
     826             :     case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
     827          41 :         return checkTypeArgument(location, yyscanner, type.subtypes.front());
     828             :     default:
     829         213 :         return true;
     830             :     }
     831             : }
     832             : 
     833        2817 : bool checkInstantiatedPolymorphicStructTypeArgument(
     834             :     unoidl::detail::SourceProviderType const & type, OUString const & name)
     835             : {
     836        2817 :     if (type.type
     837        2817 :         == unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT)
     838             :     {
     839         204 :         for (std::vector<unoidl::detail::SourceProviderType>::const_iterator i(
     840          36 :                  type.subtypes.begin());
     841         136 :              i != type.subtypes.end(); ++i)
     842             :         {
     843         116 :             if (checkInstantiatedPolymorphicStructTypeArgument(*i, name)
     844         150 :                 || i->getName() == name) // no need to worry about typedef
     845             :             {
     846           6 :                 return true;
     847             :             }
     848             :         }
     849             :     }
     850        2811 :     return false;
     851             : }
     852             : 
     853       53227 : std::vector<OUString> annotations(bool deprecated) {
     854       53227 :     std::vector<OUString> ann;
     855       53227 :     if (deprecated) {
     856         531 :         ann.push_back("deprecated");
     857             :     }
     858       53227 :     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        6238 : %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       22974 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
     963       22974 :       OUString name(convertToFullName(data, $2));
     964       22974 :       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       22974 :                       unoidl::detail::SourceProviderEntity::KIND_MODULE))));
     971       45948 :       if (!p.second
     972       23582 :           && (p.first->second.kind
     973         608 :               != unoidl::detail::SourceProviderEntity::KIND_MODULE))
     974             :       {
     975           0 :           error(@2, yyscanner, "multiple entities named " + name);
     976           0 :           YYERROR;
     977       22974 :       }
     978             :   }
     979       22920 :   '{' definitions '}' ';' { yyget_extra(yyscanner)->modules.pop_back(); }
     980             : ;
     981             : 
     982             : enumDefn:
     983             :   deprecated_opt published_opt TOK_ENUM identifier
     984             :   {
     985         437 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
     986         437 :       data->publishedContext = $2;
     987         437 :       convertToCurrentName(data, $4);
     988         874 :       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         874 :                           $2)))).
     994         437 :           second)
     995             :       {
     996           0 :           error(@4, yyscanner, "multiple entities named " + data->currentName);
     997           0 :           YYERROR;
     998             :       }
     999             :   }
    1000             :   '{' enumMembers '}' ';'
    1001             :   {
    1002         437 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1003         437 :       unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
    1004             :       unoidl::detail::SourceProviderEnumTypeEntityPad * pad =
    1005             :           dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
    1006         437 :               ent->pad.get());
    1007             :       assert(pad != 0);
    1008        1748 :       ent->entity = new unoidl::EnumTypeEntity(
    1009        1748 :           pad->isPublished(), pad->members, annotations($1));
    1010         437 :       ent->pad.clear();
    1011         437 :       clearCurrentState(data);
    1012             :   }
    1013             : ;
    1014             : 
    1015             : enumMembers:
    1016             : | enumMembers ',' enumMember
    1017             : | enumMember
    1018             : ;
    1019             : 
    1020             : enumMember:
    1021             :   deprecated_opt identifier
    1022             :   {
    1023        1291 :       OUString id(convertName($2));
    1024        1291 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1025             :       rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
    1026        2582 :           getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
    1027             :       sal_Int32 v;
    1028        1291 :       if (pad->members.empty()) {
    1029         271 :           v = 0;
    1030             :       } else {
    1031        1020 :           v = pad->members.back().value;
    1032        1020 :           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        1020 :           ++v;
    1040             :       }
    1041        1291 :       pad->members.push_back(
    1042        3873 :           unoidl::EnumTypeEntity::Member(id, v, annotations($1)));
    1043             :   }
    1044             : | deprecated_opt identifier '=' expr
    1045             :   {
    1046        1224 :       OUString id(convertName($2));
    1047        1224 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1048             :       rtl::Reference<unoidl::detail::SourceProviderEnumTypeEntityPad> pad(
    1049        2448 :           getCurrentPad<unoidl::detail::SourceProviderEnumTypeEntityPad>(data));
    1050             :       sal_Int32 v;
    1051        1224 :       switch ($4.type) {
    1052             :       case unoidl::detail::SourceProviderExpr::TYPE_INT:
    1053           4 :           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           4 :           v = static_cast<sal_Int32>($4.ival);
    1061           4 :           break;
    1062             :       case unoidl::detail::SourceProviderExpr::TYPE_UINT:
    1063        1220 :           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        1220 :           v = static_cast<sal_Int32>($4.uval);
    1071        1220 :           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        1224 :       pad->members.push_back(
    1081        3672 :           unoidl::EnumTypeEntity::Member(id, v, annotations($1)));
    1082             :   }
    1083             : ;
    1084             : 
    1085             : plainStructDefn:
    1086             :   deprecated_opt published_opt TOK_STRUCT identifier singleInheritance_opt
    1087             :   {
    1088         765 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1089         765 :       data->publishedContext = $2;
    1090         765 :       convertToCurrentName(data, $4);
    1091         765 :       OUString baseName;
    1092        1524 :       rtl::Reference<unoidl::PlainStructTypeEntity> baseEnt;
    1093         765 :       if ($5 != 0) {
    1094         192 :           baseName = convertName($5);
    1095             :           unoidl::detail::SourceProviderEntity const * p;
    1096         192 :           if (findEntity(@5, yyscanner, data, false, &baseName, &p, 0, 0)
    1097             :               == FOUND_ERROR)
    1098             :           {
    1099           6 :               YYERROR;
    1100             :           }
    1101         574 :           if (p == 0 || !p->entity.is()
    1102         382 :               || p->entity->getSort() != unoidl::Entity::SORT_PLAIN_STRUCT_TYPE)
    1103             :           {
    1104             :               error(
    1105             :                   @5, yyscanner,
    1106           8 :                   ("plain struct type " + data->currentName + " base "
    1107           8 :                    + baseName
    1108           4 :                    + " does not resolve to an existing plain struct type"));
    1109           4 :               YYERROR;
    1110             :           }
    1111             :           baseEnt = static_cast<unoidl::PlainStructTypeEntity *>(
    1112         188 :               p->entity.get());
    1113         188 :           if ($2 && !baseEnt->isPublished()) {
    1114             :               error(
    1115             :                   @5, yyscanner,
    1116           4 :                   ("published plain struct type " + data->currentName + " base "
    1117           2 :                    + baseName + " is unpublished"));
    1118           2 :               YYERROR;
    1119             :           }
    1120             :       }
    1121        1518 :       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        1518 :                           $2, baseName, baseEnt)))).
    1127         759 :           second)
    1128             :       {
    1129           0 :           error(@4, yyscanner, "multiple entities named " + data->currentName);
    1130           0 :           YYERROR;
    1131         759 :       }
    1132             :   }
    1133             :   '{' structMembers '}' ';'
    1134             :   {
    1135         711 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1136         711 :       unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
    1137             :       unoidl::detail::SourceProviderPlainStructTypeEntityPad * pad =
    1138             :           dynamic_cast<
    1139             :               unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
    1140         711 :                   ent->pad.get());
    1141             :       assert(pad != 0);
    1142        2844 :       ent->entity = new unoidl::PlainStructTypeEntity(
    1143        2844 :           pad->isPublished(), pad->baseName, pad->members, annotations($1));
    1144         711 :       ent->pad.clear();
    1145         711 :       clearCurrentState(data);
    1146             :   }
    1147             : ;
    1148             : 
    1149             : polymorphicStructTemplateDefn:
    1150             :   deprecated_opt published_opt TOK_STRUCT identifier '<'
    1151             :   {
    1152         150 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1153         150 :       data->publishedContext = $2;
    1154         150 :       convertToCurrentName(data, $4);
    1155         300 :       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         300 :                           $2)))).
    1161         150 :           second)
    1162             :       {
    1163           0 :           error(@4, yyscanner, "multiple entities named " + data->currentName);
    1164           0 :           YYERROR;
    1165             :       }
    1166             :   }
    1167             :   typeParameters '>' '{' structMembers '}' ';'
    1168             :   {
    1169         122 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1170         122 :       unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
    1171             :       unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
    1172             :           pad = dynamic_cast<
    1173             :               unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
    1174         122 :                   ent->pad.get());
    1175             :       assert(pad != 0);
    1176         488 :       ent->entity = new unoidl::PolymorphicStructTypeTemplateEntity(
    1177         122 :           pad->isPublished(), pad->typeParameters, pad->members,
    1178         366 :           annotations($1));
    1179         122 :       ent->pad.clear();
    1180         122 :       clearCurrentState(data);
    1181             :   }
    1182             : ;
    1183             : 
    1184             : typeParameters:
    1185             :   typeParameters ',' identifier
    1186             :   {
    1187           9 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1188             :       rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
    1189             :           pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
    1190           9 :                   data));
    1191          16 :       OUString id(convertName($3));
    1192          27 :       if (std::find(pad->typeParameters.begin(), pad->typeParameters.end(), id)
    1193          27 :           != pad->typeParameters.end())
    1194             :       {
    1195             :           error(
    1196             :               @3, yyscanner,
    1197           4 :               ("polymorphic struct type template " + data->currentName
    1198           4 :                + " type parameter " + id
    1199           2 :                + " has same identifier as another type parameter"));
    1200           2 :           YYERROR;
    1201             :       }
    1202          14 :       pad->typeParameters.push_back(id);
    1203             :   }
    1204             : | identifier
    1205             :   {
    1206         150 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1207             :       rtl::Reference<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>
    1208             :           pad(getCurrentPad<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad>(
    1209         150 :                   data));
    1210         300 :       OUString id(convertName($1));
    1211             :       assert(pad->typeParameters.empty());
    1212         300 :       pad->typeParameters.push_back(id);
    1213             :   }
    1214             : ;
    1215             : 
    1216             : exceptionDefn:
    1217             :   deprecated_opt published_opt TOK_EXCEPTION identifier singleInheritance_opt
    1218             :   {
    1219         501 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1220         501 :       data->publishedContext = $2;
    1221         501 :       convertToCurrentName(data, $4);
    1222         501 :       OUString baseName;
    1223        1000 :       rtl::Reference<unoidl::ExceptionTypeEntity> baseEnt;
    1224         501 :       if ($5 != 0) {
    1225         427 :           baseName = convertName($5);
    1226             :           unoidl::detail::SourceProviderEntity const * p;
    1227         427 :           if (findEntity(@5, yyscanner, data, false, &baseName, &p, 0, 0)
    1228             :               == FOUND_ERROR)
    1229             :           {
    1230           2 :               YYERROR;
    1231             :           }
    1232        1281 :           if (p == 0 || !p->entity.is()
    1233         854 :               || 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         427 :               p->entity.get());
    1243         427 :           if ($2 && !baseEnt->isPublished()) {
    1244             :               error(
    1245             :                   @5, yyscanner,
    1246           4 :                   ("published exception type " + data->currentName + " base "
    1247           2 :                    + baseName + " is unpublished"));
    1248           2 :               YYERROR;
    1249             :           }
    1250             :       }
    1251         998 :       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         998 :                           $2, baseName, baseEnt)))).
    1257         499 :           second)
    1258             :       {
    1259           0 :           error(@4, yyscanner, "multiple entities named " + data->currentName);
    1260           0 :           YYERROR;
    1261         499 :       }
    1262             :   }
    1263             :  '{' structMembers '}' ';'
    1264             :   {
    1265         497 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1266         497 :       unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
    1267             :       unoidl::detail::SourceProviderExceptionTypeEntityPad * pad =
    1268             :           dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
    1269         497 :               ent->pad.get());
    1270             :       assert(pad != 0);
    1271        1988 :       ent->entity = new unoidl::ExceptionTypeEntity(
    1272        1988 :           pad->isPublished(), pad->baseName, pad->members, annotations($1));
    1273         497 :       ent->pad.clear();
    1274         497 :       clearCurrentState(data);
    1275             :   }
    1276             : ;
    1277             : 
    1278             : structMembers:
    1279             :   structMembers structMember
    1280             : | /* empty */
    1281             : ;
    1282             : 
    1283             : structMember:
    1284             :   deprecated_opt type identifier ';'
    1285             :   {
    1286        2785 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1287        2785 :       unoidl::detail::SourceProviderType t(*$2);
    1288        2785 :       delete $2;
    1289        5560 :       OUString id(convertName($3));
    1290        2785 :       switch (t.type) {
    1291             :       case unoidl::detail::SourceProviderType::TYPE_VOID:
    1292             :       case unoidl::detail::SourceProviderType::TYPE_EXCEPTION:
    1293             :           error(
    1294           4 :               @2, yyscanner,
    1295           8 :               ("illegal struct/exception type " + data->currentName
    1296           8 :                + " direct member " + id + " type"));
    1297           4 :           YYERROR;
    1298             :           break;
    1299             :       default:
    1300        2781 :           break;
    1301             :       }
    1302        8404 :       if (t.type != unoidl::detail::SourceProviderType::TYPE_PARAMETER
    1303       11063 :           && t.getName() == data->currentName) // no need to worry about typedef
    1304             :       {
    1305             :           error(
    1306           2 :               @2, yyscanner,
    1307           4 :               ("struct/exception type " + data->currentName + " direct member "
    1308           4 :                + id + " has same type as the type itself"));
    1309           2 :           YYERROR;
    1310             :       }
    1311        2779 :       if (checkInstantiatedPolymorphicStructTypeArgument(t, data->currentName))
    1312             :       {
    1313             :           error(
    1314           4 :               @2, yyscanner,
    1315           8 :               ("struct/exception type " + data->currentName + " direct member "
    1316           8 :                + id
    1317           8 :                + (" has instantiated polymorphic struct type that uses the type"
    1318           8 :                   " itself as an argument")));
    1319           4 :           YYERROR;
    1320             :       }
    1321        2775 :       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        2775 :       unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
    1329             :       unoidl::detail::SourceProviderPlainStructTypeEntityPad * p1 =
    1330             :           dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
    1331        2775 :               ent->pad.get());
    1332        2775 :       if (p1 != 0) {
    1333       24093 :           for (std::vector<unoidl::PlainStructTypeEntity::Member>::iterator i(
    1334        2381 :                    p1->members.begin());
    1335       16062 :                i != p1->members.end(); ++i)
    1336             :           {
    1337        5650 :               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        2381 :           if (p1->baseEntity.is()) {
    1347         406 :               OUString baseName(p1->baseName);
    1348             :               for (rtl::Reference<unoidl::PlainStructTypeEntity> baseEnt(
    1349         406 :                        p1->baseEntity);;)
    1350             :               {
    1351         473 :                   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        3459 :                   for (std::vector<unoidl::PlainStructTypeEntity::Member>::const_iterator i(
    1361         473 :                            baseEnt->getDirectMembers().begin());
    1362        2306 :                        i != baseEnt->getDirectMembers().end(); ++i)
    1363             :                   {
    1364         680 :                       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         473 :                   baseName = baseEnt->getDirectBase();
    1375         473 :                   if (baseName.isEmpty()) {
    1376         406 :                       break;
    1377             :                   }
    1378             :                   unoidl::detail::SourceProviderEntity const * p;
    1379          67 :                   if (findEntity(
    1380          67 :                           @2, yyscanner, data, false, &baseName, &p, 0, 0)
    1381             :                       == FOUND_ERROR)
    1382             :                   {
    1383           0 :                       YYERROR;
    1384             :                   }
    1385         201 :                   if (p == 0 || !p->entity.is()
    1386         134 :                       || (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          67 :                       p->entity.get());
    1399         406 :               }
    1400             :           }
    1401             :           p1->members.push_back(
    1402             :               unoidl::PlainStructTypeEntity::Member(
    1403        2381 :                   id, t.getName(), annotations($1)));
    1404             :       } else {
    1405             :           unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
    1406             :               p2 = dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
    1407         394 :                   ent->pad.get());
    1408         394 :           if (p2 != 0) {
    1409         402 :               for (std::vector<unoidl::PolymorphicStructTypeTemplateEntity::Member>::iterator i(
    1410         128 :                        p2->members.begin());
    1411         268 :                    i != p2->members.end(); ++i)
    1412             :               {
    1413           6 :                   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         128 :                       annotations($1)));
    1428             :           } else {
    1429             :               unoidl::detail::SourceProviderExceptionTypeEntityPad * p3
    1430             :                   = dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
    1431         266 :                       ent->pad.get());
    1432             :               assert(p3 != 0);
    1433        1440 :               for (std::vector<unoidl::ExceptionTypeEntity::Member>::iterator i(
    1434         266 :                        p3->members.begin());
    1435         960 :                    i != p3->members.end(); ++i)
    1436             :               {
    1437         214 :                   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         266 :               if (p3->baseEntity.is()) {
    1447         256 :                   OUString baseName(p3->baseName);
    1448             :                   for (rtl::Reference<unoidl::ExceptionTypeEntity> baseEnt(
    1449         256 :                            p3->baseEntity);;)
    1450             :                   {
    1451         436 :                       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        3297 :                       for (std::vector<unoidl::ExceptionTypeEntity::Member>::const_iterator i(
    1461         436 :                                baseEnt->getDirectMembers().begin());
    1462        2198 :                            i != baseEnt->getDirectMembers().end(); ++i)
    1463             :                       {
    1464         663 :                           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         436 :                       baseName = baseEnt->getDirectBase();
    1475         436 :                       if (baseName.isEmpty()) {
    1476         256 :                           break;
    1477             :                       }
    1478             :                       unoidl::detail::SourceProviderEntity const * p;
    1479         180 :                       if (findEntity(
    1480         180 :                               @2, yyscanner, data, false, &baseName, &p, 0, 0)
    1481             :                           == FOUND_ERROR)
    1482             :                       {
    1483           0 :                           YYERROR;
    1484             :                       }
    1485         540 :                       if (p == 0 || !p->entity.is()
    1486         360 :                           || (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         180 :                           p->entity.get());
    1499         256 :                   }
    1500             :               }
    1501             :               p3->members.push_back(
    1502             :                   unoidl::ExceptionTypeEntity::Member(
    1503         266 :                       id, t.getName(), annotations($1)));
    1504             :           }
    1505        2775 :       }
    1506             :   }
    1507             : ;
    1508             : 
    1509             : interfaceDefn:
    1510             :   deprecated_opt published_opt TOK_INTERFACE identifier singleInheritance_opt
    1511             :   {
    1512        3699 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1513        3699 :       data->publishedContext = $2;
    1514        3699 :       convertToCurrentName(data, $4);
    1515        3699 :       OUString baseName;
    1516        7390 :       rtl::Reference<unoidl::InterfaceTypeEntity> baseEnt;
    1517        3699 :       if ($5 != 0) {
    1518        1533 :           baseName = convertName($5);
    1519             :           unoidl::detail::SourceProviderEntity const * p;
    1520        1533 :           if (findEntity(@5, yyscanner, data, true, &baseName, &p, 0, 0)
    1521             :               == FOUND_ERROR)
    1522             :           {
    1523           8 :               YYERROR;
    1524             :           }
    1525        4591 :           if (p == 0 || !p->entity.is()
    1526        3060 :               || p->entity->getSort() != unoidl::Entity::SORT_INTERFACE_TYPE)
    1527             :           {
    1528             :               error(
    1529             :                   @5, yyscanner,
    1530           4 :                   ("interface type " + data->currentName + " direct base "
    1531           4 :                    + baseName
    1532           2 :                    + " does not resolve to an existing interface type"));
    1533           2 :               YYERROR;
    1534             :           }
    1535        1529 :           baseEnt = static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get());
    1536        1529 :           if ($2 && !baseEnt->isPublished()) {
    1537             :               error(
    1538             :                   @5, yyscanner,
    1539           4 :                   ("published interface type " + data->currentName
    1540           2 :                    + " direct base " + baseName + " is unpublished"));
    1541           2 :               YYERROR;
    1542             :           }
    1543             :       }
    1544             :       std::map<OUString, unoidl::detail::SourceProviderEntity>::iterator i(
    1545        3693 :           data->entities.find(data->currentName));
    1546        3693 :       if (i != data->entities.end()) {
    1547         242 :           switch (i->second.kind) {
    1548             :           case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
    1549           6 :               break;
    1550             :           case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
    1551         236 :               if (!$2) {
    1552             :                   error(
    1553           2 :                       @4, yyscanner,
    1554           4 :                       ("unpublished interface type " + data->currentName
    1555           4 :                        + " has been declared published"));
    1556           2 :                   YYERROR;
    1557             :               }
    1558         234 :               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        3691 :               $2, baseEnt.is()));
    1570       13237 :       if (baseEnt.is()
    1571       10436 :           && !pad->addDirectBase(
    1572        1527 :               @4, yyscanner, data,
    1573             :               unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
    1574             :                   baseName, baseEnt, std::vector<OUString>()),
    1575        8272 :               false))
    1576             :       {
    1577           0 :           YYERROR;
    1578             :       }
    1579        7382 :       data->entities[data->currentName] = unoidl::detail::SourceProviderEntity(
    1580       14764 :           pad.get());
    1581             :   }
    1582             :   '{' interfaceMembers '}' ';'
    1583             :   {
    1584        3587 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1585        3587 :       unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
    1586             :       unoidl::detail::SourceProviderInterfaceTypeEntityPad * pad =
    1587             :           dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
    1588        3587 :               ent->pad.get());
    1589             :       assert(pad != 0);
    1590        7174 :       if (pad->directMandatoryBases.empty()
    1591        3587 :           && data->currentName != "com.sun.star.uno.XInterface")
    1592             :       {
    1593         455 :           OUString base(".com.sun.star.uno.XInterface");
    1594             :           unoidl::detail::SourceProviderEntity const * p;
    1595         455 :           if (findEntity(@4, yyscanner, data, true, &base, &p, 0, 0)
    1596             :               == FOUND_ERROR)
    1597             :           {
    1598           0 :               YYERROR;
    1599             :           }
    1600        1365 :           if (p == 0 || !p->entity.is()
    1601         910 :               || 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         910 :           if (!pad->addDirectBase(
    1611         455 :                   @3, yyscanner, data,
    1612             :                   unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
    1613             :                       base,
    1614             :                       static_cast<unoidl::InterfaceTypeEntity *>(
    1615         455 :                           p->entity.get()),
    1616             :                       std::vector<OUString>()),
    1617        1820 :                   false))
    1618             :           {
    1619           0 :               YYERROR;
    1620         455 :           }
    1621             :       }
    1622        3587 :       std::vector<unoidl::AnnotatedReference> mbases;
    1623       21774 :       for (std::vector<unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase>::const_iterator
    1624        3587 :                i(pad->directMandatoryBases.begin());
    1625       14516 :            i != pad->directMandatoryBases.end(); ++i)
    1626             :       {
    1627        3671 :           mbases.push_back(unoidl::AnnotatedReference(i->name, i->annotations));
    1628             :       }
    1629        7174 :       std::vector<unoidl::AnnotatedReference> obases;
    1630       10971 :       for (std::vector<unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase>::const_iterator
    1631        3587 :                i(pad->directOptionalBases.begin());
    1632        7314 :            i != pad->directOptionalBases.end(); ++i)
    1633             :       {
    1634          70 :           obases.push_back(unoidl::AnnotatedReference(i->name, i->annotations));
    1635             :       }
    1636       14348 :       ent->entity = new unoidl::InterfaceTypeEntity(
    1637        3587 :           pad->isPublished(), mbases, obases, pad->directAttributes,
    1638       10761 :           pad->directMethods, annotations($1));
    1639        3587 :       ent->pad.clear();
    1640        7174 :       clearCurrentState(data);
    1641             :   }
    1642             : ;
    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        1839 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1659        1839 :       OUString name(convertName($4));
    1660             :       rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
    1661             :           getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
    1662        3632 :               data));
    1663        1839 :       if (pad->singleBase) {
    1664             :           error(
    1665           0 :               @3, yyscanner,
    1666           0 :               "single-inheritance interface cannot have additional bases");
    1667           0 :           YYERROR;
    1668             :       }
    1669        1839 :       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        1839 :       bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
    1676        3632 :       OUString orgName(name);
    1677             :       unoidl::detail::SourceProviderEntity const * p;
    1678        1839 :       bool typedefed = false;
    1679        1839 :       if (findEntity(@4, yyscanner, data, true, &name, &p, &typedefed, 0)
    1680             :           == FOUND_ERROR)
    1681             :       {
    1682           4 :           YYERROR;
    1683             :       }
    1684        5505 :       if (p == 0 || !p->entity.is()
    1685        3670 :           || 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        1835 :       if (typedefed) {
    1694             :           error(
    1695           4 :               @4, yyscanner,
    1696           8 :               ("interface type " + data->currentName + " direct base " + orgName
    1697           8 :                + " is a typedef"));
    1698           4 :           YYERROR;
    1699             :       }
    1700             :       rtl::Reference<unoidl::InterfaceTypeEntity> ent(
    1701        3624 :           static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get()));
    1702        1831 :       if (data->publishedContext && !ent->isPublished()) {
    1703             :           error(
    1704           4 :               @4, yyscanner,
    1705           8 :               ("published interface type " + data->currentName + " direct base "
    1706           8 :                + name + " is unpublished"));
    1707           4 :           YYERROR;
    1708             :       }
    1709        3654 :       if (!pad->addDirectBase(
    1710        1827 :               @4, yyscanner, data,
    1711             :               unoidl::detail::SourceProviderInterfaceTypeEntityPad::DirectBase(
    1712        1827 :                   name, ent, annotations($1)),
    1713        7308 :               opt))
    1714             :       {
    1715          34 :           YYERROR;
    1716        1793 :       }
    1717             :   }
    1718             : ;
    1719             : 
    1720             : interfaceAttribute:
    1721             :   deprecated_opt flagSection type identifier
    1722             :   {
    1723        1398 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1724        1398 :       unoidl::detail::SourceProviderType t(*$3);
    1725        1398 :       delete $3;
    1726        2780 :       OUString id(convertName($4));
    1727        1398 :       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        2796 :       if (($2
    1734        1398 :            & ~(unoidl::detail::FLAG_ATTRIBUTE | unoidl::detail::FLAG_BOUND
    1735             :                | unoidl::detail::FLAG_READONLY))
    1736             :           != 0)
    1737             :       {
    1738             :           error(
    1739          14 :               @2, yyscanner,
    1740             :               ("interface attribute can only be flagged as [attribute,"
    1741          28 :                " optional]"));
    1742          14 :           YYERROR;
    1743             :       }
    1744        1384 :       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        1384 :           break;
    1755             :       }
    1756             :       rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad> pad(
    1757             :           getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
    1758        1384 :               data));
    1759        1384 :       if (!pad->addDirectMember(@4, yyscanner, data, id)) {
    1760           2 :           YYERROR;
    1761             :       }
    1762        1382 :       pad->directAttributes.push_back(
    1763             :           unoidl::InterfaceTypeEntity::Attribute(
    1764        1382 :               id, t.getName(), ($2 & unoidl::detail::FLAG_BOUND) != 0,
    1765        1382 :               ($2 & unoidl::detail::FLAG_READONLY) != 0,
    1766             :               std::vector<OUString>(), std::vector<OUString>(),
    1767        6910 :               annotations($1)));
    1768             :   }
    1769             :   attributeAccessDecls_opt ';'
    1770             : ;
    1771             : 
    1772             : attributeAccessDecls_opt:
    1773             :   '{' attributeAccessDecls '}'
    1774             : | /* empty */
    1775             : ;
    1776             : 
    1777             : attributeAccessDecls:
    1778             :   attributeAccessDecls attributeAccessDecl
    1779             :   {
    1780         234 :       if (($1 & $2) != 0) {
    1781             :           error(
    1782           2 :               @2, yyscanner, "duplicate get/set attribute access declaration");
    1783           2 :           YYERROR;
    1784             :       }
    1785         232 :       $$ = unoidl::detail::SourceProviderAccessDecls($1 | $2);
    1786             :   }
    1787         160 : | /* empty */ { $$ = unoidl::detail::SourceProviderAccessDecls(0); }
    1788             : ;
    1789             : 
    1790             : attributeAccessDecl:
    1791             :   TOK_GET exceptionSpec ';'
    1792             :   {
    1793         112 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1794             :       rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
    1795             :           pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
    1796         112 :               data));
    1797             :       assert(!pad->directAttributes.empty());
    1798         112 :       pad->directAttributes.back().getExceptions = *$2;
    1799         112 :       delete $2;
    1800         112 :       $$ = unoidl::detail::ACCESS_DECL_GET;
    1801             :   }
    1802             : | TOK_SET exceptionSpec ';'
    1803             :   {
    1804         124 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1805             :       rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
    1806             :           pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
    1807         124 :               data));
    1808             :       assert(!pad->directAttributes.empty());
    1809         124 :       pad->directAttributes.back().setExceptions = *$2;
    1810         124 :       delete $2;
    1811         124 :       if (pad->directAttributes.back().readOnly) {
    1812             :           error(
    1813           2 :               @1, yyscanner,
    1814           4 :               ("interface type " + data->currentName
    1815           4 :                + " direct read-only attribute "
    1816           6 :                + pad->directAttributes.back().name
    1817           4 :                + " cannot have set access declaration"));
    1818           2 :           YYERROR;
    1819             :       }
    1820         122 :       $$ = unoidl::detail::ACCESS_DECL_SET;
    1821             :   }
    1822             : ;
    1823             : 
    1824             : interfaceMethod:
    1825             :   deprecated_opt type identifier
    1826             :   {
    1827       10631 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1828       10631 :       unoidl::detail::SourceProviderType t(*$2);
    1829       10631 :       delete $2;
    1830       21254 :       OUString id(convertName($3));
    1831       10631 :       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       21254 :               data));
    1841       10631 :       if (!pad->addDirectMember(@3, yyscanner, data, id)) {
    1842           8 :           YYERROR;
    1843             :       }
    1844       10623 :       pad->directMethods.push_back(
    1845             :           unoidl::InterfaceTypeEntity::Method(
    1846             :               id, t.getName(),
    1847             :               std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>(),
    1848       31869 :               std::vector<OUString>(), annotations($1)));
    1849             :   }
    1850             :   '(' methodParams_opt ')' exceptionSpec_opt ';'
    1851             :   {
    1852       10613 :       if ($8 != 0) {
    1853             :           unoidl::detail::SourceProviderScannerData * data
    1854        3258 :               = yyget_extra(yyscanner);
    1855             :           rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
    1856             :               pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
    1857        3258 :                   data));
    1858             :           assert(!pad->directMethods.empty());
    1859        3258 :           pad->directMethods.back().exceptions = *$8;
    1860        3258 :           delete $8;
    1861             :       }
    1862             :   }
    1863             : ;
    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       10758 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1879       10758 :       unoidl::detail::SourceProviderType t(*$4);
    1880       10758 :       delete $4;
    1881       21516 :       OUString id(convertName($5));
    1882             :       rtl::Reference<unoidl::detail::SourceProviderInterfaceTypeEntityPad>
    1883             :           pad(getCurrentPad<unoidl::detail::SourceProviderInterfaceTypeEntityPad>(
    1884       21516 :               data));
    1885             :       assert(!pad->directMethods.empty());
    1886       10758 :       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       10758 :           break;
    1898             :       }
    1899       66279 :       for (std::vector<unoidl::InterfaceTypeEntity::Method::Parameter>::iterator
    1900       10758 :                i(pad->directMethods.back().parameters.begin());
    1901       44186 :            i != pad->directMethods.back().parameters.end(); ++i)
    1902             :       {
    1903       11335 :           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       10758 :       pad->directMethods.back().parameters.push_back(
    1913       32274 :           unoidl::InterfaceTypeEntity::Method::Parameter(id, t.getName(), $2));
    1914             :   }
    1915             : ;
    1916             : 
    1917             : direction:
    1918       11145 :   TOK_IN { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN; }
    1919             : | TOK_OUT
    1920         144 :   { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_OUT; }
    1921             : | TOK_INOUT
    1922          74 :   { $$ = unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN_OUT; }
    1923             : ;
    1924             : 
    1925             : typedefDefn:
    1926             :   deprecated_opt published_opt TOK_TYPEDEF type identifier ';'
    1927             :   {
    1928         144 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    1929         144 :       data->publishedContext = $2;
    1930         144 :       unoidl::detail::SourceProviderType t(*$4);
    1931         144 :       delete $4;
    1932         276 :       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         144 :       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           6 :           error(@4, yyscanner, "bad typedef type");
    1943           6 :           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          46 :           if ($2) {
    1949          12 :               bool unpub = false;
    1950          12 :               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          12 :                       = !(t.entity->entity.is()
    1962             :                           ? static_cast<unoidl::PublishableEntity *>(
    1963          12 :                               t.entity->entity.get())->isPublished()
    1964          24 :                           : t.entity->pad->isPublished());
    1965          12 :                   break;
    1966             :               }
    1967          12 :               if (unpub) {
    1968             :                   error(
    1969           6 :                       @4, yyscanner,
    1970          12 :                       "published typedef " + name + " type is unpublished");
    1971           6 :                   YYERROR;
    1972             :               }
    1973             :           }
    1974          40 :           break;
    1975             :       case unoidl::detail::SourceProviderType::TYPE_PARAMETER:
    1976             :           assert(false && "this cannot happen");
    1977             :       default:
    1978          92 :           break;
    1979             :       }
    1980         264 :       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         264 :                           $2, t.getName(), annotations($1))))).
    1987         132 :           second)
    1988             :       {
    1989           0 :           error(@5, yyscanner, "multiple entities named " + name);
    1990           0 :           YYERROR;
    1991             :       }
    1992         264 :       clearCurrentState(data);
    1993             :   }
    1994             : ;
    1995             : 
    1996             : constantGroupDefn:
    1997             :   deprecated_opt published_opt TOK_CONSTANTS identifier
    1998             :   {
    1999        1519 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2000        1519 :       data->publishedContext = $2;
    2001        1519 :       convertToCurrentName(data, $4);
    2002        3038 :       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        3038 :                           $2)))).
    2008        1519 :           second)
    2009             :       {
    2010           0 :           error(@4, yyscanner, "multiple entities named " + data->currentName);
    2011           0 :           YYERROR;
    2012             :       }
    2013             :   }
    2014             :   '{' constants '}' ';'
    2015             :   {
    2016        1421 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2017        1421 :       unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
    2018             :       unoidl::detail::SourceProviderConstantGroupEntityPad * pad =
    2019             :           dynamic_cast<unoidl::detail::SourceProviderConstantGroupEntityPad *>(
    2020        1421 :               ent->pad.get());
    2021             :       assert(pad != 0);
    2022        5684 :       ent->entity = new unoidl::ConstantGroupEntity(
    2023        5684 :           pad->isPublished(), pad->members, annotations($1));
    2024        1421 :       ent->pad.clear();
    2025        1421 :       clearCurrentState(data);
    2026             :   }
    2027             : ;
    2028             : 
    2029             : constants:
    2030             :   constants constant
    2031             : | /* empty */
    2032             : ;
    2033             : 
    2034             : constant:
    2035             :   deprecated_opt TOK_CONST type identifier '=' expr ';'
    2036             :   {
    2037       13906 :       OUString id(convertName($4));
    2038       13906 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2039             :       rtl::Reference<unoidl::detail::SourceProviderConstantGroupEntityPad> pad(
    2040             :           getCurrentPad<unoidl::detail::SourceProviderConstantGroupEntityPad>(
    2041       27738 :               data));
    2042       27738 :       unoidl::detail::SourceProviderType t(*$3);
    2043       13906 :       delete $3;
    2044       13906 :       unoidl::ConstantValue v(false); // dummy value
    2045       13906 :       switch (t.type) {
    2046             :       case unoidl::detail::SourceProviderType::TYPE_BOOLEAN:
    2047           2 :           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           2 :           v = unoidl::ConstantValue($6.bval);
    2055           2 :           break;
    2056             :       case unoidl::detail::SourceProviderType::TYPE_BYTE:
    2057         287 :           switch ($6.type) {
    2058             :           case unoidl::detail::SourceProviderExpr::TYPE_INT:
    2059          15 :               if ($6.ival < SAL_MIN_INT8 || $6.ival > SAL_MAX_INT8) {
    2060             :                   error(
    2061           6 :                       @6, yyscanner,
    2062          12 :                       ("out-of-range byte-typed constant " + data->currentName
    2063          24 :                        + "." + id + " value " + OUString::number($6.ival)));
    2064           6 :                   YYERROR;
    2065             :               }
    2066           9 :               v = unoidl::ConstantValue(static_cast<sal_Int8>($6.ival));
    2067           9 :               break;
    2068             :           case unoidl::detail::SourceProviderExpr::TYPE_UINT:
    2069         272 :               if ($6.uval > SAL_MAX_INT8) {
    2070             :                   error(
    2071           8 :                       @6, yyscanner,
    2072          16 :                       ("out-of-range byte-typed constant " + data->currentName
    2073          32 :                        + "." + id + " value " + OUString::number($6.uval)));
    2074           8 :                   YYERROR;
    2075             :               }
    2076         264 :               v = unoidl::ConstantValue(static_cast<sal_Int8>($6.uval));
    2077         264 :               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         273 :           break;
    2087             :       case unoidl::detail::SourceProviderType::TYPE_SHORT:
    2088        3262 :           switch ($6.type) {
    2089             :           case unoidl::detail::SourceProviderExpr::TYPE_INT:
    2090          33 :               if ($6.ival < SAL_MIN_INT16 || $6.ival > SAL_MAX_INT16) {
    2091             :                   error(
    2092           6 :                       @6, yyscanner,
    2093          12 :                       ("out-of-range short-typed constant " + data->currentName
    2094          24 :                        + "." + id + " value " + OUString::number($6.ival)));
    2095           6 :                   YYERROR;
    2096             :               }
    2097          27 :               v = unoidl::ConstantValue(static_cast<sal_Int16>($6.ival));
    2098          27 :               break;
    2099             :           case unoidl::detail::SourceProviderExpr::TYPE_UINT:
    2100        3229 :               if ($6.uval > SAL_MAX_INT16) {
    2101             :                   error(
    2102           6 :                       @6, yyscanner,
    2103          12 :                       ("out-of-range short-typed constant " + data->currentName
    2104          24 :                        + "." + id + " value " + OUString::number($6.uval)));
    2105           6 :                   YYERROR;
    2106             :               }
    2107        3223 :               v = unoidl::ConstantValue(static_cast<sal_Int16>($6.uval));
    2108        3223 :               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        3250 :           break;
    2118             :       case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
    2119          26 :           switch ($6.type) {
    2120             :           case unoidl::detail::SourceProviderExpr::TYPE_INT:
    2121           6 :               if ($6.ival < 0 || $6.ival > SAL_MAX_UINT16) {
    2122             :                   error(
    2123           6 :                       @6, yyscanner,
    2124             :                       ("out-of-range unsigned-short-typed constant "
    2125          12 :                        + data->currentName + "." + id + " value "
    2126          24 :                        + OUString::number($6.ival)));
    2127           6 :                   YYERROR;
    2128             :               }
    2129           0 :               v = unoidl::ConstantValue(static_cast<sal_uInt16>($6.ival));
    2130           0 :               break;
    2131             :           case unoidl::detail::SourceProviderExpr::TYPE_UINT:
    2132          20 :               if ($6.uval > SAL_MAX_UINT16) {
    2133             :                   error(
    2134           6 :                       @6, yyscanner,
    2135             :                       ("out-of-range unsigned-short-typed constant "
    2136          12 :                        + data->currentName + "." + id + " value "
    2137          24 :                        + OUString::number($6.uval)));
    2138           6 :                   YYERROR;
    2139             :               }
    2140          14 :               v = unoidl::ConstantValue(static_cast<sal_uInt16>($6.uval));
    2141          14 :               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          14 :           break;
    2151             :       case unoidl::detail::SourceProviderType::TYPE_LONG:
    2152       10159 :           switch ($6.type) {
    2153             :           case unoidl::detail::SourceProviderExpr::TYPE_INT:
    2154         637 :               if ($6.ival < SAL_MIN_INT32 || $6.ival > SAL_MAX_INT32) {
    2155             :                   error(
    2156           6 :                       @6, yyscanner,
    2157          12 :                       ("out-of-range long-typed constant " + data->currentName
    2158          24 :                        + "." + id + " value " + OUString::number($6.ival)));
    2159           6 :                   YYERROR;
    2160             :               }
    2161         631 :               v = unoidl::ConstantValue(static_cast<sal_Int32>($6.ival));
    2162         631 :               break;
    2163             :           case unoidl::detail::SourceProviderExpr::TYPE_UINT:
    2164        9522 :               if ($6.uval > SAL_MAX_INT32) {
    2165             :                   error(
    2166           6 :                       @6, yyscanner,
    2167          12 :                       ("out-of-range long-typed constant " + data->currentName
    2168          24 :                        + "." + id + " value " + OUString::number($6.uval)));
    2169           6 :                   YYERROR;
    2170             :               }
    2171        9516 :               v = unoidl::ConstantValue(static_cast<sal_Int32>($6.uval));
    2172        9516 :               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       10147 :           break;
    2182             :       case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
    2183          26 :           switch ($6.type) {
    2184             :           case unoidl::detail::SourceProviderExpr::TYPE_INT:
    2185           6 :               if ($6.ival < 0 || $6.ival > SAL_MAX_UINT32) {
    2186             :                   error(
    2187           6 :                       @6, yyscanner,
    2188             :                       ("out-of-range unsigned-long-typed constant "
    2189          12 :                        + data->currentName + "." + id + " value "
    2190          24 :                        + OUString::number($6.ival)));
    2191           6 :                   YYERROR;
    2192             :               }
    2193           0 :               v = unoidl::ConstantValue(static_cast<sal_uInt32>($6.ival));
    2194           0 :               break;
    2195             :           case unoidl::detail::SourceProviderExpr::TYPE_UINT:
    2196          20 :               if ($6.uval > SAL_MAX_UINT32) {
    2197             :                   error(
    2198           6 :                       @6, yyscanner,
    2199             :                       ("out-of-range unsigned-long-typed constant "
    2200          12 :                        + data->currentName + "." + id + " value "
    2201          24 :                        + OUString::number($6.uval)));
    2202           6 :                   YYERROR;
    2203             :               }
    2204          14 :               v = unoidl::ConstantValue(static_cast<sal_uInt32>($6.uval));
    2205          14 :               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          14 :           break;
    2215             :       case unoidl::detail::SourceProviderType::TYPE_HYPER:
    2216          80 :           switch ($6.type) {
    2217             :           case unoidl::detail::SourceProviderExpr::TYPE_INT:
    2218           7 :               v = unoidl::ConstantValue($6.ival);
    2219           7 :               break;
    2220             :           case unoidl::detail::SourceProviderExpr::TYPE_UINT:
    2221          73 :               if ($6.uval > SAL_MAX_INT64) {
    2222             :                   error(
    2223           6 :                       @6, yyscanner,
    2224          12 :                       ("out-of-range hyper-typed constant " + data->currentName
    2225          24 :                        + "." + id + " value " + OUString::number($6.uval)));
    2226           6 :                   YYERROR;
    2227             :               }
    2228          67 :               v = unoidl::ConstantValue(static_cast<sal_Int64>($6.uval));
    2229          67 :               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          74 :           break;
    2239             :       case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
    2240          20 :           switch ($6.type) {
    2241             :           case unoidl::detail::SourceProviderExpr::TYPE_INT:
    2242           6 :               if ($6.ival < 0) {
    2243             :                   error(
    2244           6 :                       @6, yyscanner,
    2245             :                       ("out-of-range unsigned-hyper-typed constant "
    2246          12 :                        + data->currentName + "." + id + " value "
    2247          24 :                        + OUString::number($6.ival)));
    2248           6 :                   YYERROR;
    2249             :               }
    2250           0 :               v = unoidl::ConstantValue(static_cast<sal_uInt64>($6.ival));
    2251           0 :               break;
    2252             :           case unoidl::detail::SourceProviderExpr::TYPE_UINT:
    2253          14 :               v = unoidl::ConstantValue($6.uval);
    2254          14 :               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          14 :           break;
    2264             :       case unoidl::detail::SourceProviderType::TYPE_FLOAT:
    2265          42 :           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          20 :               v = unoidl::ConstantValue(static_cast<float>($6.uval));
    2278          20 :               break;
    2279             :           case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
    2280          22 :               v = unoidl::ConstantValue(static_cast<float>($6.fval));
    2281          22 :               break;
    2282             :           }
    2283          42 :           break;
    2284             :       case unoidl::detail::SourceProviderType::TYPE_DOUBLE:
    2285           2 :           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           2 :               v = unoidl::ConstantValue($6.fval);
    2301           2 :               break;
    2302             :           }
    2303           2 :           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       13832 :       pad->members.push_back(
    2312       41496 :           unoidl::ConstantGroupEntity::Member(id, v, annotations($1)));
    2313             :   }
    2314             : ;
    2315             : 
    2316             : singleInterfaceBasedServiceDefn:
    2317             :   deprecated_opt published_opt TOK_SERVICE identifier singleInheritance
    2318             :   {
    2319         687 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2320         687 :       data->publishedContext = $2;
    2321         687 :       convertToCurrentName(data, $4);
    2322         687 :       OUString base(convertName($5));
    2323             :       unoidl::detail::SourceProviderEntity const * p;
    2324         687 :       if (findEntity(@5, yyscanner, data, false, &base, &p, 0, 0)
    2325             :           == FOUND_ERROR)
    2326             :       {
    2327           0 :           YYERROR;
    2328             :       }
    2329         687 :       bool ifcBase = false;
    2330         687 :       bool pubBase = false;
    2331         687 :       if (p != 0) {
    2332         687 :           switch (p->kind) {
    2333             :           case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
    2334          15 :               ifcBase = true;
    2335          15 :               pubBase = false;
    2336          15 :               break;
    2337             :           case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
    2338          20 :               ifcBase = true;
    2339          20 :               pubBase = true;
    2340          20 :               break;
    2341             :           default:
    2342        1304 :               if (p->entity.is()
    2343         652 :                   && (p->entity->getSort()
    2344             :                       == unoidl::Entity::SORT_INTERFACE_TYPE))
    2345             :               {
    2346         652 :                   ifcBase = true;
    2347             :                   pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
    2348         652 :                       p->entity.get())->isPublished();
    2349             :               }
    2350         652 :               break;
    2351             :           }
    2352             :       }
    2353         687 :       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         687 :       if ($2 && !pubBase) {
    2361             :           error(
    2362             :               @5, yyscanner,
    2363           4 :               ("published single-interface--based service " + data->currentName
    2364           2 :                + " base " + base + " is unpublished"));
    2365           2 :           YYERROR;
    2366             :       }
    2367        1370 :       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        1370 :                           $2, base)))).
    2373         685 :           second)
    2374             :       {
    2375           0 :           error(@4, yyscanner, "multiple entities named " + data->currentName);
    2376           0 :           YYERROR;
    2377         685 :       }
    2378             :   }
    2379             :   ctors_opt ';'
    2380             :   {
    2381         663 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2382         663 :       unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
    2383             :       unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad * pad =
    2384             :           dynamic_cast<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad *>(
    2385         663 :               ent->pad.get());
    2386             :       assert(pad != 0);
    2387         663 :       std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor> ctors;
    2388         663 :       if ($7) {
    2389        1956 :           for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor>::iterator
    2390         308 :                    i(pad->constructors.begin());
    2391        1304 :                i != pad->constructors.end(); ++i)
    2392             :           {
    2393         344 :               std::vector<unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter> parms;
    2394        2721 :               for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter>::iterator
    2395         344 :                        j(i->parameters.begin());
    2396        1814 :                    j != i->parameters.end(); ++j)
    2397             :               {
    2398             :                   parms.push_back(
    2399             :                       unoidl::SingleInterfaceBasedServiceEntity::Constructor::Parameter(
    2400         563 :                           j->name, j->type.getName(), j->rest));
    2401             :               }
    2402             :               ctors.push_back(
    2403             :                   unoidl::SingleInterfaceBasedServiceEntity::Constructor(
    2404         344 :                       i->name, parms, i->exceptions, i->annotations));
    2405         344 :           }
    2406             :       } else {
    2407             :           assert(pad->constructors.empty());
    2408             :           ctors.push_back(
    2409         355 :               unoidl::SingleInterfaceBasedServiceEntity::Constructor());
    2410             :       }
    2411        2652 :       ent->entity = new unoidl::SingleInterfaceBasedServiceEntity(
    2412        2652 :           pad->isPublished(), pad->base, ctors, annotations($1));
    2413         663 :       ent->pad.clear();
    2414         663 :       clearCurrentState(data);
    2415             :   }
    2416             : ;
    2417             : 
    2418             : ctors_opt:
    2419         308 :   '{' ctors '}' { $$ = true; }
    2420         355 : | /* empty */ { $$ = false; }
    2421             : ;
    2422             : 
    2423             : ctors:
    2424             :   ctors ctor
    2425             : | /* empty */
    2426             : ;
    2427             : 
    2428             : ctor:
    2429             :   deprecated_opt identifier
    2430             :   {
    2431         374 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2432         374 :       OUString id(convertName($2));
    2433             :       rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
    2434             :           pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
    2435         746 :                   data));
    2436        1374 :       for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor>::iterator
    2437         374 :                i(pad->constructors.begin());
    2438         916 :            i != pad->constructors.end(); ++i)
    2439             :       {
    2440          86 :           if (id == i->name) {
    2441             :               error(
    2442             :                   @2, yyscanner,
    2443           4 :                   ("single-interface--based service " + data->currentName
    2444           4 :                    + " constructor " + id
    2445           2 :                    + " has same identifier as another constructor"));
    2446           2 :               YYERROR;
    2447             :           }
    2448             :       }
    2449         372 :       pad->constructors.push_back(
    2450             :           unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor(
    2451        1116 :               id, annotations($1)));
    2452             :   }
    2453             :   '(' ctorParams_opt ')' exceptionSpec_opt ';'
    2454             :   {
    2455         358 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2456             :       rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
    2457             :           pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
    2458         358 :                   data));
    2459             :       assert(!pad->constructors.empty());
    2460         358 :       if ($7 != 0) {
    2461          48 :           pad->constructors.back().exceptions = *$7;
    2462          48 :           delete $7;
    2463             :       }
    2464        1308 :       for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor>::iterator
    2465         358 :                i(pad->constructors.begin());
    2466         872 :            i != pad->constructors.end() - 1; ++i)
    2467             :       {
    2468         168 :           if (i->parameters.size()
    2469          84 :               == pad->constructors.back().parameters.size())
    2470             :           {
    2471          22 :               bool same = true;
    2472         102 :               for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter>::iterator
    2473          22 :                        j(i->parameters.begin()),
    2474          22 :                        k(pad->constructors.back().parameters.begin());
    2475          68 :                    j != i->parameters.end(); ++j, ++k)
    2476             :               {
    2477          28 :                   if (!j->type.equals(k->type) || j->rest != k->rest) {
    2478          16 :                       same = false;
    2479          16 :                       break;
    2480             :                   }
    2481             :               }
    2482          22 :               if (same) {
    2483             :                   error(
    2484           6 :                       @2, yyscanner,
    2485          12 :                       ("single-interface--based service " + data->currentName
    2486          18 :                        + " constructor " + pad->constructors.back().name
    2487          12 :                        + " has similar paramete list to constructor "
    2488          18 :                        + i->name));
    2489          12 :                   YYERROR;
    2490             :               }
    2491             :           }
    2492         352 :       }
    2493             :   }
    2494             : ;
    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         595 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2510         595 :       unoidl::detail::SourceProviderType t(*$4);
    2511         595 :       delete $4;
    2512        1180 :       OUString id(convertName($6));
    2513             :       rtl::Reference<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>
    2514             :           pad(getCurrentPad<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad>(
    2515        1180 :               data));
    2516             :       assert(!pad->constructors.empty());
    2517         595 :       if ($2 != unoidl::InterfaceTypeEntity::Method::Parameter::DIRECTION_IN) {
    2518             :           error(
    2519           4 :               @4, yyscanner,
    2520           8 :               ("single-interface--based service " + data->currentName
    2521          12 :                + " constructor " + pad->constructors.back().name + " parameter "
    2522           8 :                + id + " direction must be [in]"));
    2523           4 :           YYERROR;
    2524             :       }
    2525         591 :       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         591 :           break;
    2537             :       }
    2538         591 :       if ($5) {
    2539          20 :           if (t.type != unoidl::detail::SourceProviderType::TYPE_ANY) {
    2540             :               error(
    2541           2 :                   @4, yyscanner,
    2542             :                   ("illegal single-interface--based service "
    2543           4 :                    + data->currentName + " constructor "
    2544           6 :                    + pad->constructors.back().name + " rest parameter " + id
    2545           4 :                    + " non-any type"));
    2546           2 :               YYERROR;
    2547             :           }
    2548          18 :           if (!pad->constructors.back().parameters.empty()) {
    2549             :               error(
    2550           2 :                   @5, yyscanner,
    2551           4 :                   ("single-interface--based service " + data->currentName
    2552           6 :                    + " constructor " + pad->constructors.back().name
    2553           4 :                    + " rest parameter " + id + " must be first parameter"));
    2554           2 :               YYERROR;
    2555             :           }
    2556        1142 :       } else if (!pad->constructors.back().parameters.empty()
    2557         571 :                  && pad->constructors.back().parameters.back().rest)
    2558             :       {
    2559             :           error(
    2560           2 :               @1, yyscanner,
    2561           4 :               ("single-interface--based service " + data->currentName
    2562           6 :                + " constructor " + pad->constructors.back().name
    2563           4 :                + " rest parameter must be last parameter"));
    2564           2 :           YYERROR;
    2565             :       }
    2566       14403 :       for (std::vector<unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter>::iterator
    2567         585 :                i(pad->constructors.back().parameters.begin());
    2568        9602 :            i != pad->constructors.back().parameters.end(); ++i)
    2569             :       {
    2570        4216 :           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         585 :       pad->constructors.back().parameters.push_back(
    2581             :           unoidl::detail::SourceProviderSingleInterfaceBasedServiceEntityPad::Constructor::Parameter(
    2582        1755 :               id, t, $5));
    2583             :   }
    2584             : ;
    2585             : 
    2586             : ellipsis_opt:
    2587          22 :   TOK_ELLIPSIS { $$ = true; }
    2588         573 : | /* empty */ { $$ = false; }
    2589             : 
    2590             : accumulationBasedServiceDefn:
    2591             :   deprecated_opt published_opt TOK_SERVICE identifier
    2592             :   {
    2593        1822 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2594        1822 :       data->publishedContext = $2;
    2595        1822 :       convertToCurrentName(data, $4);
    2596        3644 :       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        3644 :                           $2)))).
    2602        1822 :           second)
    2603             :       {
    2604           0 :           error(@4, yyscanner, "multiple entities named " + data->currentName);
    2605           0 :           YYERROR;
    2606             :       }
    2607             :   }
    2608             :   '{' serviceMembers '}' ';'
    2609             :   {
    2610        1804 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2611        1804 :       unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
    2612             :       unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad * pad =
    2613             :           dynamic_cast<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad *>(
    2614        1804 :               ent->pad.get());
    2615             :       assert(pad != 0);
    2616        7216 :       ent->entity = new unoidl::AccumulationBasedServiceEntity(
    2617        1804 :           pad->isPublished(), pad->directMandatoryBaseServices,
    2618             :           pad->directOptionalBaseServices, pad->directMandatoryBaseInterfaces,
    2619             :           pad->directOptionalBaseInterfaces, pad->directProperties,
    2620        5412 :           annotations($1));
    2621        1804 :       ent->pad.clear();
    2622        1804 :       clearCurrentState(data);
    2623             :   }
    2624             : ;
    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        1439 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2641        1439 :       OUString name(convertName($4));
    2642             :       rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad> pad(
    2643             :           getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
    2644        2872 :               data));
    2645        1439 :       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        1439 :       bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
    2652             :       unoidl::detail::SourceProviderEntity const * p;
    2653        1439 :       if (findEntity(@4, yyscanner, data, false, &name, &p, 0, 0)
    2654             :           == FOUND_ERROR)
    2655             :       {
    2656           0 :           YYERROR;
    2657             :       }
    2658        4317 :       if (p == 0 || !p->entity.is()
    2659        2878 :           || (p->entity->getSort()
    2660             :               != unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE))
    2661             :       {
    2662             :           error(
    2663           2 :               @4, yyscanner,
    2664           4 :               ("accumulation-based service " + data->currentName
    2665           4 :                + " direct base service " + name
    2666           4 :                + " does not resolve to an accumulation-based service"));
    2667           2 :           YYERROR;
    2668             :       }
    2669        1437 :       if (data->publishedContext
    2670        2705 :           && !static_cast<unoidl::AccumulationBasedServiceEntity *>(
    2671        1268 :               p->entity.get())->isPublished())
    2672             :       {
    2673             :           error(
    2674           4 :               @4, yyscanner,
    2675           8 :               ("published accumulation-based service " + data->currentName
    2676           8 :                + " direct base service " + name + " is unpublished"));
    2677           4 :           YYERROR;
    2678             :       }
    2679             :       std::vector<unoidl::AnnotatedReference> & v(
    2680             :           opt
    2681        1433 :           ? pad->directOptionalBaseServices : pad->directMandatoryBaseServices);
    2682        7629 :       for (std::vector<unoidl::AnnotatedReference>::iterator i(v.begin());
    2683        5086 :            i != v.end(); ++i)
    2684             :       {
    2685        1110 :           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        2866 :       v.push_back(unoidl::AnnotatedReference(name, annotations($1)));
    2694             :   }
    2695             : ;
    2696             : 
    2697             : serviceInterfaceBase:
    2698             :   deprecated_opt flagSection_opt TOK_INTERFACE name ';'
    2699             :   {
    2700        3092 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2701        3092 :       OUString name(convertName($4));
    2702             :       rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad> pad(
    2703             :           getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
    2704        6182 :               data));
    2705        3092 :       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        3092 :       bool opt = ($2 & unoidl::detail::FLAG_OPTIONAL) != 0;
    2712             :       unoidl::detail::SourceProviderEntity const * p;
    2713        3092 :       if (findEntity(@4, yyscanner, data, false, &name, &p, 0, 0)
    2714             :           == FOUND_ERROR)
    2715             :       {
    2716           0 :           YYERROR;
    2717             :       }
    2718        3092 :       bool ifcBase = false;
    2719        3092 :       bool pubBase = false;
    2720        3092 :       if (p != 0) {
    2721        3092 :           switch (p->kind) {
    2722             :           case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
    2723          52 :               ifcBase = true;
    2724          52 :               pubBase = false;
    2725          52 :               break;
    2726             :           case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
    2727         132 :               ifcBase = true;
    2728         132 :               pubBase = true;
    2729         132 :               break;
    2730             :           default:
    2731        5816 :               if (p->entity.is()
    2732        2908 :                   && (p->entity->getSort()
    2733             :                       == unoidl::Entity::SORT_INTERFACE_TYPE))
    2734             :               {
    2735        2908 :                   ifcBase = true;
    2736             :                   pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
    2737        2908 :                       p->entity.get())->isPublished();
    2738             :               }
    2739        2908 :               break;
    2740             :           }
    2741             :       }
    2742        3092 :       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        3092 :       if (data->publishedContext && !opt && !pubBase) {
    2751             :           error(
    2752           2 :               @4, yyscanner,
    2753           4 :               ("published accumulation-based service " + data->currentName
    2754           4 :                + " direct base interface " + name + " is unpublished"));
    2755           2 :           YYERROR;
    2756             :       }
    2757             :       std::vector<unoidl::AnnotatedReference> & v(
    2758             :           opt
    2759         540 :           ? pad->directOptionalBaseInterfaces
    2760        3630 :           : pad->directMandatoryBaseInterfaces);
    2761       22254 :       for (std::vector<unoidl::AnnotatedReference>::iterator i(v.begin());
    2762       14836 :            i != v.end(); ++i)
    2763             :       {
    2764        4328 :           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        6180 :       v.push_back(unoidl::AnnotatedReference(name, annotations($1)));
    2773             :   }
    2774             : ;
    2775             : 
    2776             : serviceProperty:
    2777             :   deprecated_opt flagSection type identifier ';'
    2778             :   {
    2779        5803 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2780        5803 :       unoidl::detail::SourceProviderType t(*$3);
    2781        5803 :       delete $3;
    2782       11606 :       OUString id(convertName($4));
    2783        5803 :       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       11606 :       if (($2
    2791        5803 :            & ~(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        5803 :       int att = 0;
    2808        5803 :       if (($2 & unoidl::detail::FLAG_BOUND) != 0) {
    2809           4 :           att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_BOUND;
    2810             :       }
    2811        5803 :       if (($2 & unoidl::detail::FLAG_CONSTRAINED) != 0) {
    2812           0 :           att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_CONSTRAINED;
    2813             :       }
    2814        5803 :       if (($2 & unoidl::detail::FLAG_MAYBEAMBIGUOUS) != 0) {
    2815           0 :           att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_AMBIGUOUS;
    2816             :       }
    2817        5803 :       if (($2 & unoidl::detail::FLAG_MAYBEDEFAULT) != 0) {
    2818           3 :           att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_DEFAULT;
    2819             :       }
    2820        5803 :       if (($2 & unoidl::detail::FLAG_MAYBEVOID) != 0) {
    2821         198 :           att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_MAYBE_VOID;
    2822             :       }
    2823        5803 :       if (($2 & unoidl::detail::FLAG_OPTIONAL) != 0) {
    2824        1947 :           att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_OPTIONAL;
    2825             :       }
    2826        5803 :       if (($2 & unoidl::detail::FLAG_READONLY) != 0) {
    2827         421 :           att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_READ_ONLY;
    2828             :       }
    2829        5803 :       if (($2 & unoidl::detail::FLAG_REMOVABLE) != 0) {
    2830           0 :           att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_REMOVABLE;
    2831             :       }
    2832        5803 :       if (($2 & unoidl::detail::FLAG_TRANSIENT) != 0) {
    2833          15 :           att |= unoidl::AccumulationBasedServiceEntity::Property::ATTRIBUTE_TRANSIENT;
    2834             :       }
    2835        5803 :       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        5803 :           break;
    2846             :       }
    2847             :       rtl::Reference<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>
    2848             :           pad(getCurrentPad<unoidl::detail::SourceProviderAccumulationBasedServiceEntityPad>(
    2849        5803 :                   data));
    2850      197841 :       for (std::vector<unoidl::AccumulationBasedServiceEntity::Property>::iterator
    2851        5803 :                i(pad->directProperties.begin());
    2852      131894 :            i != pad->directProperties.end(); ++i)
    2853             :       {
    2854       60144 :           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        5803 :       pad->directProperties.push_back(
    2863             :           unoidl::AccumulationBasedServiceEntity::Property(
    2864             :               id, t.getName(),
    2865             :               unoidl::AccumulationBasedServiceEntity::Property::Attributes(att),
    2866       17409 :               annotations($1)));
    2867             :   }
    2868             : ;
    2869             : 
    2870             : interfaceBasedSingletonDefn:
    2871             :   deprecated_opt published_opt TOK_SINGLETON identifier singleInheritance ';'
    2872             :   {
    2873         192 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2874         192 :       data->publishedContext = $2;
    2875         192 :       OUString name(convertToFullName(data, $4));
    2876         382 :       OUString base(convertName($5));
    2877             :       unoidl::detail::SourceProviderEntity const * p;
    2878         192 :       if (findEntity(@5, yyscanner, data, false, &base, &p, 0, 0)
    2879             :           == FOUND_ERROR)
    2880             :       {
    2881           0 :           YYERROR;
    2882             :       }
    2883         192 :       bool ifcBase = false;
    2884         192 :       bool pubBase = false;
    2885         192 :       if (p != 0) {
    2886         192 :           switch (p->kind) {
    2887             :           case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
    2888           2 :               ifcBase = true;
    2889           2 :               pubBase = false;
    2890           2 :               break;
    2891             :           case unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL:
    2892           2 :               ifcBase = true;
    2893           2 :               pubBase = true;
    2894           2 :               break;
    2895             :           default:
    2896         376 :               if (p->entity.is()
    2897         188 :                   && (p->entity->getSort()
    2898             :                       == unoidl::Entity::SORT_INTERFACE_TYPE))
    2899             :               {
    2900         188 :                   ifcBase = true;
    2901             :                   pubBase = static_cast<unoidl::InterfaceTypeEntity *>(
    2902         188 :                       p->entity.get())->isPublished();
    2903             :               }
    2904         188 :               break;
    2905             :           }
    2906             :       }
    2907         192 :       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         192 :       if ($2 && !pubBase) {
    2915             :           error(
    2916           2 :               @5, yyscanner,
    2917           4 :               ("published interface-based singleton " + name + " base " + base
    2918           4 :                + " is unpublished"));
    2919           2 :           YYERROR;
    2920             :       }
    2921         380 :       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         380 :                           $2, base, annotations($1))))).
    2928         190 :           second)
    2929             :       {
    2930           0 :           error(@4, yyscanner, "multiple entities named " + name);
    2931           0 :           YYERROR;
    2932             :       }
    2933         380 :       clearCurrentState(data);
    2934             :   }
    2935             : ;
    2936             : 
    2937             : serviceBasedSingletonDefn:
    2938             :   deprecated_opt published_opt TOK_SINGLETON identifier '{' TOK_SERVICE name ';'
    2939             :   '}' ';'
    2940             :   {
    2941          15 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    2942          15 :       data->publishedContext = $2;
    2943          15 :       OUString name(convertToFullName(data, $4));
    2944          26 :       OUString base(convertName($7));
    2945             :       unoidl::detail::SourceProviderEntity const * p;
    2946          15 :       if (findEntity(@7, yyscanner, data, false, &base, &p, 0, 0)
    2947             :           == FOUND_ERROR)
    2948             :       {
    2949           0 :           YYERROR;
    2950             :       }
    2951          30 :       if (p == 0
    2952          15 :           || !p->entity.is()
    2953          30 :           || (p->entity->getSort()
    2954             :               != unoidl::Entity::SORT_ACCUMULATION_BASED_SERVICE))
    2955             :       {
    2956             :           error(
    2957           2 :               @7, yyscanner,
    2958           4 :               ("service-based singleton " + name + " base " + base
    2959           4 :                + " does not resolve to an accumulation-based service"));
    2960           2 :           YYERROR;
    2961             :       }
    2962          26 :       if ($2
    2963          19 :           && !static_cast<unoidl::AccumulationBasedServiceEntity *>(
    2964           6 :               p->entity.get())->isPublished())
    2965             :       {
    2966             :           error(
    2967           2 :               @7, yyscanner,
    2968           4 :               ("published service-based singleton " + name + " base " + base
    2969           4 :                + " is unpublished"));
    2970           2 :           YYERROR;
    2971             :       }
    2972          22 :       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          22 :                           $2, base, annotations($1))))).
    2979          11 :           second)
    2980             :       {
    2981           0 :           error(@4, yyscanner, "multiple entities named " + name);
    2982           0 :           YYERROR;
    2983             :       }
    2984          22 :       clearCurrentState(data);
    2985             :   }
    2986             : ;
    2987             : 
    2988             : singleInheritance_opt:
    2989             :   singleInheritance
    2990        2813 : | /* empty */ { $$ = 0; }
    2991             : ;
    2992             : 
    2993        3033 : singleInheritance: ':' name { $$ = $2; }
    2994             : ;
    2995             : 
    2996             : exceptionSpec_opt:
    2997             :   exceptionSpec
    2998        7665 : | /* empty */ { $$ = 0; }
    2999             : ;
    3000             : 
    3001        3542 : exceptionSpec: TOK_RAISES '(' exceptions ')' { $$ = $3; }
    3002             : ;
    3003             : 
    3004             : exceptions:
    3005             :   exceptions ',' name
    3006             :   {
    3007        1369 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    3008        1369 :       OUString name(convertName($3));
    3009             :       unoidl::detail::SourceProviderEntity const * p;
    3010        1369 :       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        2738 :       if (p == 0
    3017        1369 :           || !p->entity.is()
    3018        2738 :           || (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        1369 :       if (data->publishedContext
    3027        2351 :           && !(static_cast<unoidl::ExceptionTypeEntity *>(p->entity.get())
    3028         982 :                ->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        1369 :       if (std::find($1->begin(), $1->end(), name) != $1->end()) {
    3037           2 :           delete $1; /* see commented-out %destructor above */
    3038             :           error(
    3039           2 :               @3, yyscanner, ("exception " + name + " listed more than once"));
    3040           2 :           YYERROR;
    3041             :       }
    3042        1367 :       $1->push_back(name);
    3043        1367 :       $$ = $1;
    3044             :   }
    3045             : | name
    3046             :   {
    3047        3550 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    3048        3550 :       OUString name(convertName($1));
    3049             :       unoidl::detail::SourceProviderEntity const * p;
    3050        3550 :       if (findEntity(@1, yyscanner, data, false, &name, &p, 0, 0)
    3051             :           == FOUND_ERROR)
    3052             :       {
    3053           0 :           YYERROR;
    3054             :       }
    3055        7100 :       if (p == 0
    3056        3550 :           || !p->entity.is()
    3057        7100 :           || (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        3550 :       if (data->publishedContext
    3065        5734 :           && !(static_cast<unoidl::ExceptionTypeEntity *>(p->entity.get())
    3066        2184 :                ->isPublished()))
    3067             :       {
    3068             :           error(
    3069             :               @1, yyscanner,
    3070           6 :               ("unpublished exception " + name + " used in published context"));
    3071           6 :           YYERROR;
    3072             :       }
    3073        3544 :       $$ = new std::vector<OUString>; $$->push_back(name);
    3074             :   }
    3075             : ;
    3076             : 
    3077             : interfaceDecl:
    3078             :   deprecated_opt/*ignored*/ published_opt TOK_INTERFACE identifier ';'
    3079             :   {
    3080        1029 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    3081        1029 :       data->publishedContext = $2;
    3082        1029 :       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        1029 :                       $2
    3089             :                       ? unoidl::detail::SourceProviderEntity::KIND_PUBLISHED_INTERFACE_DECL
    3090        1029 :                       : unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL))));
    3091        1029 :       if (!p.second) {
    3092          90 :           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          90 :               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        1029 :       clearCurrentState(data);
    3124             :   }
    3125             : ;
    3126             : 
    3127             : published_opt:
    3128        6560 :   TOK_PUBLISHED { $$ = true; }
    3129        4414 : | /* empty */ { $$ = false; }
    3130             : ;
    3131             : 
    3132             : flagSection_opt:
    3133             :   flagSection
    3134        5608 : | /* empty */ { $$ = unoidl::detail::SourceProviderFlags(0); }
    3135             : ;
    3136             : 
    3137        7975 : flagSection: '[' flags ']' { $$ = $2; }
    3138             : ;
    3139             : 
    3140             : flags:
    3141             :   flags ',' flag
    3142             :   {
    3143        3060 :       if (($1 & $3) != 0) {
    3144           0 :           error(@3, yyscanner, "duplicate flag " + flagName($3));
    3145           0 :           YYERROR;
    3146             :       }
    3147        3060 :       $$ = unoidl::detail::SourceProviderFlags($1 | $3);
    3148             :   }
    3149             : | flag
    3150             : ;
    3151             : 
    3152             : flag:
    3153        1402 :   TOK_ATTRIBUTE { $$ = unoidl::detail::FLAG_ATTRIBUTE; }
    3154         165 : | TOK_BOUND { $$ = unoidl::detail::FLAG_BOUND; }
    3155           2 : | TOK_CONSTRAINED { $$ = unoidl::detail::FLAG_CONSTRAINED; }
    3156           0 : | TOK_MAYBEAMBIGUOUS { $$ = unoidl::detail::FLAG_MAYBEAMBIGUOUS; }
    3157           5 : | TOK_MAYBEDEFAULT { $$ = unoidl::detail::FLAG_MAYBEDEFAULT; }
    3158         200 : | TOK_MAYBEVOID { $$ = unoidl::detail::FLAG_MAYBEVOID; }
    3159        2721 : | TOK_OPTIONAL { $$ = unoidl::detail::FLAG_OPTIONAL; }
    3160        5815 : | TOK_PROPERTY { $$ = unoidl::detail::FLAG_PROPERTY; }
    3161         708 : | TOK_READONLY { $$ = unoidl::detail::FLAG_READONLY; }
    3162           2 : | TOK_REMOVABLE { $$ = unoidl::detail::FLAG_REMOVABLE; }
    3163          17 : | TOK_TRANSIENT { $$ = unoidl::detail::FLAG_TRANSIENT; }
    3164             : ;
    3165             : 
    3166             : expr: orExpr
    3167             : ;
    3168             : 
    3169             : orExpr:
    3170             :   orExpr '|' xorExpr
    3171             :   {
    3172          16 :       if (!coerce(@1, yyscanner, &$1, &$3)) {
    3173           0 :           YYERROR;
    3174             :       }
    3175          16 :       switch ($1.type) {
    3176             :       case unoidl::detail::SourceProviderExpr::TYPE_INT:
    3177          16 :           $$ = unoidl::detail::SourceProviderExpr::Int($1.ival | $3.ival);
    3178          16 :           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             : | 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             : | 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             : | 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             : | 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             : | addExpr
    3327             : ;
    3328             : 
    3329             : addExpr:
    3330             :   addExpr '+' multExpr
    3331             :   {
    3332          60 :       if (!coerce(@1, yyscanner, &$1, &$3)) {
    3333           0 :           YYERROR;
    3334             :       }
    3335          60 :       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          60 :           $$ = unoidl::detail::SourceProviderExpr::Uint($1.uval + $3.uval); //TODO: overflow
    3345          60 :           break;
    3346             :       case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
    3347           0 :           $$ = unoidl::detail::SourceProviderExpr::Float($1.fval + $3.fval);
    3348           0 :           break;
    3349             :       }
    3350             :   }
    3351             : | 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             : | 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             : | 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             : | 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             : | 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             : | '-' primaryExpr
    3469             :   {
    3470         688 :       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         688 :           if ($2.uval == SAL_CONST_UINT64(0x8000000000000000)) {
    3484           7 :               $$ = unoidl::detail::SourceProviderExpr::Int(SAL_MIN_INT64);
    3485             :           } else {
    3486         681 :               if ($2.uval > SAL_MAX_INT64) {
    3487             :                   error(
    3488             :                       @2, yyscanner,
    3489             :                       ("cannot negate out-of-range value "
    3490           6 :                        + OUString::number($2.uval)));
    3491           6 :                   YYERROR;
    3492             :               }
    3493             :               $$ = unoidl::detail::SourceProviderExpr::Int(
    3494         675 :                   -static_cast<sal_Int64>($2.uval));
    3495             :           }
    3496         682 :           break;
    3497             :       case unoidl::detail::SourceProviderExpr::TYPE_FLOAT:
    3498           0 :           $$ = unoidl::detail::SourceProviderExpr::Float(-$2.fval);
    3499           0 :           break;
    3500             :       }
    3501             :   }
    3502             : | '~' 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             : | primaryExpr
    3518             : ;
    3519             : 
    3520             : primaryExpr:
    3521           0 :   '(' expr ')' { $$ = $2; }
    3522           2 : | TOK_FALSE { $$ = unoidl::detail::SourceProviderExpr::Bool(false); }
    3523           0 : | TOK_TRUE { $$ = unoidl::detail::SourceProviderExpr::Bool(true); }
    3524       15078 : | TOK_INTEGER { $$ = unoidl::detail::SourceProviderExpr::Uint($1); }
    3525          24 : | TOK_FLOATING { $$ = unoidl::detail::SourceProviderExpr::Float($1); }
    3526             : | name
    3527             :   {
    3528         110 :       OUString name(convertName($1));
    3529         110 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    3530         110 :       unoidl::ConstantValue v(false); // dummy value
    3531         110 :       bool found = false;
    3532         110 :       bool unpub = false;
    3533         110 :       sal_Int32 i = name.lastIndexOf('.');
    3534         110 :       if (i == -1) {
    3535             :           rtl::Reference<unoidl::detail::SourceProviderEntityPad> pad(
    3536         100 :               getCurrentEntity(data)->pad);
    3537             :           unoidl::detail::SourceProviderEnumTypeEntityPad * p1 = dynamic_cast<
    3538         100 :               unoidl::detail::SourceProviderEnumTypeEntityPad *>(pad.get());
    3539         100 :           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         100 :                           pad.get());
    3555         100 :               if (p2 != 0) {
    3556        7263 :                   for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator
    3557         100 :                            j(p2->members.begin());
    3558        4842 :                        j != p2->members.end(); ++j)
    3559             :                   {
    3560        2421 :                       if (j->name == name) {
    3561         100 :                           v = j->value;
    3562         100 :                           found = true;
    3563         100 :                           break;
    3564             :                       }
    3565             :                   }
    3566             :               }
    3567         100 :           }
    3568             :       } else {
    3569          10 :           OUString scope(name.copy(0, i));
    3570             :           unoidl::detail::SourceProviderEntity const * ent;
    3571          10 :           if (findEntity(@1, yyscanner, data, false, &scope, &ent, 0, 0)
    3572             :               == FOUND_ERROR)
    3573             :           {
    3574           0 :               YYERROR;
    3575             :           }
    3576          10 :           if (ent != 0) {
    3577          10 :               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          10 :               if (ent->entity.is()) {
    3581          10 :                   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          10 :                                   ent->entity.get())->
    3588          10 :                               getMembers());
    3589          33 :                       for (std::vector<unoidl::ConstantGroupEntity::Member>::const_iterator j(
    3590          10 :                                mems.begin());
    3591          22 :                            j != mems.end(); ++j)
    3592             :                       {
    3593          11 :                           if (j->name == id) {
    3594          10 :                               v = j->value;
    3595          10 :                               found = true;
    3596             :                               unpub
    3597             :                                   = !static_cast<unoidl::ConstantGroupEntity *>(
    3598          10 :                                       ent->entity.get())->isPublished();
    3599          10 :                               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          10 :               }
    3622          10 :           }
    3623             :       }
    3624         110 :       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         110 :       if (data->publishedContext && unpub) {
    3633             :           error(
    3634             :               @1, yyscanner,
    3635           2 :               "unpublished value " + name + " used in published context");
    3636           2 :           YYERROR;
    3637             :       }
    3638         108 :       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          67 :           $$ = unoidl::detail::SourceProviderExpr::Int(v.shortValue);
    3647          67 :           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          41 :           $$ = unoidl::detail::SourceProviderExpr::Int(v.longValue);
    3653          41 :           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         108 :       }
    3670             :   }
    3671             : ;
    3672             : 
    3673             : typeArguments:
    3674             :   typeArguments ',' type
    3675             :   {
    3676          40 :       unoidl::detail::SourceProviderType t(*$3);
    3677          40 :       delete $3;
    3678          40 :       if (!checkTypeArgument(@3, yyscanner, t)) {
    3679           2 :           delete $1; /* see commented-out %destructor above */
    3680           2 :           YYERROR;
    3681             :       }
    3682          38 :       $1->push_back(t);
    3683          38 :       $$ = $1;
    3684             :   }
    3685             : | type
    3686             :   {
    3687         191 :       unoidl::detail::SourceProviderType t(*$1);
    3688         191 :       delete $1;
    3689         191 :       if (!checkTypeArgument(@1, yyscanner, t)) {
    3690          16 :           YYERROR;
    3691             :       }
    3692         175 :       $$ = new std::vector<unoidl::detail::SourceProviderType>;
    3693         175 :       $$->push_back(t);
    3694             :   }
    3695             : ;
    3696             : 
    3697             : type:
    3698             :   TOK_VOID
    3699             :   {
    3700             :       $$ = new unoidl::detail::SourceProviderType(
    3701        4678 :           unoidl::detail::SourceProviderType::TYPE_VOID);
    3702             :   }
    3703             : | TOK_BOOLEAN
    3704             :   {
    3705             :       $$ = new unoidl::detail::SourceProviderType(
    3706        3821 :           unoidl::detail::SourceProviderType::TYPE_BOOLEAN);
    3707             :   }
    3708             : | TOK_BYTE
    3709             :   {
    3710             :       $$ = new unoidl::detail::SourceProviderType(
    3711         582 :           unoidl::detail::SourceProviderType::TYPE_BYTE);
    3712             :   }
    3713             : | TOK_SHORT
    3714             :   {
    3715             :       $$ = new unoidl::detail::SourceProviderType(
    3716        5003 :           unoidl::detail::SourceProviderType::TYPE_SHORT);
    3717             :   }
    3718             : | TOK_UNSIGNED TOK_SHORT
    3719             :   {
    3720             :       $$ = new unoidl::detail::SourceProviderType(
    3721         111 :           unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT);
    3722             :   }
    3723             : | TOK_LONG
    3724             :   {
    3725             :       $$ = new unoidl::detail::SourceProviderType(
    3726       14276 :           unoidl::detail::SourceProviderType::TYPE_LONG);
    3727             :   }
    3728             : | TOK_UNSIGNED TOK_LONG
    3729             :   {
    3730             :       $$ = new unoidl::detail::SourceProviderType(
    3731          89 :           unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG);
    3732             :   }
    3733             : | TOK_HYPER
    3734             :   {
    3735             :       $$ = new unoidl::detail::SourceProviderType(
    3736         223 :           unoidl::detail::SourceProviderType::TYPE_HYPER);
    3737             :   }
    3738             : | TOK_UNSIGNED TOK_HYPER
    3739             :   {
    3740             :       $$ = new unoidl::detail::SourceProviderType(
    3741          47 :           unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER);
    3742             :   }
    3743             : | TOK_FLOAT
    3744             :   {
    3745             :       $$ = new unoidl::detail::SourceProviderType(
    3746         181 :           unoidl::detail::SourceProviderType::TYPE_FLOAT);
    3747             :   }
    3748             : | TOK_DOUBLE
    3749             :   {
    3750             :       $$ = new unoidl::detail::SourceProviderType(
    3751         689 :           unoidl::detail::SourceProviderType::TYPE_DOUBLE);
    3752             :   }
    3753             : | TOK_CHAR
    3754             :   {
    3755             :       $$ = new unoidl::detail::SourceProviderType(
    3756          89 :           unoidl::detail::SourceProviderType::TYPE_CHAR);
    3757             :   }
    3758             : | TOK_STRING
    3759             :   {
    3760             :       $$ = new unoidl::detail::SourceProviderType(
    3761        5647 :           unoidl::detail::SourceProviderType::TYPE_STRING);
    3762             :   }
    3763             : | TOK_TYPE
    3764             :   {
    3765             :       $$ = new unoidl::detail::SourceProviderType(
    3766         337 :           unoidl::detail::SourceProviderType::TYPE_TYPE);
    3767             :   }
    3768             : | TOK_ANY
    3769             :   {
    3770             :       $$ = new unoidl::detail::SourceProviderType(
    3771        2066 :           unoidl::detail::SourceProviderType::TYPE_ANY);
    3772             :   }
    3773             : | TOK_SEQUENCE '<' type '>'
    3774             :   {
    3775        2122 :       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           4 :           error(@3, yyscanner, "illegal sequence type component type");
    3780           4 :           YYERROR;
    3781             :           break;
    3782             :       default:
    3783        2118 :           break;
    3784             :       }
    3785        2118 :       $$ = new unoidl::detail::SourceProviderType($3);
    3786        2118 :       delete $3;
    3787             :   }
    3788             : | name
    3789             :   {
    3790        8329 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    3791        8329 :       OUString name(convertName($1));
    3792        8329 :       bool done = false;
    3793        8329 :       if (name.indexOf('.') == -1 && !data->currentName.isEmpty()) {
    3794        1943 :           unoidl::detail::SourceProviderEntity * ent = getCurrentEntity(data);
    3795             :           unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *
    3796             :               pad = dynamic_cast<
    3797             :                   unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
    3798        1943 :                       ent->pad.get());
    3799        5759 :           if (pad != 0
    3800        2153 :               && (std::find(
    3801             :                       pad->typeParameters.begin(), pad->typeParameters.end(),
    3802          70 :                       name)
    3803        2223 :                   != pad->typeParameters.end()))
    3804             :           {
    3805          61 :               $$ = new unoidl::detail::SourceProviderType(name);
    3806          61 :               done = true;
    3807             :           }
    3808             :       }
    3809        8329 :       if (!done) {
    3810             :           unoidl::detail::SourceProviderEntity const * ent;
    3811        8268 :           unoidl::detail::SourceProviderType t;
    3812        8268 :           switch (findEntity(@1, yyscanner, data, false, &name, &ent, 0, &t)) {
    3813             :           case FOUND_ERROR:
    3814           6 :               YYERROR;
    3815             :               break;
    3816             :           case FOUND_TYPE:
    3817         470 :               $$ = new unoidl::detail::SourceProviderType(t);
    3818         470 :               break;
    3819             :           case FOUND_ENTITY:
    3820        7792 :               if (ent == 0) {
    3821           2 :                   error(@1, yyscanner, "unknown entity " + name);
    3822           2 :                   YYERROR;
    3823             :               }
    3824        7790 :               bool ok = false;
    3825        7790 :               switch (ent->kind) {
    3826             :               case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
    3827        1827 :                   if (ent->pad.is()) {
    3828         196 :                       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         196 :                       if (dynamic_cast<unoidl::detail::SourceProviderEnumTypeEntityPad *>(
    3836         392 :                               ent->pad.get())
    3837         392 :                           != 0)
    3838             :                       {
    3839             :                           $$ = new unoidl::detail::SourceProviderType(
    3840             :                               unoidl::detail::SourceProviderType::TYPE_ENUM,
    3841           0 :                               name, ent);
    3842           0 :                           ok = true;
    3843         196 :                       } else if (dynamic_cast<unoidl::detail::SourceProviderPlainStructTypeEntityPad *>(
    3844         392 :                                      ent->pad.get())
    3845         392 :                                  != 0)
    3846             :                       {
    3847             :                           $$ = new unoidl::detail::SourceProviderType(
    3848             :                               unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
    3849          21 :                               name, ent);
    3850          21 :                           ok = true;
    3851         175 :                       } else if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
    3852         350 :                                      ent->pad.get())
    3853         350 :                                  != 0)
    3854             :                       {
    3855             :                           error(
    3856             :                               @1, yyscanner,
    3857             :                               (("recursive reference to polymorphic struct type"
    3858             :                                 " template ")
    3859          10 :                                + name));
    3860          10 :                           YYERROR;
    3861         165 :                       } else if (dynamic_cast<unoidl::detail::SourceProviderExceptionTypeEntityPad *>(
    3862         330 :                                      ent->pad.get())
    3863         330 :                                  != 0)
    3864             :                       {
    3865             :                           $$ = new unoidl::detail::SourceProviderType(
    3866             :                               unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
    3867           0 :                               name, ent);
    3868           0 :                           ok = true;
    3869         165 :                       } else if (dynamic_cast<unoidl::detail::SourceProviderInterfaceTypeEntityPad *>(
    3870         330 :                                      ent->pad.get())
    3871         330 :                                  != 0)
    3872             :                       {
    3873             :                           $$ = new unoidl::detail::SourceProviderType(
    3874             :                               unoidl::detail::SourceProviderType::TYPE_INTERFACE,
    3875         165 :                               name, ent);
    3876         165 :                           ok = true;
    3877             :                       }
    3878         186 :                       break;
    3879             :                   }
    3880             :                   assert(ent->entity.is());
    3881             :                   // fall through
    3882             :               case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
    3883        6480 :                   if (data->publishedContext
    3884        4372 :                       && ent->entity->getSort() != unoidl::Entity::SORT_MODULE
    3885       10852 :                       && !static_cast<unoidl::PublishableEntity *>(
    3886        4372 :                           ent->entity.get())->isPublished())
    3887             :                   {
    3888             :                       error(
    3889             :                           @1, yyscanner,
    3890          44 :                           ("unpublished entity " + name
    3891          22 :                            + " used in published context"));
    3892          22 :                       YYERROR;
    3893             :                   }
    3894        6458 :                   switch (ent->entity->getSort()) {
    3895             :                   case unoidl::Entity::SORT_ENUM_TYPE:
    3896             :                       $$ = new unoidl::detail::SourceProviderType(
    3897             :                           unoidl::detail::SourceProviderType::TYPE_ENUM, name,
    3898         632 :                           ent);
    3899         632 :                       ok = true;
    3900         632 :                       break;
    3901             :                   case unoidl::Entity::SORT_PLAIN_STRUCT_TYPE:
    3902             :                       $$ = new unoidl::detail::SourceProviderType(
    3903             :                           unoidl::detail::SourceProviderType::TYPE_PLAIN_STRUCT,
    3904        2745 :                           name, ent);
    3905        2745 :                       ok = true;
    3906        2745 :                       break;
    3907             :                   case unoidl::Entity::SORT_POLYMORPHIC_STRUCT_TYPE_TEMPLATE:
    3908             :                       error(
    3909             :                           @1, yyscanner,
    3910           4 :                           ("polymorphic struct type template " + name
    3911           2 :                            + " without type arguments"));
    3912           2 :                       YYERROR;
    3913             :                       break;
    3914             :                   case unoidl::Entity::SORT_EXCEPTION_TYPE:
    3915             :                       $$ = new unoidl::detail::SourceProviderType(
    3916             :                           unoidl::detail::SourceProviderType::TYPE_EXCEPTION,
    3917           8 :                           name, ent);
    3918           8 :                       ok = true;
    3919           8 :                       break;
    3920             :                   case unoidl::Entity::SORT_INTERFACE_TYPE:
    3921             :                       $$ = new unoidl::detail::SourceProviderType(
    3922             :                           unoidl::detail::SourceProviderType::TYPE_INTERFACE,
    3923        3069 :                           name, ent);
    3924        3069 :                       ok = true;
    3925        3069 :                       break;
    3926             :                   case unoidl::Entity::SORT_TYPEDEF:
    3927             :                       assert(false && "this cannot happen");
    3928             :                       // fall through
    3929             :                   default:
    3930           2 :                       break;
    3931             :                   }
    3932        6456 :                   break;
    3933             :               case unoidl::detail::SourceProviderEntity::KIND_INTERFACE_DECL:
    3934         377 :                   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        1114 :                       ent);
    3946        1114 :                   ok = true;
    3947        1114 :                   break;
    3948             :               case unoidl::detail::SourceProviderEntity::KIND_MODULE:
    3949             :                   assert(false && "this cannot happen");
    3950             :               }
    3951        7756 :               if (!ok) {
    3952           2 :                   error(@1, yyscanner, "non-type entity " + name);
    3953           2 :                   YYERROR;
    3954             :               }
    3955        7754 :               break;
    3956        8224 :           }
    3957        8285 :       }
    3958             :   }
    3959             : | name '<' typeArguments '>'
    3960             :   {
    3961         173 :       unoidl::detail::SourceProviderScannerData * data = yyget_extra(yyscanner);
    3962         173 :       OUString name(convertName($1));
    3963         326 :       std::vector<unoidl::detail::SourceProviderType> args(*$3);
    3964         173 :       delete $3;
    3965             :       unoidl::detail::SourceProviderEntity const * ent;
    3966         173 :       if (findEntity(@1, yyscanner, data, false, &name, &ent, 0, 0)
    3967             :           == FOUND_ERROR)
    3968             :       {
    3969           0 :           YYERROR;
    3970             :       }
    3971         173 :       if (ent == 0) {
    3972           2 :           error(@1, yyscanner, "unknown entity " + name);
    3973           2 :           YYERROR;
    3974             :       }
    3975         171 :       bool ok = false;
    3976         171 :       switch (ent->kind) {
    3977             :       case unoidl::detail::SourceProviderEntity::KIND_LOCAL:
    3978         151 :           if (ent->pad.is()) {
    3979          12 :               if (dynamic_cast<unoidl::detail::SourceProviderPolymorphicStructTypeTemplateEntityPad *>(
    3980          24 :                       ent->pad.get())
    3981          24 :                   != 0)
    3982             :               {
    3983             :                   error(
    3984          12 :                       @1, yyscanner,
    3985             :                       (("recursive reference to polymorphic struct type"
    3986             :                         " template ")
    3987          24 :                        + name));
    3988          12 :                   YYERROR;
    3989             :               }
    3990           0 :               break;
    3991             :           }
    3992             :           assert(ent->entity.is());
    3993             :           // fall through
    3994             :       case unoidl::detail::SourceProviderEntity::KIND_EXTERNAL:
    3995         159 :           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         159 :                       ent->entity.get()));
    4001         159 :               if (args.size() != e->getTypeParameters().size()) {
    4002             :                   error(
    4003           2 :                       @1, yyscanner,
    4004           4 :                       ("bad number of polymorphic struct type template " + name
    4005           4 :                        + " type arguments"));
    4006           2 :                   YYERROR;
    4007             :               }
    4008         157 :               if (data->publishedContext && !e->isPublished()) {
    4009             :                   error(
    4010           4 :                       @1, yyscanner,
    4011           8 :                       ("unpublished polymorphic struct type template " + name
    4012           8 :                        + " used in published context"));
    4013           4 :                   YYERROR;
    4014             :               }
    4015         153 :               $$ = new unoidl::detail::SourceProviderType(name, ent, args);
    4016         153 :               ok = true;
    4017             :           }
    4018         153 :           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         153 :       if (!ok) {
    4026           0 :           error(@1, yyscanner, "non-type entity " + name);
    4027           0 :           YYERROR;
    4028         153 :       }
    4029             :   }
    4030             : ;
    4031             : 
    4032             : name:
    4033       75267 :   name TOK_COLONS identifier { *$1 += "." + *$3; delete $3; $$ = $1; }
    4034        9849 : | TOK_COLONS identifier { *$2 = "." + *$2; $$ = $2; }
    4035             : | identifier
    4036             : ;
    4037             : 
    4038             : identifier:
    4039             :   TOK_IDENTIFIER
    4040           8 : | TOK_GET { $$ = new OString("get"); }
    4041           0 : | TOK_PUBLISHED { $$ = new OString("published"); }
    4042           6 : | TOK_SET { $$ = new OString("set"); }
    4043             : ;
    4044             : 
    4045             : deprecated_opt:
    4046         531 :   TOK_DEPRECATED { $$ = true; }
    4047       54329 : | /* empty */ { $$ = false; }
    4048             : ;
    4049             : 
    4050             : %%
    4051             : 
    4052             : namespace unoidl { namespace detail {
    4053             : 
    4054       37323 : OUString SourceProviderType::getName() const {
    4055       37323 :     if (!typedefName.isEmpty()) {
    4056         490 :         return typedefName;
    4057             :     }
    4058       36833 :     switch (type) {
    4059             :     case unoidl::detail::SourceProviderType::TYPE_VOID:
    4060        4662 :         return OUString("void");
    4061             :     case unoidl::detail::SourceProviderType::TYPE_BOOLEAN:
    4062        4060 :         return OUString("boolean");
    4063             :     case unoidl::detail::SourceProviderType::TYPE_BYTE:
    4064         353 :         return OUString("byte");
    4065             :     case unoidl::detail::SourceProviderType::TYPE_SHORT:
    4066        1978 :         return OUString("short");
    4067             :     case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_SHORT:
    4068         139 :         return OUString("unsigned short");
    4069             :     case unoidl::detail::SourceProviderType::TYPE_LONG:
    4070        4646 :         return OUString("long");
    4071             :     case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_LONG:
    4072          88 :         return OUString("unsigned long");
    4073             :     case unoidl::detail::SourceProviderType::TYPE_HYPER:
    4074         167 :         return OUString("hyper");
    4075             :     case unoidl::detail::SourceProviderType::TYPE_UNSIGNED_HYPER:
    4076          24 :         return OUString("unsigned hyper");
    4077             :     case unoidl::detail::SourceProviderType::TYPE_FLOAT:
    4078         159 :         return OUString("float");
    4079             :     case unoidl::detail::SourceProviderType::TYPE_DOUBLE:
    4080         823 :         return OUString("double");
    4081             :     case unoidl::detail::SourceProviderType::TYPE_CHAR:
    4082         110 :         return OUString("char");
    4083             :     case unoidl::detail::SourceProviderType::TYPE_STRING:
    4084        6282 :         return OUString("string");
    4085             :     case unoidl::detail::SourceProviderType::TYPE_TYPE:
    4086         350 :         return OUString("type");
    4087             :     case unoidl::detail::SourceProviderType::TYPE_ANY:
    4088        2197 :         return OUString("any");
    4089             :     case unoidl::detail::SourceProviderType::TYPE_SEQUENCE:
    4090             :         assert(subtypes.size() == 1);
    4091        2300 :         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        8304 :         return name;
    4098             :     case unoidl::detail::SourceProviderType::TYPE_INSTANTIATED_POLYMORPHIC_STRUCT:
    4099             :         {
    4100         191 :             OUString n(name + "<");
    4101        1266 :             for (std::vector<SourceProviderType>::const_iterator i(
    4102         191 :                      subtypes.begin());
    4103         844 :                  i != subtypes.end(); ++i)
    4104             :             {
    4105         231 :                 if (i != subtypes.begin()) {
    4106          40 :                     n += ",";
    4107             :                 }
    4108         231 :                 n += i->getName();
    4109             :             }
    4110         191 :             return n + ">";
    4111             :         }
    4112             :     default:
    4113           0 :         assert(false && "this cannot happen"); for (;;) { std::abort(); }
    4114             :     }
    4115             : }
    4116             : 
    4117          31 : bool SourceProviderType::equals(SourceProviderType const & other) const {
    4118          81 :     if (type != other.type || name != other.name
    4119          46 :         || subtypes.size() != other.subtypes.size())
    4120             :     {
    4121          16 :         return false;
    4122             :     }
    4123          51 :     for (std::vector<SourceProviderType>::const_iterator
    4124          15 :              i(subtypes.begin()), j(other.subtypes.begin());
    4125          34 :          i != subtypes.end(); ++i, ++j)
    4126             :     {
    4127           3 :         if (!i->equals(*j)) {
    4128           1 :             return false;
    4129             :         }
    4130             :     }
    4131          14 :     return true;
    4132             : }
    4133             : 
    4134        3809 : bool SourceProviderInterfaceTypeEntityPad::addDirectBase(
    4135             :     YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
    4136             :     DirectBase const & base, bool optional)
    4137             : {
    4138        3809 :     std::set<OUString> seen;
    4139        3809 :     if (!(checkBaseClashes(
    4140             :               location, yyscanner, data, base.name, base.entity, true, optional,
    4141        3809 :               optional, &seen)
    4142             :           && addBase(
    4143             :               location, yyscanner, data, base.name, base.name, base.entity,
    4144        3809 :               true, optional)))
    4145             :     {
    4146          34 :         return false;
    4147             :     }
    4148        3775 :     if (optional) {
    4149             :         addOptionalBaseMembers(
    4150          82 :             location, yyscanner, data, base.name, base.entity);
    4151             :     }
    4152        3775 :     (optional ? directOptionalBases : directMandatoryBases).push_back(base);
    4153        3775 :     return true;
    4154             : }
    4155             : 
    4156       12015 : bool SourceProviderInterfaceTypeEntityPad::addDirectMember(
    4157             :     YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
    4158             :     OUString const & name)
    4159             : {
    4160             :     assert(data != 0);
    4161       12015 :     if (!checkMemberClashes(location, yyscanner, data, "", name, true)) {
    4162          10 :         return false;
    4163             :     }
    4164             :     allMembers.insert(
    4165             :         std::map<OUString, Member>::value_type(
    4166       12005 :             name, Member(data->currentName)));
    4167       12005 :     return true;
    4168             : }
    4169             : 
    4170        6482 : 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        6482 :     if (direct || optional || seen->insert(name).second) {
    4180        6323 :         std::map<OUString, BaseKind>::const_iterator i(allBases.find(name));
    4181        6323 :         if (i != allBases.end()) {
    4182         412 :             switch (i->second) {
    4183             :             case BASE_INDIRECT_OPTIONAL:
    4184           4 :                 if (direct && optional) {
    4185             :                     error(
    4186             :                         location, yyscanner,
    4187           4 :                         ("interface type " + data->currentName
    4188           2 :                          + " duplicate base " + name));
    4189         430 :                     return false;
    4190             :                 }
    4191           2 :                 break;
    4192             :             case BASE_DIRECT_OPTIONAL:
    4193          12 :                 if (direct || !outerOptional) {
    4194             :                     error(
    4195             :                         location, yyscanner,
    4196          16 :                         ("interface type " + data->currentName
    4197           8 :                          + " duplicate base " + name));
    4198           8 :                     return false;
    4199             :                 }
    4200           4 :                 return true;
    4201             :             case BASE_INDIRECT_MANDATORY:
    4202         384 :                 if (direct) {
    4203             :                     error(
    4204             :                         location, yyscanner,
    4205          12 :                         ("interface type " + data->currentName
    4206           6 :                          + " duplicate base " + name));
    4207           6 :                     return false;
    4208             :                 }
    4209         378 :                 return true;
    4210             :             case BASE_DIRECT_MANDATORY:
    4211          12 :                 if (direct || (!optional && !outerOptional)) {
    4212             :                     error(
    4213             :                         location, yyscanner,
    4214          12 :                         ("interface type " + data->currentName
    4215           6 :                          + " duplicate base " + name));
    4216           6 :                     return false;
    4217             :                 }
    4218           6 :                 return true;
    4219             :             }
    4220             :         }
    4221        5913 :         if (direct || !optional) {
    4222       19769 :             for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
    4223        5905 :                      entity->getDirectMandatoryBases().begin());
    4224       17116 :                  j != entity->getDirectMandatoryBases().end(); ++j)
    4225             :             {
    4226        2657 :                 OUString n("." + j->name);
    4227             :                 unoidl::detail::SourceProviderEntity const * p;
    4228        2657 :                 if (findEntity(location, yyscanner, data, true, &n, &p, 0, 0)
    4229             :                     == FOUND_ERROR)
    4230             :                 {
    4231           0 :                     return false;
    4232             :                 }
    4233        7971 :                 if (p == 0 || !p->entity.is()
    4234        5314 :                     || (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        5314 :                 if (!checkBaseClashes(
    4245             :                         location, yyscanner, data, n,
    4246             :                         static_cast<unoidl::InterfaceTypeEntity *>(
    4247        2657 :                             p->entity.get()),
    4248        7971 :                         false, false, outerOptional, seen))
    4249             :                 {
    4250           4 :                     return false;
    4251             :                 }
    4252        2653 :             }
    4253       11844 :             for (std::vector<unoidl::AnnotatedReference>::const_iterator j(
    4254        5901 :                      entity->getDirectOptionalBases().begin());
    4255       11830 :                  j != entity->getDirectOptionalBases().end(); ++j)
    4256             :             {
    4257          16 :                 OUString n("." + j->name);
    4258             :                 unoidl::detail::SourceProviderEntity const * p;
    4259          16 :                 if (findEntity(location, yyscanner, data, true, &n, &p, 0, 0)
    4260             :                     == FOUND_ERROR)
    4261             :                 {
    4262           0 :                     return false;
    4263             :                 }
    4264          48 :                 if (p == 0 || !p->entity.is()
    4265          32 :                     || (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          32 :                 if (!checkBaseClashes(
    4276             :                         location, yyscanner, data, n,
    4277             :                         static_cast<unoidl::InterfaceTypeEntity *>(
    4278          16 :                             p->entity.get()),
    4279          48 :                         false, true, outerOptional, seen))
    4280             :                 {
    4281           2 :                     return false;
    4282             :                 }
    4283          14 :             }
    4284       20463 :             for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
    4285        5899 :                      j(entity->getDirectAttributes().begin());
    4286       13642 :                  j != entity->getDirectAttributes().end(); ++j)
    4287             :             {
    4288         924 :                 if (!checkMemberClashes(
    4289         924 :                         location, yyscanner, data, name, j->name,
    4290        1848 :                         !outerOptional))
    4291             :                 {
    4292           2 :                     return false;
    4293             :                 }
    4294             :             }
    4295       70038 :             for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator
    4296        5897 :                      j(entity->getDirectMethods().begin());
    4297       46692 :                  j != entity->getDirectMethods().end(); ++j)
    4298             :             {
    4299       17459 :                 if (!checkMemberClashes(
    4300       17459 :                         location, yyscanner, data, name, j->name,
    4301       34918 :                         !outerOptional))
    4302             :                 {
    4303          10 :                     return false;
    4304             :                 }
    4305             :             }
    4306             :         }
    4307             :     }
    4308        6054 :     return true;
    4309             : }
    4310             : 
    4311       30398 : bool SourceProviderInterfaceTypeEntityPad::checkMemberClashes(
    4312             :     YYLTYPE location, yyscan_t yyscanner, SourceProviderScannerData * data,
    4313             :     OUString const & interfaceName, OUString const & memberName,
    4314             :     bool checkOptional) const
    4315             : {
    4316       30398 :     std::map<OUString, Member>::const_iterator i(allMembers.find(memberName));
    4317       30398 :     if (i != allMembers.end()) {
    4318         174 :         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          18 :             if (i->second.mandatory != interfaceName) {
    4322             :                 error(
    4323             :                     location, yyscanner,
    4324          36 :                     ("interface type " + data->currentName
    4325          18 :                      + " duplicate member " + memberName));
    4326          18 :                 return false;
    4327             :             }
    4328         156 :         } else if (checkOptional) {
    4329         732 :             for (std::set<OUString>::const_iterator j(
    4330         124 :                      i->second.optional.begin());
    4331         488 :                  j != i->second.optional.end(); ++j)
    4332             :             {
    4333         124 :                 if (*j != interfaceName) {
    4334             :                     error(
    4335             :                         location, yyscanner,
    4336           8 :                         ("interface type " + data->currentName
    4337           4 :                          + " duplicate member " + memberName));
    4338           4 :                     return false;
    4339             :                 }
    4340             :             }
    4341             :         }
    4342             :     }
    4343       30376 :     return true;
    4344             : }
    4345             : 
    4346        6328 : 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        6328 :         : direct ? BASE_DIRECT_MANDATORY : BASE_INDIRECT_MANDATORY;
    4357             :     std::pair<std::map<OUString, BaseKind>::iterator, bool> p(
    4358             :         allBases.insert(
    4359        6328 :             std::map<OUString, BaseKind>::value_type(name, kind)));
    4360        6328 :     bool seen = !p.second && p.first->second >= BASE_INDIRECT_MANDATORY;
    4361        6328 :     if (!p.second && kind > p.first->second) {
    4362           2 :         p.first->second = kind;
    4363             :     }
    4364        6328 :     if (!optional && !seen) {
    4365       19095 :         for (std::vector<unoidl::AnnotatedReference>::const_iterator i(
    4366        5727 :                  entity->getDirectMandatoryBases().begin());
    4367       16548 :              i != entity->getDirectMandatoryBases().end(); ++i)
    4368             :         {
    4369        2547 :             OUString n("." + i->name);
    4370             :             unoidl::detail::SourceProviderEntity const * q;
    4371        2547 :             if (findEntity(location, yyscanner, data, true, &n, &q, 0, 0)
    4372             :                 == FOUND_ERROR)
    4373             :             {
    4374           0 :                 return false;
    4375             :             }
    4376        7641 :             if (q == 0 || !q->entity.is()
    4377        5094 :                 || 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        5094 :             if (!addBase(
    4387             :                     location, yyscanner, data, directBaseName, n,
    4388        2547 :                     static_cast<unoidl::InterfaceTypeEntity *>(q->entity.get()),
    4389        5094 :                     false, false))
    4390             :             {
    4391           0 :                 return false;
    4392             :             }
    4393        2547 :         }
    4394       11472 :         for (std::vector<unoidl::AnnotatedReference>::const_iterator i(
    4395        5727 :                  entity->getDirectOptionalBases().begin());
    4396       11466 :              i != entity->getDirectOptionalBases().end(); ++i)
    4397             :         {
    4398           6 :             OUString n("." + i->name);
    4399             :             unoidl::detail::SourceProviderEntity const * q;
    4400           6 :             if (findEntity(location, yyscanner, data, true, &n, &q, 0, 0)
    4401             :                 == FOUND_ERROR)
    4402             :             {
    4403           0 :                 return false;
    4404             :             }
    4405          18 :             if (q == 0 || !q->entity.is()
    4406          12 :                 || 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          12 :             if (!addBase(
    4416             :                     location, yyscanner, data, directBaseName, n,
    4417           6 :                     static_cast<unoidl::InterfaceTypeEntity *>(q->entity.get()),
    4418          12 :                     false, true))
    4419             :             {
    4420           0 :                 return false;
    4421             :             }
    4422           6 :         }
    4423       19938 :         for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator
    4424        5727 :                  i(entity->getDirectAttributes().begin());
    4425       13292 :              i != entity->getDirectAttributes().end(); ++i)
    4426             :         {
    4427             :             allMembers.insert(
    4428         919 :                 std::map<OUString, Member>::value_type(i->name, Member(name)));
    4429             :         }
    4430       68724 :         for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator i(
    4431        5727 :                  entity->getDirectMethods().begin());
    4432       45816 :              i != entity->getDirectMethods().end(); ++i)
    4433             :         {
    4434             :             allMembers.insert(
    4435       17181 :                 std::map<OUString, Member>::value_type(i->name, Member(name)));
    4436             :         }
    4437             :     }
    4438        6328 :     return true;
    4439             : }
    4440             : 
    4441         180 : 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         654 :     for (std::vector<unoidl::AnnotatedReference>::const_iterator i(
    4448         180 :              entity->getDirectMandatoryBases().begin());
    4449         556 :          i != entity->getDirectMandatoryBases().end(); ++i)
    4450             :     {
    4451          98 :         OUString n("." + i->name);
    4452             :         unoidl::detail::SourceProviderEntity const * p;
    4453          98 :         if (findEntity(location, yyscanner, data, true, &n, &p, 0, 0)
    4454             :             == FOUND_ERROR)
    4455             :         {
    4456           0 :             return false;
    4457             :         }
    4458         294 :         if (p == 0 || !p->entity.is()
    4459         196 :             || 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         196 :         if (!addOptionalBaseMembers(
    4469             :                 location, yyscanner, data, n,
    4470         196 :                 static_cast<unoidl::InterfaceTypeEntity *>(p->entity.get())))
    4471             :         {
    4472           0 :             return false;
    4473             :         }
    4474          98 :     }
    4475         549 :     for (std::vector<unoidl::InterfaceTypeEntity::Attribute>::const_iterator i(
    4476         180 :              entity->getDirectAttributes().begin());
    4477         366 :          i != entity->getDirectAttributes().end(); ++i)
    4478             :     {
    4479             :         Member & m(
    4480             :             allMembers.insert(
    4481             :                 std::map<OUString, Member>::value_type(
    4482           6 :                     i->name, Member("")))
    4483           3 :             .first->second);
    4484           3 :         if (m.mandatory.isEmpty()) {
    4485           3 :             m.optional.insert(name);
    4486             :         }
    4487             :     }
    4488        1470 :     for (std::vector<unoidl::InterfaceTypeEntity::Method>::const_iterator i(
    4489         180 :              entity->getDirectMethods().begin());
    4490         980 :          i != entity->getDirectMethods().end(); ++i)
    4491             :     {
    4492             :         Member & m(
    4493             :             allMembers.insert(
    4494             :                 std::map<OUString, Member>::value_type(
    4495         620 :                     i->name, Member("")))
    4496         310 :             .first->second);
    4497         310 :         if (m.mandatory.isEmpty()) {
    4498         244 :             m.optional.insert(name);
    4499             :         }
    4500             :     }
    4501         180 :     return true;
    4502             : }
    4503             : 
    4504       12934 : bool parse(OUString const & uri, SourceProviderScannerData * data) {
    4505             :     assert(data != 0);
    4506             :     oslFileHandle handle;
    4507       12934 :     oslFileError e = osl_openFile(uri.pData, &handle, osl_File_OpenFlag_Read);
    4508       12934 :     switch (e) {
    4509             :     case osl_File_E_None:
    4510        6238 :         break;
    4511             :     case osl_File_E_NOENT:
    4512        6696 :         return false;
    4513             :     default:
    4514           0 :         throw FileFormatException(uri, "cannot open: " + OUString::number(e));
    4515             :     }
    4516             :     sal_uInt64 size;
    4517        6238 :     e = osl_getFileSize(handle, &size);
    4518        6238 :     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        6238 :     e = osl_mapFile(handle, &address, size, 0, osl_File_MapFlag_RandomAccess);
    4528        6238 :     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        6238 :         data->setSource(address, size);
    4537             :         yyscan_t yyscanner;
    4538        6238 :         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        6238 :         int e2 = yyparse(yyscanner);
    4548        6238 :         yylex_destroy(yyscanner);
    4549        6238 :         switch (e2) {
    4550             :         case 0:
    4551        5868 :             break;
    4552             :         default:
    4553             :             assert(false);
    4554             :             // fall through
    4555             :         case 1:
    4556             :             throw FileFormatException(
    4557             :                 uri,
    4558             :                 ("cannot parse"
    4559        1110 :                  + (data->errorLine == 0
    4560         740 :                     ? OUString() : " line " + OUString::number(data->errorLine))
    4561        1110 :                  + (data->parserError.isEmpty()
    4562             :                     ? OUString()
    4563             :                     : (", "
    4564         416 :                        + OStringToOUString(
    4565        1156 :                            data->parserError, osl_getThreadTextEncoding())))
    4566        1110 :                  + (data->errorMessage.isEmpty()
    4567        1480 :                     ? OUString() : ": \"" + data->errorMessage + "\"")));
    4568             :         case 2:
    4569           0 :             throw std::bad_alloc();
    4570             :         }
    4571         370 :     } catch (...) {
    4572         370 :         e = osl_unmapMappedFile(handle, address, size);
    4573             :         SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
    4574         370 :         e = osl_closeFile(handle);
    4575             :         SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
    4576         370 :         throw;
    4577             :     }
    4578        5868 :     e = osl_unmapMappedFile(handle, address, size);
    4579             :     SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot unmap: " << +e);
    4580        5868 :     e = osl_closeFile(handle);
    4581             :     SAL_WARN_IF(e != osl_File_E_None, "unoidl", "cannot close: " << +e);
    4582        5868 :     return true;
    4583             : }
    4584             : 
    4585             : } }
    4586             : 
    4587             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10